Chromium Code Reviews| 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. | |
| 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 NewInst ? NewInst : State.getConverted(Binop->getOperand(0)), | |
|
jvoung (off chromium)
2013/05/10 01:22:44
NewInst is always null entering this branch?
Derek Schuff
2013/05/11 00:11:45
Done.
| |
| 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 } | |
| OLD | NEW |