blob: 78b6214f2f198f7afe2a8895d2d61bcaa314d365 [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//
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 Brukmanfd939082005-04-21 23:48:37 +00007//
Reid Spencer42e83fe2004-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 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"
Reid Spencer551ccae2004-09-01 22:55:40 +000025#include "llvm/ADT/StringExtras.h"
Reid Spencer42e83fe2004-08-21 21:39:24 +000026#include <algorithm>
27#include <map>
Duraid Madinab5186852005-12-26 13:48:44 +000028#include <functional>
Reid Spencer42e83fe2004-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 Spencer9133fe22007-02-05 23:32:05 +000040class VISIBILITY_HIDDEN LowerPacked
41 : public FunctionPass, public InstVisitor<LowerPacked> {
Reid Spencer42e83fe2004-08-21 21:39:24 +000042public:
Devang Patel19974732007-05-03 01:11:54 +000043 static char ID; // Pass identifcation, replacement for typeid
Devang Patel794fd752007-05-01 21:15:47 +000044 LowerPacked() : FunctionPass((intptr_t)&ID) {}
45
Misha Brukmanfd939082005-04-21 23:48:37 +000046 /// @brief Lowers packed operations to scalar operations.
Reid Spencer42e83fe2004-08-21 21:39:24 +000047 /// @param F The fuction to process
48 virtual bool runOnFunction(Function &F);
49
50 /// @brief Lowers packed load instructions.
51 /// @param LI the load instruction to convert
52 void visitLoadInst(LoadInst& LI);
53
54 /// @brief Lowers packed store instructions.
55 /// @param SI the store instruction to convert
56 void visitStoreInst(StoreInst& SI);
57
58 /// @brief Lowers packed binary operations.
59 /// @param BO the binary operator to convert
60 void visitBinaryOperator(BinaryOperator& BO);
61
Reid Spencere4d87aa2006-12-23 06:05:41 +000062 /// @brief Lowers packed icmp operations.
63 /// @param CI the icmp operator to convert
64 void visitICmpInst(ICmpInst& IC);
65
Reid Spencer42e83fe2004-08-21 21:39:24 +000066 /// @brief Lowers packed select instructions.
67 /// @param SELI the select operator to convert
68 void visitSelectInst(SelectInst& SELI);
69
Robert Bocchino56107e22006-01-10 19:05:05 +000070 /// @brief Lowers packed extractelement instructions.
71 /// @param EI the extractelement operator to convert
Robert Bocchino8fcf01e2006-01-17 20:06:55 +000072 void visitExtractElementInst(ExtractElementInst& EE);
73
74 /// @brief Lowers packed insertelement instructions.
75 /// @param EI the insertelement operator to convert
76 void visitInsertElementInst(InsertElementInst& IE);
Robert Bocchino56107e22006-01-10 19:05:05 +000077
Reid Spencer9d6565a2007-02-15 02:26:10 +000078 /// This function asserts if the instruction is a VectorType but
Reid Spencer42e83fe2004-08-21 21:39:24 +000079 /// is handled by another function.
Misha Brukmanfd939082005-04-21 23:48:37 +000080 ///
Reid Spencer9d6565a2007-02-15 02:26:10 +000081 /// @brief Asserts if VectorType instruction is not handled elsewhere.
Reid Spencer42e83fe2004-08-21 21:39:24 +000082 /// @param I the unhandled instruction
Bill Wendlingb7427032006-11-26 09:46:52 +000083 void visitInstruction(Instruction &I) {
Reid Spencer9d6565a2007-02-15 02:26:10 +000084 if (isa<VectorType>(I.getType()))
Bill Wendlinge8156192006-12-07 01:30:32 +000085 cerr << "Unhandled Instruction with Packed ReturnType: " << I << '\n';
Reid Spencer42e83fe2004-08-21 21:39:24 +000086 }
87private:
88 /// @brief Retrieves lowered values for a packed value.
89 /// @param val the packed value
90 /// @return the lowered values
91 std::vector<Value*>& getValues(Value* val);
92
93 /// @brief Sets lowered values for a packed value.
94 /// @param val the packed value
95 /// @param values the corresponding lowered values
96 void setValues(Value* val,const std::vector<Value*>& values);
97
98 // Data Members
Misha Brukmanfd939082005-04-21 23:48:37 +000099 /// @brief whether we changed the function or not
Reid Spencer42e83fe2004-08-21 21:39:24 +0000100 bool Changed;
101
102 /// @brief a map from old packed values to new smaller packed values
103 std::map<Value*,std::vector<Value*> > packedToScalarMap;
104
105 /// Instructions in the source program to get rid of
106 /// after we do a pass (the old packed instructions)
107 std::vector<Instruction*> instrsToRemove;
Misha Brukmanfd939082005-04-21 23:48:37 +0000108};
Reid Spencer42e83fe2004-08-21 21:39:24 +0000109
Devang Patel19974732007-05-03 01:11:54 +0000110char LowerPacked::ID = 0;
Chris Lattner7f8897f2006-08-27 22:42:52 +0000111RegisterPass<LowerPacked>
Misha Brukmanfd939082005-04-21 23:48:37 +0000112X("lower-packed",
Reid Spencer42e83fe2004-08-21 21:39:24 +0000113 "lowers packed operations to operations on smaller packed datatypes");
114
Misha Brukmanfd939082005-04-21 23:48:37 +0000115} // end namespace
Reid Spencer42e83fe2004-08-21 21:39:24 +0000116
Chris Lattner7b73a662004-11-19 16:49:34 +0000117FunctionPass *llvm::createLowerPackedPass() { return new LowerPacked(); }
Chris Lattner56de0362004-11-18 17:24:20 +0000118
119
Reid Spencer42e83fe2004-08-21 21:39:24 +0000120// This function sets lowered values for a corresponding
121// packed value. Note, in the case of a forward reference
Misha Brukmanfd939082005-04-21 23:48:37 +0000122// getValues(Value*) will have already been called for
123// the packed parameter. This function will then replace
124// all references in the in the function of the "dummy"
125// value the previous getValues(Value*) call
Reid Spencer42e83fe2004-08-21 21:39:24 +0000126// returned with actual references.
127void LowerPacked::setValues(Value* value,const std::vector<Value*>& values)
128{
Misha Brukmanfd939082005-04-21 23:48:37 +0000129 std::map<Value*,std::vector<Value*> >::iterator it =
Reid Spencer42e83fe2004-08-21 21:39:24 +0000130 packedToScalarMap.lower_bound(value);
131 if (it == packedToScalarMap.end() || it->first != value) {
132 // there was not a forward reference to this element
133 packedToScalarMap.insert(it,std::make_pair(value,values));
134 }
135 else {
136 // replace forward declarations with actual definitions
Misha Brukmanfd939082005-04-21 23:48:37 +0000137 assert(it->second.size() == values.size() &&
Reid Spencer42e83fe2004-08-21 21:39:24 +0000138 "Error forward refences and actual definition differ in size");
139 for (unsigned i = 0, e = values.size(); i != e; ++i) {
140 // replace and get rid of old forward references
141 it->second[i]->replaceAllUsesWith(values[i]);
142 delete it->second[i];
143 it->second[i] = values[i];
144 }
145 }
146}
147
148// This function will examine the packed value parameter
149// and if it is a packed constant or a forward reference
150// properly create the lowered values needed. Otherwise
Misha Brukmanfd939082005-04-21 23:48:37 +0000151// it will simply retreive values from a
152// setValues(Value*,const std::vector<Value*>&)
Reid Spencer42e83fe2004-08-21 21:39:24 +0000153// call. Failing both of these cases, it will abort
154// the program.
155std::vector<Value*>& LowerPacked::getValues(Value* value)
156{
Reid Spencer9d6565a2007-02-15 02:26:10 +0000157 assert(isa<VectorType>(value->getType()) &&
158 "Value must be VectorType");
Reid Spencer42e83fe2004-08-21 21:39:24 +0000159
160 // reject further processing if this one has
161 // already been handled
Misha Brukmanfd939082005-04-21 23:48:37 +0000162 std::map<Value*,std::vector<Value*> >::iterator it =
Reid Spencer42e83fe2004-08-21 21:39:24 +0000163 packedToScalarMap.lower_bound(value);
164 if (it != packedToScalarMap.end() && it->first == value) {
165 return it->second;
166 }
167
Reid Spencer9d6565a2007-02-15 02:26:10 +0000168 if (ConstantVector* CP = dyn_cast<ConstantVector>(value)) {
Reid Spencer42e83fe2004-08-21 21:39:24 +0000169 // non-zero constant case
170 std::vector<Value*> results;
171 results.reserve(CP->getNumOperands());
172 for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) {
173 results.push_back(CP->getOperand(i));
174 }
175 return packedToScalarMap.insert(it,
176 std::make_pair(value,results))->second;
177 }
178 else if (ConstantAggregateZero* CAZ =
179 dyn_cast<ConstantAggregateZero>(value)) {
Misha Brukmanfd939082005-04-21 23:48:37 +0000180 // zero constant
Reid Spencer9d6565a2007-02-15 02:26:10 +0000181 const VectorType* PKT = cast<VectorType>(CAZ->getType());
Reid Spencer42e83fe2004-08-21 21:39:24 +0000182 std::vector<Value*> results;
183 results.reserve(PKT->getNumElements());
Misha Brukmanfd939082005-04-21 23:48:37 +0000184
Reid Spencer42e83fe2004-08-21 21:39:24 +0000185 Constant* C = Constant::getNullValue(PKT->getElementType());
186 for (unsigned i = 0, e = PKT->getNumElements(); i != e; ++i) {
187 results.push_back(C);
188 }
189 return packedToScalarMap.insert(it,
190 std::make_pair(value,results))->second;
191 }
192 else if (isa<Instruction>(value)) {
193 // foward reference
Reid Spencer9d6565a2007-02-15 02:26:10 +0000194 const VectorType* PKT = cast<VectorType>(value->getType());
Reid Spencer42e83fe2004-08-21 21:39:24 +0000195 std::vector<Value*> results;
196 results.reserve(PKT->getNumElements());
Misha Brukmanfd939082005-04-21 23:48:37 +0000197
Reid Spencer42e83fe2004-08-21 21:39:24 +0000198 for (unsigned i = 0, e = PKT->getNumElements(); i != e; ++i) {
199 results.push_back(new Argument(PKT->getElementType()));
200 }
201 return packedToScalarMap.insert(it,
202 std::make_pair(value,results))->second;
203 }
204 else {
205 // we don't know what it is, and we are trying to retrieve
206 // a value for it
Reid Spencer9d6565a2007-02-15 02:26:10 +0000207 assert(false && "Unhandled VectorType value");
Reid Spencer42e83fe2004-08-21 21:39:24 +0000208 abort();
209 }
210}
211
212void LowerPacked::visitLoadInst(LoadInst& LI)
213{
Reid Spencerac9dcb92007-02-15 03:39:18 +0000214 // Make sure what we are dealing with is a vector type
Reid Spencer9d6565a2007-02-15 02:26:10 +0000215 if (const VectorType* PKT = dyn_cast<VectorType>(LI.getType())) {
Reid Spencer42e83fe2004-08-21 21:39:24 +0000216 // Initialization, Idx is needed for getelementptr needed later
217 std::vector<Value*> Idx(2);
Reid Spencerc5b206b2006-12-31 05:48:39 +0000218 Idx[0] = ConstantInt::get(Type::Int32Ty,0);
Reid Spencer42e83fe2004-08-21 21:39:24 +0000219
220 ArrayType* AT = ArrayType::get(PKT->getContainedType(0),
221 PKT->getNumElements());
222 PointerType* APT = PointerType::get(AT);
223
Reid Spencerac9dcb92007-02-15 03:39:18 +0000224 // Cast the pointer to vector type to an equivalent array
Reid Spencer3da59db2006-11-27 01:05:10 +0000225 Value* array = new BitCastInst(LI.getPointerOperand(), APT,
226 LI.getName() + ".a", &LI);
Reid Spencer42e83fe2004-08-21 21:39:24 +0000227
228 // Convert this load into num elements number of loads
229 std::vector<Value*> values;
230 values.reserve(PKT->getNumElements());
231
232 for (unsigned i = 0, e = PKT->getNumElements(); i != e; ++i) {
233 // Calculate the second index we will need
Reid Spencerc5b206b2006-12-31 05:48:39 +0000234 Idx[1] = ConstantInt::get(Type::Int32Ty,i);
Reid Spencer42e83fe2004-08-21 21:39:24 +0000235
236 // Get the pointer
Misha Brukmanfd939082005-04-21 23:48:37 +0000237 Value* val = new GetElementPtrInst(array,
Chris Lattner1ccd1852007-02-12 22:56:41 +0000238 &Idx[0], Idx.size(),
Misha Brukmanfd939082005-04-21 23:48:37 +0000239 LI.getName() +
Reid Spencer42e83fe2004-08-21 21:39:24 +0000240 ".ge." + utostr(i),
241 &LI);
242
243 // generate the new load and save the result in packedToScalar map
Reid Spencer3da59db2006-11-27 01:05:10 +0000244 values.push_back(new LoadInst(val, LI.getName()+"."+utostr(i),
245 LI.isVolatile(), &LI));
Reid Spencer42e83fe2004-08-21 21:39:24 +0000246 }
Misha Brukmanfd939082005-04-21 23:48:37 +0000247
Reid Spencer42e83fe2004-08-21 21:39:24 +0000248 setValues(&LI,values);
249 Changed = true;
250 instrsToRemove.push_back(&LI);
251 }
252}
253
254void LowerPacked::visitBinaryOperator(BinaryOperator& BO)
255{
Reid Spencer9d6565a2007-02-15 02:26:10 +0000256 // Make sure both operands are VectorTypes
257 if (isa<VectorType>(BO.getOperand(0)->getType())) {
Reid Spencer42e83fe2004-08-21 21:39:24 +0000258 std::vector<Value*>& op0Vals = getValues(BO.getOperand(0));
259 std::vector<Value*>& op1Vals = getValues(BO.getOperand(1));
260 std::vector<Value*> result;
261 assert((op0Vals.size() == op1Vals.size()) &&
262 "The two packed operand to scalar maps must be equal in size.");
263
264 result.reserve(op0Vals.size());
Misha Brukmanfd939082005-04-21 23:48:37 +0000265
Reid Spencer42e83fe2004-08-21 21:39:24 +0000266 // generate the new binary op and save the result
267 for (unsigned i = 0; i != op0Vals.size(); ++i) {
Misha Brukmanfd939082005-04-21 23:48:37 +0000268 result.push_back(BinaryOperator::create(BO.getOpcode(),
269 op0Vals[i],
Reid Spencer42e83fe2004-08-21 21:39:24 +0000270 op1Vals[i],
Misha Brukmanfd939082005-04-21 23:48:37 +0000271 BO.getName() +
Reid Spencer42e83fe2004-08-21 21:39:24 +0000272 "." + utostr(i),
273 &BO));
274 }
275
276 setValues(&BO,result);
277 Changed = true;
278 instrsToRemove.push_back(&BO);
279 }
280}
281
Reid Spencere4d87aa2006-12-23 06:05:41 +0000282void LowerPacked::visitICmpInst(ICmpInst& IC)
283{
Reid Spencer9d6565a2007-02-15 02:26:10 +0000284 // Make sure both operands are VectorTypes
285 if (isa<VectorType>(IC.getOperand(0)->getType())) {
Reid Spencere4d87aa2006-12-23 06:05:41 +0000286 std::vector<Value*>& op0Vals = getValues(IC.getOperand(0));
287 std::vector<Value*>& op1Vals = getValues(IC.getOperand(1));
288 std::vector<Value*> result;
289 assert((op0Vals.size() == op1Vals.size()) &&
290 "The two packed operand to scalar maps must be equal in size.");
291
292 result.reserve(op0Vals.size());
293
294 // generate the new binary op and save the result
295 for (unsigned i = 0; i != op0Vals.size(); ++i) {
296 result.push_back(CmpInst::create(IC.getOpcode(),
297 IC.getPredicate(),
298 op0Vals[i],
299 op1Vals[i],
300 IC.getName() +
301 "." + utostr(i),
302 &IC));
303 }
304
305 setValues(&IC,result);
306 Changed = true;
307 instrsToRemove.push_back(&IC);
308 }
309}
310
Reid Spencer42e83fe2004-08-21 21:39:24 +0000311void LowerPacked::visitStoreInst(StoreInst& SI)
312{
Reid Spencer9d6565a2007-02-15 02:26:10 +0000313 if (const VectorType* PKT =
314 dyn_cast<VectorType>(SI.getOperand(0)->getType())) {
Reid Spencer42e83fe2004-08-21 21:39:24 +0000315 // We will need this for getelementptr
316 std::vector<Value*> Idx(2);
Reid Spencerc5b206b2006-12-31 05:48:39 +0000317 Idx[0] = ConstantInt::get(Type::Int32Ty,0);
Misha Brukmanfd939082005-04-21 23:48:37 +0000318
Reid Spencer42e83fe2004-08-21 21:39:24 +0000319 ArrayType* AT = ArrayType::get(PKT->getContainedType(0),
320 PKT->getNumElements());
321 PointerType* APT = PointerType::get(AT);
322
Reid Spencer3da59db2006-11-27 01:05:10 +0000323 // Cast the pointer to packed to an array of equivalent type
324 Value* array = new BitCastInst(SI.getPointerOperand(), APT,
325 "store.ge.a.", &SI);
326
Reid Spencer42e83fe2004-08-21 21:39:24 +0000327 std::vector<Value*>& values = getValues(SI.getOperand(0));
Misha Brukmanfd939082005-04-21 23:48:37 +0000328
Reid Spencer42e83fe2004-08-21 21:39:24 +0000329 assert((values.size() == PKT->getNumElements()) &&
Reid Spencerd29b8b82007-02-15 03:11:20 +0000330 "Scalar must have the same number of elements as Vector Type");
Reid Spencer42e83fe2004-08-21 21:39:24 +0000331
332 for (unsigned i = 0, e = PKT->getNumElements(); i != e; ++i) {
333 // Generate the indices for getelementptr
Reid Spencerc5b206b2006-12-31 05:48:39 +0000334 Idx[1] = ConstantInt::get(Type::Int32Ty,i);
Misha Brukmanfd939082005-04-21 23:48:37 +0000335 Value* val = new GetElementPtrInst(array,
Chris Lattner1ccd1852007-02-12 22:56:41 +0000336 &Idx[0], Idx.size(),
Reid Spencer42e83fe2004-08-21 21:39:24 +0000337 "store.ge." +
338 utostr(i) + ".",
339 &SI);
340 new StoreInst(values[i], val, SI.isVolatile(),&SI);
341 }
Misha Brukmanfd939082005-04-21 23:48:37 +0000342
Reid Spencer42e83fe2004-08-21 21:39:24 +0000343 Changed = true;
344 instrsToRemove.push_back(&SI);
345 }
346}
347
348void LowerPacked::visitSelectInst(SelectInst& SELI)
349{
Reid Spencer9d6565a2007-02-15 02:26:10 +0000350 // Make sure both operands are VectorTypes
351 if (isa<VectorType>(SELI.getType())) {
Reid Spencer42e83fe2004-08-21 21:39:24 +0000352 std::vector<Value*>& op0Vals = getValues(SELI.getTrueValue());
353 std::vector<Value*>& op1Vals = getValues(SELI.getFalseValue());
354 std::vector<Value*> result;
355
356 assert((op0Vals.size() == op1Vals.size()) &&
357 "The two packed operand to scalar maps must be equal in size.");
358
359 for (unsigned i = 0; i != op0Vals.size(); ++i) {
360 result.push_back(new SelectInst(SELI.getCondition(),
Misha Brukmanfd939082005-04-21 23:48:37 +0000361 op0Vals[i],
Reid Spencer42e83fe2004-08-21 21:39:24 +0000362 op1Vals[i],
363 SELI.getName()+ "." + utostr(i),
364 &SELI));
365 }
Misha Brukmanfd939082005-04-21 23:48:37 +0000366
Reid Spencer42e83fe2004-08-21 21:39:24 +0000367 setValues(&SELI,result);
368 Changed = true;
369 instrsToRemove.push_back(&SELI);
370 }
371}
372
Robert Bocchino56107e22006-01-10 19:05:05 +0000373void LowerPacked::visitExtractElementInst(ExtractElementInst& EI)
374{
375 std::vector<Value*>& op0Vals = getValues(EI.getOperand(0));
Reid Spencer9d6565a2007-02-15 02:26:10 +0000376 const VectorType *PTy = cast<VectorType>(EI.getOperand(0)->getType());
Robert Bocchino56107e22006-01-10 19:05:05 +0000377 Value *op1 = EI.getOperand(1);
378
Reid Spencerb83eb642006-10-20 07:07:24 +0000379 if (ConstantInt *C = dyn_cast<ConstantInt>(op1)) {
380 EI.replaceAllUsesWith(op0Vals[C->getZExtValue()]);
Robert Bocchino56107e22006-01-10 19:05:05 +0000381 } else {
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000382 AllocaInst *alloca =
383 new AllocaInst(PTy->getElementType(),
Reid Spencerc5b206b2006-12-31 05:48:39 +0000384 ConstantInt::get(Type::Int32Ty, PTy->getNumElements()),
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000385 EI.getName() + ".alloca",
Anton Korobeynikovbed29462007-04-16 18:10:23 +0000386 EI.getParent()->getParent()->getEntryBlock().begin());
Robert Bocchino56107e22006-01-10 19:05:05 +0000387 for (unsigned i = 0; i < PTy->getNumElements(); ++i) {
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000388 GetElementPtrInst *GEP =
Reid Spencerc5b206b2006-12-31 05:48:39 +0000389 new GetElementPtrInst(alloca, ConstantInt::get(Type::Int32Ty, i),
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000390 "store.ge", &EI);
Robert Bocchino56107e22006-01-10 19:05:05 +0000391 new StoreInst(op0Vals[i], GEP, &EI);
392 }
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000393 GetElementPtrInst *GEP =
394 new GetElementPtrInst(alloca, op1, EI.getName() + ".ge", &EI);
Robert Bocchino56107e22006-01-10 19:05:05 +0000395 LoadInst *load = new LoadInst(GEP, EI.getName() + ".load", &EI);
396 EI.replaceAllUsesWith(load);
397 }
398
399 Changed = true;
400 instrsToRemove.push_back(&EI);
401}
402
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000403void LowerPacked::visitInsertElementInst(InsertElementInst& IE)
404{
405 std::vector<Value*>& Vals = getValues(IE.getOperand(0));
406 Value *Elt = IE.getOperand(1);
407 Value *Idx = IE.getOperand(2);
408 std::vector<Value*> result;
409 result.reserve(Vals.size());
410
Reid Spencerb83eb642006-10-20 07:07:24 +0000411 if (ConstantInt *C = dyn_cast<ConstantInt>(Idx)) {
412 unsigned idxVal = C->getZExtValue();
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000413 for (unsigned i = 0; i != Vals.size(); ++i) {
414 result.push_back(i == idxVal ? Elt : Vals[i]);
415 }
416 } else {
417 for (unsigned i = 0; i != Vals.size(); ++i) {
Reid Spencere4d87aa2006-12-23 06:05:41 +0000418 ICmpInst *icmp =
419 new ICmpInst(ICmpInst::ICMP_EQ, Idx,
Reid Spencerc5b206b2006-12-31 05:48:39 +0000420 ConstantInt::get(Type::Int32Ty, i),
Reid Spencere4d87aa2006-12-23 06:05:41 +0000421 "icmp", &IE);
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000422 SelectInst *select =
Reid Spencere4d87aa2006-12-23 06:05:41 +0000423 new SelectInst(icmp, Elt, Vals[i], "select", &IE);
Robert Bocchino8fcf01e2006-01-17 20:06:55 +0000424 result.push_back(select);
425 }
426 }
427
428 setValues(&IE, result);
429 Changed = true;
430 instrsToRemove.push_back(&IE);
431}
432
Reid Spencer42e83fe2004-08-21 21:39:24 +0000433bool LowerPacked::runOnFunction(Function& F)
434{
435 // initialize
Misha Brukmanfd939082005-04-21 23:48:37 +0000436 Changed = false;
437
Reid Spencer42e83fe2004-08-21 21:39:24 +0000438 // Does three passes:
Misha Brukmanfd939082005-04-21 23:48:37 +0000439 // Pass 1) Converts Packed Operations to
Reid Spencer42e83fe2004-08-21 21:39:24 +0000440 // new Packed Operations on smaller
441 // datatypes
442 visit(F);
Misha Brukmanfd939082005-04-21 23:48:37 +0000443
Reid Spencer42e83fe2004-08-21 21:39:24 +0000444 // Pass 2) Drop all references
445 std::for_each(instrsToRemove.begin(),
446 instrsToRemove.end(),
447 std::mem_fun(&Instruction::dropAllReferences));
448
449 // Pass 3) Delete the Instructions to remove aka packed instructions
Misha Brukmanfd939082005-04-21 23:48:37 +0000450 for (std::vector<Instruction*>::iterator i = instrsToRemove.begin(),
451 e = instrsToRemove.end();
Reid Spencer42e83fe2004-08-21 21:39:24 +0000452 i != e; ++i) {
Misha Brukmanfd939082005-04-21 23:48:37 +0000453 (*i)->getParent()->getInstList().erase(*i);
Reid Spencer42e83fe2004-08-21 21:39:24 +0000454 }
455
456 // clean-up
457 packedToScalarMap.clear();
458 instrsToRemove.clear();
459
460 return Changed;
461}
462