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