Misha Brukman | 373086d | 2003-05-20 21:01:22 +0000 | [diff] [blame] | 1 | //===- ConstantProp.cpp - Code to perform Simple Constant Propagation -----===// |
Misha Brukman | b1c9317 | 2005-04-21 23:48:37 +0000 | [diff] [blame] | 2 | // |
John Criswell | 482202a | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
Chris Lattner | f3ebc3f | 2007-12-29 20:36:04 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
Misha Brukman | b1c9317 | 2005-04-21 23:48:37 +0000 | [diff] [blame] | 7 | // |
John Criswell | 482202a | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 9 | // |
Misha Brukman | 373086d | 2003-05-20 21:01:22 +0000 | [diff] [blame] | 10 | // This file implements constant propagation and merging: |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 11 | // |
| 12 | // Specifically, this: |
Chris Lattner | e548507 | 2002-05-06 18:21:31 +0000 | [diff] [blame] | 13 | // * Converts instructions like "add int 1, 2" into 3 |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 14 | // |
| 15 | // Notice that: |
| 16 | // * This pass has a habit of making definitions be dead. It is a good idea |
Duncan Sands | c1e48b5 | 2008-08-01 12:23:49 +0000 | [diff] [blame] | 17 | // to run a DIE pass sometime after running this pass. |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 18 | // |
| 19 | //===----------------------------------------------------------------------===// |
| 20 | |
Zhizhou Yang | cc633af | 2018-11-13 00:31:22 +0000 | [diff] [blame] | 21 | #include "llvm/ADT/SmallPtrSet.h" |
| 22 | #include "llvm/ADT/SmallVector.h" |
Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 23 | #include "llvm/ADT/Statistic.h" |
Chris Lattner | 024f4ab | 2007-01-30 23:46:24 +0000 | [diff] [blame] | 24 | #include "llvm/Analysis/ConstantFolding.h" |
Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 25 | #include "llvm/Analysis/TargetLibraryInfo.h" |
Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 26 | #include "llvm/IR/Constant.h" |
Chandler Carruth | 8394857 | 2014-03-04 10:30:26 +0000 | [diff] [blame] | 27 | #include "llvm/IR/InstIterator.h" |
Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 28 | #include "llvm/IR/Instruction.h" |
Chris Lattner | 04805fa | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 29 | #include "llvm/Pass.h" |
Zhizhou Yang | cc633af | 2018-11-13 00:31:22 +0000 | [diff] [blame] | 30 | #include "llvm/Support/DebugCounter.h" |
Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 31 | #include "llvm/Transforms/Scalar.h" |
Zhizhou Yang | cc633af | 2018-11-13 00:31:22 +0000 | [diff] [blame] | 32 | #include "llvm/Transforms/Utils/Local.h" |
Chris Lattner | 49525f8 | 2004-01-09 06:02:20 +0000 | [diff] [blame] | 33 | using namespace llvm; |
Brian Gaeke | 960707c | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 34 | |
Chandler Carruth | 964daaa | 2014-04-22 02:55:47 +0000 | [diff] [blame] | 35 | #define DEBUG_TYPE "constprop" |
| 36 | |
Chris Lattner | 79a42ac | 2006-12-19 21:40:18 +0000 | [diff] [blame] | 37 | STATISTIC(NumInstKilled, "Number of instructions killed"); |
Zhizhou Yang | cc633af | 2018-11-13 00:31:22 +0000 | [diff] [blame] | 38 | DEBUG_COUNTER(CPCounter, "constprop-transform", |
| 39 | "Controls which instructions are killed"); |
Chris Lattner | bf3a099 | 2002-10-01 22:38:41 +0000 | [diff] [blame] | 40 | |
Chris Lattner | 79a42ac | 2006-12-19 21:40:18 +0000 | [diff] [blame] | 41 | namespace { |
Chris Lattner | 2dd09db | 2009-09-02 06:11:42 +0000 | [diff] [blame] | 42 | struct ConstantPropagation : public FunctionPass { |
Nick Lewycky | e7da2d6 | 2007-05-06 13:37:16 +0000 | [diff] [blame] | 43 | static char ID; // Pass identification, replacement for typeid |
Owen Anderson | 6c18d1a | 2010-10-19 17:21:58 +0000 | [diff] [blame] | 44 | ConstantPropagation() : FunctionPass(ID) { |
| 45 | initializeConstantPropagationPass(*PassRegistry::getPassRegistry()); |
| 46 | } |
Devang Patel | 09f162c | 2007-05-01 21:15:47 +0000 | [diff] [blame] | 47 | |
Craig Topper | 3e4c697 | 2014-03-05 09:10:37 +0000 | [diff] [blame] | 48 | bool runOnFunction(Function &F) override; |
Chris Lattner | f12cc84 | 2002-04-28 21:27:06 +0000 | [diff] [blame] | 49 | |
Craig Topper | 3e4c697 | 2014-03-05 09:10:37 +0000 | [diff] [blame] | 50 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
Chris Lattner | 820d971 | 2002-10-21 20:00:28 +0000 | [diff] [blame] | 51 | AU.setPreservesCFG(); |
Chandler Carruth | b98f63d | 2015-01-15 10:41:28 +0000 | [diff] [blame] | 52 | AU.addRequired<TargetLibraryInfoWrapperPass>(); |
Chris Lattner | f12cc84 | 2002-04-28 21:27:06 +0000 | [diff] [blame] | 53 | } |
Chris Lattner | 04805fa | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 54 | }; |
Alexander Kornienko | f00654e | 2015-06-23 09:49:53 +0000 | [diff] [blame] | 55 | } |
Chris Lattner | 04805fa | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 56 | |
Dan Gohman | d78c400 | 2008-05-13 00:00:25 +0000 | [diff] [blame] | 57 | char ConstantPropagation::ID = 0; |
Chad Rosier | e6de63d | 2011-12-01 21:29:16 +0000 | [diff] [blame] | 58 | INITIALIZE_PASS_BEGIN(ConstantPropagation, "constprop", |
| 59 | "Simple constant propagation", false, false) |
Chandler Carruth | b98f63d | 2015-01-15 10:41:28 +0000 | [diff] [blame] | 60 | INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) |
Chad Rosier | e6de63d | 2011-12-01 21:29:16 +0000 | [diff] [blame] | 61 | INITIALIZE_PASS_END(ConstantPropagation, "constprop", |
Owen Anderson | df7a4f2 | 2010-10-07 22:25:06 +0000 | [diff] [blame] | 62 | "Simple constant propagation", false, false) |
Dan Gohman | d78c400 | 2008-05-13 00:00:25 +0000 | [diff] [blame] | 63 | |
Chris Lattner | 3e86084 | 2004-09-20 04:43:15 +0000 | [diff] [blame] | 64 | FunctionPass *llvm::createConstantPropagationPass() { |
Misha Brukman | 373086d | 2003-05-20 21:01:22 +0000 | [diff] [blame] | 65 | return new ConstantPropagation(); |
Chris Lattner | 04805fa | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 66 | } |
| 67 | |
Misha Brukman | 373086d | 2003-05-20 21:01:22 +0000 | [diff] [blame] | 68 | bool ConstantPropagation::runOnFunction(Function &F) { |
Andrew Kaylor | 50271f7 | 2016-05-03 22:32:30 +0000 | [diff] [blame] | 69 | if (skipFunction(F)) |
| 70 | return false; |
| 71 | |
Chris Lattner | e548507 | 2002-05-06 18:21:31 +0000 | [diff] [blame] | 72 | // Initialize the worklist to all of the instructions ready to process... |
Zhizhou Yang | cc633af | 2018-11-13 00:31:22 +0000 | [diff] [blame] | 73 | SmallPtrSet<Instruction *, 16> WorkList; |
| 74 | // The SmallVector of WorkList ensures that we do iteration at stable order. |
| 75 | // We use two containers rather than one SetVector, since remove is |
| 76 | // linear-time, and we don't care enough to remove from Vec. |
| 77 | SmallVector<Instruction *, 16> WorkListVec; |
| 78 | for (Instruction &I : instructions(&F)) { |
Sanjay Patel | e77c7de | 2016-04-04 23:05:06 +0000 | [diff] [blame] | 79 | WorkList.insert(&I); |
Zhizhou Yang | cc633af | 2018-11-13 00:31:22 +0000 | [diff] [blame] | 80 | WorkListVec.push_back(&I); |
| 81 | } |
Sanjay Patel | e77c7de | 2016-04-04 23:05:06 +0000 | [diff] [blame] | 82 | |
Chris Lattner | e548507 | 2002-05-06 18:21:31 +0000 | [diff] [blame] | 83 | bool Changed = false; |
Mehdi Amini | 46a4355 | 2015-03-04 18:43:29 +0000 | [diff] [blame] | 84 | const DataLayout &DL = F.getParent()->getDataLayout(); |
Chandler Carruth | b98f63d | 2015-01-15 10:41:28 +0000 | [diff] [blame] | 85 | TargetLibraryInfo *TLI = |
| 86 | &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); |
Chris Lattner | e548507 | 2002-05-06 18:21:31 +0000 | [diff] [blame] | 87 | |
| 88 | while (!WorkList.empty()) { |
Zhizhou Yang | cc633af | 2018-11-13 00:31:22 +0000 | [diff] [blame] | 89 | SmallVector<Instruction*, 16> NewWorkListVec; |
| 90 | for (auto *I : WorkListVec) { |
| 91 | WorkList.erase(I); // Remove element from the worklist... |
Chris Lattner | e548507 | 2002-05-06 18:21:31 +0000 | [diff] [blame] | 92 | |
Zhizhou Yang | cc633af | 2018-11-13 00:31:22 +0000 | [diff] [blame] | 93 | if (!I->use_empty()) // Don't muck with dead instructions... |
| 94 | if (Constant *C = ConstantFoldInstruction(I, DL, TLI)) { |
| 95 | if (!DebugCounter::shouldExecute(CPCounter)) |
| 96 | continue; |
Misha Brukman | b1c9317 | 2005-04-21 23:48:37 +0000 | [diff] [blame] | 97 | |
Zhizhou Yang | cc633af | 2018-11-13 00:31:22 +0000 | [diff] [blame] | 98 | // Add all of the users of this instruction to the worklist, they might |
| 99 | // be constant propagatable now... |
| 100 | for (User *U : I->users()) { |
| 101 | // If user not in the set, then add it to the vector. |
| 102 | if (WorkList.insert(cast<Instruction>(U)).second) |
| 103 | NewWorkListVec.push_back(cast<Instruction>(U)); |
| 104 | } |
Chris Lattner | 0b18c1d | 2002-05-10 15:38:35 +0000 | [diff] [blame] | 105 | |
Zhizhou Yang | cc633af | 2018-11-13 00:31:22 +0000 | [diff] [blame] | 106 | // Replace all of the uses of a variable with uses of the constant. |
| 107 | I->replaceAllUsesWith(C); |
| 108 | |
| 109 | if (isInstructionTriviallyDead(I, TLI)) { |
| 110 | I->eraseFromParent(); |
| 111 | ++NumInstKilled; |
| 112 | } |
| 113 | |
| 114 | // We made a change to the function... |
| 115 | Changed = true; |
David Majnemer | 522a911 | 2016-07-22 04:54:44 +0000 | [diff] [blame] | 116 | } |
Zhizhou Yang | cc633af | 2018-11-13 00:31:22 +0000 | [diff] [blame] | 117 | } |
| 118 | WorkListVec = std::move(NewWorkListVec); |
Chris Lattner | e548507 | 2002-05-06 18:21:31 +0000 | [diff] [blame] | 119 | } |
| 120 | return Changed; |
| 121 | } |