/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Transforms/Scalar/ConstantProp.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- ConstantProp.cpp - Code to perform Simple Constant Propagation -----===// |
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 constant propagation and merging: |
11 | | // |
12 | | // Specifically, this: |
13 | | // * Converts instructions like "add int 1, 2" into 3 |
14 | | // |
15 | | // Notice that: |
16 | | // * This pass has a habit of making definitions be dead. It is a good idea |
17 | | // to run a DIE pass sometime after running this pass. |
18 | | // |
19 | | //===----------------------------------------------------------------------===// |
20 | | |
21 | | #include "llvm/ADT/Statistic.h" |
22 | | #include "llvm/Analysis/ConstantFolding.h" |
23 | | #include "llvm/Analysis/TargetLibraryInfo.h" |
24 | | #include "llvm/IR/Constant.h" |
25 | | #include "llvm/IR/InstIterator.h" |
26 | | #include "llvm/IR/Instruction.h" |
27 | | #include "llvm/Pass.h" |
28 | | #include "llvm/Transforms/Scalar.h" |
29 | | #include "llvm/Transforms/Utils/Local.h" |
30 | | #include <set> |
31 | | using namespace llvm; |
32 | | |
33 | | #define DEBUG_TYPE "constprop" |
34 | | |
35 | | STATISTIC(NumInstKilled, "Number of instructions killed"); |
36 | | |
37 | | namespace { |
38 | | struct ConstantPropagation : public FunctionPass { |
39 | | static char ID; // Pass identification, replacement for typeid |
40 | 47 | ConstantPropagation() : FunctionPass(ID) { |
41 | 47 | initializeConstantPropagationPass(*PassRegistry::getPassRegistry()); |
42 | 47 | } |
43 | | |
44 | | bool runOnFunction(Function &F) override; |
45 | | |
46 | 47 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
47 | 47 | AU.setPreservesCFG(); |
48 | 47 | AU.addRequired<TargetLibraryInfoWrapperPass>(); |
49 | 47 | } |
50 | | }; |
51 | | } |
52 | | |
53 | | char ConstantPropagation::ID = 0; |
54 | 24.6k | INITIALIZE_PASS_BEGIN24.6k (ConstantPropagation, "constprop",
|
55 | 24.6k | "Simple constant propagation", false, false) |
56 | 24.6k | INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) |
57 | 24.6k | INITIALIZE_PASS_END(ConstantPropagation, "constprop", |
58 | | "Simple constant propagation", false, false) |
59 | | |
60 | 7 | FunctionPass *llvm::createConstantPropagationPass() { |
61 | 7 | return new ConstantPropagation(); |
62 | 7 | } |
63 | | |
64 | 139 | bool ConstantPropagation::runOnFunction(Function &F) { |
65 | 139 | if (skipFunction(F)) |
66 | 0 | return false; |
67 | 139 | |
68 | 139 | // Initialize the worklist to all of the instructions ready to process... |
69 | 139 | std::set<Instruction*> WorkList; |
70 | 139 | for (Instruction &I: instructions(&F)) |
71 | 730 | WorkList.insert(&I); |
72 | 139 | |
73 | 139 | bool Changed = false; |
74 | 139 | const DataLayout &DL = F.getParent()->getDataLayout(); |
75 | 139 | TargetLibraryInfo *TLI = |
76 | 139 | &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); |
77 | 139 | |
78 | 880 | while (!WorkList.empty()880 ) { |
79 | 741 | Instruction *I = *WorkList.begin(); |
80 | 741 | WorkList.erase(WorkList.begin()); // Get an element from the worklist... |
81 | 741 | |
82 | 741 | if (!I->use_empty()) // Don't muck with dead instructions... |
83 | 444 | if (Constant *444 C444 = ConstantFoldInstruction(I, DL, TLI)) { |
84 | 252 | // Add all of the users of this instruction to the worklist, they might |
85 | 252 | // be constant propagatable now... |
86 | 252 | for (User *U : I->users()) |
87 | 265 | WorkList.insert(cast<Instruction>(U)); |
88 | 252 | |
89 | 252 | // Replace all of the uses of a variable with uses of the constant. |
90 | 252 | I->replaceAllUsesWith(C); |
91 | 252 | |
92 | 252 | // Remove the dead instruction. |
93 | 252 | WorkList.erase(I); |
94 | 252 | if (isInstructionTriviallyDead(I, TLI)252 ) { |
95 | 252 | I->eraseFromParent(); |
96 | 252 | ++NumInstKilled; |
97 | 252 | } |
98 | 444 | |
99 | 444 | // We made a change to the function... |
100 | 444 | Changed = true; |
101 | 444 | } |
102 | 741 | } |
103 | 139 | return Changed; |
104 | 139 | } |