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