LLVM 23.0.0git
LoopExtractor.cpp
Go to the documentation of this file.
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
17#include "llvm/ADT/Statistic.h"
20#include "llvm/IR/Dominators.h"
22#include "llvm/IR/Module.h"
23#include "llvm/IR/PassManager.h"
25#include "llvm/Pass.h"
26#include "llvm/Transforms/IPO.h"
29using namespace llvm;
30
31#define DEBUG_TYPE "loop-extract"
32
33STATISTIC(NumExtracted, "Number of loops extracted");
34
35namespace {
36struct 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
44 bool runOnModule(Module &M) override;
45
46 void getAnalysisUsage(AnalysisUsage &AU) const override {
48 AU.addRequired<DominatorTreeWrapperPass>();
49 AU.addRequired<LoopInfoWrapperPass>();
50 AU.addPreserved<LoopInfoWrapperPass>();
52 AU.addUsedIfAvailable<AssumptionCacheTracker>();
53 }
54};
55
56struct LoopExtractor {
57 explicit LoopExtractor(
58 unsigned NumLoops,
59 function_ref<DominatorTree &(Function &)> LookupDomTree,
60 function_ref<LoopInfo &(Function &)> LookupLoopInfo,
61 function_ref<AssumptionCache *(Function &)> LookupAssumptionCache)
62 : NumLoops(NumLoops), LookupDomTree(LookupDomTree),
63 LookupLoopInfo(LookupLoopInfo),
64 LookupAssumptionCache(LookupAssumptionCache) {}
65 bool runOnModule(Module &M);
66
67private:
68 // The number of natural loops to extract from the program into functions.
69 unsigned NumLoops;
70
71 function_ref<DominatorTree &(Function &)> LookupDomTree;
72 function_ref<LoopInfo &(Function &)> LookupLoopInfo;
73 function_ref<AssumptionCache *(Function &)> LookupAssumptionCache;
74
75 bool runOnFunction(Function &F);
76
77 bool extractLoops(Loop::iterator From, Loop::iterator To, LoopInfo &LI,
78 DominatorTree &DT);
79 bool extractLoop(Loop *L, LoopInfo &LI, DominatorTree &DT);
80};
81} // namespace
82
83char LoopExtractorLegacyPass::ID = 0;
84INITIALIZE_PASS_BEGIN(LoopExtractorLegacyPass, "loop-extract",
85 "Extract loops into new functions", false, false)
86INITIALIZE_PASS_DEPENDENCY(BreakCriticalEdges)
90INITIALIZE_PASS_END(LoopExtractorLegacyPass, "loop-extract",
91 "Extract loops into new functions", false, false)
92
93namespace {
94 /// SingleLoopExtractor - For bugpoint.
95struct SingleLoopExtractor : public LoopExtractorLegacyPass {
96 static char ID; // Pass identification, replacement for typeid
97 SingleLoopExtractor() : LoopExtractorLegacyPass(1) {}
98};
99} // End anonymous namespace
100
101char SingleLoopExtractor::ID = 0;
102INITIALIZE_PASS(SingleLoopExtractor, "loop-extract-single",
103 "Extract at most one loop into a new function", false, false)
104
105// createLoopExtractorPass - This pass extracts all natural loops from the
106// program into a function if it can.
107//
108Pass *llvm::createLoopExtractorPass() { return new LoopExtractorLegacyPass(); }
109
110bool LoopExtractorLegacyPass::runOnModule(Module &M) {
111 if (skipModule(M))
112 return false;
113
114 bool Changed = false;
115 auto LookupDomTree = [this](Function &F) -> DominatorTree & {
116 return this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
117 };
118 auto LookupLoopInfo = [this, &Changed](Function &F) -> LoopInfo & {
119 return this->getAnalysis<LoopInfoWrapperPass>(F, &Changed).getLoopInfo();
120 };
121 auto LookupACT = [this](Function &F) -> AssumptionCache * {
122 if (auto *ACT = this->getAnalysisIfAvailable<AssumptionCacheTracker>())
123 return ACT->lookupAssumptionCache(F);
124 return nullptr;
125 };
126 return LoopExtractor(NumLoops, LookupDomTree, LookupLoopInfo, LookupACT)
127 .runOnModule(M) ||
128 Changed;
129}
130
131bool LoopExtractor::runOnModule(Module &M) {
132 if (M.empty())
133 return false;
134
135 if (!NumLoops)
136 return false;
137
138 bool Changed = false;
139
140 // The end of the function list may change (new functions will be added at the
141 // end), so we run from the first to the current last.
142 auto I = M.begin(), E = --M.end();
143 while (true) {
144 Function &F = *I;
145
147 if (!NumLoops)
148 break;
149
150 // If this is the last function.
151 if (I == E)
152 break;
153
154 ++I;
155 }
156 return Changed;
157}
158
159bool LoopExtractor::runOnFunction(Function &F) {
160 // Do not modify `optnone` functions.
161 if (F.hasOptNone())
162 return false;
163
164 if (F.empty())
165 return false;
166
167 bool Changed = false;
168 LoopInfo &LI = LookupLoopInfo(F);
169
170 // If there are no loops in the function.
171 if (LI.empty())
172 return Changed;
173
174 DominatorTree &DT = LookupDomTree(F);
175
176 // If there is more than one top-level loop in this function, extract all of
177 // the loops.
178 if (std::next(LI.begin()) != LI.end())
179 return Changed | extractLoops(LI.begin(), LI.end(), LI, DT);
180
181 // Otherwise there is exactly one top-level loop.
182 Loop *TLL = *LI.begin();
183
184 // If the loop is in LoopSimplify form, then extract it only if this function
185 // is more than a minimal wrapper around the loop.
186 if (TLL->isLoopSimplifyForm()) {
187 bool ShouldExtractLoop = false;
188
189 // Extract the loop if the entry block doesn't branch to the loop header.
190 Instruction *EntryTI = F.getEntryBlock().getTerminator();
191 if (!isa<BranchInst>(EntryTI) ||
192 !cast<BranchInst>(EntryTI)->isUnconditional() ||
193 EntryTI->getSuccessor(0) != TLL->getHeader()) {
194 ShouldExtractLoop = true;
195 } else {
196 // Check to see if any exits from the loop are more than just return
197 // blocks.
198 SmallVector<BasicBlock *, 8> ExitBlocks;
199 TLL->getExitBlocks(ExitBlocks);
200 for (auto *ExitBlock : ExitBlocks)
201 if (!isa<ReturnInst>(ExitBlock->getTerminator())) {
202 ShouldExtractLoop = true;
203 break;
204 }
205 }
206
207 if (ShouldExtractLoop)
208 return Changed | extractLoop(TLL, LI, DT);
209 }
210
211 // Okay, this function is a minimal container around the specified loop.
212 // If we extract the loop, we will continue to just keep extracting it
213 // infinitely... so don't extract it. However, if the loop contains any
214 // sub-loops, extract them.
215 return Changed | extractLoops(TLL->begin(), TLL->end(), LI, DT);
216}
217
218bool LoopExtractor::extractLoops(Loop::iterator From, Loop::iterator To,
219 LoopInfo &LI, DominatorTree &DT) {
220 bool Changed = false;
221 SmallVector<Loop *, 8> Loops;
222
223 // Save the list of loops, as it may change.
224 Loops.assign(From, To);
225 for (Loop *L : Loops) {
226 // If LoopSimplify form is not available, stay out of trouble.
227 if (!L->isLoopSimplifyForm())
228 continue;
229
230 Changed |= extractLoop(L, LI, DT);
231 if (!NumLoops)
232 break;
233 }
234 return Changed;
235}
236
237bool LoopExtractor::extractLoop(Loop *L, LoopInfo &LI, DominatorTree &DT) {
238 assert(NumLoops != 0);
239 Function &Func = *L->getHeader()->getParent();
240 AssumptionCache *AC = LookupAssumptionCache(Func);
241 CodeExtractorAnalysisCache CEAC(Func);
242 CodeExtractor Extractor(L->getBlocks(), &DT, false, nullptr, nullptr, AC);
243 if (Extractor.extractCodeRegion(CEAC)) {
244 LI.erase(L);
245 --NumLoops;
246 ++NumExtracted;
247 return true;
248 }
249 return false;
250}
251
252// createSingleLoopExtractorPass - This pass extracts one natural loop from the
253// program into a function if it can. This is used by bugpoint.
254//
256 return new SingleLoopExtractor();
257}
258
260 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
261 auto LookupDomTree = [&FAM](Function &F) -> DominatorTree & {
262 return FAM.getResult<DominatorTreeAnalysis>(F);
263 };
264 auto LookupLoopInfo = [&FAM](Function &F) -> LoopInfo & {
265 return FAM.getResult<LoopAnalysis>(F);
266 };
267 auto LookupAssumptionCache = [&FAM](Function &F) -> AssumptionCache * {
268 return FAM.getCachedResult<AssumptionAnalysis>(F);
269 };
270 if (!LoopExtractor(NumLoops, LookupDomTree, LookupLoopInfo,
271 LookupAssumptionCache)
272 .runOnModule(M))
273 return PreservedAnalyses::all();
274
277 return PA;
278}
279
281 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
283 OS, MapClassName2PassName);
284 OS << '<';
285 if (NumLoops == 1)
286 OS << "single";
287 OS << '>';
288}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool runOnFunction(Function &F, bool PostInlining)
Hexagon Hardware Loops
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM_ABI AnalysisUsage & addRequiredID(const void *ID)
Definition Pass.cpp:284
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
Analysis pass which computes a DominatorTree.
Definition Dominators.h:283
Legacy analysis pass which computes a DominatorTree.
Definition Dominators.h:321
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:164
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
Analysis pass that exposes the LoopInfo for a function.
Definition LoopInfo.h:569
void getExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all of the successor blocks of this loop.
BlockT * getHeader() const
iterator end() const
iterator begin() const
iterator end() const
iterator begin() const
The legacy pass manager's analysis pass to compute loop information.
Definition LoopInfo.h:596
LLVM_ABI void erase(Loop *L)
Update LoopInfo after removing the last backedge from a loop.
Definition LoopInfo.cpp:909
bool isLoopSimplifyForm() const
Return true if the Loop is in the form that the LoopSimplify form transforms loops to,...
Definition LoopInfo.cpp:502
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition Pass.h:255
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
Pass interface - Implemented by all 'passes'.
Definition Pass.h:99
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Changed
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
NodeAddr< FuncNode * > Func
Definition RDFGraph.h:393
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
LLVM_ABI char & LoopSimplifyID
LLVM_ABI Pass * createLoopExtractorPass()
createLoopExtractorPass - This pass extracts all natural loops from the program into a function if it...
LLVM_ABI char & BreakCriticalEdgesID
LLVM_ABI Pass * createSingleLoopExtractorPass()
createSingleLoopExtractorPass - This pass extracts one natural loop from the program into a function ...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition PassManager.h:70