19#include "llvm/Analysis/CallGraph.h"
20#include "llvm/Analysis/CallGraphSCCPass.h"
21#include "llvm/Analysis/OptimizationRemarkEmitter.h"
22#include "llvm/Analysis/RegionInfo.h"
23#include "llvm/IR/Dominators.h"
24#include "llvm/IR/PassManager.h"
25#include "llvm/Passes/PassBuilder.h"
26#include "llvm/Transforms/IPO/AlwaysInliner.h"
29#define DEBUG_TYPE "polly-scop-inliner"
38template <
typename SCC_t>
bool runScopInlinerImpl(
Function *F, SCC_t &SCC) {
43 assert(SCC.size() == 1 &&
"found empty SCC");
48 if (F->isDeclaration()) {
50 <<
"because it is a declaration.\n");
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);
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);
75 const bool HasScopAsTopLevelRegion =
79 if (HasScopAsTopLevelRegion) {
81 <<
" has scop as top level region");
82 F->addFnAttr(llvm::Attribute::AlwaysInline);
84 ModulePassManager MPM;
85 MPM.addPass(AlwaysInlinerPass());
87 assert(
M &&
"Function has illegal module");
88 PreservedAnalyses PA = MPM.run(*
M, MAM);
89 if (!PA.areAllPreserved())
93 <<
" does NOT have scop as top level region\n");
99class ScopInlinerWrapperPass final :
public CallGraphSCCPass {
100 using llvm::Pass::doInitialization;
105 ScopInlinerWrapperPass() : CallGraphSCCPass(ID) {}
107 bool doInitialization(CallGraph &CG)
override {
110 "Aborting from ScopInliner because it only makes sense to run with "
111 "-polly-allow-full-function. "
112 "The heurtistic for ScopInliner checks that the full function is a "
113 "Scop, which happens if and only if polly-allow-full-function is "
115 " If not, the entry block is not included in the Scop");
120 bool runOnSCC(CallGraphSCC &SCC)
override {
121 Function *F = (*SCC.begin())->getFunction();
122 return runScopInlinerImpl(F, SCC);
125 void getAnalysisUsage(AnalysisUsage &AU)
const override {
126 CallGraphSCCPass::getAnalysisUsage(AU);
130char ScopInlinerWrapperPass::ID;
133 ScopInlinerWrapperPass *pass =
new ScopInlinerWrapperPass();
138 ScopInlinerWrapperPass,
"polly-scop-inliner",
139 "inline functions based on how much of the function is a scop.",
false,
142 ScopInlinerWrapperPass,
"polly-scop-inliner",
143 "inline functions based on how much of the function is a scop.",
false,
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 "
154 " If not, the entry block is not included in the Scop");
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();
INITIALIZE_PASS_END(DependenceInfo, "polly-dependences", "Polly - Calculate dependences", false, false) namespace
polly dump Polly Dump Function
polly dump Polly Dump Module
static RegisterPass< ScopPrinterWrapperPass > M("dot-scops", "Polly - Print Scops of function")
INITIALIZE_PASS_BEGIN(ScopInlinerWrapperPass, "polly-scop-inliner", "inline functions based on how much of the function is a scop.", false, false) INITIALIZE_PASS_END(ScopInlinerWrapperPass
Pass to detect the maximal static control parts (Scops) of a function.
llvm::PreservedAnalyses run(llvm::LazyCallGraph::SCC &C, llvm::CGSCCAnalysisManager &AM, llvm::LazyCallGraph &CG, llvm::CGSCCUpdateResult &UR)
bool PollyAllowFullFunction
llvm::Pass * createScopInlinerWrapperPass()