1 //===---- Canonicalization.cpp - Run canonicalization passes --------------===// 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 // Run the set of default canonicalization passes. 10 // 11 // This pass is mainly used for debugging. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "polly/Canonicalization.h" 16 #include "polly/LinkAllPasses.h" 17 #include "polly/Options.h" 18 #include "polly/RewriteByReferenceParameters.h" 19 #include "llvm/Analysis/GlobalsModRef.h" 20 #include "llvm/Analysis/ProfileSummaryInfo.h" 21 #include "llvm/IR/LegacyPassManager.h" 22 #include "llvm/Transforms/IPO.h" 23 #include "llvm/Transforms/IPO/FunctionAttrs.h" 24 #include "llvm/Transforms/InstCombine/InstCombine.h" 25 #include "llvm/Transforms/Scalar.h" 26 #include "llvm/Transforms/Scalar/EarlyCSE.h" 27 #include "llvm/Transforms/Scalar/IndVarSimplify.h" 28 #include "llvm/Transforms/Scalar/LoopRotation.h" 29 #include "llvm/Transforms/Scalar/Reassociate.h" 30 #include "llvm/Transforms/Scalar/SimplifyCFG.h" 31 #include "llvm/Transforms/Scalar/TailRecursionElimination.h" 32 #include "llvm/Transforms/Utils.h" 33 #include "llvm/Transforms/Utils/Mem2Reg.h" 34 35 using namespace llvm; 36 using namespace polly; 37 38 static cl::opt<bool> 39 PollyInliner("polly-run-inliner", 40 cl::desc("Run an early inliner pass before Polly"), cl::Hidden, 41 cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory)); 42 43 void polly::registerCanonicalicationPasses(llvm::legacy::PassManagerBase &PM) { 44 bool UseMemSSA = true; 45 PM.add(polly::createRewriteByrefParamsWrapperPass()); 46 PM.add(llvm::createPromoteMemoryToRegisterPass()); 47 PM.add(llvm::createEarlyCSEPass(UseMemSSA)); 48 PM.add(llvm::createInstructionCombiningPass()); 49 PM.add(llvm::createCFGSimplificationPass()); 50 PM.add(llvm::createTailCallEliminationPass()); 51 PM.add(llvm::createCFGSimplificationPass()); 52 PM.add(llvm::createReassociatePass()); 53 PM.add(llvm::createLoopRotatePass()); 54 if (PollyInliner) { 55 PM.add(llvm::createFunctionInliningPass(200)); 56 PM.add(llvm::createPromoteMemoryToRegisterPass()); 57 PM.add(llvm::createCFGSimplificationPass()); 58 PM.add(llvm::createInstructionCombiningPass()); 59 PM.add(createBarrierNoopPass()); 60 } 61 PM.add(llvm::createInstructionCombiningPass()); 62 PM.add(llvm::createIndVarSimplifyPass()); 63 } 64 65 /// Adapted from llvm::PassBuilder::buildInlinerPipeline 66 static ModuleInlinerWrapperPass 67 buildInlinePasses(llvm::OptimizationLevel Level) { 68 InlineParams IP = getInlineParams(200); 69 ModuleInlinerWrapperPass MIWP(IP); 70 71 // Require the GlobalsAA analysis for the module so we can query it within 72 // the CGSCC pipeline. 73 MIWP.addModulePass(RequireAnalysisPass<GlobalsAA, Module>()); 74 // Invalidate AAManager so it can be recreated and pick up the newly available 75 // GlobalsAA. 76 MIWP.addModulePass( 77 createModuleToFunctionPassAdaptor(InvalidateAnalysisPass<AAManager>())); 78 79 // Require the ProfileSummaryAnalysis for the module so we can query it within 80 // the inliner pass. 81 MIWP.addModulePass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>()); 82 83 // Now begin the main postorder CGSCC pipeline. 84 // FIXME: The current CGSCC pipeline has its origins in the legacy pass 85 // manager and trying to emulate its precise behavior. Much of this doesn't 86 // make a lot of sense and we should revisit the core CGSCC structure. 87 CGSCCPassManager &MainCGPipeline = MIWP.getPM(); 88 89 // Now deduce any function attributes based in the current code. 90 MainCGPipeline.addPass(PostOrderFunctionAttrsPass()); 91 92 return MIWP; 93 } 94 95 FunctionPassManager 96 polly::buildCanonicalicationPassesForNPM(llvm::ModulePassManager &MPM, 97 llvm::OptimizationLevel Level) { 98 FunctionPassManager FPM; 99 100 bool UseMemSSA = true; 101 FPM.addPass(RewriteByrefParamsPass()); 102 FPM.addPass(PromotePass()); 103 FPM.addPass(EarlyCSEPass(UseMemSSA)); 104 FPM.addPass(InstCombinePass()); 105 FPM.addPass(SimplifyCFGPass()); 106 FPM.addPass(TailCallElimPass()); 107 FPM.addPass(SimplifyCFGPass()); 108 FPM.addPass(ReassociatePass()); 109 { 110 LoopPassManager LPM; 111 LPM.addPass(LoopRotatePass(Level != OptimizationLevel::Oz)); 112 FPM.addPass(createFunctionToLoopPassAdaptor<LoopPassManager>( 113 std::move(LPM), /*UseMemorySSA=*/false, 114 /*UseBlockFrequencyInfo=*/false)); 115 } 116 if (PollyInliner) { 117 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); 118 MPM.addPass(buildInlinePasses(Level)); 119 FPM = FunctionPassManager(); 120 121 FPM.addPass(PromotePass()); 122 FPM.addPass(SimplifyCFGPass()); 123 FPM.addPass(InstCombinePass()); 124 } 125 FPM.addPass(InstCombinePass()); 126 { 127 LoopPassManager LPM; 128 LPM.addPass(IndVarSimplifyPass()); 129 FPM.addPass(createFunctionToLoopPassAdaptor<LoopPassManager>( 130 std::move(LPM), /*UseMemorySSA=*/false, 131 /*UseBlockFrequencyInfo=*/true)); 132 } 133 134 return FPM; 135 } 136 137 namespace { 138 class PollyCanonicalize : public ModulePass { 139 PollyCanonicalize(const PollyCanonicalize &) = delete; 140 const PollyCanonicalize &operator=(const PollyCanonicalize &) = delete; 141 142 public: 143 static char ID; 144 145 explicit PollyCanonicalize() : ModulePass(ID) {} 146 ~PollyCanonicalize(); 147 148 /// @name FunctionPass interface. 149 //@{ 150 void getAnalysisUsage(AnalysisUsage &AU) const override; 151 void releaseMemory() override; 152 bool runOnModule(Module &M) override; 153 void print(raw_ostream &OS, const Module *) const override; 154 //@} 155 }; 156 } // namespace 157 158 PollyCanonicalize::~PollyCanonicalize() {} 159 160 void PollyCanonicalize::getAnalysisUsage(AnalysisUsage &AU) const {} 161 162 void PollyCanonicalize::releaseMemory() {} 163 164 bool PollyCanonicalize::runOnModule(Module &M) { 165 legacy::PassManager PM; 166 registerCanonicalicationPasses(PM); 167 PM.run(M); 168 169 return true; 170 } 171 172 void PollyCanonicalize::print(raw_ostream &OS, const Module *) const {} 173 174 char PollyCanonicalize::ID = 0; 175 176 Pass *polly::createPollyCanonicalizePass() { return new PollyCanonicalize(); } 177 178 INITIALIZE_PASS_BEGIN(PollyCanonicalize, "polly-canonicalize", 179 "Polly - Run canonicalization passes", false, false) 180 INITIALIZE_PASS_END(PollyCanonicalize, "polly-canonicalize", 181 "Polly - Run canonicalization passes", false, false) 182