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