OLD | NEW |
---|---|
(Empty) | |
1 //===- PromoteIntegers.cpp - Promote illegal integers for PNaCl ABI -------===// | |
2 // | |
3 // The LLVM Compiler Infrastructure | |
4 // | |
5 // This file is distributed under the University of Illinois Open Source | |
6 // License. See LICENSE.TXT for details. | |
7 // | |
8 // A limited set of transformations to promote illegal-sized int types. | |
Mark Seaborn
2013/05/09 01:00:22
Add //==---... spacer before this, to follow the s
Derek Schuff
2013/05/09 18:30:24
Done.
| |
9 // Legal sizes are currently 1, 8, 16, 32, 64 (and higher, see note below) | |
10 // Operations on illegal integers and int pointers are be changed to operate | |
11 // on the next-higher legal size. | |
12 // It always maintains the invariant that the upper bits (above the size of the | |
Mark Seaborn
2013/05/09 01:00:22
I don't think that's the best choice of invariant,
Derek Schuff
2013/05/09 18:30:24
I did think about doing that. For the operations t
Mark Seaborn
2013/05/09 19:27:48
FWIW, that's not true. For addition, digit n in t
Derek Schuff
2013/05/09 20:19:43
OK, true.
In any case it doesn't matter for the in
| |
13 // original type) are zero; therefore after operations which can overwrite these | |
14 // bits (e.g. add, shl, sext), the bits are cleared. | |
15 // | |
16 // Limitations: | |
17 // 1) It can't change function signatures or global variables | |
18 // 2) It won't promote (and can't expand) types larger than i64 | |
19 // 3) Doesn't support mul/div operators | |
20 // 4) Doesn't handle arrays or structs (or GEPs) with illegal types | |
21 // 5) Doesn't handle constant expressions | |
22 //===----------------------------------------------------------------------===// | |
Mark Seaborn
2013/05/09 01:00:22
Follow the style here and end comment with:
//
//=
Derek Schuff
2013/05/09 18:30:24
Done.
| |
23 // | |
24 | |
25 #include "llvm/ADT/DenseMap.h" | |
26 #include "llvm/ADT/SmallVector.h" | |
27 #include "llvm/IR/DerivedTypes.h" | |
28 #include "llvm/IR/Function.h" | |
29 #include "llvm/IR/Instructions.h" | |
30 #include "llvm/IR/IRBuilder.h" | |
31 #include "llvm/Pass.h" | |
32 #include "llvm/Support/raw_ostream.h" | |
33 | |
34 using namespace llvm; | |
Mark Seaborn
2013/05/09 01:00:22
Add empty line after this
Derek Schuff
2013/05/09 18:30:24
Done.
| |
35 namespace { | |
36 class PromoteIntegers : public FunctionPass { | |
37 public: | |
38 static char ID; | |
39 PromoteIntegers() : FunctionPass(ID) { | |
40 initializePromoteIntegersPass(*PassRegistry::getPassRegistry()); | |
41 } | |
42 virtual bool runOnFunction(Function &F); | |
43 }; | |
44 } | |
45 | |
46 char PromoteIntegers::ID = 0; | |
47 INITIALIZE_PASS(PromoteIntegers, "nacl-promote-ints", | |
48 "Promote integer types which are illegal in PNaCl", | |
49 false, false) | |
50 | |
51 | |
52 // Legal sizes are currently 1, 8, 16, 32, and 64. | |
53 // We can't yet expand types above 64 bit, so don't try to touch them for now. | |
54 static bool isLegalSize(unsigned Size) { | |
55 // TODO(dschuff): expand >64bit types or disallow >64bit packed bitfields | |
56 if (Size > 64) return true; | |
57 return Size == 1 || Size == 8 || Size == 16 || Size == 32 || Size == 64; | |
58 } | |
59 | |
60 static Type *getPromotedIntType(IntegerType *Ty) { | |
61 unsigned Width = Ty->getBitWidth(); | |
62 assert(Width <= 64 && "Don't know how to legalize >64 bit types yet"); | |
63 if (isLegalSize(Width)) | |
64 return Ty; | |
65 return IntegerType::get(Ty->getContext(), NextPowerOf2(Width)); | |
Mark Seaborn
2013/05/09 01:00:22
NextPowerOf2() isn't right for i3, which should be
Derek Schuff
2013/05/09 18:30:24
Done.
| |
66 } | |
67 | |
68 // Return a legal integer or pointer-to-integer type, promoting to a larger | |
69 // size if necessary. | |
70 static Type *getPromotedType(Type *Ty) { | |
71 assert((isa<IntegerType>(Ty) || isa<PointerType>(Ty)) && | |
72 "Trying to convert a non-integer type"); | |
73 | |
74 if (isa<PointerType>(Ty)) | |
75 return getPromotedIntType( | |
76 cast<IntegerType>(Ty->getContainedType(0)))->getPointerTo(); | |
77 | |
78 return getPromotedIntType(cast<IntegerType>(Ty)); | |
79 } | |
80 | |
81 // Return true if Val is an int or pointer-to-int which should be converted. | |
82 static bool shouldConvert(Value *Val) { | |
83 Type *Ty = Val->getType(); | |
84 if (PointerType *Pty = dyn_cast<PointerType>(Ty)) | |
85 Ty = Pty->getContainedType(0); | |
86 if (IntegerType *ITy = dyn_cast<IntegerType>(Ty)) { | |
87 if (!isLegalSize(ITy->getBitWidth())) { | |
88 return true; | |
89 } | |
90 } | |
91 return false; | |
92 } | |
93 | |
94 // Return a constant which has been promoted to a legal size. | |
95 static Value *convertConstant(Constant *C, bool SignExt=false) { | |
96 assert(shouldConvert(C)); | |
97 ConstantInt *CInt = cast<ConstantInt>(C); | |
98 return ConstantInt::get( | |
99 getPromotedType(cast<IntegerType>(CInt->getType())), | |
100 SignExt ? CInt->getSExtValue() : CInt->getZExtValue(), | |
101 /*isSigned=*/SignExt); | |
102 } | |
103 | |
104 // Holds the state for converting/replacing values. Conversion is done in one | |
105 // pass, with each value requiring conversion possibly having two stages. When | |
106 // an instruction needs to be replaced (i.e. it has illegal operands or result) | |
107 // a new instruction is created, and the pass calls getConverted to get its | |
108 // operands. If the original operand has already been converted, the new value | |
109 // is returned. Otherwise, a placeholder is created and used in the new | |
110 // instruction. After a new instruction is created to replace an illegal one, | |
111 // recordConverted is called to register the replacement. All users are updated, | |
112 // and if there is a placeholder, its users are also updated. | |
113 // recordConverted also queues the old value for deletion. | |
114 // This strategy avoids the need for recursion or worklists for conversion. | |
115 class ConversionState { | |
116 public: | |
117 // Return the promoted value for Val. If Val has not yet been converted, | |
118 // return a placeholder, which will be converted later. | |
119 Value *getConverted(Value *Val) { | |
120 if (!shouldConvert(Val)) | |
121 return Val; | |
122 assert(!isa<GlobalVariable>(Val) && "Can't convert GlobalVariables"); | |
123 if (RewrittenMap.count(Val)) | |
124 return RewrittenMap[Val]; | |
125 Value *P; | |
126 // Directly convert constants. | |
127 if (Constant *C = dyn_cast<Constant>(Val)) { | |
128 return convertConstant(C, /*SignExt=*/false); | |
jvoung (off chromium)
2013/05/09 00:06:44
Is it possible to keep constants in RewrittenMap?
Derek Schuff
2013/05/09 18:30:24
It is possible because the clients that want sign
| |
129 } else { | |
130 // No converted value available yet, so create a placeholder. | |
131 P = new Argument(getPromotedType(Val->getType())); | |
132 } | |
133 RewrittenMap[Val] = P; | |
134 Placeholders[Val] = P; | |
135 return P; | |
136 } | |
137 | |
138 // Replace the uses of From with To, replace the uses of any | |
139 // placeholders for From, and optionally give From's name to To. | |
140 // Also mark To for deletion. | |
141 void recordConverted(Instruction *From, Value *To, bool TakeName=true) { | |
142 ToErase.push_back(cast<Instruction>(From)); | |
jvoung (off chromium)
2013/05/09 00:06:44
do you still need a cast?
Derek Schuff
2013/05/09 18:30:24
Done.
| |
143 if (!shouldConvert(From)) { | |
jvoung (off chromium)
2013/05/09 00:06:44
Haven't read through everything, yet, but it seems
Derek Schuff
2013/05/09 18:30:24
Done.
| |
144 From->replaceAllUsesWith(To); | |
145 } else { | |
146 if (Placeholders.count(From)) { | |
147 // Resolve placeholder. | |
148 Placeholders[From]->replaceAllUsesWith(To); | |
149 Placeholders.erase(From); | |
150 } | |
jvoung (off chromium)
2013/05/09 00:06:44
should there be an else {
From->replaceAllUsesWi
Derek Schuff
2013/05/09 18:30:24
added comment
| |
151 RewrittenMap[From] = To; | |
152 } | |
153 if (TakeName) { | |
154 To->takeName(From); | |
155 } | |
156 } | |
157 ~ConversionState() { | |
Mark Seaborn
2013/05/09 01:00:22
The destructor should come before other methods.
Derek Schuff
2013/05/09 18:30:24
Done.
| |
158 for (SmallVectorImpl<Instruction*>::iterator I = ToErase.begin(), | |
159 E = ToErase.end(); I != E; ++I) | |
160 (*I)->dropAllReferences(); | |
161 for (SmallVectorImpl<Instruction*>::iterator I = ToErase.begin(), | |
162 E = ToErase.end(); I != E; ++I) | |
163 (*I)->eraseFromParent(); | |
164 } | |
165 private: | |
166 // Maps illegal values to their new converted values (or placeholders | |
167 // if no new value is available yet) | |
168 DenseMap<Value *, Value *> RewrittenMap; | |
169 // Maps illegal values with no conversion available yet to their placeholders | |
170 DenseMap<Value *, Value *> Placeholders; | |
171 // Illegal values which have already been converted, to erase on distruction. | |
jvoung (off chromium)
2013/05/09 00:06:44
nits:
distruction -> destruction
consistency wit
Derek Schuff
2013/05/09 18:30:24
Done.
| |
172 SmallVector<Instruction*, 8> ToErase; | |
173 }; | |
174 | |
175 // Split an illegal load into multiple legal loads and return the resulting | |
176 // promoted value. The size of the load is assumed to be a multiple of 8. | |
Mark Seaborn
2013/05/09 01:00:22
Does this mean the pass doesn't handle i2...i7?
Derek Schuff
2013/05/09 18:30:24
Not for loads and stores. The rest of the ops shou
| |
177 static Value *splitLoad(LoadInst *Inst, ConversionState &State) { | |
178 assert(!Inst->isVolatile() && !Inst->isAtomic() && | |
Mark Seaborn
2013/05/09 01:00:22
This can get compiled out of release builds. Do a
Derek Schuff
2013/05/09 18:30:24
Done.
| |
179 "Can't split volatile/atomic loads"); | |
180 assert(cast<IntegerType>(Inst->getType())->getBitWidth() % 8 == 0); | |
Mark Seaborn
2013/05/09 01:00:22
This should be a report_fatal_error() too since it
Derek Schuff
2013/05/09 18:30:24
Done.
| |
181 | |
182 Value *OrigPtr = State.getConverted(Inst->getPointerOperand()); | |
183 // OrigPtr is a placeholder in recursive calls, and so has no name | |
184 if (OrigPtr->getName().empty()) | |
185 OrigPtr->setName(Inst->getPointerOperand()->getName()); | |
186 unsigned Width = cast<IntegerType>(Inst->getType())->getBitWidth(); | |
187 Type *NewType = getPromotedType(Inst->getType()); | |
188 unsigned LoWidth = Width; | |
189 | |
190 while (!isLegalSize(LoWidth)) LoWidth -= 8; | |
191 IntegerType *LoType = IntegerType::get(Inst->getContext(), LoWidth); | |
192 IntegerType *HiType = IntegerType::get(Inst->getContext(), Width - LoWidth); | |
193 IRBuilder<> IRB(Inst->getParent(), Inst); | |
194 | |
195 Value *BCLo = IRB.CreateBitCast( | |
196 OrigPtr, | |
197 LoType->getPointerTo(), | |
198 OrigPtr->getName() + ".loty"); | |
199 Value *LoadLo = IRB.CreateAlignedLoad( | |
200 BCLo, Inst->getAlignment(), Inst->getName() + ".lo"); | |
201 Value *LoExt = IRB.CreateZExt(LoadLo, NewType, LoadLo->getName() + ".ext"); | |
202 Value *GEPHi = IRB.CreateConstGEP1_32(BCLo, 1, OrigPtr->getName() + ".hi"); | |
203 Value *BCHi = IRB.CreateBitCast( | |
204 GEPHi, | |
205 HiType->getPointerTo(), | |
206 OrigPtr->getName() + ".hity"); | |
207 | |
208 Value *LoadHi = IRB.CreateLoad(BCHi, Inst->getName() + ".hi"); | |
209 if (!isLegalSize(Width - LoWidth)) { | |
210 LoadHi = splitLoad(cast<LoadInst>(LoadHi), State); | |
211 // BCHi was still illegal, and has been replaced with a placeholder in the | |
212 // recursive call. Since it is redundant with BCLo in the recursive call, | |
213 // just splice it out entirely. | |
214 State.recordConverted(cast<Instruction>(BCHi), GEPHi, /*TakeName=*/false); | |
215 } | |
216 | |
217 Value *HiExt = IRB.CreateZExt(LoadHi, NewType, LoadHi->getName() + ".ext"); | |
218 Value *HiShift = IRB.CreateShl(HiExt, LoWidth, HiExt->getName() + ".sh"); | |
219 Value *Result = IRB.CreateOr(LoExt, HiShift); | |
220 | |
221 State.recordConverted(Inst, Result); | |
222 | |
223 return Result; | |
224 } | |
225 | |
226 static Value *splitStore(StoreInst *Inst, ConversionState &State) { | |
227 assert(!Inst->isVolatile() && !Inst->isAtomic() && | |
228 "Can't split volatile/atomic stores"); | |
229 assert(cast<IntegerType>(Inst->getValueOperand()->getType())->getBitWidth() % 8 | |
Mark Seaborn
2013/05/09 01:00:22
Line >80 chars
Derek Schuff
2013/05/09 18:30:24
Done.
| |
230 == 0); | |
231 | |
232 Value *OrigPtr = State.getConverted(Inst->getPointerOperand()); | |
233 // OrigPtr is now a placeholder in recursive calls, and so has no name. | |
234 if (OrigPtr->getName().empty()) | |
235 OrigPtr->setName(Inst->getPointerOperand()->getName()); | |
236 Value *OrigVal = State.getConverted(Inst->getValueOperand()); | |
237 unsigned Width = cast<IntegerType>( | |
238 Inst->getValueOperand()->getType())->getBitWidth(); | |
239 unsigned LoWidth = Width; | |
240 | |
241 while (!isLegalSize(LoWidth)) LoWidth -= 8; | |
242 IntegerType *LoType = IntegerType::get(Inst->getContext(), LoWidth); | |
243 IntegerType *HiType = IntegerType::get(Inst->getContext(), Width - LoWidth); | |
244 IRBuilder<> IRB(Inst->getParent(), Inst); | |
245 | |
246 Value *BCLo = IRB.CreateBitCast( | |
247 OrigPtr, | |
248 LoType->getPointerTo(), | |
249 OrigPtr->getName() + ".loty"); | |
250 Value *LoTrunc = IRB.CreateTrunc( | |
251 OrigVal, LoType, OrigVal->getName() + ".lo"); | |
252 IRB.CreateAlignedStore(LoTrunc, BCLo, Inst->getAlignment()); | |
253 | |
254 Value *HiLShr = IRB.CreateLShr( | |
255 OrigVal, LoWidth, OrigVal->getName() + ".hi.sh"); | |
256 Value *GEPHi = IRB.CreateConstGEP1_32(BCLo, 1, OrigPtr->getName() + ".hi"); | |
257 Value *HiTrunc = IRB.CreateTrunc( | |
258 HiLShr, HiType, OrigVal->getName() + ".hi"); | |
259 Value *BCHi = IRB.CreateBitCast( | |
260 GEPHi, | |
261 HiType->getPointerTo(), | |
262 OrigPtr->getName() + ".hity"); | |
263 | |
264 Value *StoreHi = IRB.CreateStore(HiTrunc, BCHi); | |
265 | |
266 if (!isLegalSize(Width - LoWidth)) { | |
267 // HiTrunc is still illegal, and is redundant with the truncate in the | |
268 // recursive call, so just get rid of it. | |
269 State.recordConverted(cast<Instruction>(HiTrunc), HiLShr, /*TakeName=*/false ); | |
Mark Seaborn
2013/05/09 01:00:22
Line >80 chars
Derek Schuff
2013/05/09 18:30:24
Done.
| |
270 StoreHi = splitStore(cast<StoreInst>(StoreHi), State); | |
271 // BCHi was still illegal, and has been replaced with a placeholder in the | |
272 // recursive call. Since it is redundant with BCLo in the recursive call, | |
273 // just splice it out entirely. | |
274 State.recordConverted(cast<Instruction>(BCHi), GEPHi, /*TakeName=*/false); | |
275 } | |
276 State.recordConverted(Inst, StoreHi, /*TakeName=*/false); | |
277 return StoreHi; | |
278 } | |
279 | |
280 // Return a value with the bits of the operand above the size of the original | |
281 // type cleared. The operand is assumed to have been legalized already. | |
282 static Value *getClearUpper(Value *Operand, Type *OrigType, | |
283 Instruction *InsertPt) { | |
284 // If the operand is a constant, it will have been created by | |
285 // ConversionState.getConverted, which zero-extends by default. | |
286 if (isa<Constant>(Operand)) | |
287 return Operand; | |
288 return BinaryOperator::Create( | |
289 Instruction::And, | |
290 Operand, | |
291 ConstantInt::get( | |
292 getPromotedType(OrigType), | |
293 APInt::getLowBitsSet(getPromotedType(OrigType)->getIntegerBitWidth(), | |
294 OrigType->getIntegerBitWidth())), | |
295 Operand->getName() + ".clear", | |
296 InsertPt); | |
297 } | |
298 | |
299 // Return a value with the bits of the operand above the size of the original | |
300 // type equal to the sign bit of the original operand. The new operand is | |
301 // assumed to have been legalized already. | |
302 // This is done by shifting the sign bit of the smaller value up to the MSB | |
303 // position in the larger size, and then arithmetic-shifting it back down. | |
304 static Value *getSignExtend(Value *Operand, Value *OrigOperand, | |
305 Instruction *InsertPt) { | |
306 // If OrigOperand was a constant, NewOperand will have been created by | |
307 // ConversionState.getConverted, which zero-extends by default. But that is | |
308 // wrong here, so replace it with a sign-extended constant. | |
309 if (Constant *C = dyn_cast<Constant>(OrigOperand)) | |
310 return convertConstant(C, /*SignExt=*/true); | |
311 Type *OrigType = OrigOperand->getType(); | |
312 ConstantInt *ShiftAmt = ConstantInt::getSigned( | |
313 cast<IntegerType>(getPromotedType(OrigType)), | |
314 getPromotedType(OrigType)->getIntegerBitWidth() - | |
315 OrigType->getIntegerBitWidth()); | |
316 BinaryOperator *Shl = BinaryOperator::Create( | |
317 Instruction::Shl, | |
318 Operand, | |
319 ShiftAmt, | |
320 Operand->getName() + ".getsign", | |
321 InsertPt); | |
322 return BinaryOperator::Create( | |
323 Instruction::AShr, | |
324 Shl, | |
325 ShiftAmt, | |
326 Operand->getName() + ".signed", | |
327 InsertPt); | |
328 } | |
329 | |
330 static void convertInstruction(Instruction *Inst, ConversionState &State) { | |
331 if (SExtInst *Sext = dyn_cast<SExtInst>(Inst)) { | |
332 Value *Op = Sext->getOperand(0); | |
333 Value *NewInst = NULL; | |
334 // If the operand to be extended is illegal, we first need to fill its | |
335 // upper bits (which are zero) with its sign bit. | |
336 if (shouldConvert(Op)) { | |
337 NewInst = getSignExtend(State.getConverted(Op), Op, Sext); | |
338 } | |
339 // If the converted type of the operand is the same as the converted | |
340 // type of the result, we won't actually be changing the type of the | |
341 // variable, just its value. | |
342 if (getPromotedType(Op->getType()) != | |
343 getPromotedType(Sext->getType())) { | |
344 NewInst = new SExtInst( | |
345 NewInst ? NewInst : State.getConverted(Op), | |
346 getPromotedType(cast<IntegerType>(Sext->getType())), | |
347 Sext->getName() + ".sext", Sext); | |
348 } | |
349 // Now all the bits of the result are correct, but we need to restore | |
350 // the bits above its type to zero. | |
351 if (shouldConvert(Sext)) { | |
352 NewInst = getClearUpper(NewInst, Sext->getType(), Sext); | |
353 } | |
354 assert(NewInst && "Failed to convert sign extension"); | |
355 State.recordConverted(Sext, NewInst); | |
356 } else if (ZExtInst *Zext = dyn_cast<ZExtInst>(Inst)) { | |
357 Value *Op = Zext->getOperand(0); | |
358 Value *NewInst = NULL; | |
359 // TODO(dschuff): Some of these zexts could be no-ops. | |
360 if (shouldConvert(Op)) { | |
361 NewInst = getClearUpper(State.getConverted(Op), | |
362 Op->getType(), | |
363 Zext); | |
364 } | |
365 // If the converted type of the operand is the same as the converted | |
366 // type of the result, we won't actually be changing the type of the | |
367 // variable, just its value. | |
368 if (getPromotedType(Op->getType()) != | |
369 getPromotedType(Zext->getType())) { | |
370 NewInst = CastInst::CreateZExtOrBitCast( | |
371 NewInst ? NewInst : State.getConverted(Op), | |
372 getPromotedType(cast<IntegerType>(Zext->getType())), | |
373 "", Zext); | |
374 } | |
375 assert(NewInst); | |
376 State.recordConverted(Zext, NewInst); | |
377 } else if (TruncInst *Trunc = dyn_cast<TruncInst>(Inst)) { | |
378 Value *Op = Trunc->getOperand(0); | |
379 Value *NewInst = NULL; | |
380 // If the converted type of the operand is the same as the converted | |
381 // type of the result, we won't actually be changing the type of the | |
382 // variable, just its value. | |
383 if (getPromotedType(Op->getType()) != | |
384 getPromotedType(Trunc->getType())) { | |
385 NewInst = new TruncInst( | |
386 State.getConverted(Op), | |
387 getPromotedType(cast<IntegerType>(Trunc->getType())), | |
388 State.getConverted(Op)->getName() + ".trunc", | |
389 Trunc); | |
390 } | |
391 // Restoring the upper-bits-are-zero invariant effectively truncates the | |
392 // value. | |
393 if (shouldConvert(Trunc)) { | |
394 NewInst = getClearUpper(NewInst ? NewInst : Op, | |
395 Trunc->getType(), | |
396 Trunc); | |
397 } | |
398 assert(NewInst); | |
399 State.recordConverted(Trunc, NewInst); | |
400 } else if (AllocaInst *Alloc = dyn_cast<AllocaInst>(Inst)) { | |
401 // Don't handle arrays of illegal types, but we could handle an array | |
402 // with size specified as an illegal type, as unlikely as that seems. | |
403 assert(!(shouldConvert(Alloc) && Alloc->isArrayAllocation())); | |
404 AllocaInst *NewInst = new AllocaInst( | |
405 getPromotedType(Alloc->getAllocatedType()), | |
406 State.getConverted(Alloc->getArraySize()), | |
407 "", Alloc); | |
408 NewInst->setAlignment(Alloc->getAlignment()); | |
409 State.recordConverted(Alloc, NewInst); | |
410 } else if (BitCastInst *BCInst = dyn_cast<BitCastInst>(Inst)) { | |
411 // Only handle pointers. Ints can't be casted to/from other ints | |
412 if (shouldConvert(BCInst) || shouldConvert(BCInst->getOperand(0))) { | |
413 BitCastInst *NewInst = new BitCastInst( | |
414 State.getConverted(BCInst->getOperand(0)), | |
415 getPromotedType(BCInst->getDestTy()), | |
416 "", BCInst); | |
417 State.recordConverted(BCInst, NewInst); | |
418 } | |
419 } else if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) { | |
420 if (shouldConvert(Load)) { | |
421 splitLoad(Load, State); | |
422 } | |
423 } else if (StoreInst *Store = dyn_cast<StoreInst>(Inst)) { | |
424 if (shouldConvert(Store->getValueOperand())) { | |
425 splitStore(Store, State); | |
426 } | |
427 } else if (CallInst *Call = dyn_cast<CallInst>(Inst)) { | |
428 llvm_unreachable("can't convert calls"); | |
429 for (unsigned I = 0; I < Call->getNumArgOperands(); ++I) { | |
Mark Seaborn
2013/05/09 01:00:22
Drop the dead code here since it's after llvm_unre
Derek Schuff
2013/05/09 18:30:24
Done.
| |
430 Value *Arg = Call->getArgOperand(I); | |
431 Call->setArgOperand(I, State.getConverted(Arg)); | |
432 } | |
433 } else if (BinaryOperator *Binop = dyn_cast<BinaryOperator>(Inst)) { | |
434 Value *NewInst = NULL; | |
435 if (Binop->getOpcode() == Instruction::AShr) { | |
436 // The AShr operand needs to be sign-extended to the promoted size | |
437 // before shifting. Because the sign-extension is implemented with | |
438 // with AShr, it can be combined with the original operation. | |
439 Value *Op = Binop->getOperand(0); | |
440 Value *ShiftAmount = NULL; | |
441 APInt SignShiftAmt = APInt( | |
442 getPromotedType(Op->getType())->getIntegerBitWidth(), | |
443 getPromotedType(Op->getType())->getIntegerBitWidth() - | |
444 Op->getType()->getIntegerBitWidth()); | |
445 NewInst = BinaryOperator::Create( | |
446 Instruction::Shl, | |
447 State.getConverted(Op), | |
448 ConstantInt::get(getPromotedType(Op->getType()), SignShiftAmt), | |
449 State.getConverted(Op)->getName() + ".getsign", | |
450 Binop); | |
451 if (ConstantInt *C = dyn_cast<ConstantInt>( | |
452 State.getConverted(Binop->getOperand(1)))) { | |
453 ShiftAmount = ConstantInt::get(getPromotedType(Op->getType()), | |
454 SignShiftAmt + C->getValue()); | |
455 } else { | |
456 ShiftAmount = BinaryOperator::Create( | |
457 Instruction::Add, | |
458 State.getConverted(Binop->getOperand(1)), | |
459 ConstantInt::get( | |
460 getPromotedType(Binop->getOperand(1)->getType()), | |
461 SignShiftAmt), | |
462 State.getConverted(Op)->getName() + ".shamt", Binop); | |
463 } | |
464 NewInst = BinaryOperator::Create( | |
465 Instruction::AShr, | |
466 NewInst, | |
467 ShiftAmount, | |
468 Binop->getName() + ".result", Binop); | |
469 } else { | |
470 // If the original operation is not AShr, just recreate it as usual. | |
471 NewInst = BinaryOperator::Create( | |
472 Binop->getOpcode(), | |
473 NewInst ? NewInst : State.getConverted(Binop->getOperand(0)), | |
474 State.getConverted(Binop->getOperand(1)), | |
475 Binop->getName() + ".result", Binop); | |
476 } | |
477 | |
478 // Now restore the invariant if necessary. | |
479 // This switch also sanity-checks the operation. | |
480 switch (Binop->getOpcode()) { | |
481 case Instruction::And: | |
482 case Instruction::Or: | |
483 case Instruction::Xor: | |
484 case Instruction::LShr: | |
485 // These won't change the upper bits. | |
486 break; | |
487 case Instruction::Add: | |
488 case Instruction::Sub: | |
489 case Instruction::Shl: | |
490 case Instruction::AShr: | |
491 // These can change the upper bits, so clear them now. | |
492 NewInst = getClearUpper(NewInst, Binop->getType(), Binop); | |
493 break; | |
494 | |
495 // We should not see FP operators here. | |
496 // We don't handle mul/div. | |
497 case Instruction::FAdd: | |
498 case Instruction::FSub: | |
499 case Instruction::Mul: | |
500 case Instruction::FMul: | |
501 case Instruction::UDiv: | |
502 case Instruction::SDiv: | |
503 case Instruction::FDiv: | |
504 case Instruction::URem: | |
505 case Instruction::SRem: | |
506 case Instruction::FRem: | |
507 case Instruction::BinaryOpsEnd: | |
508 errs() << *Inst << "\n"; | |
509 llvm_unreachable("Cannot handle binary operator"); | |
510 break; | |
511 } | |
512 | |
513 State.recordConverted(Binop, NewInst); | |
514 } else if (ICmpInst *Cmp = dyn_cast<ICmpInst>(Inst)) { | |
515 Value *Op0, *Op1; | |
516 // For signed compares, operands are sign-extended to their | |
517 // promoted type. For unsigned or equality compares, the comparison | |
518 // is equivalent with the larger type because they are already | |
519 // zero-extended. | |
520 if (Cmp->isSigned()) { | |
521 Op0 = getSignExtend(State.getConverted(Cmp->getOperand(0)), | |
522 Cmp->getOperand(0), | |
523 Cmp); | |
524 Op1 = getSignExtend(State.getConverted(Cmp->getOperand(1)), | |
525 Cmp->getOperand(1), | |
526 Cmp); | |
527 } else { | |
528 Op0 = State.getConverted(Cmp->getOperand(0)); | |
529 Op1 = State.getConverted(Cmp->getOperand(1)); | |
530 } | |
531 ICmpInst *NewInst = new ICmpInst( | |
532 Cmp, Cmp->getPredicate(), Op0, Op1, ""); | |
533 State.recordConverted(Cmp, NewInst); | |
534 } else if (SelectInst *Select = dyn_cast<SelectInst>(Inst)) { | |
535 SelectInst *NewInst = SelectInst::Create( | |
536 Select->getCondition(), | |
537 State.getConverted(Select->getTrueValue()), | |
538 State.getConverted(Select->getFalseValue()), | |
539 "", Select); | |
540 State.recordConverted(Select, NewInst); | |
541 } else if (PHINode *Phi = dyn_cast<PHINode>(Inst)) { | |
542 PHINode *NewPhi = PHINode::Create( | |
543 getPromotedType(Phi->getType()), | |
544 Phi->getNumIncomingValues(), | |
545 "", Phi); | |
546 for (unsigned I = 0, E = Phi->getNumIncomingValues(); I < E; ++I) { | |
547 NewPhi->addIncoming(State.getConverted(Phi->getIncomingValue(I)), | |
548 Phi->getIncomingBlock(I)); | |
549 } | |
550 State.recordConverted(Phi, NewPhi); | |
551 } else { | |
552 errs() << *Inst<<"\n"; | |
553 llvm_unreachable("unhandled instruction"); | |
554 } | |
555 } | |
556 | |
557 bool PromoteIntegers::runOnFunction(Function &F) { | |
558 // Don't support changing the function arguments. This should not be | |
559 // generated by clang. | |
560 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { | |
561 Value *Arg = I; | |
562 if (shouldConvert(Arg)) { | |
563 errs() << "Function " << F.getName() << ": " << *Arg << "\n"; | |
564 llvm_unreachable("Function has illegal integer/pointer argument"); | |
565 } | |
566 } | |
567 | |
568 ConversionState State; | |
569 bool Modified = false; | |
570 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) { | |
571 for (BasicBlock::iterator BBI = FI->begin(), BBE = FI->end(); BBI != BBE;) { | |
572 Instruction *Inst = BBI++; | |
573 // Only attempt to convert an instruction if its result or any of its | |
574 // operands are illegal. | |
575 bool ShouldConvert = shouldConvert(Inst); | |
576 for (User::op_iterator OI = Inst->op_begin(), OE = Inst->op_end(); | |
577 OI != OE; ++OI) | |
578 ShouldConvert |= shouldConvert(cast<Value>(OI)); | |
579 | |
580 if (ShouldConvert) { | |
581 convertInstruction(Inst, State); | |
582 Modified = true; | |
583 } | |
584 } | |
585 } | |
586 | |
587 return Modified; | |
588 } | |
OLD | NEW |