1 //===- AggressiveInstCombine.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 // This file implements the aggressive expression pattern combiner classes.
11 // Currently, it handles expression patterns for:
12 //  * Truncate instruction
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h"
17 #include "AggressiveInstCombineInternal.h"
18 #include "llvm/Analysis/AliasAnalysis.h"
19 #include "llvm/Analysis/BasicAliasAnalysis.h"
20 #include "llvm/Analysis/GlobalsModRef.h"
21 #include "llvm/Analysis/TargetLibraryInfo.h"
22 #include "llvm/IR/DataLayout.h"
23 #include "llvm/IR/Dominators.h"
24 #include "llvm/Pass.h"
25 #include "llvm/Transforms/Scalar.h"
26 using namespace llvm;
27 
28 #define DEBUG_TYPE "aggressive-instcombine"
29 
30 namespace {
31 /// Contains expression pattern combiner logic.
32 /// This class provides both the logic to combine expression patterns and
33 /// combine them. It differs from InstCombiner class in that each pattern
34 /// combiner runs only once as opposed to InstCombine's multi-iteration,
35 /// which allows pattern combiner to have higher complexity than the O(1)
36 /// required by the instruction combiner.
37 class AggressiveInstCombinerLegacyPass : public FunctionPass {
38 public:
39   static char ID; // Pass identification, replacement for typeid
40 
41   AggressiveInstCombinerLegacyPass() : FunctionPass(ID) {
42     initializeAggressiveInstCombinerLegacyPassPass(
43         *PassRegistry::getPassRegistry());
44   }
45 
46   void getAnalysisUsage(AnalysisUsage &AU) const override;
47 
48   /// Run all expression pattern optimizations on the given /p F function.
49   ///
50   /// \param F function to optimize.
51   /// \returns true if the IR is changed.
52   bool runOnFunction(Function &F) override;
53 };
54 } // namespace
55 
56 void AggressiveInstCombinerLegacyPass::getAnalysisUsage(
57     AnalysisUsage &AU) const {
58   AU.setPreservesCFG();
59   AU.addRequired<DominatorTreeWrapperPass>();
60   AU.addRequired<TargetLibraryInfoWrapperPass>();
61   AU.addPreserved<AAResultsWrapperPass>();
62   AU.addPreserved<BasicAAWrapperPass>();
63   AU.addPreserved<DominatorTreeWrapperPass>();
64   AU.addPreserved<GlobalsAAWrapperPass>();
65 }
66 
67 bool AggressiveInstCombinerLegacyPass::runOnFunction(Function &F) {
68   auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
69   auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
70   auto &DL = F.getParent()->getDataLayout();
71 
72   bool MadeIRChange = false;
73 
74   // Handle TruncInst patterns
75   TruncInstCombine TIC(TLI, DL, DT);
76   MadeIRChange |= TIC.run(F);
77 
78   // TODO: add more patterns to handle...
79 
80   return MadeIRChange;
81 }
82 
83 PreservedAnalyses AggressiveInstCombinePass::run(Function &F,
84                                                  FunctionAnalysisManager &AM) {
85   auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
86   auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
87   auto &DL = F.getParent()->getDataLayout();
88   bool MadeIRChange = false;
89 
90   // Handle TruncInst patterns
91   TruncInstCombine TIC(TLI, DL, DT);
92   MadeIRChange |= TIC.run(F);
93   if (!MadeIRChange)
94     // No changes, all analyses are preserved.
95     return PreservedAnalyses::all();
96 
97   // Mark all the analyses that instcombine updates as preserved.
98   PreservedAnalyses PA;
99   PA.preserveSet<CFGAnalyses>();
100   PA.preserve<AAManager>();
101   PA.preserve<GlobalsAA>();
102   return PA;
103 }
104 
105 char AggressiveInstCombinerLegacyPass::ID = 0;
106 INITIALIZE_PASS_BEGIN(AggressiveInstCombinerLegacyPass,
107                       "aggressive-instcombine",
108                       "Combine pattern based expressions", false, false)
109 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
110 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
111 INITIALIZE_PASS_END(AggressiveInstCombinerLegacyPass, "aggressive-instcombine",
112                     "Combine pattern based expressions", false, false)
113 
114 FunctionPass *llvm::createAggressiveInstCombinerPass() {
115   return new AggressiveInstCombinerLegacyPass();
116 }
117