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