blob: 359e29b4e6276f767de2ceff963d4c8534142201 [file] [log] [blame]
Reid Spencer42e83fe2004-08-21 21:39:24 +00001//===- LowerPacked.cpp - Implementation of LowerPacked Transform ---------===//
Misha Brukmanfd939082005-04-21 23:48:37 +00002//
Reid Spencer42e83fe2004-08-21 21:39:24 +00003// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Misha Brukmanfd939082005-04-21 23:48:37 +00007//
Reid Spencer42e83fe2004-08-21 21:39:24 +00008//===----------------------------------------------------------------------===//
9//
Gordon Henriksenc86b6772007-11-04 16:15:04 +000010// This file implements lowering vector datatypes into more primitive
11// vector datatypes, and finally to scalar operations.
Reid Spencer42e83fe2004-08-21 21:39:24 +000012//
13//===----------------------------------------------------------------------===//
14
Chris Lattner7b73a662004-11-19 16:49:34 +000015#include "llvm/Transforms/Scalar.h"
Reid Spencer42e83fe2004-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 Spencer9133fe22007-02-05 23:32:05 +000022#include "llvm/Support/Compiler.h"
Reid Spencer42e83fe2004-08-21 21:39:24 +000023#include "llvm/Support/InstVisitor.h"
Bill Wendlingb7427032006-11-26 09:46:52 +000024#include "llvm/Support/Streams.h"
Dan Gohman767cf702007-10-29 20:24:00 +000025#include "llvm/ADT/STLExtras.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000026#include "llvm/ADT/StringExtras.h"
Reid Spencer42e83fe2004-08-21 21:39:24 +000027#include <algorithm>
28#include <map>
Duraid Madinab5186852005-12-26 13:48:44 +000029#include <functional>
Reid Spencer42e83fe2004-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 Spencer9133fe22007-02-05 23:32:05 +000041class VISIBILITY_HIDDEN LowerPacked
42 : public FunctionPass, public InstVisitor<LowerPacked> {
Reid Spencer42e83fe2004-08-21 21:39:24 +000043public:
Nick Lewyckyecd94c82007-05-06 13:37:16 +000044 static char ID; // Pass identification, replacement for typeid
Devang Patel794fd752007-05-01 21:15:47 +000045 LowerPacked() : FunctionPass((intptr_t)&ID) {}
46
Misha Brukmanfd939082005-04-21 23:48:37 +000047 /// @brief Lowers packed operations to scalar operations.
Reid Spencer42e83fe2004-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 Spencere4d87aa2006-12-23 06:05:41 +000063 /// @brief Lowers packed icmp operations.
Reid Spencer81a75722007-08-05 19:35:22 +000064 /// @param IC the icmp operator to convert
Reid Spencere4d87aa2006-12-23 06:05:41 +000065 void visitICmpInst(ICmpInst& IC);
66
Reid Spencer42e83fe2004-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 Bocchino56107e22006-01-10 19:05:05 +000071 /// @brief Lowers packed extractelement instructions.
Reid Spencer81a75722007-08-05 19:35:22 +000072 /// @param EE the extractelement operator to convert
Robert Bocchino8fcf01e2006-01-17 20:06:55 +000073 void visitExtractElementInst(ExtractElementInst& EE);
74
75 /// @brief Lowers packed insertelement instructions.
Reid Spencer81a75722007-08-05 19:35:22 +000076 /// @param IE the insertelement operator to convert
Robert Bocchino8fcf01e2006-01-17 20:06:55 +000077 void visitInsertElementInst(InsertElementInst& IE);
Robert Bocchino56107e22006-01-10 19:05:05 +000078
Dan Gohman767cf702007-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 Brukmanfd939082005-04-21 23:48:37 +000082 ///
Reid Spencer9d6565a2007-02-15 02:26:10 +000083 /// @brief Asserts if VectorType instruction is not handled elsewhere.
Reid Spencer42e83fe2004-08-21 21:39:24 +000084 /// @param I the unhandled instruction
Bill Wendlingb7427032006-11-26 09:46:52 +000085 void visitInstruction(Instruction &I) {
Dan Gohman7f21fd52007-10-29 20:14:29 +000086 assert(!isa<VectorType>(I.getType()) &&
87 "Unhandled Instruction with Packed ReturnType!");
Reid Spencer42e83fe2004-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 Brukmanfd939082005-04-21 23:48:37 +0000101 /// @brief whether we changed the function or not
Reid Spencer42e83fe2004-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 Brukmanfd939082005-04-21 23:48:37 +0000110};
Reid Spencer42e83fe2004-08-21 21:39:24 +0000111
Devang Patel19974732007-05-03 01:11:54 +0000112char LowerPacked::ID = 0;
Chris Lattner7f8897f2006-08-27 22:42:52 +0000113RegisterPass<LowerPacked>
Misha Brukmanfd939082005-04-21 23:48:37 +0000114X("lower-packed",
Reid Spencer42e83fe2004-08-21 21:39:24 +0000115 "lowers packed operations to operations on smaller packed datatypes");
116
Misha Brukmanfd939082005-04-21 23:48:37 +0000117} // end namespace
Reid Spencer42e83fe2004-08-21 21:39:24 +0000118
Chris Lattner7b73a662004-11-19 16:49:34 +0000119FunctionPass *llvm::createLowerPackedPass() { return new LowerPacked(); }
Chris Lattner56de0362004-11-18 17:24:20 +0000120
121
Reid Spencer42e83fe2004-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 Brukmanfd939082005-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 Spencer42e83fe2004-08-21 21:39:24 +0000128// returned with actual references.
129void LowerPacked::setValues(Value* value,const std::vector<Value*>& values)
130{
Misha Brukmanfd939082005-04-21 23:48:37 +0000131 std::map<Value*,std::vector<Value*> >::iterator it =
Reid Spencer42e83fe2004-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 Brukmanfd939082005-04-21 23:48:37 +0000139 assert(it->second.size() == values.size() &&
Reid Spencer42e83fe2004-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 Brukmanfd939082005-04-21 23:48:37 +0000153// it will simply retreive values from a
154// setValues(Value*,const std::vector<Value*>&)
Reid Spencer42e83fe2004-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 Spencer9d6565a2007-02-15 02:26:10 +0000159 assert(isa<VectorType>(value->getType()) &&
160 "Value must be VectorType");
Reid Spencer42e83fe2004-08-21 21:39:24 +0000161
162 // reject further processing if this one has
163 // already been handled
Misha Brukmanfd939082005-04-21 23:48:37 +0000164 std::map<Value*,std::vector<Value*> >::iterator it =
Reid Spencer42e83fe2004-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 Spencer9d6565a2007-02-15 02:26:10 +0000170 if (ConstantVector* CP = dyn_cast<ConstantVector>(value)) {
Reid Spencer42e83fe2004-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 Brukmanfd939082005-04-21 23:48:37 +0000182 // zero constant
Reid Spencer9d6565a2007-02-15 02:26:10 +0000183 const VectorType* PKT = cast<VectorType>(CAZ->getType());
Reid Spencer42e83fe2004-08-21 21:39:24 +0000184 std::vector<Value*> results;
185 results.reserve(PKT->getNumElements());
Misha Brukmanfd939082005-04-21 23:48:37 +0000186
Reid Spencer42e83fe2004-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 Spencer9d6565a2007-02-15 02:26:10 +0000196 const VectorType* PKT = cast<VectorType>(value->getType());
Reid Spencer42e83fe2004-08-21 21:39:24 +0000197 std::vector<Value*> results;
198 results.reserve(PKT->getNumElements());
Misha Brukmanfd939082005-04-21 23:48:37 +0000199
Reid Spencer42e83fe2004-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 Spencer9d6565a2007-02-15 02:26:10 +0000209 assert(false && "Unhandled VectorType value");
Reid Spencer42e83fe2004-08-21 21:39:24 +0000210 abort();
211 }
212}
213
214void LowerPacked::visitLoadInst(LoadInst& LI)
215{
Reid Spencerac9dcb92007-02-15 03:39:18 +0000216 // Make sure what we are dealing with is a vector type
Reid Spencer9d6565a2007-02-15 02:26:10 +0000217 if (const VectorType* PKT = dyn_cast<VectorType>(LI.getType())) {
Reid Spencer42e83fe2004-08-21 21:39:24 +0000218 // Initialization, Idx is needed for getelementptr needed later
Dan Gohman767cf702007-10-29 20:24:00 +0000219 Value *Idx[2];
Dan Gohmana8cc4d32007-10-29 20:34:35 +0000220 Idx[0] = ConstantInt::get(Type::Int32Ty, 0);
Reid Spencer42e83fe2004-08-21 21:39:24 +0000221
222 // Convert this load into num elements number of loads
223 std::vector<Value*> values;
224 values.reserve(PKT->getNumElements());
225
226 for (unsigned i = 0, e = PKT->getNumElements(); i != e; ++i) {
227 // Calculate the second index we will need
Reid Spencerc5b206b2006-12-31 05:48:39 +0000228 Idx[1] = ConstantInt::get(Type::Int32Ty,i);
Reid Spencer42e83fe2004-08-21 21:39:24 +0000229
230 // Get the pointer
Dan Gohmana8cc4d32007-10-29 20:34:35 +0000231 Value* val = new GetElementPtrInst(LI.getPointerOperand(),
Dan Gohman767cf702007-10-29 20:24:00 +0000232 Idx, array_endof(Idx),
Misha Brukmanfd939082005-04-21 23:48:37 +0000233 LI.getName() +
Reid Spencer42e83fe2004-08-21 21:39:24 +0000234 ".ge." + utostr(i),
235 &LI);
236
237 // generate the new load and save the result in packedToScalar map
Reid Spencer3da59db2006-11-27 01:05:10 +0000238 values.push_back(new LoadInst(val, LI.getName()+"."+utostr(i),
239 LI.isVolatile(), &LI));
Reid Spencer42e83fe2004-08-21 21:39:24 +0000240 }
Misha Brukmanfd939082005-04-21 23:48:37 +0000241
Reid Spencer42e83fe2004-08-21 21:39:24 +0000242 setValues(&LI,values);
243 Changed = true;
244 instrsToRemove.push_back(&LI);
245 }
246}
247
248void LowerPacked::visitBinaryOperator(BinaryOperator& BO)
249{
Reid Spencer9d6565a2007-02-15 02:26:10 +0000250 // Make sure both operands are VectorTypes
251 if (isa<VectorType>(BO.getOperand(0)->getType())) {
Reid Spencer42e83fe2004-08-21 21:39:24 +0000252 std::vector<Value*>& op0Vals = getValues(BO.getOperand(0));
253 std::vector<Value*>& op1Vals = getValues(BO.getOperand(1));
254 std::vector<Value*> result;
255 assert((op0Vals.size() == op1Vals.size()) &&
256 "The two packed operand to scalar maps must be equal in size.");
257
258 result.reserve(op0Vals.size());
Misha Brukmanfd939082005-04-21 23:48:37 +0000259
Reid Spencer42e83fe2004-08-21 21:39:24 +0000260 // generate the new binary op and save the result
261 for (unsigned i = 0; i != op0Vals.size(); ++i) {
Misha Brukmanfd939082005-04-21 23:48:37 +0000262 result.push_back(BinaryOperator::create(BO.getOpcode(),
263 op0Vals[i],
Reid Spencer42e83fe2004-08-21 21:39:24 +0000264 op1Vals[i],
Misha Brukmanfd939082005-04-21 23:48:37 +0000265 BO.getName() +
Reid Spencer42e83fe2004-08-21 21:39:24 +0000266 "." + utostr(i),
267 &BO));
268 }
269
270 setValues(&BO,result);
271 Changed = true;
272 instrsToRemove.push_back(&BO);
273 }
274}
275
Reid Spencere4d87aa2006-12-23 06:05:41 +0000276void LowerPacked::visitICmpInst(ICmpInst& IC)
277{
Reid Spencer9d6565a2007-02-15 02:26:10 +0000278 // Make sure both operands are VectorTypes
279 if (isa<VectorType>(IC.getOperand(0)->getType())) {
Reid Spencere4d87aa2006-12-23 06:05:41 +0000280 std::vector<Value*>& op0Vals = getValues(IC.getOperand(0));
281 std::vector<Value*>& op1Vals = getValues(IC.getOperand(1));
282 std::vector<Value*> result;
283 assert((op0Vals.size() == op1Vals.size()) &&
284 "The two packed operand to scalar maps must be equal in size.");
285
286 result.reserve(op0Vals.size());
287
288 // generate the new binary op and save the result
289 for (unsigned i = 0; i != op0Vals.size(); ++i) {
290 result.push_back(CmpInst::create(IC.getOpcode(),
291 IC.getPredicate(),
292 op0Vals[i],
293 op1Vals[i],
294 IC.getName() +
295 "." + utostr(i),
296 &IC));
297 }
298
299 setValues(&IC,result);
300 Changed = true;
301 instrsToRemove.push_back(&IC);
302 }
303}
304
Reid Spencer42e83fe2004-08-21 21:39:24 +0000305void LowerPacked::visitStoreInst(StoreInst& SI)
306{
Reid Spencer9d6565a2007-02-15 02:26:10 +0000307 if (const VectorType* PKT =
308 dyn_cast<VectorType>(SI.getOperand(0)->getType())) {
Reid Spencer42e83fe2004-08-21 21:39:24 +0000309 // We will need this for getelementptr
Dan Gohman767cf702007-10-29 20:24:00 +0000310 Value *Idx[2];
Dan Gohmana8cc4d32007-10-29 20:34:35 +0000311 Idx[0] = ConstantInt::get(Type::Int32Ty, 0);
Reid Spencer3da59db2006-11-27 01:05:10 +0000312
Reid Spencer42e83fe2004-08-21 21:39:24 +0000313 std::vector<Value*>& values = getValues(SI.getOperand(0));
Misha Brukmanfd939082005-04-21 23:48:37 +0000314
Reid Spencer42e83fe2004-08-21 21:39:24 +0000315 assert((values.size() == PKT->getNumElements()) &&
Reid Spencerd29b8b82007-02-15 03:11:20 +0000316 "Scalar must have the same number of elements as Vector Type");
Reid Spencer42e83fe2004-08-21 21:39:24 +0000317
318 for (unsigned i = 0, e = PKT->getNumElements(); i != e; ++i) {
319 // Generate the indices for getelementptr
Reid Spencerc5b206b2006-12-31 05:48:39 +0000320 Idx[1] = ConstantInt::get(Type::Int32Ty,i);
Dan Gohmana8cc4d32007-10-29 20:34:35 +0000321 Value* val = new GetElementPtrInst(SI.getPointerOperand(),
Dan Gohman767cf702007-10-29 20:24:00 +0000322 Idx, array_endof(Idx),
Reid Spencer42e83fe2004-08-21 21:39:24 +0000323 "store.ge." +
324 utostr(i) + ".",
325 &SI);
326 new StoreInst(values[i], val, SI.isVolatile(),&SI);
327 }
Misha Brukmanfd939082005-04-21 23:48:37 +0000328
Reid Spencer42e83fe2004-08-21 21:39:24 +0000329 Changed = true;
330 instrsToRemove.push_back(&SI);
331 }
332}
333
334void LowerPacked::visitSelectInst(SelectInst& SELI)
335{
Reid Spencer9d6565a2007-02-15 02:26:10 +0000336 // Make sure both operands are VectorTypes
337 if (isa<VectorType>(SELI.getType())) {
Reid Spencer42e83fe2004-08-21 21:39:24 +0000338 std::vector<Value*>& op0Vals = getValues(SELI.getTrueValue());
339 std::vector<Value*>& op1Vals = getValues(SELI.getFalseValue());
340 std::vector<Value*> result;
341
342 assert((op0Vals.size() == op1Vals.size()) &&
343 "The two packed operand to scalar maps must be equal in size.");
344
345 for (unsigned i = 0; i != op0Vals.size(); ++i) {
346 result.push_back(new SelectInst(SELI.getCondition(),
Misha Brukmanfd939082005-04-21 23:48:37 +0000347 op0Vals[i],
Reid Spencer42e83fe2004-08-21 21:39:24 +0000348 op1Vals[i],
349 SELI.getName()+ "." + utostr(i),
350 &SELI));
351 }
Misha Brukmanfd939082005-04-21 23:48:37 +0000352
Reid Spencer42e83fe2004-08-21 21:39:24 +0000353 setValues(&SELI,result);
354 Changed = true;
355 instrsToRemove.push_back(&SELI);
356 }
357}
358
Robert Bocchino56107e22006-01-10 19:05:05 +0000359void LowerPacked::visitExtractElementInst(ExtractElementInst& EI)
360{
361 std::vector<Value*>& op0Vals = getValues(EI.getOperand(0));
Reid Spencer9d6565a2007-02-15 02:26:10 +0000362 const VectorType *PTy = cast<VectorType>(EI.getOperand(0)->getType());
Robert Bocchino56107e22006-01-10 19:05:05 +0000363 Value *op1 = EI.getOperand(1);
364
Reid Spencerb83eb642006-10-20 07:07:24 +0000365 if (ConstantInt *C = dyn_cast<ConstantInt>(op1)) {
366 EI.replaceAllUsesWith(op0Vals[C->getZExtValue()]);
Robert Bocchino56107e22006-01-10 19:05:05 +0000367 } else {
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000368 AllocaInst *alloca =
369 new AllocaInst(PTy->getElementType(),
Reid Spencerc5b206b2006-12-31 05:48:39 +0000370 ConstantInt::get(Type::Int32Ty, PTy->getNumElements()),
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000371 EI.getName() + ".alloca",
Anton Korobeynikovbed29462007-04-16 18:10:23 +0000372 EI.getParent()->getParent()->getEntryBlock().begin());
Robert Bocchino56107e22006-01-10 19:05:05 +0000373 for (unsigned i = 0; i < PTy->getNumElements(); ++i) {
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000374 GetElementPtrInst *GEP =
Reid Spencerc5b206b2006-12-31 05:48:39 +0000375 new GetElementPtrInst(alloca, ConstantInt::get(Type::Int32Ty, i),
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000376 "store.ge", &EI);
Robert Bocchino56107e22006-01-10 19:05:05 +0000377 new StoreInst(op0Vals[i], GEP, &EI);
378 }
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000379 GetElementPtrInst *GEP =
380 new GetElementPtrInst(alloca, op1, EI.getName() + ".ge", &EI);
Robert Bocchino56107e22006-01-10 19:05:05 +0000381 LoadInst *load = new LoadInst(GEP, EI.getName() + ".load", &EI);
382 EI.replaceAllUsesWith(load);
383 }
384
385 Changed = true;
386 instrsToRemove.push_back(&EI);
387}
388
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000389void LowerPacked::visitInsertElementInst(InsertElementInst& IE)
390{
391 std::vector<Value*>& Vals = getValues(IE.getOperand(0));
392 Value *Elt = IE.getOperand(1);
393 Value *Idx = IE.getOperand(2);
394 std::vector<Value*> result;
395 result.reserve(Vals.size());
396
Reid Spencerb83eb642006-10-20 07:07:24 +0000397 if (ConstantInt *C = dyn_cast<ConstantInt>(Idx)) {
398 unsigned idxVal = C->getZExtValue();
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000399 for (unsigned i = 0; i != Vals.size(); ++i) {
400 result.push_back(i == idxVal ? Elt : Vals[i]);
401 }
402 } else {
403 for (unsigned i = 0; i != Vals.size(); ++i) {
Reid Spencere4d87aa2006-12-23 06:05:41 +0000404 ICmpInst *icmp =
405 new ICmpInst(ICmpInst::ICMP_EQ, Idx,
Reid Spencerc5b206b2006-12-31 05:48:39 +0000406 ConstantInt::get(Type::Int32Ty, i),
Reid Spencere4d87aa2006-12-23 06:05:41 +0000407 "icmp", &IE);
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000408 SelectInst *select =
Reid Spencere4d87aa2006-12-23 06:05:41 +0000409 new SelectInst(icmp, Elt, Vals[i], "select", &IE);
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000410 result.push_back(select);
411 }
412 }
413
414 setValues(&IE, result);
415 Changed = true;
416 instrsToRemove.push_back(&IE);
417}
418
Reid Spencer42e83fe2004-08-21 21:39:24 +0000419bool LowerPacked::runOnFunction(Function& F)
420{
421 // initialize
Misha Brukmanfd939082005-04-21 23:48:37 +0000422 Changed = false;
423
Reid Spencer42e83fe2004-08-21 21:39:24 +0000424 // Does three passes:
Misha Brukmanfd939082005-04-21 23:48:37 +0000425 // Pass 1) Converts Packed Operations to
Reid Spencer42e83fe2004-08-21 21:39:24 +0000426 // new Packed Operations on smaller
427 // datatypes
428 visit(F);
Misha Brukmanfd939082005-04-21 23:48:37 +0000429
Reid Spencer42e83fe2004-08-21 21:39:24 +0000430 // Pass 2) Drop all references
431 std::for_each(instrsToRemove.begin(),
432 instrsToRemove.end(),
433 std::mem_fun(&Instruction::dropAllReferences));
434
435 // Pass 3) Delete the Instructions to remove aka packed instructions
Misha Brukmanfd939082005-04-21 23:48:37 +0000436 for (std::vector<Instruction*>::iterator i = instrsToRemove.begin(),
437 e = instrsToRemove.end();
Reid Spencer42e83fe2004-08-21 21:39:24 +0000438 i != e; ++i) {
Misha Brukmanfd939082005-04-21 23:48:37 +0000439 (*i)->getParent()->getInstList().erase(*i);
Reid Spencer42e83fe2004-08-21 21:39:24 +0000440 }
441
442 // clean-up
443 packedToScalarMap.clear();
444 instrsToRemove.clear();
445
446 return Changed;
447}
448