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