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::PassBuilder::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 polly::buildCanonicalicationPassesForNPM( 96 llvm::ModulePassManager &MPM, llvm::PassBuilder::OptimizationLevel Level) { 97 FunctionPassManager FPM; 98 99 bool UseMemSSA = true; 100 FPM.addPass(RewriteByrefParamsPass()); 101 FPM.addPass(PromotePass()); 102 FPM.addPass(EarlyCSEPass(UseMemSSA)); 103 FPM.addPass(InstCombinePass()); 104 FPM.addPass(SimplifyCFGPass()); 105 FPM.addPass(TailCallElimPass()); 106 FPM.addPass(SimplifyCFGPass()); 107 FPM.addPass(ReassociatePass()); 108 { 109 LoopPassManager LPM; 110 LPM.addPass(LoopRotatePass(Level != PassBuilder::OptimizationLevel::Oz)); 111 FPM.addPass(createFunctionToLoopPassAdaptor<LoopPassManager>( 112 std::move(LPM), /*UseMemorySSA=*/false, 113 /*UseBlockFrequencyInfo=*/false)); 114 } 115 if (PollyInliner) { 116 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); 117 MPM.addPass(buildInlinePasses(Level)); 118 FPM = FunctionPassManager(); 119 120 FPM.addPass(PromotePass()); 121 FPM.addPass(SimplifyCFGPass()); 122 FPM.addPass(InstCombinePass()); 123 } 124 FPM.addPass(InstCombinePass()); 125 { 126 LoopPassManager LPM; 127 LPM.addPass(IndVarSimplifyPass()); 128 FPM.addPass(createFunctionToLoopPassAdaptor<LoopPassManager>( 129 std::move(LPM), /*UseMemorySSA=*/false, 130 /*UseBlockFrequencyInfo=*/true)); 131 } 132 133 return FPM; 134 } 135 136 namespace { 137 class PollyCanonicalize : public ModulePass { 138 PollyCanonicalize(const PollyCanonicalize &) = delete; 139 const PollyCanonicalize &operator=(const PollyCanonicalize &) = delete; 140 141 public: 142 static char ID; 143 144 explicit PollyCanonicalize() : ModulePass(ID) {} 145 ~PollyCanonicalize(); 146 147 /// @name FunctionPass interface. 148 //@{ 149 void getAnalysisUsage(AnalysisUsage &AU) const override; 150 void releaseMemory() override; 151 bool runOnModule(Module &M) override; 152 void print(raw_ostream &OS, const Module *) const override; 153 //@} 154 }; 155 } // namespace 156 157 PollyCanonicalize::~PollyCanonicalize() {} 158 159 void PollyCanonicalize::getAnalysisUsage(AnalysisUsage &AU) const {} 160 161 void PollyCanonicalize::releaseMemory() {} 162 163 bool PollyCanonicalize::runOnModule(Module &M) { 164 legacy::PassManager PM; 165 registerCanonicalicationPasses(PM); 166 PM.run(M); 167 168 return true; 169 } 170 171 void PollyCanonicalize::print(raw_ostream &OS, const Module *) const {} 172 173 char PollyCanonicalize::ID = 0; 174 175 Pass *polly::createPollyCanonicalizePass() { return new PollyCanonicalize(); } 176 177 INITIALIZE_PASS_BEGIN(PollyCanonicalize, "polly-canonicalize", 178 "Polly - Run canonicalization passes", false, false) 179 INITIALIZE_PASS_END(PollyCanonicalize, "polly-canonicalize", 180 "Polly - Run canonicalization passes", false, false) 181