28#include "llvm/ADT/PriorityWorklist.h"
29#include "llvm/Analysis/AssumptionCache.h"
30#include "llvm/Analysis/OptimizationRemarkEmitter.h"
31#include "llvm/Analysis/TargetTransformInfo.h"
32#include "llvm/IR/Module.h"
34#define DEBUG_TYPE "polly-pass"
42static void addRegionIntoQueue(Region &R, SmallVector<Region *> &RQ) {
44 for (
const auto &E : R)
45 addRegionIntoQueue(*E, RQ);
58 FunctionAnalysisManager &FAM;
62 PhaseManager(Function &F, FunctionAnalysisManager &FAM,
PollyPassOptions Opts)
63 : F(F), FAM(FAM), Opts(std::move(Opts)) {}
74 LoopInfo &LI = FAM.getResult<LoopAnalysis>(F);
75 DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
76 bool ModifiedIR =
false;
84 PA.preserve<DominatorTreeAnalysis>();
85 PA.preserve<LoopAnalysis>();
86 FAM.invalidate(F, PA);
95 AAResults &AA = FAM.getResult<AAManager>(F);
96 ScalarEvolution &SE = FAM.getResult<ScalarEvolutionAnalysis>(F);
97 OptimizationRemarkEmitter &ORE =
98 FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
102 RegionInfo RI = RegionInfoAnalysis().run(F, FAM);
108 outs() <<
"Detected Scops in Function " << F.getName() <<
"\n";
110 outs() <<
"Valid Region for Scop: " << R->getNameStr() <<
'\n';
115 printGraphForFunction(F, &SD,
"scops",
false);
117 printGraphForFunction(F, &SD,
"scopsonly",
true);
119 auto ViewScops = [&](
const char *Name,
bool IsSimply) {
124 viewGraphForFunction(F, &SD, Name, IsSimply);
132 AssumptionCache &AC = FAM.getResult<AssumptionAnalysis>(F);
133 const DataLayout &DL = F.getParent()->getDataLayout();
134 ScopInfo Info(DL, SD, SE, LI, AA, DT, AC, ORE);
136 if (Region *TLR = RI.getTopLevelRegion()) {
137 SmallVector<Region *> Regions;
138 addRegionIntoQueue(*TLR, Regions);
141 for (Region *R : reverse(Regions)) {
143 outs() <<
"Printing analysis 'Polly - Create polyhedral "
144 "description of Scops' for region: '"
145 << R->
getNameStr() <<
"' in function '" << F.getName()
150 outs() <<
"Invalid Scop!\n";
155 SmallPriorityWorklist<Region *, 4> Worklist;
156 for (
auto &[R,
S] : Info)
160 TargetTransformInfo &TTI = FAM.getResult<TargetIRAnalysis>(F);
161 while (!Worklist.empty()) {
162 Region *R = Worklist.pop_back_val();
167 POLLY_DEBUG(dbgs() <<
"SCoP in Region '" << *R <<
"' disappeared");
193 bool ModifiedSinceSimplify =
true;
196 ModifiedSinceSimplify =
false;
202 ModifiedSinceSimplify |= ModifiedByOptree;
208 ModifiedSinceSimplify |= ModifiedByDelicm;
216 ModifiedSinceSimplify =
false;
249 if (ModifiedByCodeGen) {
271 return "print-detect";
275 return "dot-scops-only";
279 return "view-scops-only";
283 return "print-scops";
291 return "import-jscop";
309 return "export-jscop";
315 llvm_unreachable(
"Unexpected phase");
320 return StringSwitch<PassPhase>(Name)
407 return make_error<StringError>(
408 formatv(
"'{0}' requires 'detect' to be enabled",
getPhaseName(P))
410 inconvertibleErrorCode());
416 return make_error<StringError>(
417 formatv(
"'{0}' requires 'scops' to be enabled",
getPhaseName(P))
419 inconvertibleErrorCode());
422 return make_error<StringError>(
424 inconvertibleErrorCode());
428 return make_error<StringError>(
"'codegen' requires 'ast' to be enabled",
429 inconvertibleErrorCode());
431 return Error::success();
436 return PhaseManager(F, FAM, std::move(Opts)).run();
The accumulated dependence information for a SCoP.
void print(llvm::raw_ostream &OS) const
Print the stored dependence information.
Options for the Polly pass.
Dependences::AnalysisLevel PrintDepsAnalysisLevel
void enableDefaultOpts()
Enabled the default optimization phases.
void setPhaseEnabled(PassPhase Phase, bool Enabled=true)
void enableEnd2End()
Enable all phases that are necessary for a roundtrip from LLVM-IR back to LLVM-IR.
void disableAfter(PassPhase Phase)
Disable all phases following Phase.
bool isPhaseEnabled(PassPhase Phase) const
llvm::Error checkConsistency() const
Check whether the options are coherent relative to each other.
Pass to detect the maximal static control parts (Scops) of a function.
bool isMaxRegionInScop(const Region &R, bool Verify=true)
Is the region is the maximum region of a Scop?
Scop * getScop(Region *R) const
Get the Scop object for the given Region.
void recompute()
Recompute the Scop-Information for a function.
std::string getNameStr() const
Get the name of this Scop.
PassPhase parsePhase(StringRef Name)
void runExportJSON(Scop &S)
This pass exports a scop to a jscop file.
void runImportJSON(Scop &S, DependenceAnalysis::Result &DA)
This pass imports a scop from a jscop file.
StringRef getPhaseName(PassPhase Phase)
bool runCodePreparation(llvm::Function &F, llvm::DominatorTree *DT, llvm::LoopInfo *LI, llvm::RegionInfo *RI)
void runFlattenSchedulePass(Scop &S)
bool runPollyPass(Function &F, llvm::FunctionAnalysisManager &FAM, PollyPassOptions Opts)
Run Polly and its phases on F.
bool runPruneUnprofitable(Scop &S)
bool runDeadCodeElim(Scop &S, DependenceAnalysis::Result &DA)
DependenceAnalysis::Result runDependenceAnalysis(Scop &S)
bool runSimplify(Scop &S, int CallNo)
std::unique_ptr< IslAstInfo > runIslAstGen(Scop &S, DependenceAnalysis::Result &DA)
bool runCodeGeneration(Scop &S, llvm::RegionInfo &RI, IslAstInfo &AI)
bool dependsOnDependenceInfo(PassPhase Phase)
PassPhase
Phases (in execution order) within the Polly pass.
bool runForwardOpTree(Scop &S)
Pass that redirects scalar reads to array elements that are known to contain the same value.
void runIslScheduleOptimizer(Scop &S, llvm::TargetTransformInfo *TTI, DependenceAnalysis::Result &Deps)
void runMaximalStaticExpansion(Scop &S, DependenceAnalysis::Result &DI)
const Dependences & getDependences(Dependences::AnalysisLevel Level)
Return the dependence information for the current SCoP.