Polly 20.0.0git
ScopInliner.cpp
Go to the documentation of this file.
1//===---- ScopInliner.cpp - Polyhedral based inliner ----------------------===//
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// Take a SCC and:
10// 1. If it has more than one component, bail out (contains cycles)
11// 2. If it has just one component, and if the function is entirely a scop,
12// inline it.
13//
14//===----------------------------------------------------------------------===//
15
16#include "polly/LinkAllPasses.h"
17#include "polly/ScopDetection.h"
18#include "llvm/Analysis/CallGraph.h"
19#include "llvm/Analysis/CallGraphSCCPass.h"
20#include "llvm/IR/PassManager.h"
21#include "llvm/Passes/PassBuilder.h"
22#include "llvm/Transforms/IPO/AlwaysInliner.h"
23
25#define DEBUG_TYPE "polly-scop-inliner"
26
27using namespace llvm;
28using namespace polly;
29
30namespace {
31class ScopInliner final : public CallGraphSCCPass {
32 using llvm::Pass::doInitialization;
33
34public:
35 static char ID;
36
37 ScopInliner() : CallGraphSCCPass(ID) {}
38
39 bool doInitialization(CallGraph &CG) override {
41 report_fatal_error(
42 "Aborting from ScopInliner because it only makes sense to run with "
43 "-polly-allow-full-function. "
44 "The heurtistic for ScopInliner checks that the full function is a "
45 "Scop, which happens if and only if polly-allow-full-function is "
46 " enabled. "
47 " If not, the entry block is not included in the Scop");
48 }
49 return true;
50 }
51
52 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");
58 Function *F = (*SCC.begin())->getFunction();
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;
107 };
108
109 void getAnalysisUsage(AnalysisUsage &AU) const override {
110 CallGraphSCCPass::getAnalysisUsage(AU);
111 }
112};
113} // namespace
114char ScopInliner::ID;
115
117 ScopInliner *pass = new ScopInliner();
118 return pass;
119}
120
122 ScopInliner, "polly-scop-inliner",
123 "inline functions based on how much of the function is a scop.", false,
124 false)
126 ScopInliner, "polly-scop-inliner",
127 "inline functions based on how much of the function is a scop.", false,
128 false)
INITIALIZE_PASS_END(DependenceInfo, "polly-dependences", "Polly - Calculate dependences", false, false) namespace
polly dump function
polly dump Polly Dump Function
polly dump Polly Dump Module
#define POLLY_DEBUG(X)
Definition: PollyDebug.h:23
static RegisterPass< ScopPrinterWrapperPass > M("dot-scops", "Polly - Print Scops of function")
polly scop functions based on how much of the function is a scop
polly scop inliner
INITIALIZE_PASS_BEGIN(ScopInliner, "polly-scop-inliner", "inline functions based on how much of the function is a scop.", false, false) INITIALIZE_PASS_END(ScopInliner
Pass to detect the maximal static control parts (Scops) of a function.
#define assert(exp)
This file contains the declaration of the PolyhedralInfo class, which will provide an interface to ex...
bool PollyAllowFullFunction
llvm::Pass * createScopInlinerPass()
a(0)