blob: 626c1301141b872fe7b129cf541cd78502f371f4 [file] [log] [blame]
Chris Lattnerca081252001-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 Lattner65b529f2002-04-08 20:18:09 +000018#include "llvm/ConstantHandling.h"
Chris Lattner62b7fd12002-04-07 20:49:59 +000019#include "llvm/Function.h"
Chris Lattnerca081252001-12-14 16:52:21 +000020#include "llvm/iMemory.h"
Chris Lattner3a60d042002-04-15 19:45:29 +000021#include "llvm/iOther.h"
Chris Lattner260ab202002-04-18 17:39:14 +000022#include "llvm/iOperators.h"
Chris Lattner04805fa2002-02-26 21:46:54 +000023#include "llvm/Pass.h"
Chris Lattner60a65912002-02-12 21:07:25 +000024#include "llvm/Support/InstIterator.h"
Chris Lattner260ab202002-04-18 17:39:14 +000025#include "llvm/Support/InstVisitor.h"
Chris Lattneree965ab2002-01-21 23:17:48 +000026#include "../TransformInternals.h"
Chris Lattnerca081252001-12-14 16:52:21 +000027
Chris Lattnerca081252001-12-14 16:52:21 +000028
Chris Lattner260ab202002-04-18 17:39:14 +000029namespace {
Chris Lattnerc8e66542002-04-27 06:56:12 +000030 class InstCombiner : public FunctionPass,
Chris Lattner260ab202002-04-18 17:39:14 +000031 public InstVisitor<InstCombiner, Instruction*> {
32 // Worklist of all of the instructions that need to be simplified.
33 std::vector<Instruction*> WorkList;
34
35 void AddUsesToWorkList(Instruction *I) {
36 // The instruction was simplified, add all users of the instruction to
37 // the work lists because they might get more simplified now...
38 //
39 for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
40 UI != UE; ++UI)
41 WorkList.push_back(cast<Instruction>(*UI));
42 }
43
44 public:
Chris Lattnerc8e66542002-04-27 06:56:12 +000045 virtual bool runOnFunction(Function *F);
Chris Lattner260ab202002-04-18 17:39:14 +000046
Chris Lattnerf12cc842002-04-28 21:27:06 +000047 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
48 AU.preservesCFG();
49 }
50
Chris Lattner260ab202002-04-18 17:39:14 +000051 // Visitation implementation - Implement instruction combining for different
52 // instruction types. The semantics are as follows:
53 // Return Value:
54 // null - No change was made
55 // I - Change was made, I is still valid
56 // otherwise - Change was made, replace I with returned instruction
57 //
58
59 Instruction *visitAdd(BinaryOperator *I);
60 Instruction *visitSub(BinaryOperator *I);
61 Instruction *visitMul(BinaryOperator *I);
62 Instruction *visitCastInst(CastInst *CI);
63 Instruction *visitMemAccessInst(MemAccessInst *MAI);
64
65 // visitInstruction - Specify what to return for unhandled instructions...
66 Instruction *visitInstruction(Instruction *I) { return 0; }
67 };
68}
69
70
71
72// Make sure that this instruction has a constant on the right hand side if it
73// has any constant arguments. If not, fix it an return true.
74//
75static bool SimplifyBinOp(BinaryOperator *I) {
Chris Lattnerca081252001-12-14 16:52:21 +000076 if (isa<Constant>(I->getOperand(0)) && !isa<Constant>(I->getOperand(1)))
77 if (!I->swapOperands())
Chris Lattner260ab202002-04-18 17:39:14 +000078 return true;
79 return false;
80}
Chris Lattnerca081252001-12-14 16:52:21 +000081
Chris Lattner260ab202002-04-18 17:39:14 +000082Instruction *InstCombiner::visitAdd(BinaryOperator *I) {
83 if (I->use_empty()) return 0; // Don't fix dead add instructions...
84 bool Changed = SimplifyBinOp(I);
85 Value *Op1 = I->getOperand(0);
86
87 // Simplify add instructions with a constant RHS...
88 if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(1))) {
89 // Eliminate 'add int %X, 0'
90 if (I->getType()->isIntegral() && Op2->isNullValue()) {
91 AddUsesToWorkList(I); // Add all modified instrs to worklist
92 I->replaceAllUsesWith(Op1);
93 return I;
94 }
95
96 if (BinaryOperator *IOp1 = dyn_cast<BinaryOperator>(Op1)) {
97 Changed |= SimplifyBinOp(IOp1);
98
99 if (IOp1->getOpcode() == Instruction::Add &&
100 isa<Constant>(IOp1->getOperand(1))) {
101 // Fold:
102 // %Y = add int %X, 1
103 // %Z = add int %Y, 1
104 // into:
105 // %Z = add int %X, 2
106 //
107 if (Constant *Val = *Op2 + *cast<Constant>(IOp1->getOperand(1))) {
108 I->setOperand(0, IOp1->getOperand(0));
109 I->setOperand(1, Val);
Chris Lattnerbee86622002-03-11 23:28:45 +0000110 return I;
Chris Lattner04805fa2002-02-26 21:46:54 +0000111 }
Chris Lattnerca081252001-12-14 16:52:21 +0000112 }
113 }
Chris Lattnerca081252001-12-14 16:52:21 +0000114 }
115
Chris Lattner260ab202002-04-18 17:39:14 +0000116 return Changed ? I : 0;
117}
118
119Instruction *InstCombiner::visitSub(BinaryOperator *I) {
120 if (I->use_empty()) return 0; // Don't fix dead add instructions...
121 bool Changed = SimplifyBinOp(I);
122
123 // If this is a subtract instruction with a constant RHS, convert it to an add
124 // instruction of a negative constant
125 //
126 if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(1)))
127 // Calculate 0 - RHS
Chris Lattner2716b5e2002-04-27 02:25:14 +0000128 if (Constant *RHS = *Constant::getNullValue(I->getType()) - *Op2) {
Chris Lattner260ab202002-04-18 17:39:14 +0000129 return BinaryOperator::create(Instruction::Add, I->getOperand(0), RHS,
130 I->getName());
131 }
132
133 return Changed ? I : 0;
134}
135
136Instruction *InstCombiner::visitMul(BinaryOperator *I) {
137 if (I->use_empty()) return 0; // Don't fix dead add instructions...
138 bool Changed = SimplifyBinOp(I);
139 Value *Op1 = I->getOperand(0);
140
141 // Simplify add instructions with a constant RHS...
142 if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(1))) {
143 if (I->getType()->isIntegral() && cast<ConstantInt>(Op2)->equalsInt(1)){
144 // Eliminate 'mul int %X, 1'
145 AddUsesToWorkList(I); // Add all modified instrs to worklist
146 I->replaceAllUsesWith(Op1);
147 return I;
148 }
149 }
150
151 return Changed ? I : 0;
152}
153
154
155// CastInst simplification - If the user is casting a value to the same type,
156// eliminate this cast instruction...
157//
158Instruction *InstCombiner::visitCastInst(CastInst *CI) {
159 if (CI->getType() == CI->getOperand(0)->getType() && !CI->use_empty()) {
160 AddUsesToWorkList(CI); // Add all modified instrs to worklist
161 CI->replaceAllUsesWith(CI->getOperand(0));
162 return CI;
163 }
164 return 0;
Chris Lattnerca081252001-12-14 16:52:21 +0000165}
166
167// Combine Indices - If the source pointer to this mem access instruction is a
168// getelementptr instruction, combine the indices of the GEP into this
169// instruction
170//
Chris Lattner260ab202002-04-18 17:39:14 +0000171Instruction *InstCombiner::visitMemAccessInst(MemAccessInst *MAI) {
Chris Lattnerca081252001-12-14 16:52:21 +0000172 GetElementPtrInst *Src =
173 dyn_cast<GetElementPtrInst>(MAI->getPointerOperand());
174 if (!Src) return 0;
175
Chris Lattner7f74a562002-01-20 22:54:45 +0000176 std::vector<Value *> Indices;
Chris Lattnerca081252001-12-14 16:52:21 +0000177
178 // Only special case we have to watch out for is pointer arithmetic on the
179 // 0th index of MAI.
180 unsigned FirstIdx = MAI->getFirstIndexOperandNumber();
181 if (FirstIdx == MAI->getNumOperands() ||
182 (FirstIdx == MAI->getNumOperands()-1 &&
183 MAI->getOperand(FirstIdx) == ConstantUInt::get(Type::UIntTy, 0))) {
184 // Replace the index list on this MAI with the index on the getelementptr
185 Indices.insert(Indices.end(), Src->idx_begin(), Src->idx_end());
186 } else if (*MAI->idx_begin() == ConstantUInt::get(Type::UIntTy, 0)) {
187 // Otherwise we can do the fold if the first index of the GEP is a zero
188 Indices.insert(Indices.end(), Src->idx_begin(), Src->idx_end());
189 Indices.insert(Indices.end(), MAI->idx_begin()+1, MAI->idx_end());
190 }
191
192 if (Indices.empty()) return 0; // Can't do the fold?
193
194 switch (MAI->getOpcode()) {
195 case Instruction::GetElementPtr:
196 return new GetElementPtrInst(Src->getOperand(0), Indices, MAI->getName());
197 case Instruction::Load:
198 return new LoadInst(Src->getOperand(0), Indices, MAI->getName());
199 case Instruction::Store:
Chris Lattnerf40379e2002-04-18 14:43:54 +0000200 return new StoreInst(MAI->getOperand(0), Src->getOperand(0), Indices);
Chris Lattnerca081252001-12-14 16:52:21 +0000201 default:
202 assert(0 && "Unknown memaccessinst!");
203 break;
204 }
205 abort();
206 return 0;
207}
208
Chris Lattnerca081252001-12-14 16:52:21 +0000209
Chris Lattnerc8e66542002-04-27 06:56:12 +0000210bool InstCombiner::runOnFunction(Function *F) {
Chris Lattner260ab202002-04-18 17:39:14 +0000211 bool Changed = false;
Chris Lattnerca081252001-12-14 16:52:21 +0000212
Chris Lattner260ab202002-04-18 17:39:14 +0000213 WorkList.insert(WorkList.end(), inst_begin(F), inst_end(F));
Chris Lattnerca081252001-12-14 16:52:21 +0000214
215 while (!WorkList.empty()) {
216 Instruction *I = WorkList.back(); // Get an instruction from the worklist
217 WorkList.pop_back();
218
219 // Now that we have an instruction, try combining it to simplify it...
Chris Lattner260ab202002-04-18 17:39:14 +0000220 Instruction *Result = visit(I);
221 if (Result) {
222 // Should we replace the old instruction with a new one?
223 if (Result != I)
224 ReplaceInstWithInst(I, Result);
225
226 WorkList.push_back(Result);
227 AddUsesToWorkList(Result);
228 Changed = true;
Chris Lattnerca081252001-12-14 16:52:21 +0000229 }
230 }
231
Chris Lattner260ab202002-04-18 17:39:14 +0000232 return Changed;
Chris Lattner04805fa2002-02-26 21:46:54 +0000233}
234
235Pass *createInstructionCombiningPass() {
Chris Lattner260ab202002-04-18 17:39:14 +0000236 return new InstCombiner();
Chris Lattner04805fa2002-02-26 21:46:54 +0000237}