1 //===- CodegenCleanup.cpp -------------------------------------------------===//
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 #include "polly/CodeGen/CodegenCleanup.h"
10 
11 #include "llvm/Analysis/ScopedNoAliasAA.h"
12 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
13 #include "llvm/IR/Function.h"
14 #include "llvm/IR/LegacyPassManager.h"
15 #include "llvm/PassInfo.h"
16 #include "llvm/PassRegistry.h"
17 #include "llvm/PassSupport.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Transforms/InstCombine/InstCombine.h"
20 #include "llvm/Transforms/Scalar.h"
21 #include "llvm/Transforms/Scalar/GVN.h"
22 #include "llvm/Transforms/Utils.h"
23 
24 #define DEBUG_TYPE "polly-cleanup"
25 
26 using namespace llvm;
27 using namespace polly;
28 
29 namespace {
30 
31 class CodegenCleanup : public FunctionPass {
32 private:
33   CodegenCleanup(const CodegenCleanup &) = delete;
34   const CodegenCleanup &operator=(const CodegenCleanup &) = delete;
35 
36   llvm::legacy::FunctionPassManager *FPM;
37 
38 public:
39   static char ID;
40   explicit CodegenCleanup() : FunctionPass(ID), FPM(nullptr) {}
41 
42   /// @name FunctionPass interface
43   //@{
44   virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {}
45 
46   virtual bool doInitialization(Module &M) override {
47     assert(!FPM);
48 
49     FPM = new llvm::legacy::FunctionPassManager(&M);
50 
51     // TODO: How to make parent passes discoverable?
52     // TODO: Should be sensitive to compiler options in PassManagerBuilder, to
53     // which we do not have access here.
54     FPM->add(createScopedNoAliasAAWrapperPass());
55     FPM->add(createTypeBasedAAWrapperPass());
56     FPM->add(createAAResultsWrapperPass());
57 
58     // TODO: These are non-conditional passes that run between
59     // EP_ModuleOptimizerEarly and EP_VectorizerStart just to ensure we do not
60     // miss any optimization that would have run after Polly with
61     // -polly-position=early. This can probably be reduced to a more compact set
62     // of passes.
63     FPM->add(createCFGSimplificationPass());
64     FPM->add(createSROAPass());
65     FPM->add(createEarlyCSEPass());
66 
67     FPM->add(createPromoteMemoryToRegisterPass());
68     FPM->add(createInstructionCombiningPass(true));
69     FPM->add(createCFGSimplificationPass());
70     FPM->add(createSROAPass());
71     FPM->add(createEarlyCSEPass(true));
72     FPM->add(createSpeculativeExecutionIfHasBranchDivergencePass());
73     FPM->add(createJumpThreadingPass());
74     FPM->add(createCorrelatedValuePropagationPass());
75     FPM->add(createCFGSimplificationPass());
76     FPM->add(createInstructionCombiningPass(true));
77     FPM->add(createLibCallsShrinkWrapPass());
78     FPM->add(createTailCallEliminationPass());
79     FPM->add(createCFGSimplificationPass());
80     FPM->add(createReassociatePass());
81     FPM->add(createLoopRotatePass(-1));
82     FPM->add(createGVNPass());
83     FPM->add(createLICMPass());
84     FPM->add(createLoopUnswitchPass());
85     FPM->add(createCFGSimplificationPass());
86     FPM->add(createInstructionCombiningPass(true));
87     FPM->add(createIndVarSimplifyPass());
88     FPM->add(createLoopIdiomPass());
89     FPM->add(createLoopDeletionPass());
90     FPM->add(createCFGSimplificationPass());
91     FPM->add(createSimpleLoopUnrollPass(3));
92     FPM->add(createMergedLoadStoreMotionPass());
93     FPM->add(createGVNPass());
94     FPM->add(createMemCpyOptPass());
95     FPM->add(createSCCPPass());
96     FPM->add(createBitTrackingDCEPass());
97     FPM->add(createInstructionCombiningPass(true));
98     FPM->add(createJumpThreadingPass());
99     FPM->add(createCorrelatedValuePropagationPass());
100     FPM->add(createDeadStoreEliminationPass());
101     FPM->add(createLICMPass());
102     FPM->add(createAggressiveDCEPass());
103     FPM->add(createCFGSimplificationPass());
104     FPM->add(createInstructionCombiningPass(true));
105     FPM->add(createFloat2IntPass());
106 
107     return FPM->doInitialization();
108   }
109 
110   virtual bool doFinalization(Module &M) override {
111     bool Result = FPM->doFinalization();
112 
113     delete FPM;
114     FPM = nullptr;
115 
116     return Result;
117   }
118 
119   virtual bool runOnFunction(llvm::Function &F) override {
120     if (!F.hasFnAttribute("polly-optimized")) {
121       LLVM_DEBUG(
122           dbgs() << F.getName()
123                  << ": Skipping cleanup because Polly did not optimize it.");
124       return false;
125     }
126 
127     LLVM_DEBUG(dbgs() << F.getName() << ": Running codegen cleanup...");
128     return FPM->run(F);
129   }
130   //@}
131 };
132 
133 char CodegenCleanup::ID;
134 } // namespace
135 
136 FunctionPass *polly::createCodegenCleanupPass() { return new CodegenCleanup(); }
137 
138 INITIALIZE_PASS_BEGIN(CodegenCleanup, "polly-cleanup",
139                       "Polly - Cleanup after code generation", false, false)
140 INITIALIZE_PASS_END(CodegenCleanup, "polly-cleanup",
141                     "Polly - Cleanup after code generation", false, false)
142