blob: eb06a5b1f928aa4ff416e9a38de128db94dbf0e4 [file] [log] [blame]
Chris Lattner4d1e46e2002-05-07 18:07:59 +00001//===-- Local.cpp - Functions to perform local transformations ------------===//
2//
3// This family of functions perform various local transformations to the
4// program.
5//
6//===----------------------------------------------------------------------===//
7
8#include "llvm/Transforms/Utils/Local.h"
9#include "llvm/iTerminators.h"
10#include "llvm/ConstantHandling.h"
11
12//===----------------------------------------------------------------------===//
13// Local constant propogation...
14//
15
16// ConstantFoldInstruction - If an instruction references constants, try to fold
17// them together...
18//
19bool doConstantPropogation(BasicBlock *BB, BasicBlock::iterator &II) {
20 Instruction *Inst = *II;
21 if (Constant *C = ConstantFoldInstruction(Inst)) {
22 // Replaces all of the uses of a variable with uses of the constant.
23 Inst->replaceAllUsesWith(C);
24
25 // Remove the instruction from the basic block...
26 delete BB->getInstList().remove(II);
27 return true;
28 }
29
30 return false;
31}
32
33// ConstantFoldTerminator - If a terminator instruction is predicated on a
34// constant value, convert it into an unconditional branch to the constant
35// destination.
36//
Chris Lattner76ae3442002-05-21 20:04:50 +000037bool ConstantFoldTerminator(BasicBlock *BB) {
38 TerminatorInst *T = BB->getTerminator();
39
Chris Lattner4d1e46e2002-05-07 18:07:59 +000040 // Branch - See if we are conditional jumping on constant
41 if (BranchInst *BI = dyn_cast<BranchInst>(T)) {
42 if (BI->isUnconditional()) return false; // Can't optimize uncond branch
43 BasicBlock *Dest1 = cast<BasicBlock>(BI->getOperand(0));
44 BasicBlock *Dest2 = cast<BasicBlock>(BI->getOperand(1));
45
46 if (ConstantBool *Cond = dyn_cast<ConstantBool>(BI->getCondition())) {
47 // Are we branching on constant?
48 // YES. Change to unconditional branch...
49 BasicBlock *Destination = Cond->getValue() ? Dest1 : Dest2;
50 BasicBlock *OldDest = Cond->getValue() ? Dest2 : Dest1;
51
52 //cerr << "Function: " << T->getParent()->getParent()
53 // << "\nRemoving branch from " << T->getParent()
54 // << "\n\nTo: " << OldDest << endl;
55
56 // Let the basic block know that we are letting go of it. Based on this,
57 // it will adjust it's PHI nodes.
58 assert(BI->getParent() && "Terminator not inserted in block!");
59 OldDest->removePredecessor(BI->getParent());
60
61 // Set the unconditional destination, and change the insn to be an
62 // unconditional branch.
63 BI->setUnconditionalDest(Destination);
Chris Lattner4d1e46e2002-05-07 18:07:59 +000064 return true;
65 }
66#if 0
67 // FIXME: TODO: This doesn't work if the destination has PHI nodes with
68 // different incoming values on each branch!
69 //
70 else if (Dest2 == Dest1) { // Conditional branch to same location?
71 // This branch matches something like this:
72 // br bool %cond, label %Dest, label %Dest
73 // and changes it into: br label %Dest
74
75 // Let the basic block know that we are letting go of one copy of it.
76 assert(BI->getParent() && "Terminator not inserted in block!");
77 Dest1->removePredecessor(BI->getParent());
78
79 // Change a conditional branch to unconditional.
80 BI->setUnconditionalDest(Dest1);
81 return true;
82 }
83#endif
84 }
85 return false;
86}
87
88
89
90//===----------------------------------------------------------------------===//
91// Local dead code elimination...
92//
93
94bool isInstructionTriviallyDead(Instruction *I) {
95 return I->use_empty() && !I->hasSideEffects() && !isa<TerminatorInst>(I);
96}
97
98// dceInstruction - Inspect the instruction at *BBI and figure out if it's
99// [trivially] dead. If so, remove the instruction and update the iterator
100// to point to the instruction that immediately succeeded the original
101// instruction.
102//
103bool dceInstruction(BasicBlock::InstListType &BBIL,
104 BasicBlock::iterator &BBI) {
105 // Look for un"used" definitions...
106 if (isInstructionTriviallyDead(*BBI)) {
107 delete BBIL.remove(BBI); // Bye bye
108 return true;
109 }
110 return false;
111}