blob: 4e1d280b1ec2bb93e27b7f0084555ae23dcdb73d [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"
Reid Spencer7c16caa2004-09-01 22:55:40 +000025#include "llvm/ADT/StringExtras.h"
Reid Spencerf39f66e2004-08-21 21:39:24 +000026#include <algorithm>
27#include <map>
Duraid Madina7a3ad6c2005-12-26 13:48:44 +000028#include <functional>
Reid Spencerf39f66e2004-08-21 21:39:24 +000029using namespace llvm;
30
31namespace {
32
33/// This pass converts packed operators to an
34/// equivalent operations on smaller packed data, to possibly
35/// scalar operations. Currently it supports lowering
36/// to scalar operations.
37///
38/// @brief Transforms packed instructions to simpler instructions.
39///
Reid Spencer557ab152007-02-05 23:32:05 +000040class VISIBILITY_HIDDEN LowerPacked
41 : public FunctionPass, public InstVisitor<LowerPacked> {
Reid Spencerf39f66e2004-08-21 21:39:24 +000042public:
Misha Brukmanb1c93172005-04-21 23:48:37 +000043 /// @brief Lowers packed operations to scalar operations.
Reid Spencerf39f66e2004-08-21 21:39:24 +000044 /// @param F The fuction to process
45 virtual bool runOnFunction(Function &F);
46
47 /// @brief Lowers packed load instructions.
48 /// @param LI the load instruction to convert
49 void visitLoadInst(LoadInst& LI);
50
51 /// @brief Lowers packed store instructions.
52 /// @param SI the store instruction to convert
53 void visitStoreInst(StoreInst& SI);
54
55 /// @brief Lowers packed binary operations.
56 /// @param BO the binary operator to convert
57 void visitBinaryOperator(BinaryOperator& BO);
58
Reid Spencer266e42b2006-12-23 06:05:41 +000059 /// @brief Lowers packed icmp operations.
60 /// @param CI the icmp operator to convert
61 void visitICmpInst(ICmpInst& IC);
62
Reid Spencerf39f66e2004-08-21 21:39:24 +000063 /// @brief Lowers packed select instructions.
64 /// @param SELI the select operator to convert
65 void visitSelectInst(SelectInst& SELI);
66
Robert Bocchinobd518d12006-01-10 19:05:05 +000067 /// @brief Lowers packed extractelement instructions.
68 /// @param EI the extractelement operator to convert
Robert Bocchino6dce2502006-01-17 20:06:55 +000069 void visitExtractElementInst(ExtractElementInst& EE);
70
71 /// @brief Lowers packed insertelement instructions.
72 /// @param EI the insertelement operator to convert
73 void visitInsertElementInst(InsertElementInst& IE);
Robert Bocchinobd518d12006-01-10 19:05:05 +000074
Reid Spencerd84d35b2007-02-15 02:26:10 +000075 /// This function asserts if the instruction is a VectorType but
Reid Spencerf39f66e2004-08-21 21:39:24 +000076 /// is handled by another function.
Misha Brukmanb1c93172005-04-21 23:48:37 +000077 ///
Reid Spencerd84d35b2007-02-15 02:26:10 +000078 /// @brief Asserts if VectorType instruction is not handled elsewhere.
Reid Spencerf39f66e2004-08-21 21:39:24 +000079 /// @param I the unhandled instruction
Bill Wendling5dbf43c2006-11-26 09:46:52 +000080 void visitInstruction(Instruction &I) {
Reid Spencerd84d35b2007-02-15 02:26:10 +000081 if (isa<VectorType>(I.getType()))
Bill Wendlingf3baad32006-12-07 01:30:32 +000082 cerr << "Unhandled Instruction with Packed ReturnType: " << I << '\n';
Reid Spencerf39f66e2004-08-21 21:39:24 +000083 }
84private:
85 /// @brief Retrieves lowered values for a packed value.
86 /// @param val the packed value
87 /// @return the lowered values
88 std::vector<Value*>& getValues(Value* val);
89
90 /// @brief Sets lowered values for a packed value.
91 /// @param val the packed value
92 /// @param values the corresponding lowered values
93 void setValues(Value* val,const std::vector<Value*>& values);
94
95 // Data Members
Misha Brukmanb1c93172005-04-21 23:48:37 +000096 /// @brief whether we changed the function or not
Reid Spencerf39f66e2004-08-21 21:39:24 +000097 bool Changed;
98
99 /// @brief a map from old packed values to new smaller packed values
100 std::map<Value*,std::vector<Value*> > packedToScalarMap;
101
102 /// Instructions in the source program to get rid of
103 /// after we do a pass (the old packed instructions)
104 std::vector<Instruction*> instrsToRemove;
Misha Brukmanb1c93172005-04-21 23:48:37 +0000105};
Reid Spencerf39f66e2004-08-21 21:39:24 +0000106
Chris Lattnerc2d3d312006-08-27 22:42:52 +0000107RegisterPass<LowerPacked>
Misha Brukmanb1c93172005-04-21 23:48:37 +0000108X("lower-packed",
Reid Spencerf39f66e2004-08-21 21:39:24 +0000109 "lowers packed operations to operations on smaller packed datatypes");
110
Misha Brukmanb1c93172005-04-21 23:48:37 +0000111} // end namespace
Reid Spencerf39f66e2004-08-21 21:39:24 +0000112
Chris Lattner446948e2004-11-19 16:49:34 +0000113FunctionPass *llvm::createLowerPackedPass() { return new LowerPacked(); }
Chris Lattnerc08ac112004-11-18 17:24:20 +0000114
115
Reid Spencerf39f66e2004-08-21 21:39:24 +0000116// This function sets lowered values for a corresponding
117// packed value. Note, in the case of a forward reference
Misha Brukmanb1c93172005-04-21 23:48:37 +0000118// getValues(Value*) will have already been called for
119// the packed parameter. This function will then replace
120// all references in the in the function of the "dummy"
121// value the previous getValues(Value*) call
Reid Spencerf39f66e2004-08-21 21:39:24 +0000122// returned with actual references.
123void LowerPacked::setValues(Value* value,const std::vector<Value*>& values)
124{
Misha Brukmanb1c93172005-04-21 23:48:37 +0000125 std::map<Value*,std::vector<Value*> >::iterator it =
Reid Spencerf39f66e2004-08-21 21:39:24 +0000126 packedToScalarMap.lower_bound(value);
127 if (it == packedToScalarMap.end() || it->first != value) {
128 // there was not a forward reference to this element
129 packedToScalarMap.insert(it,std::make_pair(value,values));
130 }
131 else {
132 // replace forward declarations with actual definitions
Misha Brukmanb1c93172005-04-21 23:48:37 +0000133 assert(it->second.size() == values.size() &&
Reid Spencerf39f66e2004-08-21 21:39:24 +0000134 "Error forward refences and actual definition differ in size");
135 for (unsigned i = 0, e = values.size(); i != e; ++i) {
136 // replace and get rid of old forward references
137 it->second[i]->replaceAllUsesWith(values[i]);
138 delete it->second[i];
139 it->second[i] = values[i];
140 }
141 }
142}
143
144// This function will examine the packed value parameter
145// and if it is a packed constant or a forward reference
146// properly create the lowered values needed. Otherwise
Misha Brukmanb1c93172005-04-21 23:48:37 +0000147// it will simply retreive values from a
148// setValues(Value*,const std::vector<Value*>&)
Reid Spencerf39f66e2004-08-21 21:39:24 +0000149// call. Failing both of these cases, it will abort
150// the program.
151std::vector<Value*>& LowerPacked::getValues(Value* value)
152{
Reid Spencerd84d35b2007-02-15 02:26:10 +0000153 assert(isa<VectorType>(value->getType()) &&
154 "Value must be VectorType");
Reid Spencerf39f66e2004-08-21 21:39:24 +0000155
156 // reject further processing if this one has
157 // already been handled
Misha Brukmanb1c93172005-04-21 23:48:37 +0000158 std::map<Value*,std::vector<Value*> >::iterator it =
Reid Spencerf39f66e2004-08-21 21:39:24 +0000159 packedToScalarMap.lower_bound(value);
160 if (it != packedToScalarMap.end() && it->first == value) {
161 return it->second;
162 }
163
Reid Spencerd84d35b2007-02-15 02:26:10 +0000164 if (ConstantVector* CP = dyn_cast<ConstantVector>(value)) {
Reid Spencerf39f66e2004-08-21 21:39:24 +0000165 // non-zero constant case
166 std::vector<Value*> results;
167 results.reserve(CP->getNumOperands());
168 for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) {
169 results.push_back(CP->getOperand(i));
170 }
171 return packedToScalarMap.insert(it,
172 std::make_pair(value,results))->second;
173 }
174 else if (ConstantAggregateZero* CAZ =
175 dyn_cast<ConstantAggregateZero>(value)) {
Misha Brukmanb1c93172005-04-21 23:48:37 +0000176 // zero constant
Reid Spencerd84d35b2007-02-15 02:26:10 +0000177 const VectorType* PKT = cast<VectorType>(CAZ->getType());
Reid Spencerf39f66e2004-08-21 21:39:24 +0000178 std::vector<Value*> results;
179 results.reserve(PKT->getNumElements());
Misha Brukmanb1c93172005-04-21 23:48:37 +0000180
Reid Spencerf39f66e2004-08-21 21:39:24 +0000181 Constant* C = Constant::getNullValue(PKT->getElementType());
182 for (unsigned i = 0, e = PKT->getNumElements(); i != e; ++i) {
183 results.push_back(C);
184 }
185 return packedToScalarMap.insert(it,
186 std::make_pair(value,results))->second;
187 }
188 else if (isa<Instruction>(value)) {
189 // foward reference
Reid Spencerd84d35b2007-02-15 02:26:10 +0000190 const VectorType* PKT = cast<VectorType>(value->getType());
Reid Spencerf39f66e2004-08-21 21:39:24 +0000191 std::vector<Value*> results;
192 results.reserve(PKT->getNumElements());
Misha Brukmanb1c93172005-04-21 23:48:37 +0000193
Reid Spencerf39f66e2004-08-21 21:39:24 +0000194 for (unsigned i = 0, e = PKT->getNumElements(); i != e; ++i) {
195 results.push_back(new Argument(PKT->getElementType()));
196 }
197 return packedToScalarMap.insert(it,
198 std::make_pair(value,results))->second;
199 }
200 else {
201 // we don't know what it is, and we are trying to retrieve
202 // a value for it
Reid Spencerd84d35b2007-02-15 02:26:10 +0000203 assert(false && "Unhandled VectorType value");
Reid Spencerf39f66e2004-08-21 21:39:24 +0000204 abort();
205 }
206}
207
208void LowerPacked::visitLoadInst(LoadInst& LI)
209{
Reid Spencer09575ba2007-02-15 03:39:18 +0000210 // Make sure what we are dealing with is a vector type
Reid Spencerd84d35b2007-02-15 02:26:10 +0000211 if (const VectorType* PKT = dyn_cast<VectorType>(LI.getType())) {
Reid Spencerf39f66e2004-08-21 21:39:24 +0000212 // Initialization, Idx is needed for getelementptr needed later
213 std::vector<Value*> Idx(2);
Reid Spencerc635f472006-12-31 05:48:39 +0000214 Idx[0] = ConstantInt::get(Type::Int32Ty,0);
Reid Spencerf39f66e2004-08-21 21:39:24 +0000215
216 ArrayType* AT = ArrayType::get(PKT->getContainedType(0),
217 PKT->getNumElements());
218 PointerType* APT = PointerType::get(AT);
219
Reid Spencer09575ba2007-02-15 03:39:18 +0000220 // Cast the pointer to vector type to an equivalent array
Reid Spencer6c38f0b2006-11-27 01:05:10 +0000221 Value* array = new BitCastInst(LI.getPointerOperand(), APT,
222 LI.getName() + ".a", &LI);
Reid Spencerf39f66e2004-08-21 21:39:24 +0000223
224 // Convert this load into num elements number of loads
225 std::vector<Value*> values;
226 values.reserve(PKT->getNumElements());
227
228 for (unsigned i = 0, e = PKT->getNumElements(); i != e; ++i) {
229 // Calculate the second index we will need
Reid Spencerc635f472006-12-31 05:48:39 +0000230 Idx[1] = ConstantInt::get(Type::Int32Ty,i);
Reid Spencerf39f66e2004-08-21 21:39:24 +0000231
232 // Get the pointer
Misha Brukmanb1c93172005-04-21 23:48:37 +0000233 Value* val = new GetElementPtrInst(array,
Chris Lattnera7315132007-02-12 22:56:41 +0000234 &Idx[0], Idx.size(),
Misha Brukmanb1c93172005-04-21 23:48:37 +0000235 LI.getName() +
Reid Spencerf39f66e2004-08-21 21:39:24 +0000236 ".ge." + utostr(i),
237 &LI);
238
239 // generate the new load and save the result in packedToScalar map
Reid Spencer6c38f0b2006-11-27 01:05:10 +0000240 values.push_back(new LoadInst(val, LI.getName()+"."+utostr(i),
241 LI.isVolatile(), &LI));
Reid Spencerf39f66e2004-08-21 21:39:24 +0000242 }
Misha Brukmanb1c93172005-04-21 23:48:37 +0000243
Reid Spencerf39f66e2004-08-21 21:39:24 +0000244 setValues(&LI,values);
245 Changed = true;
246 instrsToRemove.push_back(&LI);
247 }
248}
249
250void LowerPacked::visitBinaryOperator(BinaryOperator& BO)
251{
Reid Spencerd84d35b2007-02-15 02:26:10 +0000252 // Make sure both operands are VectorTypes
253 if (isa<VectorType>(BO.getOperand(0)->getType())) {
Reid Spencerf39f66e2004-08-21 21:39:24 +0000254 std::vector<Value*>& op0Vals = getValues(BO.getOperand(0));
255 std::vector<Value*>& op1Vals = getValues(BO.getOperand(1));
256 std::vector<Value*> result;
257 assert((op0Vals.size() == op1Vals.size()) &&
258 "The two packed operand to scalar maps must be equal in size.");
259
260 result.reserve(op0Vals.size());
Misha Brukmanb1c93172005-04-21 23:48:37 +0000261
Reid Spencerf39f66e2004-08-21 21:39:24 +0000262 // generate the new binary op and save the result
263 for (unsigned i = 0; i != op0Vals.size(); ++i) {
Misha Brukmanb1c93172005-04-21 23:48:37 +0000264 result.push_back(BinaryOperator::create(BO.getOpcode(),
265 op0Vals[i],
Reid Spencerf39f66e2004-08-21 21:39:24 +0000266 op1Vals[i],
Misha Brukmanb1c93172005-04-21 23:48:37 +0000267 BO.getName() +
Reid Spencerf39f66e2004-08-21 21:39:24 +0000268 "." + utostr(i),
269 &BO));
270 }
271
272 setValues(&BO,result);
273 Changed = true;
274 instrsToRemove.push_back(&BO);
275 }
276}
277
Reid Spencer266e42b2006-12-23 06:05:41 +0000278void LowerPacked::visitICmpInst(ICmpInst& IC)
279{
Reid Spencerd84d35b2007-02-15 02:26:10 +0000280 // Make sure both operands are VectorTypes
281 if (isa<VectorType>(IC.getOperand(0)->getType())) {
Reid Spencer266e42b2006-12-23 06:05:41 +0000282 std::vector<Value*>& op0Vals = getValues(IC.getOperand(0));
283 std::vector<Value*>& op1Vals = getValues(IC.getOperand(1));
284 std::vector<Value*> result;
285 assert((op0Vals.size() == op1Vals.size()) &&
286 "The two packed operand to scalar maps must be equal in size.");
287
288 result.reserve(op0Vals.size());
289
290 // generate the new binary op and save the result
291 for (unsigned i = 0; i != op0Vals.size(); ++i) {
292 result.push_back(CmpInst::create(IC.getOpcode(),
293 IC.getPredicate(),
294 op0Vals[i],
295 op1Vals[i],
296 IC.getName() +
297 "." + utostr(i),
298 &IC));
299 }
300
301 setValues(&IC,result);
302 Changed = true;
303 instrsToRemove.push_back(&IC);
304 }
305}
306
Reid Spencerf39f66e2004-08-21 21:39:24 +0000307void LowerPacked::visitStoreInst(StoreInst& SI)
308{
Reid Spencerd84d35b2007-02-15 02:26:10 +0000309 if (const VectorType* PKT =
310 dyn_cast<VectorType>(SI.getOperand(0)->getType())) {
Reid Spencerf39f66e2004-08-21 21:39:24 +0000311 // We will need this for getelementptr
312 std::vector<Value*> Idx(2);
Reid Spencerc635f472006-12-31 05:48:39 +0000313 Idx[0] = ConstantInt::get(Type::Int32Ty,0);
Misha Brukmanb1c93172005-04-21 23:48:37 +0000314
Reid Spencerf39f66e2004-08-21 21:39:24 +0000315 ArrayType* AT = ArrayType::get(PKT->getContainedType(0),
316 PKT->getNumElements());
317 PointerType* APT = PointerType::get(AT);
318
Reid Spencer6c38f0b2006-11-27 01:05:10 +0000319 // Cast the pointer to packed to an array of equivalent type
320 Value* array = new BitCastInst(SI.getPointerOperand(), APT,
321 "store.ge.a.", &SI);
322
Reid Spencerf39f66e2004-08-21 21:39:24 +0000323 std::vector<Value*>& values = getValues(SI.getOperand(0));
Misha Brukmanb1c93172005-04-21 23:48:37 +0000324
Reid Spencerf39f66e2004-08-21 21:39:24 +0000325 assert((values.size() == PKT->getNumElements()) &&
Reid Spencer537ee022007-02-15 03:11:20 +0000326 "Scalar must have the same number of elements as Vector Type");
Reid Spencerf39f66e2004-08-21 21:39:24 +0000327
328 for (unsigned i = 0, e = PKT->getNumElements(); i != e; ++i) {
329 // Generate the indices for getelementptr
Reid Spencerc635f472006-12-31 05:48:39 +0000330 Idx[1] = ConstantInt::get(Type::Int32Ty,i);
Misha Brukmanb1c93172005-04-21 23:48:37 +0000331 Value* val = new GetElementPtrInst(array,
Chris Lattnera7315132007-02-12 22:56:41 +0000332 &Idx[0], Idx.size(),
Reid Spencerf39f66e2004-08-21 21:39:24 +0000333 "store.ge." +
334 utostr(i) + ".",
335 &SI);
336 new StoreInst(values[i], val, SI.isVolatile(),&SI);
337 }
Misha Brukmanb1c93172005-04-21 23:48:37 +0000338
Reid Spencerf39f66e2004-08-21 21:39:24 +0000339 Changed = true;
340 instrsToRemove.push_back(&SI);
341 }
342}
343
344void LowerPacked::visitSelectInst(SelectInst& SELI)
345{
Reid Spencerd84d35b2007-02-15 02:26:10 +0000346 // Make sure both operands are VectorTypes
347 if (isa<VectorType>(SELI.getType())) {
Reid Spencerf39f66e2004-08-21 21:39:24 +0000348 std::vector<Value*>& op0Vals = getValues(SELI.getTrueValue());
349 std::vector<Value*>& op1Vals = getValues(SELI.getFalseValue());
350 std::vector<Value*> result;
351
352 assert((op0Vals.size() == op1Vals.size()) &&
353 "The two packed operand to scalar maps must be equal in size.");
354
355 for (unsigned i = 0; i != op0Vals.size(); ++i) {
356 result.push_back(new SelectInst(SELI.getCondition(),
Misha Brukmanb1c93172005-04-21 23:48:37 +0000357 op0Vals[i],
Reid Spencerf39f66e2004-08-21 21:39:24 +0000358 op1Vals[i],
359 SELI.getName()+ "." + utostr(i),
360 &SELI));
361 }
Misha Brukmanb1c93172005-04-21 23:48:37 +0000362
Reid Spencerf39f66e2004-08-21 21:39:24 +0000363 setValues(&SELI,result);
364 Changed = true;
365 instrsToRemove.push_back(&SELI);
366 }
367}
368
Robert Bocchinobd518d12006-01-10 19:05:05 +0000369void LowerPacked::visitExtractElementInst(ExtractElementInst& EI)
370{
371 std::vector<Value*>& op0Vals = getValues(EI.getOperand(0));
Reid Spencerd84d35b2007-02-15 02:26:10 +0000372 const VectorType *PTy = cast<VectorType>(EI.getOperand(0)->getType());
Robert Bocchinobd518d12006-01-10 19:05:05 +0000373 Value *op1 = EI.getOperand(1);
374
Reid Spencere0fc4df2006-10-20 07:07:24 +0000375 if (ConstantInt *C = dyn_cast<ConstantInt>(op1)) {
376 EI.replaceAllUsesWith(op0Vals[C->getZExtValue()]);
Robert Bocchinobd518d12006-01-10 19:05:05 +0000377 } else {
Robert Bocchino6dce2502006-01-17 20:06:55 +0000378 AllocaInst *alloca =
379 new AllocaInst(PTy->getElementType(),
Reid Spencerc635f472006-12-31 05:48:39 +0000380 ConstantInt::get(Type::Int32Ty, PTy->getNumElements()),
Robert Bocchino6dce2502006-01-17 20:06:55 +0000381 EI.getName() + ".alloca",
382 EI.getParent()->getParent()->getEntryBlock().begin());
Robert Bocchinobd518d12006-01-10 19:05:05 +0000383 for (unsigned i = 0; i < PTy->getNumElements(); ++i) {
Robert Bocchino6dce2502006-01-17 20:06:55 +0000384 GetElementPtrInst *GEP =
Reid Spencerc635f472006-12-31 05:48:39 +0000385 new GetElementPtrInst(alloca, ConstantInt::get(Type::Int32Ty, i),
Robert Bocchino6dce2502006-01-17 20:06:55 +0000386 "store.ge", &EI);
Robert Bocchinobd518d12006-01-10 19:05:05 +0000387 new StoreInst(op0Vals[i], GEP, &EI);
388 }
Robert Bocchino6dce2502006-01-17 20:06:55 +0000389 GetElementPtrInst *GEP =
390 new GetElementPtrInst(alloca, op1, EI.getName() + ".ge", &EI);
Robert Bocchinobd518d12006-01-10 19:05:05 +0000391 LoadInst *load = new LoadInst(GEP, EI.getName() + ".load", &EI);
392 EI.replaceAllUsesWith(load);
393 }
394
395 Changed = true;
396 instrsToRemove.push_back(&EI);
397}
398
Robert Bocchino6dce2502006-01-17 20:06:55 +0000399void LowerPacked::visitInsertElementInst(InsertElementInst& IE)
400{
401 std::vector<Value*>& Vals = getValues(IE.getOperand(0));
402 Value *Elt = IE.getOperand(1);
403 Value *Idx = IE.getOperand(2);
404 std::vector<Value*> result;
405 result.reserve(Vals.size());
406
Reid Spencere0fc4df2006-10-20 07:07:24 +0000407 if (ConstantInt *C = dyn_cast<ConstantInt>(Idx)) {
408 unsigned idxVal = C->getZExtValue();
Robert Bocchino6dce2502006-01-17 20:06:55 +0000409 for (unsigned i = 0; i != Vals.size(); ++i) {
410 result.push_back(i == idxVal ? Elt : Vals[i]);
411 }
412 } else {
413 for (unsigned i = 0; i != Vals.size(); ++i) {
Reid Spencer266e42b2006-12-23 06:05:41 +0000414 ICmpInst *icmp =
415 new ICmpInst(ICmpInst::ICMP_EQ, Idx,
Reid Spencerc635f472006-12-31 05:48:39 +0000416 ConstantInt::get(Type::Int32Ty, i),
Reid Spencer266e42b2006-12-23 06:05:41 +0000417 "icmp", &IE);
Robert Bocchino6dce2502006-01-17 20:06:55 +0000418 SelectInst *select =
Reid Spencer266e42b2006-12-23 06:05:41 +0000419 new SelectInst(icmp, Elt, Vals[i], "select", &IE);
Robert Bocchino6dce2502006-01-17 20:06:55 +0000420 result.push_back(select);
421 }
422 }
423
424 setValues(&IE, result);
425 Changed = true;
426 instrsToRemove.push_back(&IE);
427}
428
Reid Spencerf39f66e2004-08-21 21:39:24 +0000429bool LowerPacked::runOnFunction(Function& F)
430{
431 // initialize
Misha Brukmanb1c93172005-04-21 23:48:37 +0000432 Changed = false;
433
Reid Spencerf39f66e2004-08-21 21:39:24 +0000434 // Does three passes:
Misha Brukmanb1c93172005-04-21 23:48:37 +0000435 // Pass 1) Converts Packed Operations to
Reid Spencerf39f66e2004-08-21 21:39:24 +0000436 // new Packed Operations on smaller
437 // datatypes
438 visit(F);
Misha Brukmanb1c93172005-04-21 23:48:37 +0000439
Reid Spencerf39f66e2004-08-21 21:39:24 +0000440 // Pass 2) Drop all references
441 std::for_each(instrsToRemove.begin(),
442 instrsToRemove.end(),
443 std::mem_fun(&Instruction::dropAllReferences));
444
445 // Pass 3) Delete the Instructions to remove aka packed instructions
Misha Brukmanb1c93172005-04-21 23:48:37 +0000446 for (std::vector<Instruction*>::iterator i = instrsToRemove.begin(),
447 e = instrsToRemove.end();
Reid Spencerf39f66e2004-08-21 21:39:24 +0000448 i != e; ++i) {
Misha Brukmanb1c93172005-04-21 23:48:37 +0000449 (*i)->getParent()->getInstList().erase(*i);
Reid Spencerf39f66e2004-08-21 21:39:24 +0000450 }
451
452 // clean-up
453 packedToScalarMap.clear();
454 instrsToRemove.clear();
455
456 return Changed;
457}
458