1313//
1414// ===----------------------------------------------------------------------===//
1515
16- #include " polly/ScopInliner .h"
16+ #include " polly/LinkAllPasses .h"
1717#include " polly/ScopDetection.h"
18- #include " polly/ScopInliner.h"
1918#include " llvm/Analysis/CallGraph.h"
2019#include " llvm/Analysis/CallGraphSCCPass.h"
21- #include " llvm/Analysis/OptimizationRemarkEmitter.h"
22- #include " llvm/Analysis/RegionInfo.h"
23- #include " llvm/IR/Dominators.h"
2420#include " llvm/IR/PassManager.h"
2521#include " llvm/Passes/PassBuilder.h"
2622#include " llvm/Transforms/IPO/AlwaysInliner.h"
@@ -32,77 +28,13 @@ using namespace llvm;
3228using namespace polly ;
3329
3430namespace {
35-
36- // / Inliner implementation that works with both, LPM (using SCC_t=CallGraph) and
37- // / NPM (using SCC_t=LazyCallGraph::SCC)
38- template <typename SCC_t> bool runScopInlinerImpl (Function *F, SCC_t &SCC) {
39- // We do not try to inline non-trivial SCCs because this would lead to
40- // "infinite" inlining if we are not careful.
41- if (SCC.size () > 1 )
42- return false ;
43- assert (SCC.size () == 1 && " found empty SCC" );
44-
45- // If the function is a nullptr, or the function is a declaration.
46- if (!F)
47- return false ;
48- if (F->isDeclaration ()) {
49- POLLY_DEBUG (dbgs () << " Skipping " << F->getName ()
50- << " because it is a declaration.\n " );
51- return false ;
52- }
53-
54- PassBuilder PB;
55- // Populate analysis managers and register Polly-specific analyses.
56- LoopAnalysisManager LAM;
57- FunctionAnalysisManager FAM;
58- CGSCCAnalysisManager CGAM;
59- ModuleAnalysisManager MAM;
60- PB.registerModuleAnalyses (MAM);
61- PB.registerCGSCCAnalyses (CGAM);
62- PB.registerFunctionAnalyses (FAM);
63- PB.registerLoopAnalyses (LAM);
64- PB.crossRegisterProxies (LAM, FAM, CGAM, MAM);
65-
66- auto &DT = FAM.getResult <DominatorTreeAnalysis>(*F);
67- auto &SE = FAM.getResult <ScalarEvolutionAnalysis>(*F);
68- auto &LI = FAM.getResult <LoopAnalysis>(*F);
69- auto &RI = FAM.getResult <RegionInfoAnalysis>(*F);
70- auto &AA = FAM.getResult <AAManager>(*F);
71- auto &ORE = FAM.getResult <OptimizationRemarkEmitterAnalysis>(*F);
72- ScopDetection SD (DT, SE, LI, RI, AA, ORE);
73- SD.detect (*F);
74-
75- const bool HasScopAsTopLevelRegion =
76- SD.ValidRegions .contains (RI.getTopLevelRegion ());
77-
78- bool Changed = false ;
79- if (HasScopAsTopLevelRegion) {
80- POLLY_DEBUG (dbgs () << " Skipping " << F->getName ()
81- << " has scop as top level region" );
82- F->addFnAttr (llvm::Attribute::AlwaysInline);
83-
84- ModulePassManager MPM;
85- MPM.addPass (AlwaysInlinerPass ());
86- Module *M = F->getParent ();
87- assert (M && " Function has illegal module" );
88- PreservedAnalyses PA = MPM.run (*M, MAM);
89- if (!PA.areAllPreserved ())
90- Changed = true ;
91- } else {
92- POLLY_DEBUG (dbgs () << F->getName ()
93- << " does NOT have scop as top level region\n " );
94- }
95-
96- return Changed;
97- }
98-
99- class ScopInlinerWrapperPass final : public CallGraphSCCPass {
31+ class ScopInliner final : public CallGraphSCCPass {
10032 using llvm::Pass::doInitialization;
10133
10234public:
10335 static char ID;
10436
105- ScopInlinerWrapperPass () : CallGraphSCCPass(ID) {}
37+ ScopInliner () : CallGraphSCCPass(ID) {}
10638
10739 bool doInitialization (CallGraph &CG) override {
10840 if (!polly::PollyAllowFullFunction) {
@@ -118,48 +50,79 @@ class ScopInlinerWrapperPass final : public CallGraphSCCPass {
11850 }
11951
12052 bool runOnSCC (CallGraphSCC &SCC) override {
53+ // We do not try to inline non-trivial SCCs because this would lead to
54+ // "infinite" inlining if we are not careful.
55+ if (SCC.size () > 1 )
56+ return false ;
57+ assert (SCC.size () == 1 && " found empty SCC" );
12158 Function *F = (*SCC.begin ())->getFunction ();
122- return runScopInlinerImpl (F, SCC);
59+
60+ // If the function is a nullptr, or the function is a declaration.
61+ if (!F)
62+ return false ;
63+ if (F->isDeclaration ()) {
64+ POLLY_DEBUG (dbgs () << " Skipping " << F->getName ()
65+ << " because it is a declaration.\n " );
66+ return false ;
67+ }
68+
69+ PassBuilder PB;
70+ // Populate analysis managers and register Polly-specific analyses.
71+ LoopAnalysisManager LAM;
72+ FunctionAnalysisManager FAM;
73+ CGSCCAnalysisManager CGAM;
74+ ModuleAnalysisManager MAM;
75+ FAM.registerPass ([] { return ScopAnalysis (); });
76+ PB.registerModuleAnalyses (MAM);
77+ PB.registerCGSCCAnalyses (CGAM);
78+ PB.registerFunctionAnalyses (FAM);
79+ PB.registerLoopAnalyses (LAM);
80+ PB.crossRegisterProxies (LAM, FAM, CGAM, MAM);
81+
82+ RegionInfo &RI = FAM.getResult <RegionInfoAnalysis>(*F);
83+ ScopDetection &SD = FAM.getResult <ScopAnalysis>(*F);
84+
85+ const bool HasScopAsTopLevelRegion =
86+ SD.ValidRegions .contains (RI.getTopLevelRegion ());
87+
88+ bool Changed = false ;
89+ if (HasScopAsTopLevelRegion) {
90+ POLLY_DEBUG (dbgs () << " Skipping " << F->getName ()
91+ << " has scop as top level region" );
92+ F->addFnAttr (llvm::Attribute::AlwaysInline);
93+
94+ ModulePassManager MPM;
95+ MPM.addPass (AlwaysInlinerPass ());
96+ Module *M = F->getParent ();
97+ assert (M && " Function has illegal module" );
98+ PreservedAnalyses PA = MPM.run (*M, MAM);
99+ if (!PA.areAllPreserved ())
100+ Changed = true ;
101+ } else {
102+ POLLY_DEBUG (dbgs () << F->getName ()
103+ << " does NOT have scop as top level region\n " );
104+ }
105+
106+ return Changed;
123107 };
124108
125109 void getAnalysisUsage (AnalysisUsage &AU) const override {
126110 CallGraphSCCPass::getAnalysisUsage (AU);
127111 }
128112};
129113} // namespace
130- char ScopInlinerWrapperPass ::ID;
114+ char ScopInliner ::ID;
131115
132- Pass *polly::createScopInlinerWrapperPass () {
133- ScopInlinerWrapperPass *pass = new ScopInlinerWrapperPass ();
116+ Pass *polly::createScopInlinerPass () {
117+ ScopInliner *pass = new ScopInliner ();
134118 return pass;
135119}
136120
137121INITIALIZE_PASS_BEGIN (
138- ScopInlinerWrapperPass , " polly-scop-inliner" ,
122+ ScopInliner , " polly-scop-inliner" ,
139123 " inline functions based on how much of the function is a scop." , false ,
140124 false )
141125INITIALIZE_PASS_END(
142- ScopInlinerWrapperPass , " polly-scop-inliner" ,
126+ ScopInliner , " polly-scop-inliner" ,
143127 " inline functions based on how much of the function is a scop." , false ,
144128 false )
145-
146- polly::ScopInlinerPass::ScopInlinerPass() {
147- if (!polly::PollyAllowFullFunction) {
148- report_fatal_error (
149- " Aborting from ScopInliner because it only makes sense to run with "
150- " -polly-allow-full-function. "
151- " The heurtistic for ScopInliner checks that the full function is a "
152- " Scop, which happens if and only if polly-allow-full-function is "
153- " enabled. "
154- " If not, the entry block is not included in the Scop" );
155- }
156- }
157-
158- PreservedAnalyses polly::ScopInlinerPass::run (llvm::LazyCallGraph::SCC &SCC,
159- llvm::CGSCCAnalysisManager &AM,
160- llvm::LazyCallGraph &CG,
161- llvm::CGSCCUpdateResult &UR) {
162- Function *F = &SCC.begin ()->getFunction ();
163- bool Changed = runScopInlinerImpl (F, SCC);
164- return Changed ? PreservedAnalyses::none () : PreservedAnalyses::all ();
165- }
0 commit comments