Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: lib/Transforms/NaCl/PromoteIntegers.cpp

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

Powered by Google App Engine
This is Rietveld 408576698