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