blob: 0bcd6f1534a36d0575b62735a3c20c28c2b97827 [file] [log] [blame]
Chris Lattner8a2a3112001-12-14 16:52:21 +00001//===- InstructionCombining.cpp - Combine multiple instructions -------------=//
2//
3// InstructionCombining - Combine instructions to form fewer, simple
4// instructions. This pass does not modify the CFG, and has a tendancy to
5// make instructions dead, so a subsequent DCE pass is useful.
6//
7// This pass combines things like:
8// %Y = add int 1, %X
9// %Z = add int 1, %Y
10// into:
11// %Z = add int 2, %X
12//
13// This is a simple worklist driven algorithm.
14//
15//===----------------------------------------------------------------------===//
16
17#include "llvm/Transforms/Scalar/InstructionCombining.h"
Chris Lattner968ddc92002-04-08 20:18:09 +000018#include "llvm/ConstantHandling.h"
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000019#include "llvm/Function.h"
Chris Lattner8a2a3112001-12-14 16:52:21 +000020#include "llvm/iMemory.h"
Chris Lattner8d70cd92002-04-15 19:45:29 +000021#include "llvm/iOther.h"
Chris Lattner455889a2002-02-12 22:39:50 +000022#include "llvm/InstrTypes.h"
Chris Lattnerbd0ef772002-02-26 21:46:54 +000023#include "llvm/Pass.h"
Chris Lattner221d6882002-02-12 21:07:25 +000024#include "llvm/Support/InstIterator.h"
Chris Lattner59b6b8e2002-01-21 23:17:48 +000025#include "../TransformInternals.h"
Chris Lattner8a2a3112001-12-14 16:52:21 +000026
27static Instruction *CombineBinOp(BinaryOperator *I) {
28 bool Changed = false;
29
30 // First thing we do is make sure that this instruction has a constant on the
31 // right hand side if it has any constant arguments.
32 //
33 if (isa<Constant>(I->getOperand(0)) && !isa<Constant>(I->getOperand(1)))
34 if (!I->swapOperands())
35 Changed = true;
36
37 bool LocalChange = true;
38 while (LocalChange) {
39 LocalChange = false;
40 Value *Op1 = I->getOperand(0);
41 if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(1))) {
Chris Lattnerbd0ef772002-02-26 21:46:54 +000042 switch (I->getOpcode()) {
43 case Instruction::Add:
44 if (I->getType()->isIntegral() && cast<ConstantInt>(Op2)->equalsInt(0)){
45 // Eliminate 'add int %X, 0'
46 I->replaceAllUsesWith(Op1); // FIXME: This breaks the worklist
Chris Lattnera007bc22002-03-11 23:28:45 +000047 Changed = true;
48 return I;
Chris Lattnerbd0ef772002-02-26 21:46:54 +000049 }
50
Chris Lattner8a2a3112001-12-14 16:52:21 +000051 if (Instruction *IOp1 = dyn_cast<Instruction>(Op1)) {
52 if (IOp1->getOpcode() == Instruction::Add &&
53 isa<Constant>(IOp1->getOperand(1))) {
54 // Fold:
55 // %Y = add int %X, 1
56 // %Z = add int %Y, 1
57 // into:
58 // %Z = add int %X, 2
59 //
60 // Constant fold both constants...
61 Constant *Val = *Op2 + *cast<Constant>(IOp1->getOperand(1));
62
63 if (Val) {
64 I->setOperand(0, IOp1->getOperand(0));
65 I->setOperand(1, Val);
66 LocalChange = true;
Chris Lattnerbd0ef772002-02-26 21:46:54 +000067 break;
Chris Lattner8a2a3112001-12-14 16:52:21 +000068 }
69 }
70
71 }
Chris Lattnerbd0ef772002-02-26 21:46:54 +000072 break;
73
74 case Instruction::Mul:
75 if (I->getType()->isIntegral() && cast<ConstantInt>(Op2)->equalsInt(1)){
76 // Eliminate 'mul int %X, 1'
77 I->replaceAllUsesWith(Op1); // FIXME: This breaks the worklist
78 LocalChange = true;
79 break;
80 }
81
82 default:
83 break;
Chris Lattner8a2a3112001-12-14 16:52:21 +000084 }
85 }
86 Changed |= LocalChange;
87 }
88
89 if (!Changed) return 0;
90 return I;
91}
92
93// Combine Indices - If the source pointer to this mem access instruction is a
94// getelementptr instruction, combine the indices of the GEP into this
95// instruction
96//
97static Instruction *CombineIndicies(MemAccessInst *MAI) {
98 GetElementPtrInst *Src =
99 dyn_cast<GetElementPtrInst>(MAI->getPointerOperand());
100 if (!Src) return 0;
101
Chris Lattner697954c2002-01-20 22:54:45 +0000102 std::vector<Value *> Indices;
Chris Lattner8a2a3112001-12-14 16:52:21 +0000103
104 // Only special case we have to watch out for is pointer arithmetic on the
105 // 0th index of MAI.
106 unsigned FirstIdx = MAI->getFirstIndexOperandNumber();
107 if (FirstIdx == MAI->getNumOperands() ||
108 (FirstIdx == MAI->getNumOperands()-1 &&
109 MAI->getOperand(FirstIdx) == ConstantUInt::get(Type::UIntTy, 0))) {
110 // Replace the index list on this MAI with the index on the getelementptr
111 Indices.insert(Indices.end(), Src->idx_begin(), Src->idx_end());
112 } else if (*MAI->idx_begin() == ConstantUInt::get(Type::UIntTy, 0)) {
113 // Otherwise we can do the fold if the first index of the GEP is a zero
114 Indices.insert(Indices.end(), Src->idx_begin(), Src->idx_end());
115 Indices.insert(Indices.end(), MAI->idx_begin()+1, MAI->idx_end());
116 }
117
118 if (Indices.empty()) return 0; // Can't do the fold?
119
120 switch (MAI->getOpcode()) {
121 case Instruction::GetElementPtr:
122 return new GetElementPtrInst(Src->getOperand(0), Indices, MAI->getName());
123 case Instruction::Load:
124 return new LoadInst(Src->getOperand(0), Indices, MAI->getName());
125 case Instruction::Store:
126 return new StoreInst(MAI->getOperand(0), Src->getOperand(0),
127 Indices, MAI->getName());
128 default:
129 assert(0 && "Unknown memaccessinst!");
130 break;
131 }
132 abort();
133 return 0;
134}
135
Chris Lattnerbd0ef772002-02-26 21:46:54 +0000136static bool CombineInstruction(Instruction *I) {
Chris Lattner8a2a3112001-12-14 16:52:21 +0000137 Instruction *Result = 0;
138 if (BinaryOperator *BOP = dyn_cast<BinaryOperator>(I))
139 Result = CombineBinOp(BOP);
140 else if (MemAccessInst *MAI = dyn_cast<MemAccessInst>(I))
141 Result = CombineIndicies(MAI);
Chris Lattner8d70cd92002-04-15 19:45:29 +0000142 else if (CastInst *CI = dyn_cast<CastInst>(I)) {
143 if (CI->getType() == CI->getOperand(0)->getType() && !CI->use_empty()) {
144 CI->replaceAllUsesWith(CI->getOperand(0));
145 return true;
146 }
147
148 }
Chris Lattner8a2a3112001-12-14 16:52:21 +0000149
150 if (!Result) return false;
151 if (Result == I) return true;
152
153 // If we get to here, we are to replace I with Result.
154 ReplaceInstWithInst(I, Result);
155 return true;
156}
157
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000158static bool doInstCombining(Function *M) {
159 // Start the worklist out with all of the instructions in the function in it.
Chris Lattner221d6882002-02-12 21:07:25 +0000160 std::vector<Instruction*> WorkList(inst_begin(M), inst_end(M));
Chris Lattner8a2a3112001-12-14 16:52:21 +0000161
162 while (!WorkList.empty()) {
163 Instruction *I = WorkList.back(); // Get an instruction from the worklist
164 WorkList.pop_back();
165
166 // Now that we have an instruction, try combining it to simplify it...
167 if (CombineInstruction(I)) {
168 // The instruction was simplified, add all users of the instruction to
169 // the work lists because they might get more simplified now...
170 //
171 for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
172 UI != UE; ++UI)
173 if (Instruction *User = dyn_cast<Instruction>(*UI))
174 WorkList.push_back(User);
175 }
176 }
177
178 return false;
179}
Chris Lattnerbd0ef772002-02-26 21:46:54 +0000180
181namespace {
182 struct InstructionCombining : public MethodPass {
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000183 virtual bool runOnMethod(Function *F) { return doInstCombining(F); }
Chris Lattnerbd0ef772002-02-26 21:46:54 +0000184 };
185}
186
187Pass *createInstructionCombiningPass() {
188 return new InstructionCombining();
189}