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/Passes/PassBuilder.h"
25#include "llvm/Transforms/IPO/AlwaysInliner.h"
28#define DEBUG_TYPE "polly-scop-inliner"
37template <
typename SCC_t>
38bool runScopInlinerImpl(Function *F, SCC_t &SCC,
39 IntrusiveRefCntPtr<vfs::FileSystem> FS) {
44 assert(SCC.size() == 1 &&
"found empty SCC");
49 if (F->isDeclaration()) {
51 <<
"because it is a declaration.\n");
55 PassBuilder PB(F->getContext(),
nullptr, std::nullopt,
57 nullptr, std::move(FS));
59 LoopAnalysisManager LAM;
60 FunctionAnalysisManager FAM;
61 CGSCCAnalysisManager CGAM;
62 ModuleAnalysisManager MAM;
63 PB.registerModuleAnalyses(MAM);
64 PB.registerCGSCCAnalyses(CGAM);
65 PB.registerFunctionAnalyses(FAM);
66 PB.registerLoopAnalyses(LAM);
67 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
69 auto &DT = FAM.getResult<DominatorTreeAnalysis>(*F);
70 auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(*F);
71 auto &LI = FAM.getResult<LoopAnalysis>(*F);
72 auto &RI = FAM.getResult<RegionInfoAnalysis>(*F);
73 auto &AA = FAM.getResult<AAManager>(*F);
74 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(*F);
78 const bool HasScopAsTopLevelRegion =
82 if (HasScopAsTopLevelRegion) {
84 <<
" has scop as top level region");
85 F->addFnAttr(llvm::Attribute::AlwaysInline);
87 ModulePassManager MPM;
88 MPM.addPass(AlwaysInlinerPass());
89 Module *M = F->getParent();
90 assert(M &&
"Function has illegal module");
91 PreservedAnalyses PA = MPM.run(*M, MAM);
92 if (!PA.areAllPreserved())
96 <<
" does NOT have scop as top level region\n");
104 :
FS(std::move(
FS)) {
107 "Aborting from ScopInliner because it only makes sense to run with "
108 "-polly-allow-full-function. "
109 "The heurtistic for ScopInliner checks that the full function is a "
110 "Scop, which happens if and only if polly-allow-full-function is "
112 " If not, the entry block is not included in the Scop");
117 llvm::CGSCCAnalysisManager &AM,
118 llvm::LazyCallGraph &CG,
119 llvm::CGSCCUpdateResult &UR) {
120 Function *F = &SCC.begin()->getFunction();
121 bool Changed = runScopInlinerImpl(F, SCC,
FS);
122 return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
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)
ScopInlinerPass(llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS)
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS
bool PollyAllowFullFunction