Polly 22.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/ScopInliner.h"
17#include "polly/ScopDetection.h"
18#include "polly/ScopInliner.h"
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"
26
28#define DEBUG_TYPE "polly-scop-inliner"
29
30using namespace llvm;
31using namespace polly;
32
33namespace {
34
35/// Inliner implementation that works with both, LPM (using SCC_t=CallGraph) and
36/// NPM (using SCC_t=LazyCallGraph::SCC)
37template <typename SCC_t> bool runScopInlinerImpl(Function *F, SCC_t &SCC) {
38 // We do not try to inline non-trivial SCCs because this would lead to
39 // "infinite" inlining if we are not careful.
40 if (SCC.size() > 1)
41 return false;
42 assert(SCC.size() == 1 && "found empty SCC");
43
44 // If the function is a nullptr, or the function is a declaration.
45 if (!F)
46 return false;
47 if (F->isDeclaration()) {
48 POLLY_DEBUG(dbgs() << "Skipping " << F->getName()
49 << "because it is a declaration.\n");
50 return false;
51 }
52
53 PassBuilder PB;
54 // Populate analysis managers and register Polly-specific analyses.
55 LoopAnalysisManager LAM;
56 FunctionAnalysisManager FAM;
57 CGSCCAnalysisManager CGAM;
58 ModuleAnalysisManager MAM;
59 PB.registerModuleAnalyses(MAM);
60 PB.registerCGSCCAnalyses(CGAM);
61 PB.registerFunctionAnalyses(FAM);
62 PB.registerLoopAnalyses(LAM);
63 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
64
65 auto &DT = FAM.getResult<DominatorTreeAnalysis>(*F);
66 auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(*F);
67 auto &LI = FAM.getResult<LoopAnalysis>(*F);
68 auto &RI = FAM.getResult<RegionInfoAnalysis>(*F);
69 auto &AA = FAM.getResult<AAManager>(*F);
70 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(*F);
71 ScopDetection SD(DT, SE, LI, RI, AA, ORE);
72 SD.detect(*F);
73
74 const bool HasScopAsTopLevelRegion =
75 SD.ValidRegions.contains(RI.getTopLevelRegion());
76
77 bool Changed = false;
78 if (HasScopAsTopLevelRegion) {
79 POLLY_DEBUG(dbgs() << "Skipping " << F->getName()
80 << " has scop as top level region");
81 F->addFnAttr(llvm::Attribute::AlwaysInline);
82
83 ModulePassManager MPM;
84 MPM.addPass(AlwaysInlinerPass());
85 Module *M = F->getParent();
86 assert(M && "Function has illegal module");
87 PreservedAnalyses PA = MPM.run(*M, MAM);
88 if (!PA.areAllPreserved())
89 Changed = true;
90 } else {
91 POLLY_DEBUG(dbgs() << F->getName()
92 << " does NOT have scop as top level region\n");
93 }
94
95 return Changed;
96}
97} // namespace
98
101 report_fatal_error(
102 "Aborting from ScopInliner because it only makes sense to run with "
103 "-polly-allow-full-function. "
104 "The heurtistic for ScopInliner checks that the full function is a "
105 "Scop, which happens if and only if polly-allow-full-function is "
106 " enabled. "
107 " If not, the entry block is not included in the Scop");
108 }
109}
110
111PreservedAnalyses polly::ScopInlinerPass::run(llvm::LazyCallGraph::SCC &SCC,
112 llvm::CGSCCAnalysisManager &AM,
113 llvm::LazyCallGraph &CG,
114 llvm::CGSCCUpdateResult &UR) {
115 Function *F = &SCC.begin()->getFunction();
116 bool Changed = runScopInlinerImpl(F, SCC);
117 return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
118}
#define POLLY_DEBUG(X)
Definition PollyDebug.h:23
Pass to detect the maximal static control parts (Scops) of a function.
void detect(Function &F)
llvm::PreservedAnalyses run(llvm::LazyCallGraph::SCC &C, llvm::CGSCCAnalysisManager &AM, llvm::LazyCallGraph &CG, llvm::CGSCCUpdateResult &UR)
#define assert(exp)
bool PollyAllowFullFunction