WarnMissedTransforms.cpp revision 360784
1//===- LoopTransformWarning.cpp -  ----------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Emit warnings if forced code transformations have not been performed.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/Transforms/Scalar/WarnMissedTransforms.h"
14#include "llvm/Analysis/OptimizationRemarkEmitter.h"
15#include "llvm/InitializePasses.h"
16#include "llvm/Transforms/Utils/LoopUtils.h"
17
18using namespace llvm;
19
20#define DEBUG_TYPE "transform-warning"
21
22/// Emit warnings for forced (i.e. user-defined) loop transformations which have
23/// still not been performed.
24static void warnAboutLeftoverTransformations(Loop *L,
25                                             OptimizationRemarkEmitter *ORE) {
26  if (hasUnrollTransformation(L) == TM_ForcedByUser) {
27    LLVM_DEBUG(dbgs() << "Leftover unroll transformation\n");
28    ORE->emit(
29        DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
30                                          "FailedRequestedUnrolling",
31                                          L->getStartLoc(), L->getHeader())
32        << "loop not unrolled: the optimizer was unable to perform the "
33           "requested transformation; the transformation might be disabled or "
34           "specified as part of an unsupported transformation ordering");
35  }
36
37  if (hasUnrollAndJamTransformation(L) == TM_ForcedByUser) {
38    LLVM_DEBUG(dbgs() << "Leftover unroll-and-jam transformation\n");
39    ORE->emit(
40        DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
41                                          "FailedRequestedUnrollAndJamming",
42                                          L->getStartLoc(), L->getHeader())
43        << "loop not unroll-and-jammed: the optimizer was unable to perform "
44           "the requested transformation; the transformation might be disabled "
45           "or specified as part of an unsupported transformation ordering");
46  }
47
48  if (hasVectorizeTransformation(L) == TM_ForcedByUser) {
49    LLVM_DEBUG(dbgs() << "Leftover vectorization transformation\n");
50    Optional<int> VectorizeWidth =
51        getOptionalIntLoopAttribute(L, "llvm.loop.vectorize.width");
52    Optional<int> InterleaveCount =
53        getOptionalIntLoopAttribute(L, "llvm.loop.interleave.count");
54
55    if (VectorizeWidth.getValueOr(0) != 1)
56      ORE->emit(
57          DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
58                                            "FailedRequestedVectorization",
59                                            L->getStartLoc(), L->getHeader())
60          << "loop not vectorized: the optimizer was unable to perform the "
61             "requested transformation; the transformation might be disabled "
62             "or specified as part of an unsupported transformation ordering");
63    else if (InterleaveCount.getValueOr(0) != 1)
64      ORE->emit(
65          DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
66                                            "FailedRequestedInterleaving",
67                                            L->getStartLoc(), L->getHeader())
68          << "loop not interleaved: the optimizer was unable to perform the "
69             "requested transformation; the transformation might be disabled "
70             "or specified as part of an unsupported transformation ordering");
71  }
72
73  if (hasDistributeTransformation(L) == TM_ForcedByUser) {
74    LLVM_DEBUG(dbgs() << "Leftover distribute transformation\n");
75    ORE->emit(
76        DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
77                                          "FailedRequestedDistribution",
78                                          L->getStartLoc(), L->getHeader())
79        << "loop not distributed: the optimizer was unable to perform the "
80           "requested transformation; the transformation might be disabled or "
81           "specified as part of an unsupported transformation ordering");
82  }
83}
84
85static void warnAboutLeftoverTransformations(Function *F, LoopInfo *LI,
86                                             OptimizationRemarkEmitter *ORE) {
87  for (auto *L : LI->getLoopsInPreorder())
88    warnAboutLeftoverTransformations(L, ORE);
89}
90
91// New pass manager boilerplate
92PreservedAnalyses
93WarnMissedTransformationsPass::run(Function &F, FunctionAnalysisManager &AM) {
94  // Do not warn about not applied transformations if optimizations are
95  // disabled.
96  if (F.hasOptNone())
97    return PreservedAnalyses::all();
98
99  auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
100  auto &LI = AM.getResult<LoopAnalysis>(F);
101
102  warnAboutLeftoverTransformations(&F, &LI, &ORE);
103
104  return PreservedAnalyses::all();
105}
106
107// Legacy pass manager boilerplate
108namespace {
109class WarnMissedTransformationsLegacy : public FunctionPass {
110public:
111  static char ID;
112
113  explicit WarnMissedTransformationsLegacy() : FunctionPass(ID) {
114    initializeWarnMissedTransformationsLegacyPass(
115        *PassRegistry::getPassRegistry());
116  }
117
118  bool runOnFunction(Function &F) override {
119    if (skipFunction(F))
120      return false;
121
122    auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
123    auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
124
125    warnAboutLeftoverTransformations(&F, &LI, &ORE);
126    return false;
127  }
128
129  void getAnalysisUsage(AnalysisUsage &AU) const override {
130    AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
131    AU.addRequired<LoopInfoWrapperPass>();
132
133    AU.setPreservesAll();
134  }
135};
136} // end anonymous namespace
137
138char WarnMissedTransformationsLegacy::ID = 0;
139
140INITIALIZE_PASS_BEGIN(WarnMissedTransformationsLegacy, "transform-warning",
141                      "Warn about non-applied transformations", false, false)
142INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
143INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
144INITIALIZE_PASS_END(WarnMissedTransformationsLegacy, "transform-warning",
145                    "Warn about non-applied transformations", false, false)
146
147Pass *llvm::createWarnMissedTransformationsPass() {
148  return new WarnMissedTransformationsLegacy();
149}
150