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

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

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

Powered by Google App Engine
This is Rietveld 408576698