blob: 57ba86d0ab715a4ab3fc7f7f3a300d59fd714a07 [file] [log] [blame]
Reid Spencerf39f66e2004-08-21 21:39:24 +00001//===- LowerPacked.cpp - Implementation of LowerPacked Transform ---------===//
Misha Brukmanb1c93172005-04-21 23:48:37 +00002//
Reid Spencerf39f66e2004-08-21 21:39:24 +00003// The LLVM Compiler Infrastructure
4//
5// This file was developed by Brad Jones and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
Misha Brukmanb1c93172005-04-21 23:48:37 +00007//
Reid Spencerf39f66e2004-08-21 21:39:24 +00008//===----------------------------------------------------------------------===//
9//
10// This file implements lowering Packed datatypes into more primitive
11// Packed datatypes, and finally to scalar operations.
12//
13//===----------------------------------------------------------------------===//
14
Chris Lattner446948e2004-11-19 16:49:34 +000015#include "llvm/Transforms/Scalar.h"
Reid Spencerf39f66e2004-08-21 21:39:24 +000016#include "llvm/Argument.h"
17#include "llvm/Constants.h"
18#include "llvm/DerivedTypes.h"
19#include "llvm/Function.h"
20#include "llvm/Instructions.h"
21#include "llvm/Pass.h"
Reid Spencer557ab152007-02-05 23:32:05 +000022#include "llvm/Support/Compiler.h"
Reid Spencerf39f66e2004-08-21 21:39:24 +000023#include "llvm/Support/InstVisitor.h"
Bill Wendling5dbf43c2006-11-26 09:46:52 +000024#include "llvm/Support/Streams.h"
Dan Gohman3bcd5fe2007-10-29 20:24:00 +000025#include "llvm/ADT/STLExtras.h"
Reid Spencer7c16caa2004-09-01 22:55:40 +000026#include "llvm/ADT/StringExtras.h"
Reid Spencerf39f66e2004-08-21 21:39:24 +000027#include <algorithm>
28#include <map>
Duraid Madina7a3ad6c2005-12-26 13:48:44 +000029#include <functional>
Reid Spencerf39f66e2004-08-21 21:39:24 +000030using namespace llvm;
31
32namespace {
33
34/// This pass converts packed operators to an
35/// equivalent operations on smaller packed data, to possibly
36/// scalar operations. Currently it supports lowering
37/// to scalar operations.
38///
39/// @brief Transforms packed instructions to simpler instructions.
40///
Reid Spencer557ab152007-02-05 23:32:05 +000041class VISIBILITY_HIDDEN LowerPacked
42 : public FunctionPass, public InstVisitor<LowerPacked> {
Reid Spencerf39f66e2004-08-21 21:39:24 +000043public:
Nick Lewyckye7da2d62007-05-06 13:37:16 +000044 static char ID; // Pass identification, replacement for typeid
Devang Patel09f162c2007-05-01 21:15:47 +000045 LowerPacked() : FunctionPass((intptr_t)&ID) {}
46
Misha Brukmanb1c93172005-04-21 23:48:37 +000047 /// @brief Lowers packed operations to scalar operations.
Reid Spencerf39f66e2004-08-21 21:39:24 +000048 /// @param F The fuction to process
49 virtual bool runOnFunction(Function &F);
50
51 /// @brief Lowers packed load instructions.
52 /// @param LI the load instruction to convert
53 void visitLoadInst(LoadInst& LI);
54
55 /// @brief Lowers packed store instructions.
56 /// @param SI the store instruction to convert
57 void visitStoreInst(StoreInst& SI);
58
59 /// @brief Lowers packed binary operations.
60 /// @param BO the binary operator to convert
61 void visitBinaryOperator(BinaryOperator& BO);
62
Reid Spencer266e42b2006-12-23 06:05:41 +000063 /// @brief Lowers packed icmp operations.
Reid Spencerd959cfc2007-08-05 19:35:22 +000064 /// @param IC the icmp operator to convert
Reid Spencer266e42b2006-12-23 06:05:41 +000065 void visitICmpInst(ICmpInst& IC);
66
Reid Spencerf39f66e2004-08-21 21:39:24 +000067 /// @brief Lowers packed select instructions.
68 /// @param SELI the select operator to convert
69 void visitSelectInst(SelectInst& SELI);
70
Robert Bocchinobd518d12006-01-10 19:05:05 +000071 /// @brief Lowers packed extractelement instructions.
Reid Spencerd959cfc2007-08-05 19:35:22 +000072 /// @param EE the extractelement operator to convert
Robert Bocchino6dce2502006-01-17 20:06:55 +000073 void visitExtractElementInst(ExtractElementInst& EE);
74
75 /// @brief Lowers packed insertelement instructions.
Reid Spencerd959cfc2007-08-05 19:35:22 +000076 /// @param IE the insertelement operator to convert
Robert Bocchino6dce2502006-01-17 20:06:55 +000077 void visitInsertElementInst(InsertElementInst& IE);
Robert Bocchinobd518d12006-01-10 19:05:05 +000078
Dan Gohman3bcd5fe2007-10-29 20:24:00 +000079 /// This function asserts that the given instruction does not have
80 /// vector type. Instructions with vector type should be handled by
81 /// the other functions in this class.
Misha Brukmanb1c93172005-04-21 23:48:37 +000082 ///
Reid Spencerd84d35b2007-02-15 02:26:10 +000083 /// @brief Asserts if VectorType instruction is not handled elsewhere.
Reid Spencerf39f66e2004-08-21 21:39:24 +000084 /// @param I the unhandled instruction
Bill Wendling5dbf43c2006-11-26 09:46:52 +000085 void visitInstruction(Instruction &I) {
Dan Gohmand9911e22007-10-29 20:14:29 +000086 assert(!isa<VectorType>(I.getType()) &&
87 "Unhandled Instruction with Packed ReturnType!");
Reid Spencerf39f66e2004-08-21 21:39:24 +000088 }
89private:
90 /// @brief Retrieves lowered values for a packed value.
91 /// @param val the packed value
92 /// @return the lowered values
93 std::vector<Value*>& getValues(Value* val);
94
95 /// @brief Sets lowered values for a packed value.
96 /// @param val the packed value
97 /// @param values the corresponding lowered values
98 void setValues(Value* val,const std::vector<Value*>& values);
99
100 // Data Members
Misha Brukmanb1c93172005-04-21 23:48:37 +0000101 /// @brief whether we changed the function or not
Reid Spencerf39f66e2004-08-21 21:39:24 +0000102 bool Changed;
103
104 /// @brief a map from old packed values to new smaller packed values
105 std::map<Value*,std::vector<Value*> > packedToScalarMap;
106
107 /// Instructions in the source program to get rid of
108 /// after we do a pass (the old packed instructions)
109 std::vector<Instruction*> instrsToRemove;
Misha Brukmanb1c93172005-04-21 23:48:37 +0000110};
Reid Spencerf39f66e2004-08-21 21:39:24 +0000111
Devang Patel8c78a0b2007-05-03 01:11:54 +0000112char LowerPacked::ID = 0;
Chris Lattnerc2d3d312006-08-27 22:42:52 +0000113RegisterPass<LowerPacked>
Misha Brukmanb1c93172005-04-21 23:48:37 +0000114X("lower-packed",
Reid Spencerf39f66e2004-08-21 21:39:24 +0000115 "lowers packed operations to operations on smaller packed datatypes");
116
Misha Brukmanb1c93172005-04-21 23:48:37 +0000117} // end namespace
Reid Spencerf39f66e2004-08-21 21:39:24 +0000118
Chris Lattner446948e2004-11-19 16:49:34 +0000119FunctionPass *llvm::createLowerPackedPass() { return new LowerPacked(); }
Chris Lattnerc08ac112004-11-18 17:24:20 +0000120
121
Reid Spencerf39f66e2004-08-21 21:39:24 +0000122// This function sets lowered values for a corresponding
123// packed value. Note, in the case of a forward reference
Misha Brukmanb1c93172005-04-21 23:48:37 +0000124// getValues(Value*) will have already been called for
125// the packed parameter. This function will then replace
126// all references in the in the function of the "dummy"
127// value the previous getValues(Value*) call
Reid Spencerf39f66e2004-08-21 21:39:24 +0000128// returned with actual references.
129void LowerPacked::setValues(Value* value,const std::vector<Value*>& values)
130{
Misha Brukmanb1c93172005-04-21 23:48:37 +0000131 std::map<Value*,std::vector<Value*> >::iterator it =
Reid Spencerf39f66e2004-08-21 21:39:24 +0000132 packedToScalarMap.lower_bound(value);
133 if (it == packedToScalarMap.end() || it->first != value) {
134 // there was not a forward reference to this element
135 packedToScalarMap.insert(it,std::make_pair(value,values));
136 }
137 else {
138 // replace forward declarations with actual definitions
Misha Brukmanb1c93172005-04-21 23:48:37 +0000139 assert(it->second.size() == values.size() &&
Reid Spencerf39f66e2004-08-21 21:39:24 +0000140 "Error forward refences and actual definition differ in size");
141 for (unsigned i = 0, e = values.size(); i != e; ++i) {
142 // replace and get rid of old forward references
143 it->second[i]->replaceAllUsesWith(values[i]);
144 delete it->second[i];
145 it->second[i] = values[i];
146 }
147 }
148}
149
150// This function will examine the packed value parameter
151// and if it is a packed constant or a forward reference
152// properly create the lowered values needed. Otherwise
Misha Brukmanb1c93172005-04-21 23:48:37 +0000153// it will simply retreive values from a
154// setValues(Value*,const std::vector<Value*>&)
Reid Spencerf39f66e2004-08-21 21:39:24 +0000155// call. Failing both of these cases, it will abort
156// the program.
157std::vector<Value*>& LowerPacked::getValues(Value* value)
158{
Reid Spencerd84d35b2007-02-15 02:26:10 +0000159 assert(isa<VectorType>(value->getType()) &&
160 "Value must be VectorType");
Reid Spencerf39f66e2004-08-21 21:39:24 +0000161
162 // reject further processing if this one has
163 // already been handled
Misha Brukmanb1c93172005-04-21 23:48:37 +0000164 std::map<Value*,std::vector<Value*> >::iterator it =
Reid Spencerf39f66e2004-08-21 21:39:24 +0000165 packedToScalarMap.lower_bound(value);
166 if (it != packedToScalarMap.end() && it->first == value) {
167 return it->second;
168 }
169
Reid Spencerd84d35b2007-02-15 02:26:10 +0000170 if (ConstantVector* CP = dyn_cast<ConstantVector>(value)) {
Reid Spencerf39f66e2004-08-21 21:39:24 +0000171 // non-zero constant case
172 std::vector<Value*> results;
173 results.reserve(CP->getNumOperands());
174 for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) {
175 results.push_back(CP->getOperand(i));
176 }
177 return packedToScalarMap.insert(it,
178 std::make_pair(value,results))->second;
179 }
180 else if (ConstantAggregateZero* CAZ =
181 dyn_cast<ConstantAggregateZero>(value)) {
Misha Brukmanb1c93172005-04-21 23:48:37 +0000182 // zero constant
Reid Spencerd84d35b2007-02-15 02:26:10 +0000183 const VectorType* PKT = cast<VectorType>(CAZ->getType());
Reid Spencerf39f66e2004-08-21 21:39:24 +0000184 std::vector<Value*> results;
185 results.reserve(PKT->getNumElements());
Misha Brukmanb1c93172005-04-21 23:48:37 +0000186
Reid Spencerf39f66e2004-08-21 21:39:24 +0000187 Constant* C = Constant::getNullValue(PKT->getElementType());
188 for (unsigned i = 0, e = PKT->getNumElements(); i != e; ++i) {
189 results.push_back(C);
190 }
191 return packedToScalarMap.insert(it,
192 std::make_pair(value,results))->second;
193 }
194 else if (isa<Instruction>(value)) {
195 // foward reference
Reid Spencerd84d35b2007-02-15 02:26:10 +0000196 const VectorType* PKT = cast<VectorType>(value->getType());
Reid Spencerf39f66e2004-08-21 21:39:24 +0000197 std::vector<Value*> results;
198 results.reserve(PKT->getNumElements());
Misha Brukmanb1c93172005-04-21 23:48:37 +0000199
Reid Spencerf39f66e2004-08-21 21:39:24 +0000200 for (unsigned i = 0, e = PKT->getNumElements(); i != e; ++i) {
201 results.push_back(new Argument(PKT->getElementType()));
202 }
203 return packedToScalarMap.insert(it,
204 std::make_pair(value,results))->second;
205 }
206 else {
207 // we don't know what it is, and we are trying to retrieve
208 // a value for it
Reid Spencerd84d35b2007-02-15 02:26:10 +0000209 assert(false && "Unhandled VectorType value");
Reid Spencerf39f66e2004-08-21 21:39:24 +0000210 abort();
211 }
212}
213
214void LowerPacked::visitLoadInst(LoadInst& LI)
215{
Reid Spencer09575ba2007-02-15 03:39:18 +0000216 // Make sure what we are dealing with is a vector type
Reid Spencerd84d35b2007-02-15 02:26:10 +0000217 if (const VectorType* PKT = dyn_cast<VectorType>(LI.getType())) {
Reid Spencerf39f66e2004-08-21 21:39:24 +0000218 // Initialization, Idx is needed for getelementptr needed later
Dan Gohman3bcd5fe2007-10-29 20:24:00 +0000219 Value *Idx[2];
Reid Spencerc635f472006-12-31 05:48:39 +0000220 Idx[0] = ConstantInt::get(Type::Int32Ty,0);
Reid Spencerf39f66e2004-08-21 21:39:24 +0000221
222 ArrayType* AT = ArrayType::get(PKT->getContainedType(0),
223 PKT->getNumElements());
224 PointerType* APT = PointerType::get(AT);
225
Reid Spencer09575ba2007-02-15 03:39:18 +0000226 // Cast the pointer to vector type to an equivalent array
Reid Spencer6c38f0b2006-11-27 01:05:10 +0000227 Value* array = new BitCastInst(LI.getPointerOperand(), APT,
228 LI.getName() + ".a", &LI);
Reid Spencerf39f66e2004-08-21 21:39:24 +0000229
230 // Convert this load into num elements number of loads
231 std::vector<Value*> values;
232 values.reserve(PKT->getNumElements());
233
234 for (unsigned i = 0, e = PKT->getNumElements(); i != e; ++i) {
235 // Calculate the second index we will need
Reid Spencerc635f472006-12-31 05:48:39 +0000236 Idx[1] = ConstantInt::get(Type::Int32Ty,i);
Reid Spencerf39f66e2004-08-21 21:39:24 +0000237
238 // Get the pointer
Misha Brukmanb1c93172005-04-21 23:48:37 +0000239 Value* val = new GetElementPtrInst(array,
Dan Gohman3bcd5fe2007-10-29 20:24:00 +0000240 Idx, array_endof(Idx),
Misha Brukmanb1c93172005-04-21 23:48:37 +0000241 LI.getName() +
Reid Spencerf39f66e2004-08-21 21:39:24 +0000242 ".ge." + utostr(i),
243 &LI);
244
245 // generate the new load and save the result in packedToScalar map
Reid Spencer6c38f0b2006-11-27 01:05:10 +0000246 values.push_back(new LoadInst(val, LI.getName()+"."+utostr(i),
247 LI.isVolatile(), &LI));
Reid Spencerf39f66e2004-08-21 21:39:24 +0000248 }
Misha Brukmanb1c93172005-04-21 23:48:37 +0000249
Reid Spencerf39f66e2004-08-21 21:39:24 +0000250 setValues(&LI,values);
251 Changed = true;
252 instrsToRemove.push_back(&LI);
253 }
254}
255
256void LowerPacked::visitBinaryOperator(BinaryOperator& BO)
257{
Reid Spencerd84d35b2007-02-15 02:26:10 +0000258 // Make sure both operands are VectorTypes
259 if (isa<VectorType>(BO.getOperand(0)->getType())) {
Reid Spencerf39f66e2004-08-21 21:39:24 +0000260 std::vector<Value*>& op0Vals = getValues(BO.getOperand(0));
261 std::vector<Value*>& op1Vals = getValues(BO.getOperand(1));
262 std::vector<Value*> result;
263 assert((op0Vals.size() == op1Vals.size()) &&
264 "The two packed operand to scalar maps must be equal in size.");
265
266 result.reserve(op0Vals.size());
Misha Brukmanb1c93172005-04-21 23:48:37 +0000267
Reid Spencerf39f66e2004-08-21 21:39:24 +0000268 // generate the new binary op and save the result
269 for (unsigned i = 0; i != op0Vals.size(); ++i) {
Misha Brukmanb1c93172005-04-21 23:48:37 +0000270 result.push_back(BinaryOperator::create(BO.getOpcode(),
271 op0Vals[i],
Reid Spencerf39f66e2004-08-21 21:39:24 +0000272 op1Vals[i],
Misha Brukmanb1c93172005-04-21 23:48:37 +0000273 BO.getName() +
Reid Spencerf39f66e2004-08-21 21:39:24 +0000274 "." + utostr(i),
275 &BO));
276 }
277
278 setValues(&BO,result);
279 Changed = true;
280 instrsToRemove.push_back(&BO);
281 }
282}
283
Reid Spencer266e42b2006-12-23 06:05:41 +0000284void LowerPacked::visitICmpInst(ICmpInst& IC)
285{
Reid Spencerd84d35b2007-02-15 02:26:10 +0000286 // Make sure both operands are VectorTypes
287 if (isa<VectorType>(IC.getOperand(0)->getType())) {
Reid Spencer266e42b2006-12-23 06:05:41 +0000288 std::vector<Value*>& op0Vals = getValues(IC.getOperand(0));
289 std::vector<Value*>& op1Vals = getValues(IC.getOperand(1));
290 std::vector<Value*> result;
291 assert((op0Vals.size() == op1Vals.size()) &&
292 "The two packed operand to scalar maps must be equal in size.");
293
294 result.reserve(op0Vals.size());
295
296 // generate the new binary op and save the result
297 for (unsigned i = 0; i != op0Vals.size(); ++i) {
298 result.push_back(CmpInst::create(IC.getOpcode(),
299 IC.getPredicate(),
300 op0Vals[i],
301 op1Vals[i],
302 IC.getName() +
303 "." + utostr(i),
304 &IC));
305 }
306
307 setValues(&IC,result);
308 Changed = true;
309 instrsToRemove.push_back(&IC);
310 }
311}
312
Reid Spencerf39f66e2004-08-21 21:39:24 +0000313void LowerPacked::visitStoreInst(StoreInst& SI)
314{
Reid Spencerd84d35b2007-02-15 02:26:10 +0000315 if (const VectorType* PKT =
316 dyn_cast<VectorType>(SI.getOperand(0)->getType())) {
Reid Spencerf39f66e2004-08-21 21:39:24 +0000317 // We will need this for getelementptr
Dan Gohman3bcd5fe2007-10-29 20:24:00 +0000318 Value *Idx[2];
Reid Spencerc635f472006-12-31 05:48:39 +0000319 Idx[0] = ConstantInt::get(Type::Int32Ty,0);
Misha Brukmanb1c93172005-04-21 23:48:37 +0000320
Reid Spencerf39f66e2004-08-21 21:39:24 +0000321 ArrayType* AT = ArrayType::get(PKT->getContainedType(0),
322 PKT->getNumElements());
323 PointerType* APT = PointerType::get(AT);
324
Reid Spencer6c38f0b2006-11-27 01:05:10 +0000325 // Cast the pointer to packed to an array of equivalent type
326 Value* array = new BitCastInst(SI.getPointerOperand(), APT,
327 "store.ge.a.", &SI);
328
Reid Spencerf39f66e2004-08-21 21:39:24 +0000329 std::vector<Value*>& values = getValues(SI.getOperand(0));
Misha Brukmanb1c93172005-04-21 23:48:37 +0000330
Reid Spencerf39f66e2004-08-21 21:39:24 +0000331 assert((values.size() == PKT->getNumElements()) &&
Reid Spencer537ee022007-02-15 03:11:20 +0000332 "Scalar must have the same number of elements as Vector Type");
Reid Spencerf39f66e2004-08-21 21:39:24 +0000333
334 for (unsigned i = 0, e = PKT->getNumElements(); i != e; ++i) {
335 // Generate the indices for getelementptr
Reid Spencerc635f472006-12-31 05:48:39 +0000336 Idx[1] = ConstantInt::get(Type::Int32Ty,i);
Misha Brukmanb1c93172005-04-21 23:48:37 +0000337 Value* val = new GetElementPtrInst(array,
Dan Gohman3bcd5fe2007-10-29 20:24:00 +0000338 Idx, array_endof(Idx),
Reid Spencerf39f66e2004-08-21 21:39:24 +0000339 "store.ge." +
340 utostr(i) + ".",
341 &SI);
342 new StoreInst(values[i], val, SI.isVolatile(),&SI);
343 }
Misha Brukmanb1c93172005-04-21 23:48:37 +0000344
Reid Spencerf39f66e2004-08-21 21:39:24 +0000345 Changed = true;
346 instrsToRemove.push_back(&SI);
347 }
348}
349
350void LowerPacked::visitSelectInst(SelectInst& SELI)
351{
Reid Spencerd84d35b2007-02-15 02:26:10 +0000352 // Make sure both operands are VectorTypes
353 if (isa<VectorType>(SELI.getType())) {
Reid Spencerf39f66e2004-08-21 21:39:24 +0000354 std::vector<Value*>& op0Vals = getValues(SELI.getTrueValue());
355 std::vector<Value*>& op1Vals = getValues(SELI.getFalseValue());
356 std::vector<Value*> result;
357
358 assert((op0Vals.size() == op1Vals.size()) &&
359 "The two packed operand to scalar maps must be equal in size.");
360
361 for (unsigned i = 0; i != op0Vals.size(); ++i) {
362 result.push_back(new SelectInst(SELI.getCondition(),
Misha Brukmanb1c93172005-04-21 23:48:37 +0000363 op0Vals[i],
Reid Spencerf39f66e2004-08-21 21:39:24 +0000364 op1Vals[i],
365 SELI.getName()+ "." + utostr(i),
366 &SELI));
367 }
Misha Brukmanb1c93172005-04-21 23:48:37 +0000368
Reid Spencerf39f66e2004-08-21 21:39:24 +0000369 setValues(&SELI,result);
370 Changed = true;
371 instrsToRemove.push_back(&SELI);
372 }
373}
374
Robert Bocchinobd518d12006-01-10 19:05:05 +0000375void LowerPacked::visitExtractElementInst(ExtractElementInst& EI)
376{
377 std::vector<Value*>& op0Vals = getValues(EI.getOperand(0));
Reid Spencerd84d35b2007-02-15 02:26:10 +0000378 const VectorType *PTy = cast<VectorType>(EI.getOperand(0)->getType());
Robert Bocchinobd518d12006-01-10 19:05:05 +0000379 Value *op1 = EI.getOperand(1);
380
Reid Spencere0fc4df2006-10-20 07:07:24 +0000381 if (ConstantInt *C = dyn_cast<ConstantInt>(op1)) {
382 EI.replaceAllUsesWith(op0Vals[C->getZExtValue()]);
Robert Bocchinobd518d12006-01-10 19:05:05 +0000383 } else {
Robert Bocchino6dce2502006-01-17 20:06:55 +0000384 AllocaInst *alloca =
385 new AllocaInst(PTy->getElementType(),
Reid Spencerc635f472006-12-31 05:48:39 +0000386 ConstantInt::get(Type::Int32Ty, PTy->getNumElements()),
Robert Bocchino6dce2502006-01-17 20:06:55 +0000387 EI.getName() + ".alloca",
Anton Korobeynikovfb801512007-04-16 18:10:23 +0000388 EI.getParent()->getParent()->getEntryBlock().begin());
Robert Bocchinobd518d12006-01-10 19:05:05 +0000389 for (unsigned i = 0; i < PTy->getNumElements(); ++i) {
Robert Bocchino6dce2502006-01-17 20:06:55 +0000390 GetElementPtrInst *GEP =
Reid Spencerc635f472006-12-31 05:48:39 +0000391 new GetElementPtrInst(alloca, ConstantInt::get(Type::Int32Ty, i),
Robert Bocchino6dce2502006-01-17 20:06:55 +0000392 "store.ge", &EI);
Robert Bocchinobd518d12006-01-10 19:05:05 +0000393 new StoreInst(op0Vals[i], GEP, &EI);
394 }
Robert Bocchino6dce2502006-01-17 20:06:55 +0000395 GetElementPtrInst *GEP =
396 new GetElementPtrInst(alloca, op1, EI.getName() + ".ge", &EI);
Robert Bocchinobd518d12006-01-10 19:05:05 +0000397 LoadInst *load = new LoadInst(GEP, EI.getName() + ".load", &EI);
398 EI.replaceAllUsesWith(load);
399 }
400
401 Changed = true;
402 instrsToRemove.push_back(&EI);
403}
404
Robert Bocchino6dce2502006-01-17 20:06:55 +0000405void LowerPacked::visitInsertElementInst(InsertElementInst& IE)
406{
407 std::vector<Value*>& Vals = getValues(IE.getOperand(0));
408 Value *Elt = IE.getOperand(1);
409 Value *Idx = IE.getOperand(2);
410 std::vector<Value*> result;
411 result.reserve(Vals.size());
412
Reid Spencere0fc4df2006-10-20 07:07:24 +0000413 if (ConstantInt *C = dyn_cast<ConstantInt>(Idx)) {
414 unsigned idxVal = C->getZExtValue();
Robert Bocchino6dce2502006-01-17 20:06:55 +0000415 for (unsigned i = 0; i != Vals.size(); ++i) {
416 result.push_back(i == idxVal ? Elt : Vals[i]);
417 }
418 } else {
419 for (unsigned i = 0; i != Vals.size(); ++i) {
Reid Spencer266e42b2006-12-23 06:05:41 +0000420 ICmpInst *icmp =
421 new ICmpInst(ICmpInst::ICMP_EQ, Idx,
Reid Spencerc635f472006-12-31 05:48:39 +0000422 ConstantInt::get(Type::Int32Ty, i),
Reid Spencer266e42b2006-12-23 06:05:41 +0000423 "icmp", &IE);
Robert Bocchino6dce2502006-01-17 20:06:55 +0000424 SelectInst *select =
Reid Spencer266e42b2006-12-23 06:05:41 +0000425 new SelectInst(icmp, Elt, Vals[i], "select", &IE);
Robert Bocchino6dce2502006-01-17 20:06:55 +0000426 result.push_back(select);
427 }
428 }
429
430 setValues(&IE, result);
431 Changed = true;
432 instrsToRemove.push_back(&IE);
433}
434
Reid Spencerf39f66e2004-08-21 21:39:24 +0000435bool LowerPacked::runOnFunction(Function& F)
436{
437 // initialize
Misha Brukmanb1c93172005-04-21 23:48:37 +0000438 Changed = false;
439
Reid Spencerf39f66e2004-08-21 21:39:24 +0000440 // Does three passes:
Misha Brukmanb1c93172005-04-21 23:48:37 +0000441 // Pass 1) Converts Packed Operations to
Reid Spencerf39f66e2004-08-21 21:39:24 +0000442 // new Packed Operations on smaller
443 // datatypes
444 visit(F);
Misha Brukmanb1c93172005-04-21 23:48:37 +0000445
Reid Spencerf39f66e2004-08-21 21:39:24 +0000446 // Pass 2) Drop all references
447 std::for_each(instrsToRemove.begin(),
448 instrsToRemove.end(),
449 std::mem_fun(&Instruction::dropAllReferences));
450
451 // Pass 3) Delete the Instructions to remove aka packed instructions
Misha Brukmanb1c93172005-04-21 23:48:37 +0000452 for (std::vector<Instruction*>::iterator i = instrsToRemove.begin(),
453 e = instrsToRemove.end();
Reid Spencerf39f66e2004-08-21 21:39:24 +0000454 i != e; ++i) {
Misha Brukmanb1c93172005-04-21 23:48:37 +0000455 (*i)->getParent()->getInstList().erase(*i);
Reid Spencerf39f66e2004-08-21 21:39:24 +0000456 }
457
458 // clean-up
459 packedToScalarMap.clear();
460 instrsToRemove.clear();
461
462 return Changed;
463}
464