xref: /freebsd/contrib/llvm-project/llvm/lib/Transforms/IPO/LoopExtractor.cpp (revision 59c8e88e72633afbc47a4ace0d2170d00d51f7dc)
1 //===- LoopExtractor.cpp - Extract each loop into a new function ----------===//
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 // A pass wrapper around the ExtractLoop() scalar transformation to extract each
10 // top-level loop into its own new function. If the loop is the ONLY loop in a
11 // given function, it is not touched. This is a pass most useful for debugging
12 // via bugpoint.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "llvm/Transforms/IPO/LoopExtractor.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/Analysis/AssumptionCache.h"
19 #include "llvm/Analysis/LoopInfo.h"
20 #include "llvm/IR/Dominators.h"
21 #include "llvm/IR/Instructions.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/IR/PassManager.h"
24 #include "llvm/InitializePasses.h"
25 #include "llvm/Pass.h"
26 #include "llvm/Transforms/IPO.h"
27 #include "llvm/Transforms/Utils.h"
28 #include "llvm/Transforms/Utils/CodeExtractor.h"
29 using namespace llvm;
30 
31 #define DEBUG_TYPE "loop-extract"
32 
33 STATISTIC(NumExtracted, "Number of loops extracted");
34 
35 namespace {
36 struct LoopExtractorLegacyPass : public ModulePass {
37   static char ID; // Pass identification, replacement for typeid
38 
39   unsigned NumLoops;
40 
41   explicit LoopExtractorLegacyPass(unsigned NumLoops = ~0)
42       : ModulePass(ID), NumLoops(NumLoops) {
43     initializeLoopExtractorLegacyPassPass(*PassRegistry::getPassRegistry());
44   }
45 
46   bool runOnModule(Module &M) override;
47 
48   void getAnalysisUsage(AnalysisUsage &AU) const override {
49     AU.addRequiredID(BreakCriticalEdgesID);
50     AU.addRequired<DominatorTreeWrapperPass>();
51     AU.addRequired<LoopInfoWrapperPass>();
52     AU.addPreserved<LoopInfoWrapperPass>();
53     AU.addRequiredID(LoopSimplifyID);
54     AU.addUsedIfAvailable<AssumptionCacheTracker>();
55   }
56 };
57 
58 struct LoopExtractor {
59   explicit LoopExtractor(
60       unsigned NumLoops,
61       function_ref<DominatorTree &(Function &)> LookupDomTree,
62       function_ref<LoopInfo &(Function &)> LookupLoopInfo,
63       function_ref<AssumptionCache *(Function &)> LookupAssumptionCache)
64       : NumLoops(NumLoops), LookupDomTree(LookupDomTree),
65         LookupLoopInfo(LookupLoopInfo),
66         LookupAssumptionCache(LookupAssumptionCache) {}
67   bool runOnModule(Module &M);
68 
69 private:
70   // The number of natural loops to extract from the program into functions.
71   unsigned NumLoops;
72 
73   function_ref<DominatorTree &(Function &)> LookupDomTree;
74   function_ref<LoopInfo &(Function &)> LookupLoopInfo;
75   function_ref<AssumptionCache *(Function &)> LookupAssumptionCache;
76 
77   bool runOnFunction(Function &F);
78 
79   bool extractLoops(Loop::iterator From, Loop::iterator To, LoopInfo &LI,
80                     DominatorTree &DT);
81   bool extractLoop(Loop *L, LoopInfo &LI, DominatorTree &DT);
82 };
83 } // namespace
84 
85 char LoopExtractorLegacyPass::ID = 0;
86 INITIALIZE_PASS_BEGIN(LoopExtractorLegacyPass, "loop-extract",
87                       "Extract loops into new functions", false, false)
88 INITIALIZE_PASS_DEPENDENCY(BreakCriticalEdges)
89 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
90 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
91 INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
92 INITIALIZE_PASS_END(LoopExtractorLegacyPass, "loop-extract",
93                     "Extract loops into new functions", false, false)
94 
95 namespace {
96   /// SingleLoopExtractor - For bugpoint.
97 struct SingleLoopExtractor : public LoopExtractorLegacyPass {
98   static char ID; // Pass identification, replacement for typeid
99   SingleLoopExtractor() : LoopExtractorLegacyPass(1) {}
100 };
101 } // End anonymous namespace
102 
103 char SingleLoopExtractor::ID = 0;
104 INITIALIZE_PASS(SingleLoopExtractor, "loop-extract-single",
105                 "Extract at most one loop into a new function", false, false)
106 
107 // createLoopExtractorPass - This pass extracts all natural loops from the
108 // program into a function if it can.
109 //
110 Pass *llvm::createLoopExtractorPass() { return new LoopExtractorLegacyPass(); }
111 
112 bool LoopExtractorLegacyPass::runOnModule(Module &M) {
113   if (skipModule(M))
114     return false;
115 
116   bool Changed = false;
117   auto LookupDomTree = [this](Function &F) -> DominatorTree & {
118     return this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
119   };
120   auto LookupLoopInfo = [this, &Changed](Function &F) -> LoopInfo & {
121     return this->getAnalysis<LoopInfoWrapperPass>(F, &Changed).getLoopInfo();
122   };
123   auto LookupACT = [this](Function &F) -> AssumptionCache * {
124     if (auto *ACT = this->getAnalysisIfAvailable<AssumptionCacheTracker>())
125       return ACT->lookupAssumptionCache(F);
126     return nullptr;
127   };
128   return LoopExtractor(NumLoops, LookupDomTree, LookupLoopInfo, LookupACT)
129              .runOnModule(M) ||
130          Changed;
131 }
132 
133 bool LoopExtractor::runOnModule(Module &M) {
134   if (M.empty())
135     return false;
136 
137   if (!NumLoops)
138     return false;
139 
140   bool Changed = false;
141 
142   // The end of the function list may change (new functions will be added at the
143   // end), so we run from the first to the current last.
144   auto I = M.begin(), E = --M.end();
145   while (true) {
146     Function &F = *I;
147 
148     Changed |= runOnFunction(F);
149     if (!NumLoops)
150       break;
151 
152     // If this is the last function.
153     if (I == E)
154       break;
155 
156     ++I;
157   }
158   return Changed;
159 }
160 
161 bool LoopExtractor::runOnFunction(Function &F) {
162   // Do not modify `optnone` functions.
163   if (F.hasOptNone())
164     return false;
165 
166   if (F.empty())
167     return false;
168 
169   bool Changed = false;
170   LoopInfo &LI = LookupLoopInfo(F);
171 
172   // If there are no loops in the function.
173   if (LI.empty())
174     return Changed;
175 
176   DominatorTree &DT = LookupDomTree(F);
177 
178   // If there is more than one top-level loop in this function, extract all of
179   // the loops.
180   if (std::next(LI.begin()) != LI.end())
181     return Changed | extractLoops(LI.begin(), LI.end(), LI, DT);
182 
183   // Otherwise there is exactly one top-level loop.
184   Loop *TLL = *LI.begin();
185 
186   // If the loop is in LoopSimplify form, then extract it only if this function
187   // is more than a minimal wrapper around the loop.
188   if (TLL->isLoopSimplifyForm()) {
189     bool ShouldExtractLoop = false;
190 
191     // Extract the loop if the entry block doesn't branch to the loop header.
192     Instruction *EntryTI = F.getEntryBlock().getTerminator();
193     if (!isa<BranchInst>(EntryTI) ||
194         !cast<BranchInst>(EntryTI)->isUnconditional() ||
195         EntryTI->getSuccessor(0) != TLL->getHeader()) {
196       ShouldExtractLoop = true;
197     } else {
198       // Check to see if any exits from the loop are more than just return
199       // blocks.
200       SmallVector<BasicBlock *, 8> ExitBlocks;
201       TLL->getExitBlocks(ExitBlocks);
202       for (auto *ExitBlock : ExitBlocks)
203         if (!isa<ReturnInst>(ExitBlock->getTerminator())) {
204           ShouldExtractLoop = true;
205           break;
206         }
207     }
208 
209     if (ShouldExtractLoop)
210       return Changed | extractLoop(TLL, LI, DT);
211   }
212 
213   // Okay, this function is a minimal container around the specified loop.
214   // If we extract the loop, we will continue to just keep extracting it
215   // infinitely... so don't extract it. However, if the loop contains any
216   // sub-loops, extract them.
217   return Changed | extractLoops(TLL->begin(), TLL->end(), LI, DT);
218 }
219 
220 bool LoopExtractor::extractLoops(Loop::iterator From, Loop::iterator To,
221                                  LoopInfo &LI, DominatorTree &DT) {
222   bool Changed = false;
223   SmallVector<Loop *, 8> Loops;
224 
225   // Save the list of loops, as it may change.
226   Loops.assign(From, To);
227   for (Loop *L : Loops) {
228     // If LoopSimplify form is not available, stay out of trouble.
229     if (!L->isLoopSimplifyForm())
230       continue;
231 
232     Changed |= extractLoop(L, LI, DT);
233     if (!NumLoops)
234       break;
235   }
236   return Changed;
237 }
238 
239 bool LoopExtractor::extractLoop(Loop *L, LoopInfo &LI, DominatorTree &DT) {
240   assert(NumLoops != 0);
241   Function &Func = *L->getHeader()->getParent();
242   AssumptionCache *AC = LookupAssumptionCache(Func);
243   CodeExtractorAnalysisCache CEAC(Func);
244   CodeExtractor Extractor(DT, *L, false, nullptr, nullptr, AC);
245   if (Extractor.extractCodeRegion(CEAC)) {
246     LI.erase(L);
247     --NumLoops;
248     ++NumExtracted;
249     return true;
250   }
251   return false;
252 }
253 
254 // createSingleLoopExtractorPass - This pass extracts one natural loop from the
255 // program into a function if it can.  This is used by bugpoint.
256 //
257 Pass *llvm::createSingleLoopExtractorPass() {
258   return new SingleLoopExtractor();
259 }
260 
261 PreservedAnalyses LoopExtractorPass::run(Module &M, ModuleAnalysisManager &AM) {
262   auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
263   auto LookupDomTree = [&FAM](Function &F) -> DominatorTree & {
264     return FAM.getResult<DominatorTreeAnalysis>(F);
265   };
266   auto LookupLoopInfo = [&FAM](Function &F) -> LoopInfo & {
267     return FAM.getResult<LoopAnalysis>(F);
268   };
269   auto LookupAssumptionCache = [&FAM](Function &F) -> AssumptionCache * {
270     return FAM.getCachedResult<AssumptionAnalysis>(F);
271   };
272   if (!LoopExtractor(NumLoops, LookupDomTree, LookupLoopInfo,
273                      LookupAssumptionCache)
274            .runOnModule(M))
275     return PreservedAnalyses::all();
276 
277   PreservedAnalyses PA;
278   PA.preserve<LoopAnalysis>();
279   return PA;
280 }
281 
282 void LoopExtractorPass::printPipeline(
283     raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
284   static_cast<PassInfoMixin<LoopExtractorPass> *>(this)->printPipeline(
285       OS, MapClassName2PassName);
286   OS << '<';
287   if (NumLoops == 1)
288     OS << "single";
289   OS << '>';
290 }
291