blob: b43f23745aab1ee7a26624af7d18cf240c12816a [file] [log] [blame]
Chris Lattnere5485072002-05-06 18:21:31 +00001//===- ConstantProp.cpp - Code to perform Simple Constant Propogation -----===//
Chris Lattner2f7c9632001-06-06 20:29:01 +00002//
3// This file implements constant propogation and merging:
4//
5// Specifically, this:
Chris Lattnere5485072002-05-06 18:21:31 +00006// * Converts instructions like "add int 1, 2" into 3
Chris Lattner2f7c9632001-06-06 20:29:01 +00007//
8// Notice that:
9// * This pass has a habit of making definitions be dead. It is a good idea
Chris Lattnere5485072002-05-06 18:21:31 +000010// to to run a DIE pass sometime after running this pass.
Chris Lattner2f7c9632001-06-06 20:29:01 +000011//
12//===----------------------------------------------------------------------===//
13
Chris Lattneree965ab2002-01-21 23:17:48 +000014#include "llvm/Transforms/Scalar/ConstantProp.h"
Chris Lattner65b529f2002-04-08 20:18:09 +000015#include "llvm/ConstantHandling.h"
Chris Lattner62b7fd12002-04-07 20:49:59 +000016#include "llvm/Function.h"
Chris Lattner2f7c9632001-06-06 20:29:01 +000017#include "llvm/BasicBlock.h"
18#include "llvm/iTerminators.h"
Chris Lattner04805fa2002-02-26 21:46:54 +000019#include "llvm/Pass.h"
Chris Lattnere5485072002-05-06 18:21:31 +000020#include "llvm/Support/InstIterator.h"
21#include <set>
Chris Lattner2f7c9632001-06-06 20:29:01 +000022
Chris Lattnere5485072002-05-06 18:21:31 +000023// FIXME: ConstantFoldInstruction & ConstantFoldTerminator should be moved out
24// to the Transformations library.
Chris Lattner2f7c9632001-06-06 20:29:01 +000025
Chris Lattnere5485072002-05-06 18:21:31 +000026// ConstantFoldInstruction - If an instruction references constants, try to fold
27// them together...
28//
29bool doConstantPropogation(BasicBlock *BB, BasicBlock::iterator &II) {
30 Instruction *Inst = *II;
31 if (Constant *C = ConstantFoldInstruction(Inst)) {
32 // Replaces all of the uses of a variable with uses of the constant.
33 Inst->replaceAllUsesWith(C);
34
35 // Remove the instruction from the basic block...
36 delete BB->getInstList().remove(II);
37 return true;
38 }
Chris Lattner2f7c9632001-06-06 20:29:01 +000039
Chris Lattnere5485072002-05-06 18:21:31 +000040 return false;
Chris Lattner940daed2002-05-06 03:01:37 +000041}
42
Chris Lattner7ce8b172001-06-29 23:56:58 +000043// ConstantFoldTerminator - If a terminator instruction is predicated on a
44// constant value, convert it into an unconditional branch to the constant
45// destination.
46//
Chris Lattner477fe082002-03-11 22:11:07 +000047bool ConstantFoldTerminator(BasicBlock *BB, BasicBlock::iterator &II,
48 TerminatorInst *T) {
Chris Lattner2f7c9632001-06-06 20:29:01 +000049 // Branch - See if we are conditional jumping on constant
Chris Lattnerda558102001-10-02 03:41:24 +000050 if (BranchInst *BI = dyn_cast<BranchInst>(T)) {
Chris Lattner7ce8b172001-06-29 23:56:58 +000051 if (BI->isUnconditional()) return false; // Can't optimize uncond branch
Chris Lattner4b717c02001-10-01 16:18:37 +000052 BasicBlock *Dest1 = cast<BasicBlock>(BI->getOperand(0));
53 BasicBlock *Dest2 = cast<BasicBlock>(BI->getOperand(1));
Chris Lattner7ce8b172001-06-29 23:56:58 +000054
Chris Lattner3462ae32001-12-03 22:26:30 +000055 if (ConstantBool *Cond = dyn_cast<ConstantBool>(BI->getCondition())) {
Chris Lattner38569342001-10-01 20:11:19 +000056 // Are we branching on constant?
Chris Lattner2f7c9632001-06-06 20:29:01 +000057 // YES. Change to unconditional branch...
Chris Lattner7ce8b172001-06-29 23:56:58 +000058 BasicBlock *Destination = Cond->getValue() ? Dest1 : Dest2;
59 BasicBlock *OldDest = Cond->getValue() ? Dest2 : Dest1;
Chris Lattnere4abb602001-06-29 05:23:10 +000060
Chris Lattner62b7fd12002-04-07 20:49:59 +000061 //cerr << "Function: " << T->getParent()->getParent()
Chris Lattner7ce8b172001-06-29 23:56:58 +000062 // << "\nRemoving branch from " << T->getParent()
63 // << "\n\nTo: " << OldDest << endl;
Chris Lattnere4abb602001-06-29 05:23:10 +000064
65 // Let the basic block know that we are letting go of it. Based on this,
66 // it will adjust it's PHI nodes.
Chris Lattner7ce8b172001-06-29 23:56:58 +000067 assert(BI->getParent() && "Terminator not inserted in block!");
68 OldDest->removePredecessor(BI->getParent());
Chris Lattner2f7c9632001-06-06 20:29:01 +000069
Chris Lattnera073acb2001-07-07 08:36:50 +000070 // Set the unconditional destination, and change the insn to be an
71 // unconditional branch.
72 BI->setUnconditionalDest(Destination);
Chris Lattner477fe082002-03-11 22:11:07 +000073 II = BB->end()-1; // Update instruction iterator!
Chris Lattner2f7c9632001-06-06 20:29:01 +000074 return true;
Chris Lattner030772d2001-09-07 16:41:30 +000075 }
76#if 0
77 // FIXME: TODO: This doesn't work if the destination has PHI nodes with
78 // different incoming values on each branch!
79 //
80 else if (Dest2 == Dest1) { // Conditional branch to same location?
Chris Lattner7ce8b172001-06-29 23:56:58 +000081 // This branch matches something like this:
82 // br bool %cond, label %Dest, label %Dest
83 // and changes it into: br label %Dest
84
85 // Let the basic block know that we are letting go of one copy of it.
86 assert(BI->getParent() && "Terminator not inserted in block!");
87 Dest1->removePredecessor(BI->getParent());
88
Chris Lattnera073acb2001-07-07 08:36:50 +000089 // Change a conditional branch to unconditional.
90 BI->setUnconditionalDest(Dest1);
Chris Lattner7ce8b172001-06-29 23:56:58 +000091 return true;
Chris Lattner2f7c9632001-06-06 20:29:01 +000092 }
Chris Lattner030772d2001-09-07 16:41:30 +000093#endif
Chris Lattner2f7c9632001-06-06 20:29:01 +000094 }
95 return false;
96}
97
Chris Lattner2f7c9632001-06-06 20:29:01 +000098
Chris Lattner2f7c9632001-06-06 20:29:01 +000099
Chris Lattner04805fa2002-02-26 21:46:54 +0000100namespace {
Chris Lattnerc8e66542002-04-27 06:56:12 +0000101 struct ConstantPropogation : public FunctionPass {
Chris Lattner37104aa2002-04-29 14:57:45 +0000102 const char *getPassName() const { return "Simple Constant Propogation"; }
103
Chris Lattnere5485072002-05-06 18:21:31 +0000104 inline bool runOnFunction(Function *F);
Chris Lattnerf12cc842002-04-28 21:27:06 +0000105
106 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
Chris Lattnere5485072002-05-06 18:21:31 +0000107 AU.preservesCFG();
Chris Lattnerf12cc842002-04-28 21:27:06 +0000108 }
Chris Lattner04805fa2002-02-26 21:46:54 +0000109 };
Chris Lattner2f7c9632001-06-06 20:29:01 +0000110}
Chris Lattner04805fa2002-02-26 21:46:54 +0000111
112Pass *createConstantPropogationPass() {
113 return new ConstantPropogation();
114}
115
Chris Lattnere5485072002-05-06 18:21:31 +0000116
117bool ConstantPropogation::runOnFunction(Function *F) {
118 // Initialize the worklist to all of the instructions ready to process...
119 std::set<Instruction*> WorkList(inst_begin(F), inst_end(F));
120 bool Changed = false;
121
122 while (!WorkList.empty()) {
123 Instruction *I = *WorkList.begin();
124 WorkList.erase(WorkList.begin()); // Get an element from the worklist...
125
126 if (!I->use_empty()) // Don't muck with dead instructions...
127 if (Constant *C = ConstantFoldInstruction(I)) {
128 // Add all of the users of this instruction to the worklist, they might
129 // be constant propogatable now...
130 for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
131 UI != UE; ++UI)
132 WorkList.insert(cast<Instruction>(*UI));
133
134 // Replace all of the uses of a variable with uses of the constant.
135 I->replaceAllUsesWith(C);
136
137 // We made a change to the function...
138 Changed = true;
139 }
140 }
141 return Changed;
142}