| OLD | NEW |
| (Empty) |
| 1 //===- ExpandI64.cpp - Expand i64 and wider integer types -------------===// | |
| 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 //===------------------------------------------------------------------===// | |
| 9 // | |
| 10 // This pass expands and lowers all operations on integers i64 and wider | |
| 11 // into 32-bit operations that can be handled by JS in a natural way. | |
| 12 // | |
| 13 // 64-bit variables become pairs of 2 32-bit variables, for the low and | |
| 14 // high 32 bit chunks. This happens for both registers and function | |
| 15 // arguments. Function return values become a return of the low 32 bits | |
| 16 // and a store of the high 32-bits in tempRet0, a global helper variable. | |
| 17 // Larger values become more chunks of 32 bits. Currently we require that | |
| 18 // types be a multiple of 32 bits. | |
| 19 // | |
| 20 // Many operations then become simple pairs of operations, for example | |
| 21 // bitwise AND becomes and AND of each 32-bit chunk. More complex operations | |
| 22 // like addition are lowered into calls into library support code in | |
| 23 // Emscripten (i64Add for example). | |
| 24 // | |
| 25 //===------------------------------------------------------------------===// | |
| 26 | |
| 27 #include "llvm/ADT/PostOrderIterator.h" | |
| 28 #include "llvm/ADT/SmallString.h" | |
| 29 #include "llvm/ADT/SmallVector.h" | |
| 30 #include "llvm/ADT/StringExtras.h" | |
| 31 #include "llvm/Analysis/ConstantFolding.h" | |
| 32 #include "llvm/Analysis/InstructionSimplify.h" | |
| 33 #include "llvm/IR/CFG.h" | |
| 34 #include "llvm/IR/DataLayout.h" | |
| 35 #include "llvm/IR/Function.h" | |
| 36 #include "llvm/IR/IRBuilder.h" | |
| 37 #include "llvm/IR/Instructions.h" | |
| 38 #include "llvm/IR/IntrinsicInst.h" | |
| 39 #include "llvm/IR/Module.h" | |
| 40 #include "llvm/Pass.h" | |
| 41 #include "llvm/Analysis/TargetLibraryInfo.h" | |
| 42 #include "llvm/Transforms/NaCl.h" | |
| 43 #include "llvm/Transforms/Utils/Local.h" | |
| 44 #include <map> | |
| 45 #include <vector> | |
| 46 | |
| 47 #include "llvm/Support/raw_ostream.h" | |
| 48 | |
| 49 #ifdef NDEBUG | |
| 50 #undef assert | |
| 51 #define assert(x) { if (!(x)) report_fatal_error(#x); } | |
| 52 #endif | |
| 53 | |
| 54 using namespace llvm; | |
| 55 | |
| 56 namespace { | |
| 57 | |
| 58 struct PhiBlockChange { | |
| 59 BasicBlock *DD, *SwitchBB, *NewBB; | |
| 60 }; | |
| 61 | |
| 62 typedef SmallVector<Value*, 2> ChunksVec; | |
| 63 typedef std::map<Value*, ChunksVec> SplitsMap; | |
| 64 | |
| 65 typedef SmallVector<PHINode *, 8> PHIVec; | |
| 66 typedef SmallVector<Instruction *, 8> DeadVec; | |
| 67 | |
| 68 // This is a ModulePass because the pass recreates functions in | |
| 69 // order to expand i64 arguments to pairs of i32s. | |
| 70 class ExpandI64 : public ModulePass { | |
| 71 bool Changed; | |
| 72 const DataLayout *DL; | |
| 73 Module *TheModule; | |
| 74 | |
| 75 SplitsMap Splits; // old illegal value to new insts | |
| 76 PHIVec Phis; | |
| 77 std::vector<PhiBlockChange> PhiBlockChanges; | |
| 78 | |
| 79 // If the function has an illegal return or argument, create a legal version | |
| 80 void ensureLegalFunc(Function *F); | |
| 81 | |
| 82 // If a function is illegal, remove it | |
| 83 void removeIllegalFunc(Function *F); | |
| 84 | |
| 85 // splits an illegal instruction into 32-bit chunks. We do | |
| 86 // not yet have the values yet, as they depend on other | |
| 87 // splits, so store the parts in Splits, for FinalizeInst. | |
| 88 bool splitInst(Instruction *I); | |
| 89 | |
| 90 // For an illegal value, returns the split out chunks | |
| 91 // representing the low and high parts, that splitInst | |
| 92 // generated. | |
| 93 // The value can also be a constant, in which case we just | |
| 94 // split it, or a function argument, in which case we | |
| 95 // map to the proper legalized new arguments | |
| 96 // | |
| 97 // @param AllowUnreachable It is possible for phi nodes | |
| 98 // to refer to unreachable blocks, | |
| 99 // which our traversal never | |
| 100 // reaches; this flag lets us | |
| 101 // ignore those - otherwise, | |
| 102 // not finding chunks is fatal | |
| 103 ChunksVec getChunks(Value *V, bool AllowUnreachable=false); | |
| 104 | |
| 105 Function *Add, *Sub, *Mul, *SDiv, *UDiv, *SRem, *URem, *LShr, *AShr, *Shl, *
GetHigh, *SetHigh, *FtoILow, *FtoIHigh, *DtoILow, *DtoIHigh, *SItoF, *UItoF, *SI
toD, *UItoD, *BItoD, *BDtoILow, *BDtoIHigh; | |
| 106 | |
| 107 void ensureFuncs(); | |
| 108 unsigned getNumChunks(Type *T); | |
| 109 | |
| 110 public: | |
| 111 static char ID; | |
| 112 ExpandI64() : ModulePass(ID) { | |
| 113 initializeExpandI64Pass(*PassRegistry::getPassRegistry()); | |
| 114 | |
| 115 Add = Sub = Mul = SDiv = UDiv = SRem = URem = LShr = AShr = Shl = GetHigh
= SetHigh = NULL; | |
| 116 } | |
| 117 | |
| 118 virtual bool runOnModule(Module &M); | |
| 119 }; | |
| 120 } | |
| 121 | |
| 122 char ExpandI64::ID = 0; | |
| 123 INITIALIZE_PASS(ExpandI64, "expand-illegal-ints", | |
| 124 "Expand and lower illegal >i32 operations into 32-bit chunks", | |
| 125 false, false) | |
| 126 | |
| 127 // Utilities | |
| 128 | |
| 129 static Instruction *CopyDebug(Instruction *NewInst, Instruction *Original) { | |
| 130 NewInst->setDebugLoc(Original->getDebugLoc()); | |
| 131 return NewInst; | |
| 132 } | |
| 133 | |
| 134 static bool isIllegal(Type *T) { | |
| 135 return T->isIntegerTy() && T->getIntegerBitWidth() > 32; | |
| 136 } | |
| 137 | |
| 138 static FunctionType *getLegalizedFunctionType(FunctionType *FT) { | |
| 139 SmallVector<Type*, 0> ArgTypes; // XXX | |
| 140 int Num = FT->getNumParams(); | |
| 141 for (int i = 0; i < Num; i++) { | |
| 142 Type *T = FT->getParamType(i); | |
| 143 if (!isIllegal(T)) { | |
| 144 ArgTypes.push_back(T); | |
| 145 } else { | |
| 146 Type *i32 = Type::getInt32Ty(FT->getContext()); | |
| 147 ArgTypes.push_back(i32); | |
| 148 ArgTypes.push_back(i32); | |
| 149 } | |
| 150 } | |
| 151 Type *RT = FT->getReturnType(); | |
| 152 Type *NewRT; | |
| 153 if (!isIllegal(RT)) { | |
| 154 NewRT = RT; | |
| 155 } else { | |
| 156 NewRT = Type::getInt32Ty(FT->getContext()); | |
| 157 } | |
| 158 return FunctionType::get(NewRT, ArgTypes, false); | |
| 159 } | |
| 160 | |
| 161 // Implementation of ExpandI64 | |
| 162 | |
| 163 static bool okToRemainIllegal(Function *F) { | |
| 164 StringRef Name = F->getName(); | |
| 165 if (Name == "llvm.dbg.value") return true; | |
| 166 | |
| 167 // XXX EMSCRIPTEN: These take an i64 immediate argument; since they're not | |
| 168 // real instructions, we don't need to legalize them. | |
| 169 if (Name == "llvm.lifetime.start") return true; | |
| 170 if (Name == "llvm.lifetime.end") return true; | |
| 171 if (Name == "llvm.invariant.start") return true; | |
| 172 if (Name == "llvm.invariant.end") return true; | |
| 173 | |
| 174 return false; | |
| 175 } | |
| 176 | |
| 177 unsigned ExpandI64::getNumChunks(Type *T) { | |
| 178 unsigned Num = DL->getTypeSizeInBits(T); | |
| 179 return (Num + 31) / 32; | |
| 180 } | |
| 181 | |
| 182 static bool isLegalFunctionType(FunctionType *FT) { | |
| 183 if (isIllegal(FT->getReturnType())) { | |
| 184 return false; | |
| 185 } | |
| 186 | |
| 187 int Num = FT->getNumParams(); | |
| 188 for (int i = 0; i < Num; i++) { | |
| 189 if (isIllegal(FT->getParamType(i))) { | |
| 190 return false; | |
| 191 } | |
| 192 } | |
| 193 | |
| 194 return true; | |
| 195 } | |
| 196 | |
| 197 static bool isLegalInstruction(const Instruction *I) { | |
| 198 if (isIllegal(I->getType())) { | |
| 199 return false; | |
| 200 } | |
| 201 | |
| 202 for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { | |
| 203 if (isIllegal(I->getOperand(i)->getType())) { | |
| 204 return false; | |
| 205 } | |
| 206 } | |
| 207 | |
| 208 return true; | |
| 209 } | |
| 210 | |
| 211 // We can't use RecreateFunction because we need to handle | |
| 212 // function and argument attributes specially. | |
| 213 static Function *RecreateFunctionLegalized(Function *F, FunctionType *NewType) { | |
| 214 Function *NewFunc = Function::Create(NewType, F->getLinkage()); | |
| 215 | |
| 216 AttributeSet Attrs = F->getAttributes(); | |
| 217 AttributeSet FnAttrs = Attrs.getFnAttributes(); | |
| 218 | |
| 219 // Legalizing the return value is done by storing part of the value into | |
| 220 // static storage. Subsequent analysis will see this as a memory access, | |
| 221 // so we can no longer claim to be readonly or readnone. | |
| 222 if (isIllegal(F->getReturnType())) { | |
| 223 FnAttrs = FnAttrs.removeAttribute(F->getContext(), | |
| 224 AttributeSet::FunctionIndex, | |
| 225 Attribute::ReadOnly); | |
| 226 FnAttrs = FnAttrs.removeAttribute(F->getContext(), | |
| 227 AttributeSet::FunctionIndex, | |
| 228 Attribute::ReadNone); | |
| 229 } | |
| 230 | |
| 231 NewFunc->addAttributes(AttributeSet::FunctionIndex, FnAttrs); | |
| 232 NewFunc->addAttributes(AttributeSet::ReturnIndex, Attrs.getRetAttributes()); | |
| 233 Function::arg_iterator AI = F->arg_begin(); | |
| 234 | |
| 235 // We need to recreate the attribute set, with the right indexes | |
| 236 AttributeSet NewAttrs; | |
| 237 unsigned NumArgs = F->arg_size(); | |
| 238 for (unsigned i = 1, j = 1; i < NumArgs+1; i++, j++, AI++) { | |
| 239 if (isIllegal(AI->getType())) { | |
| 240 j++; | |
| 241 continue; | |
| 242 } | |
| 243 if (!Attrs.hasAttributes(i)) continue; | |
| 244 AttributeSet ParamAttrs = Attrs.getParamAttributes(i); | |
| 245 AttrBuilder AB; | |
| 246 unsigned NumSlots = ParamAttrs.getNumSlots(); | |
| 247 for (unsigned k = 0; k < NumSlots; k++) { | |
| 248 for (AttributeSet::iterator I = ParamAttrs.begin(k), E = ParamAttrs.end(k)
; I != E; I++) { | |
| 249 AB.addAttribute(*I); | |
| 250 } | |
| 251 } | |
| 252 NewFunc->addAttributes(j, AttributeSet::get(F->getContext(), j, AB)); | |
| 253 } | |
| 254 | |
| 255 F->getParent()->getFunctionList().insert(F, NewFunc); | |
| 256 NewFunc->takeName(F); | |
| 257 NewFunc->getBasicBlockList().splice(NewFunc->begin(), | |
| 258 F->getBasicBlockList()); | |
| 259 F->replaceAllUsesWith( | |
| 260 ConstantExpr::getBitCast(NewFunc, | |
| 261 F->getFunctionType()->getPointerTo())); | |
| 262 return NewFunc; | |
| 263 } | |
| 264 | |
| 265 void ExpandI64::ensureLegalFunc(Function *F) { | |
| 266 if (okToRemainIllegal(F)) return; | |
| 267 | |
| 268 FunctionType *FT = F->getFunctionType(); | |
| 269 if (isLegalFunctionType(FT)) return; | |
| 270 | |
| 271 Changed = true; | |
| 272 Function *NF = RecreateFunctionLegalized(F, getLegalizedFunctionType(FT)); | |
| 273 std::string Name = NF->getName(); | |
| 274 if (strncmp(Name.c_str(), "llvm.", 5) == 0) { | |
| 275 // this is an intrinsic, and we are changing its signature, which will annoy
LLVM, so rename | |
| 276 const size_t len = Name.size(); | |
| 277 SmallString<256> NewName; | |
| 278 NewName.resize(len); | |
| 279 for (unsigned i = 0; i < len; i++) { | |
| 280 NewName[i] = Name[i] != '.' ? Name[i] : '_'; | |
| 281 } | |
| 282 NF->setName(Twine(NewName)); | |
| 283 } | |
| 284 | |
| 285 // Move and update arguments | |
| 286 for (Function::arg_iterator Arg = F->arg_begin(), E = F->arg_end(), NewArg = N
F->arg_begin(); | |
| 287 Arg != E; ++Arg) { | |
| 288 if (Arg->getType() == NewArg->getType()) { | |
| 289 NewArg->takeName(Arg); | |
| 290 Arg->replaceAllUsesWith(NewArg); | |
| 291 NewArg++; | |
| 292 } else { | |
| 293 // This was legalized | |
| 294 ChunksVec &Chunks = Splits[&*Arg]; | |
| 295 int Num = getNumChunks(Arg->getType()); | |
| 296 assert(Num == 2); | |
| 297 for (int i = 0; i < Num; i++) { | |
| 298 Chunks.push_back(&*NewArg); | |
| 299 if (NewArg->hasName()) Chunks[i]->setName(NewArg->getName() + "$" + utos
tr(i)); | |
| 300 NewArg++; | |
| 301 } | |
| 302 } | |
| 303 } | |
| 304 } | |
| 305 | |
| 306 void ExpandI64::removeIllegalFunc(Function *F) { | |
| 307 if (okToRemainIllegal(F)) return; | |
| 308 | |
| 309 FunctionType *FT = F->getFunctionType(); | |
| 310 if (!isLegalFunctionType(FT)) { | |
| 311 F->eraseFromParent(); | |
| 312 } | |
| 313 } | |
| 314 | |
| 315 bool ExpandI64::splitInst(Instruction *I) { | |
| 316 Type *i32 = Type::getInt32Ty(I->getContext()); | |
| 317 Type *i32P = i32->getPointerTo(); | |
| 318 Type *i64 = Type::getInt64Ty(I->getContext()); | |
| 319 Value *Zero = Constant::getNullValue(i32); | |
| 320 | |
| 321 ChunksVec &Chunks = Splits[I]; | |
| 322 | |
| 323 switch (I->getOpcode()) { | |
| 324 case Instruction::GetElementPtr: { | |
| 325 GetElementPtrInst *GEP = cast<GetElementPtrInst>(I); | |
| 326 SmallVector<Value*, 2> NewOps; | |
| 327 for (unsigned i = 1, e = I->getNumOperands(); i != e; ++i) { | |
| 328 Value *Op = I->getOperand(i); | |
| 329 if (isIllegal(Op->getType())) { | |
| 330 // Truncate the operand down to one chunk. | |
| 331 NewOps.push_back(getChunks(Op)[0]); | |
| 332 } else { | |
| 333 NewOps.push_back(Op); | |
| 334 } | |
| 335 } | |
| 336 Value *NewGEP = CopyDebug(GetElementPtrInst::Create(GEP->getPointerOperand
()->getType(), GEP->getPointerOperand(), NewOps, "", GEP), GEP); | |
| 337 Chunks.push_back(NewGEP); | |
| 338 I->replaceAllUsesWith(NewGEP); | |
| 339 break; | |
| 340 } | |
| 341 case Instruction::SExt: { | |
| 342 ChunksVec InputChunks; | |
| 343 Value *Op = I->getOperand(0); | |
| 344 if (isIllegal(Op->getType())) { | |
| 345 InputChunks = getChunks(Op); | |
| 346 } else { | |
| 347 InputChunks.push_back(Op); | |
| 348 } | |
| 349 | |
| 350 for (unsigned i = 0, e = InputChunks.size(); i != e; ++i) { | |
| 351 Value *Input = InputChunks[i]; | |
| 352 | |
| 353 Type *T = Input->getType(); | |
| 354 Value *Chunk; | |
| 355 if (T->getIntegerBitWidth() < 32) { | |
| 356 Chunk = CopyDebug(new SExtInst(Input, i32, "", I), I); | |
| 357 } else { | |
| 358 assert(T->getIntegerBitWidth() == 32); | |
| 359 Chunk = Input; | |
| 360 } | |
| 361 Chunks.push_back(Chunk); | |
| 362 } | |
| 363 | |
| 364 Instruction *Check = CopyDebug(new ICmpInst(I, ICmpInst::ICMP_SLT, Chunks.
back(), Zero), I); | |
| 365 int Num = getNumChunks(I->getType()); | |
| 366 for (int i = Chunks.size(); i < Num; i++) { | |
| 367 Instruction *High = CopyDebug(new SExtInst(Check, i32, "", I), I); | |
| 368 Chunks.push_back(High); | |
| 369 } | |
| 370 break; | |
| 371 } | |
| 372 case Instruction::PtrToInt: | |
| 373 case Instruction::ZExt: { | |
| 374 Value *Op = I->getOperand(0); | |
| 375 ChunksVec InputChunks; | |
| 376 if (I->getOpcode() == Instruction::PtrToInt) { | |
| 377 InputChunks.push_back(CopyDebug(new PtrToIntInst(Op, i32, "", I), I)); | |
| 378 } else if (isIllegal(Op->getType())) { | |
| 379 InputChunks = getChunks(Op); | |
| 380 } else { | |
| 381 InputChunks.push_back(Op); | |
| 382 } | |
| 383 | |
| 384 for (unsigned i = 0, e = InputChunks.size(); i != e; ++i) { | |
| 385 Value *Input = InputChunks[i]; | |
| 386 Type *T = Input->getType(); | |
| 387 | |
| 388 Value *Chunk; | |
| 389 if (T->getIntegerBitWidth() < 32) { | |
| 390 Chunk = CopyDebug(new ZExtInst(Input, i32, "", I), I); | |
| 391 } else { | |
| 392 assert(T->getIntegerBitWidth() == 32); | |
| 393 Chunk = Input; | |
| 394 } | |
| 395 Chunks.push_back(Chunk); | |
| 396 } | |
| 397 | |
| 398 int Num = getNumChunks(I->getType()); | |
| 399 for (int i = Chunks.size(); i < Num; i++) { | |
| 400 Chunks.push_back(Zero); | |
| 401 } | |
| 402 break; | |
| 403 } | |
| 404 case Instruction::IntToPtr: | |
| 405 case Instruction::Trunc: { | |
| 406 unsigned Num = getNumChunks(I->getType()); | |
| 407 unsigned NumBits = DL->getTypeSizeInBits(I->getType()); | |
| 408 ChunksVec InputChunks = getChunks(I->getOperand(0)); | |
| 409 for (unsigned i = 0; i < Num; i++) { | |
| 410 Value *Input = InputChunks[i]; | |
| 411 | |
| 412 Value *Chunk; | |
| 413 if (NumBits < 32) { | |
| 414 Chunk = CopyDebug(new TruncInst(Input, IntegerType::get(I->getContext(
), NumBits), "", I), I); | |
| 415 NumBits = 0; | |
| 416 } else { | |
| 417 Chunk = Input; | |
| 418 NumBits -= 32; | |
| 419 } | |
| 420 if (I->getOpcode() == Instruction::IntToPtr) { | |
| 421 assert(i == 0); | |
| 422 Chunk = CopyDebug(new IntToPtrInst(Chunk, I->getType(), "", I), I); | |
| 423 } | |
| 424 Chunks.push_back(Chunk); | |
| 425 } | |
| 426 if (!isIllegal(I->getType())) { | |
| 427 assert(Chunks.size() == 1); | |
| 428 I->replaceAllUsesWith(Chunks[0]); | |
| 429 } | |
| 430 break; | |
| 431 } | |
| 432 case Instruction::Load: { | |
| 433 LoadInst *LI = cast<LoadInst>(I); | |
| 434 Instruction *AI = CopyDebug(new PtrToIntInst(LI->getPointerOperand(), i32,
"", I), I); | |
| 435 int Num = getNumChunks(I->getType()); | |
| 436 for (int i = 0; i < Num; i++) { | |
| 437 Instruction *Add = i == 0 ? AI : CopyDebug(BinaryOperator::Create(Instru
ction::Add, AI, ConstantInt::get(i32, 4*i), "", I), I); | |
| 438 Instruction *Ptr = CopyDebug(new IntToPtrInst(Add, i32P, "", I), I); | |
| 439 LoadInst *Chunk = new LoadInst(Ptr, "", I); CopyDebug(Chunk, I); | |
| 440 Chunk->setAlignment(MinAlign(LI->getAlignment() == 0 ? | |
| 441 DL->getABITypeAlignment(LI->getType())
: | |
| 442 LI->getAlignment(), | |
| 443 4*i)); | |
| 444 Chunk->setVolatile(LI->isVolatile()); | |
| 445 Chunk->setOrdering(LI->getOrdering()); | |
| 446 Chunk->setSynchScope(LI->getSynchScope()); | |
| 447 Chunks.push_back(Chunk); | |
| 448 } | |
| 449 break; | |
| 450 } | |
| 451 case Instruction::Store: { | |
| 452 StoreInst *SI = cast<StoreInst>(I); | |
| 453 Instruction *AI = CopyDebug(new PtrToIntInst(SI->getPointerOperand(), i32,
"", I), I); | |
| 454 ChunksVec InputChunks = getChunks(SI->getValueOperand()); | |
| 455 int Num = InputChunks.size(); | |
| 456 for (int i = 0; i < Num; i++) { | |
| 457 Instruction *Add = i == 0 ? AI : CopyDebug(BinaryOperator::Create(Instru
ction::Add, AI, ConstantInt::get(i32, 4*i), "", I), I); | |
| 458 Instruction *Ptr = CopyDebug(new IntToPtrInst(Add, i32P, "", I), I); | |
| 459 StoreInst *Chunk = new StoreInst(InputChunks[i], Ptr, I); | |
| 460 Chunk->setAlignment(MinAlign(SI->getAlignment() == 0 ? | |
| 461 DL->getABITypeAlignment(SI->getValueOpe
rand()->getType()) : | |
| 462 SI->getAlignment(), | |
| 463 4*i)); | |
| 464 Chunk->setVolatile(SI->isVolatile()); | |
| 465 Chunk->setOrdering(SI->getOrdering()); | |
| 466 Chunk->setSynchScope(SI->getSynchScope()); | |
| 467 CopyDebug(Chunk, I); | |
| 468 } | |
| 469 break; | |
| 470 } | |
| 471 case Instruction::Ret: { | |
| 472 assert(I->getOperand(0)->getType() == i64); | |
| 473 ChunksVec InputChunks = getChunks(I->getOperand(0)); | |
| 474 ensureFuncs(); | |
| 475 SmallVector<Value *, 1> Args; | |
| 476 Args.push_back(InputChunks[1]); | |
| 477 CopyDebug(CallInst::Create(SetHigh, Args, "", I), I); | |
| 478 CopyDebug(ReturnInst::Create(I->getContext(), InputChunks[0], I), I); | |
| 479 break; | |
| 480 } | |
| 481 case Instruction::Add: | |
| 482 case Instruction::Sub: | |
| 483 case Instruction::Mul: | |
| 484 case Instruction::SDiv: | |
| 485 case Instruction::UDiv: | |
| 486 case Instruction::SRem: | |
| 487 case Instruction::URem: | |
| 488 case Instruction::LShr: | |
| 489 case Instruction::AShr: | |
| 490 case Instruction::Shl: { | |
| 491 ChunksVec LeftChunks = getChunks(I->getOperand(0)); | |
| 492 ChunksVec RightChunks = getChunks(I->getOperand(1)); | |
| 493 unsigned Num = getNumChunks(I->getType()); | |
| 494 if (Num == 2) { | |
| 495 ensureFuncs(); | |
| 496 Value *Low = NULL, *High = NULL; | |
| 497 Function *F = NULL; | |
| 498 switch (I->getOpcode()) { | |
| 499 case Instruction::Add: F = Add; break; | |
| 500 case Instruction::Sub: F = Sub; break; | |
| 501 case Instruction::Mul: F = Mul; break; | |
| 502 case Instruction::SDiv: F = SDiv; break; | |
| 503 case Instruction::UDiv: F = UDiv; break; | |
| 504 case Instruction::SRem: F = SRem; break; | |
| 505 case Instruction::URem: F = URem; break; | |
| 506 case Instruction::AShr: F = AShr; break; | |
| 507 case Instruction::LShr: { | |
| 508 if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) { | |
| 509 unsigned Shifts = CI->getZExtValue(); | |
| 510 if (Shifts == 32) { | |
| 511 Low = LeftChunks[1]; | |
| 512 High = Zero; | |
| 513 break; | |
| 514 } | |
| 515 } | |
| 516 F = LShr; | |
| 517 break; | |
| 518 } | |
| 519 case Instruction::Shl: { | |
| 520 if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) { | |
| 521 const APInt &Shifts = CI->getValue(); | |
| 522 if (Shifts == 32) { | |
| 523 Low = Zero; | |
| 524 High = LeftChunks[0]; | |
| 525 break; | |
| 526 } | |
| 527 } | |
| 528 F = Shl; | |
| 529 break; | |
| 530 } | |
| 531 default: assert(0); | |
| 532 } | |
| 533 if (F) { | |
| 534 // use a library call, no special optimization was found | |
| 535 SmallVector<Value *, 4> Args; | |
| 536 Args.push_back(LeftChunks[0]); | |
| 537 Args.push_back(LeftChunks[1]); | |
| 538 Args.push_back(RightChunks[0]); | |
| 539 Args.push_back(RightChunks[1]); | |
| 540 Low = CopyDebug(CallInst::Create(F, Args, "", I), I); | |
| 541 High = CopyDebug(CallInst::Create(GetHigh, "", I), I); | |
| 542 } | |
| 543 Chunks.push_back(Low); | |
| 544 Chunks.push_back(High); | |
| 545 } else { | |
| 546 // more than 64 bits. handle simple shifts for lshr and shl | |
| 547 assert(I->getOpcode() == Instruction::LShr || I->getOpcode() == Instruct
ion::AShr || I->getOpcode() == Instruction::Shl); | |
| 548 ConstantInt *CI = cast<ConstantInt>(I->getOperand(1)); | |
| 549 unsigned Shifts = CI->getZExtValue(); | |
| 550 unsigned Fraction = Shifts % 32; | |
| 551 Constant *Frac = ConstantInt::get(i32, Fraction); | |
| 552 Constant *Comp = ConstantInt::get(i32, 32 - Fraction); | |
| 553 Instruction::BinaryOps Opcode, Reverse; | |
| 554 unsigned ShiftChunks, Dir; | |
| 555 Value *TopFiller = Zero; | |
| 556 if (I->getOpcode() == Instruction::Shl) { | |
| 557 Opcode = Instruction::Shl; | |
| 558 Reverse = Instruction::LShr; | |
| 559 ShiftChunks = -(Shifts/32); | |
| 560 Dir = -1; | |
| 561 } else { | |
| 562 Opcode = Instruction::LShr; | |
| 563 Reverse = Instruction::Shl; | |
| 564 ShiftChunks = Shifts/32; | |
| 565 Dir = 1; | |
| 566 if (I->getOpcode() == Instruction::AShr) { | |
| 567 Value *Cond = CopyDebug(new ICmpInst(I, ICmpInst::ICMP_SLT, LeftChun
ks[LeftChunks.size()-1], Zero), I); | |
| 568 TopFiller = CopyDebug(SelectInst::Create(Cond, ConstantInt::get(i32,
-1), Zero, "", I), I); | |
| 569 } | |
| 570 } | |
| 571 for (unsigned i = 0; i < Num; i++) { | |
| 572 Value *L; | |
| 573 if (i + ShiftChunks < LeftChunks.size()) { | |
| 574 L = LeftChunks[i + ShiftChunks]; | |
| 575 } else { | |
| 576 L = Zero; | |
| 577 } | |
| 578 | |
| 579 Value *H; | |
| 580 if (i + ShiftChunks + Dir < LeftChunks.size()) { | |
| 581 H = LeftChunks[i + ShiftChunks + Dir]; | |
| 582 } else { | |
| 583 H = TopFiller; | |
| 584 } | |
| 585 | |
| 586 // shifted the fractional amount | |
| 587 if (Frac != Zero && L != Zero) { | |
| 588 if (Fraction == 32) { | |
| 589 L = Zero; | |
| 590 } else { | |
| 591 L = CopyDebug(BinaryOperator::Create(Opcode, L, Frac, "", I), I); | |
| 592 } | |
| 593 } | |
| 594 // shifted the complement-fractional amount to the other side | |
| 595 if (Comp != Zero && H != Zero) { | |
| 596 if (Fraction == 0) { | |
| 597 H = TopFiller; | |
| 598 } else { | |
| 599 H = CopyDebug(BinaryOperator::Create(Reverse, H, Comp, "", I), I); | |
| 600 } | |
| 601 } | |
| 602 | |
| 603 // Or the parts together. Since we may have zero, try to fold it away. | |
| 604 if (Value *V = SimplifyBinOp(Instruction::Or, L, H, *DL)) { | |
| 605 Chunks.push_back(V); | |
| 606 } else { | |
| 607 Chunks.push_back(CopyDebug(BinaryOperator::Create(Instruction::Or, L
, H, "", I), I)); | |
| 608 } | |
| 609 } | |
| 610 } | |
| 611 break; | |
| 612 } | |
| 613 case Instruction::ICmp: { | |
| 614 ICmpInst *CE = cast<ICmpInst>(I); | |
| 615 ICmpInst::Predicate Pred = CE->getPredicate(); | |
| 616 ChunksVec LeftChunks = getChunks(I->getOperand(0)); | |
| 617 ChunksVec RightChunks = getChunks(I->getOperand(1)); | |
| 618 switch (Pred) { | |
| 619 case ICmpInst::ICMP_EQ: | |
| 620 case ICmpInst::ICMP_NE: { | |
| 621 ICmpInst::Predicate PartPred; // the predicate to use on each of the p
arts | |
| 622 llvm::Instruction::BinaryOps CombineOp; // the predicate to use to com
bine the subcomparisons | |
| 623 int Num = LeftChunks.size(); | |
| 624 if (Pred == ICmpInst::ICMP_EQ) { | |
| 625 PartPred = ICmpInst::ICMP_EQ; | |
| 626 CombineOp = Instruction::And; | |
| 627 } else { | |
| 628 PartPred = ICmpInst::ICMP_NE; | |
| 629 CombineOp = Instruction::Or; | |
| 630 } | |
| 631 // first combine 0 and 1. then combine that with 2, etc. | |
| 632 Value *Combined = NULL; | |
| 633 for (int i = 0; i < Num; i++) { | |
| 634 Value *Cmp = CopyDebug(new ICmpInst(I, PartPred, LeftChunks[i], Righ
tChunks[i]), I); | |
| 635 Combined = !Combined ? Cmp : CopyDebug(BinaryOperator::Create(Combin
eOp, Combined, Cmp, "", I), I); | |
| 636 } | |
| 637 I->replaceAllUsesWith(Combined); | |
| 638 break; | |
| 639 } | |
| 640 case ICmpInst::ICMP_ULT: | |
| 641 case ICmpInst::ICMP_SLT: | |
| 642 case ICmpInst::ICMP_UGT: | |
| 643 case ICmpInst::ICMP_SGT: | |
| 644 case ICmpInst::ICMP_ULE: | |
| 645 case ICmpInst::ICMP_SLE: | |
| 646 case ICmpInst::ICMP_UGE: | |
| 647 case ICmpInst::ICMP_SGE: { | |
| 648 if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) { | |
| 649 if (CI->getZExtValue() == 0 && Pred == ICmpInst::ICMP_SLT) { | |
| 650 // strict < 0 is easy to do, even on non-i64, just the sign bit ma
tters | |
| 651 Instruction *NewInst = new ICmpInst(I, ICmpInst::ICMP_SLT, LeftChu
nks[LeftChunks.size()-1], Zero); | |
| 652 CopyDebug(NewInst, I); | |
| 653 I->replaceAllUsesWith(NewInst); | |
| 654 return true; | |
| 655 } | |
| 656 } | |
| 657 Type *T = I->getOperand(0)->getType(); | |
| 658 assert(T->isIntegerTy() && T->getIntegerBitWidth() % 32 == 0); | |
| 659 int NumChunks = getNumChunks(T); | |
| 660 assert(NumChunks >= 2); | |
| 661 ICmpInst::Predicate StrictPred = Pred; | |
| 662 ICmpInst::Predicate UnsignedPred = Pred; | |
| 663 switch (Pred) { | |
| 664 case ICmpInst::ICMP_ULE: StrictPred = ICmpInst::ICMP_ULT; break; | |
| 665 case ICmpInst::ICMP_UGE: StrictPred = ICmpInst::ICMP_UGT; break; | |
| 666 case ICmpInst::ICMP_SLE: StrictPred = ICmpInst::ICMP_SLT; UnsignedPr
ed = ICmpInst::ICMP_ULE; break; | |
| 667 case ICmpInst::ICMP_SGE: StrictPred = ICmpInst::ICMP_SGT; UnsignedPr
ed = ICmpInst::ICMP_UGE; break; | |
| 668 case ICmpInst::ICMP_SLT: UnsignedPr
ed = ICmpInst::ICMP_ULT; break; | |
| 669 case ICmpInst::ICMP_SGT: UnsignedPr
ed = ICmpInst::ICMP_UGT; break; | |
| 670 case ICmpInst::ICMP_ULT: break; | |
| 671 case ICmpInst::ICMP_UGT: break; | |
| 672 default: assert(0); | |
| 673 } | |
| 674 // general pattern is | |
| 675 // a,b,c < A,B,C => c < C || (c == C && b < B) || (c == C && b =
= B && a < A) | |
| 676 Instruction *Final = CopyDebug(new ICmpInst(I, StrictPred, LeftChunks[
NumChunks-1], RightChunks[NumChunks-1]), I); | |
| 677 for (int i = NumChunks-2; i >= 0; i--) { | |
| 678 Instruction *Curr = CopyDebug(new ICmpInst(I, UnsignedPred, LeftChun
ks[i], RightChunks[i]), I); | |
| 679 for (int j = NumChunks-1; j > i; j--) { | |
| 680 Instruction *Temp = CopyDebug(new ICmpInst(I, ICmpInst::ICMP_EQ, L
eftChunks[j], RightChunks[j]), I); | |
| 681 Curr = CopyDebug(BinaryOperator::Create(Instruction::And, Temp, Cu
rr, "", I), I); | |
| 682 } | |
| 683 Final = CopyDebug(BinaryOperator::Create(Instruction::Or, Final, Cur
r, "", I), I); | |
| 684 } | |
| 685 I->replaceAllUsesWith(Final); | |
| 686 break; | |
| 687 } | |
| 688 default: assert(0); | |
| 689 } | |
| 690 break; | |
| 691 } | |
| 692 case Instruction::Select: { | |
| 693 SelectInst *SI = cast<SelectInst>(I); | |
| 694 Value *Cond = SI->getCondition(); | |
| 695 ChunksVec TrueChunks = getChunks(SI->getTrueValue()); | |
| 696 ChunksVec FalseChunks = getChunks(SI->getFalseValue()); | |
| 697 unsigned Num = getNumChunks(I->getType()); | |
| 698 for (unsigned i = 0; i < Num; i++) { | |
| 699 Instruction *Part = CopyDebug(SelectInst::Create(Cond, TrueChunks[i], Fa
lseChunks[i], "", I), I); | |
| 700 Chunks.push_back(Part); | |
| 701 } | |
| 702 break; | |
| 703 } | |
| 704 case Instruction::PHI: { | |
| 705 PHINode *Parent = cast<PHINode>(I); | |
| 706 int Num = getNumChunks(I->getType()); | |
| 707 int PhiNum = Parent->getNumIncomingValues(); | |
| 708 for (int i = 0; i < Num; i++) { | |
| 709 Instruction *P = CopyDebug(PHINode::Create(i32, PhiNum, "", I), I); | |
| 710 Chunks.push_back(P); | |
| 711 } | |
| 712 // PHI node operands may not be translated yet; we'll handle them at the e
nd. | |
| 713 Phis.push_back(Parent); | |
| 714 break; | |
| 715 } | |
| 716 case Instruction::And: | |
| 717 case Instruction::Or: | |
| 718 case Instruction::Xor: { | |
| 719 BinaryOperator *BO = cast<BinaryOperator>(I); | |
| 720 ChunksVec LeftChunks = getChunks(BO->getOperand(0)); | |
| 721 ChunksVec RightChunks = getChunks(BO->getOperand(1)); | |
| 722 int Num = getNumChunks(BO->getType()); | |
| 723 for (int i = 0; i < Num; i++) { | |
| 724 // If there's a constant operand, it's likely enough that one of the | |
| 725 // chunks will be a trivial operation, so it's worth calling | |
| 726 // SimplifyBinOp here. | |
| 727 if (Value *V = SimplifyBinOp(BO->getOpcode(), LeftChunks[i], RightChunks
[i], *DL)) { | |
| 728 Chunks.push_back(V); | |
| 729 } else { | |
| 730 Chunks.push_back(CopyDebug(BinaryOperator::Create(BO->getOpcode(), Lef
tChunks[i], RightChunks[i], "", BO), BO)); | |
| 731 } | |
| 732 } | |
| 733 break; | |
| 734 } | |
| 735 case Instruction::Call: { | |
| 736 CallInst *CI = cast<CallInst>(I); | |
| 737 Function *F = CI->getCalledFunction(); | |
| 738 if (F) { | |
| 739 assert(okToRemainIllegal(F)); | |
| 740 return false; | |
| 741 } | |
| 742 Value *CV = CI->getCalledValue(); | |
| 743 FunctionType *OFT = NULL; | |
| 744 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { | |
| 745 assert(CE); | |
| 746 assert(CE->getOpcode() == Instruction::BitCast); | |
| 747 OFT = cast<FunctionType>(cast<PointerType>(CE->getType())->getElementTyp
e()); | |
| 748 Constant *C = CE->getOperand(0); | |
| 749 CV = ConstantExpr::getBitCast(C, getLegalizedFunctionType(OFT)->getPoint
erTo()); | |
| 750 } else { | |
| 751 // this is a function pointer call | |
| 752 OFT = cast<FunctionType>(cast<PointerType>(CV->getType())->getElementTyp
e()); | |
| 753 // we need to add a bitcast | |
| 754 CV = new BitCastInst(CV, getLegalizedFunctionType(OFT)->getPointerTo(),
"", I); | |
| 755 } | |
| 756 // create a call with space for legal args | |
| 757 SmallVector<Value *, 0> Args; // XXX | |
| 758 int Num = OFT->getNumParams(); | |
| 759 for (int i = 0; i < Num; i++) { | |
| 760 Type *T = OFT->getParamType(i); | |
| 761 if (!isIllegal(T)) { | |
| 762 Args.push_back(CI->getArgOperand(i)); | |
| 763 } else { | |
| 764 assert(T == i64); | |
| 765 ChunksVec ArgChunks = getChunks(CI->getArgOperand(i)); | |
| 766 Args.push_back(ArgChunks[0]); | |
| 767 Args.push_back(ArgChunks[1]); | |
| 768 } | |
| 769 } | |
| 770 Instruction *L = CopyDebug(CallInst::Create(CV, Args, "", I), I); | |
| 771 Instruction *H = NULL; | |
| 772 // legalize return value as well, if necessary | |
| 773 if (isIllegal(I->getType())) { | |
| 774 assert(I->getType() == i64); | |
| 775 ensureFuncs(); | |
| 776 H = CopyDebug(CallInst::Create(GetHigh, "", I), I); | |
| 777 Chunks.push_back(L); | |
| 778 Chunks.push_back(H); | |
| 779 } else { | |
| 780 I->replaceAllUsesWith(L); | |
| 781 } | |
| 782 break; | |
| 783 } | |
| 784 case Instruction::FPToUI: | |
| 785 case Instruction::FPToSI: { | |
| 786 assert(I->getType() == i64); | |
| 787 ensureFuncs(); | |
| 788 SmallVector<Value *, 1> Args; | |
| 789 Value *Input = I->getOperand(0); | |
| 790 Args.push_back(Input); | |
| 791 Instruction *L, *H; | |
| 792 if (Input->getType()->isFloatTy()) { | |
| 793 L = CopyDebug(CallInst::Create(FtoILow, Args, "", I), I); | |
| 794 H = CopyDebug(CallInst::Create(FtoIHigh, Args, "", I), I); | |
| 795 } else { | |
| 796 L = CopyDebug(CallInst::Create(DtoILow, Args, "", I), I); | |
| 797 H = CopyDebug(CallInst::Create(DtoIHigh, Args, "", I), I); | |
| 798 } | |
| 799 Chunks.push_back(L); | |
| 800 Chunks.push_back(H); | |
| 801 break; | |
| 802 } | |
| 803 case Instruction::BitCast: { | |
| 804 if (I->getType() == Type::getDoubleTy(TheModule->getContext())) { | |
| 805 // fall through to itofp | |
| 806 } else if (I->getOperand(0)->getType() == Type::getDoubleTy(TheModule->get
Context())) { | |
| 807 // double to i64 | |
| 808 assert(I->getType() == i64); | |
| 809 ensureFuncs(); | |
| 810 SmallVector<Value *, 1> Args; | |
| 811 Args.push_back(I->getOperand(0)); | |
| 812 Instruction *L = CopyDebug(CallInst::Create(BDtoILow, Args, "", I), I); | |
| 813 Instruction *H = CopyDebug(CallInst::Create(BDtoIHigh, Args, "", I), I); | |
| 814 Chunks.push_back(L); | |
| 815 Chunks.push_back(H); | |
| 816 break; | |
| 817 } else if (isa<VectorType>(I->getOperand(0)->getType()) && !isa<VectorType
>(I->getType())) { | |
| 818 unsigned NumElts = getNumChunks(I->getType()); | |
| 819 VectorType *IVTy = VectorType::get(i32, NumElts); | |
| 820 Instruction *B = CopyDebug(new BitCastInst(I->getOperand(0), IVTy, "",
I), I); | |
| 821 for (unsigned i = 0; i < NumElts; ++i) { | |
| 822 Constant *Idx = ConstantInt::get(i32, i); | |
| 823 Instruction *Ext = CopyDebug(ExtractElementInst::Create(B, Idx, ""
, I), I); | |
| 824 Chunks.push_back(Ext); | |
| 825 } | |
| 826 break; | |
| 827 } else { | |
| 828 // no-op bitcast | |
| 829 assert(I->getType() == I->getOperand(0)->getType()); | |
| 830 Chunks = getChunks(I->getOperand(0)); | |
| 831 break; | |
| 832 } | |
| 833 } | |
| 834 case Instruction::SIToFP: | |
| 835 case Instruction::UIToFP: { | |
| 836 assert(I->getOperand(0)->getType() == i64); | |
| 837 ensureFuncs(); | |
| 838 ChunksVec InputChunks = getChunks(I->getOperand(0)); | |
| 839 Function *F; | |
| 840 switch (I->getOpcode()) { | |
| 841 case Instruction::SIToFP: F = I->getType() == Type::getDoubleTy(TheModul
e->getContext()) ? SItoD : SItoF; break; | |
| 842 case Instruction::UIToFP: F = I->getType() == Type::getDoubleTy(TheModul
e->getContext()) ? UItoD : UItoF; break; | |
| 843 case Instruction::BitCast: { | |
| 844 assert(I->getType() == Type::getDoubleTy(TheModule->getContext())); | |
| 845 F = BItoD; | |
| 846 break; | |
| 847 } | |
| 848 default: assert(0); | |
| 849 } | |
| 850 Instruction *D = CopyDebug(CallInst::Create(F, InputChunks, "", I), I); | |
| 851 I->replaceAllUsesWith(D); | |
| 852 break; | |
| 853 } | |
| 854 case Instruction::Switch: { | |
| 855 assert(I->getOperand(0)->getType() == i64); | |
| 856 ChunksVec InputChunks = getChunks(I->getOperand(0)); | |
| 857 | |
| 858 // do a switch on the lower 32 bits, into a different basic block for each
target, then do a branch in each of those on the high 32 bits | |
| 859 SwitchInst* SI = cast<SwitchInst>(I); | |
| 860 BasicBlock *DD = SI->getDefaultDest(); | |
| 861 BasicBlock *SwitchBB = I->getParent(); | |
| 862 Function *F = SwitchBB->getParent(); | |
| 863 | |
| 864 unsigned NumItems = SI->getNumCases(); | |
| 865 SwitchInst *LowSI = SwitchInst::Create(InputChunks[0], DD, NumItems, I); /
/ same default destination: if lower bits do not match, go straight to default | |
| 866 CopyDebug(LowSI, I); | |
| 867 | |
| 868 typedef std::pair<uint32_t, BasicBlock*> Pair; | |
| 869 typedef std::vector<Pair> Vec; // vector of pairs of high 32 bits, basic b
lock | |
| 870 typedef std::map<uint32_t, Vec> Map; // maps low 32 bits to their Vec info | |
| 871 Map Groups; // (as two 64-bit values in the switc
h may share their lower bits) | |
| 872 | |
| 873 for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end(); i != e;
++i) { | |
| 874 BasicBlock *BB = i.getCaseSuccessor(); | |
| 875 uint64_t Bits = i.getCaseValue()->getZExtValue(); | |
| 876 uint32_t LowBits = (uint32_t)Bits; | |
| 877 uint32_t HighBits = (uint32_t)(Bits >> 32); | |
| 878 Vec& V = Groups[LowBits]; | |
| 879 V.push_back(Pair(HighBits, BB)); | |
| 880 } | |
| 881 | |
| 882 unsigned Counter = 0; | |
| 883 BasicBlock *InsertPoint = SwitchBB; | |
| 884 | |
| 885 for (Map::iterator GI = Groups.begin(); GI != Groups.end(); GI++) { | |
| 886 uint32_t LowBits = GI->first; | |
| 887 Vec &V = GI->second; | |
| 888 | |
| 889 BasicBlock *NewBB = BasicBlock::Create(F->getContext(), "switch64_" + ut
ostr(Counter++), F); | |
| 890 NewBB->moveAfter(InsertPoint); | |
| 891 InsertPoint = NewBB; | |
| 892 LowSI->addCase(cast<ConstantInt>(ConstantInt::get(i32, LowBits)), NewBB)
; | |
| 893 | |
| 894 /*if (V.size() == 1) { | |
| 895 // just one option, create a branch | |
| 896 Instruction *CheckHigh = CopyDebug(new ICmpInst(*NewBB, ICmpInst::ICMP
_EQ, InputChunks[1], ConstantInt::get(i32, V[0]->first)), I); | |
| 897 Split.ToFix.push_back(CheckHigh); | |
| 898 CopyDebug(BranchInst::Create(V[0]->second, DD, CheckHigh, NewBB), I); | |
| 899 } else {*/ | |
| 900 | |
| 901 // multiple options, create a switch - we could also optimize and make a
n icmp/branch if just one, as in commented code above | |
| 902 SwitchInst *HighSI = SwitchInst::Create(InputChunks[1], DD, V.size(), Ne
wBB); // same default destination: if lower bits do not match, go straight to de
fault | |
| 903 for (unsigned i = 0; i < V.size(); i++) { | |
| 904 BasicBlock *BB = V[i].second; | |
| 905 HighSI->addCase(cast<ConstantInt>(ConstantInt::get(i32, V[i].first)),
BB); | |
| 906 // fix phis, we used to go SwitchBB->BB, but now go SwitchBB->NewBB->B
B, so we look like we arrived from NewBB. Replace the phi from the | |
| 907 // now unneeded SwitchBB to the new BB | |
| 908 // We cannot do this here right now, as phis we encounter may be in th
e middle of processing (empty), so we queue these. | |
| 909 for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { | |
| 910 PHINode *Phi = dyn_cast<PHINode>(I); | |
| 911 if (!Phi) break; | |
| 912 PhiBlockChange Change; | |
| 913 Change.DD = BB; | |
| 914 Change.SwitchBB = SwitchBB; | |
| 915 Change.NewBB = NewBB; | |
| 916 PhiBlockChanges.push_back(Change); | |
| 917 break; // we saw a phi on this BB, and pushed a Change | |
| 918 } | |
| 919 } | |
| 920 | |
| 921 // We used to go SwitchBB->DD, but now go SwitchBB->NewBB->DD, fix that
like with BB above. However here we do not replace, | |
| 922 // as the switch BB is still possible to arrive from - we can arrive at
the default if either the lower bits were wrong (we | |
| 923 // arrive from the switchBB) or from the NewBB if the high bits were wro
ng. | |
| 924 PhiBlockChange Change; | |
| 925 Change.DD = DD; | |
| 926 Change.SwitchBB = SwitchBB; | |
| 927 Change.NewBB = NewBB; | |
| 928 PhiBlockChanges.push_back(Change); | |
| 929 } | |
| 930 break; | |
| 931 } | |
| 932 default: { | |
| 933 I->dump(); | |
| 934 assert(0 && "some i64 thing we can't legalize yet"); | |
| 935 } | |
| 936 } | |
| 937 | |
| 938 return true; | |
| 939 } | |
| 940 | |
| 941 ChunksVec ExpandI64::getChunks(Value *V, bool AllowUnreachable) { | |
| 942 assert(isIllegal(V->getType())); | |
| 943 | |
| 944 unsigned Num = getNumChunks(V->getType()); | |
| 945 Type *i32 = Type::getInt32Ty(V->getContext()); | |
| 946 | |
| 947 if (isa<UndefValue>(V)) | |
| 948 return ChunksVec(Num, UndefValue::get(i32)); | |
| 949 | |
| 950 if (Constant *C = dyn_cast<Constant>(V)) { | |
| 951 ChunksVec Chunks; | |
| 952 for (unsigned i = 0; i < Num; i++) { | |
| 953 Constant *Count = ConstantInt::get(C->getType(), i * 32); | |
| 954 Constant *NewC = ConstantExpr::getTrunc(ConstantExpr::getLShr(C, Count), i
32); | |
| 955 TargetLibraryInfo *TLI = 0; // TODO | |
| 956 if (ConstantExpr *NewCE = dyn_cast<ConstantExpr>(NewC)) { | |
| 957 if (Constant *FoldedC = ConstantFoldConstantExpression(NewCE, *DL, TLI))
{ | |
| 958 NewC = FoldedC; | |
| 959 } | |
| 960 } | |
| 961 | |
| 962 Chunks.push_back(NewC); | |
| 963 } | |
| 964 return Chunks; | |
| 965 } | |
| 966 | |
| 967 if (Splits.find(V) == Splits.end()) { | |
| 968 if (AllowUnreachable) | |
| 969 return ChunksVec(Num, UndefValue::get(i32)); | |
| 970 errs() << *V << "\n"; | |
| 971 report_fatal_error("could not find chunks for illegal value"); | |
| 972 } | |
| 973 assert(Splits[V].size() == Num); | |
| 974 return Splits[V]; | |
| 975 } | |
| 976 | |
| 977 void ExpandI64::ensureFuncs() { | |
| 978 if (Add != NULL) return; | |
| 979 | |
| 980 Type *i32 = Type::getInt32Ty(TheModule->getContext()); | |
| 981 | |
| 982 SmallVector<Type*, 4> FourArgTypes; | |
| 983 FourArgTypes.push_back(i32); | |
| 984 FourArgTypes.push_back(i32); | |
| 985 FourArgTypes.push_back(i32); | |
| 986 FourArgTypes.push_back(i32); | |
| 987 FunctionType *FourFunc = FunctionType::get(i32, FourArgTypes, false); | |
| 988 | |
| 989 Add = Function::Create(FourFunc, GlobalValue::ExternalLinkage, | |
| 990 "i64Add", TheModule); | |
| 991 Sub = Function::Create(FourFunc, GlobalValue::ExternalLinkage, | |
| 992 "i64Subtract", TheModule); | |
| 993 Mul = Function::Create(FourFunc, GlobalValue::ExternalLinkage, | |
| 994 "__muldi3", TheModule); | |
| 995 SDiv = Function::Create(FourFunc, GlobalValue::ExternalLinkage, | |
| 996 "__divdi3", TheModule); | |
| 997 UDiv = Function::Create(FourFunc, GlobalValue::ExternalLinkage, | |
| 998 "__udivdi3", TheModule); | |
| 999 SRem = Function::Create(FourFunc, GlobalValue::ExternalLinkage, | |
| 1000 "__remdi3", TheModule); | |
| 1001 URem = Function::Create(FourFunc, GlobalValue::ExternalLinkage, | |
| 1002 "__uremdi3", TheModule); | |
| 1003 LShr = Function::Create(FourFunc, GlobalValue::ExternalLinkage, | |
| 1004 "bitshift64Lshr", TheModule); | |
| 1005 AShr = Function::Create(FourFunc, GlobalValue::ExternalLinkage, | |
| 1006 "bitshift64Ashr", TheModule); | |
| 1007 Shl = Function::Create(FourFunc, GlobalValue::ExternalLinkage, | |
| 1008 "bitshift64Shl", TheModule); | |
| 1009 | |
| 1010 if (!(GetHigh = TheModule->getFunction("getHigh32"))) { | |
| 1011 SmallVector<Type*, 0> GetHighArgTypes; | |
| 1012 FunctionType *GetHighFunc = FunctionType::get(i32, GetHighArgTypes, false); | |
| 1013 GetHigh = Function::Create(GetHighFunc, GlobalValue::ExternalLinkage, | |
| 1014 "getHigh32", TheModule); | |
| 1015 } | |
| 1016 | |
| 1017 Type *V = Type::getVoidTy(TheModule->getContext()); | |
| 1018 | |
| 1019 SmallVector<Type*, 1> SetHighArgTypes; | |
| 1020 SetHighArgTypes.push_back(i32); | |
| 1021 FunctionType *SetHighFunc = FunctionType::get(V, SetHighArgTypes, false); | |
| 1022 SetHigh = Function::Create(SetHighFunc, GlobalValue::ExternalLinkage, | |
| 1023 "setHigh32", TheModule); | |
| 1024 | |
| 1025 Type *Double = Type::getDoubleTy(TheModule->getContext()); | |
| 1026 Type *Float = Type::getFloatTy(TheModule->getContext()); | |
| 1027 | |
| 1028 SmallVector<Type*, 1> FtoITypes; | |
| 1029 FtoITypes.push_back(Float); | |
| 1030 FunctionType *FtoIFunc = FunctionType::get(i32, FtoITypes, false); | |
| 1031 | |
| 1032 SmallVector<Type*, 1> DtoITypes; | |
| 1033 DtoITypes.push_back(Double); | |
| 1034 FunctionType *DtoIFunc = FunctionType::get(i32, DtoITypes, false); | |
| 1035 | |
| 1036 FtoILow = Function::Create(FtoIFunc, GlobalValue::ExternalLinkage, | |
| 1037 "FtoILow", TheModule); | |
| 1038 FtoIHigh = Function::Create(FtoIFunc, GlobalValue::ExternalLinkage, | |
| 1039 "FtoIHigh", TheModule); | |
| 1040 DtoILow = Function::Create(DtoIFunc, GlobalValue::ExternalLinkage, | |
| 1041 "DtoILow", TheModule); | |
| 1042 DtoIHigh = Function::Create(DtoIFunc, GlobalValue::ExternalLinkage, | |
| 1043 "DtoIHigh", TheModule); | |
| 1044 BDtoILow = Function::Create(DtoIFunc, GlobalValue::ExternalLinkage, | |
| 1045 "BDtoILow", TheModule); | |
| 1046 BDtoIHigh = Function::Create(DtoIFunc, GlobalValue::ExternalLinkage, | |
| 1047 "BDtoIHigh", TheModule); | |
| 1048 | |
| 1049 SmallVector<Type*, 2> ItoTypes; | |
| 1050 ItoTypes.push_back(i32); | |
| 1051 ItoTypes.push_back(i32); | |
| 1052 | |
| 1053 FunctionType *ItoFFunc = FunctionType::get(Float, ItoTypes, false); | |
| 1054 SItoF = Function::Create(ItoFFunc, GlobalValue::ExternalLinkage, | |
| 1055 "SItoF", TheModule); | |
| 1056 UItoF = Function::Create(ItoFFunc, GlobalValue::ExternalLinkage, | |
| 1057 "UItoF", TheModule); | |
| 1058 | |
| 1059 FunctionType *ItoDFunc = FunctionType::get(Double, ItoTypes, false); | |
| 1060 SItoD = Function::Create(ItoDFunc, GlobalValue::ExternalLinkage, | |
| 1061 "SItoD", TheModule); | |
| 1062 UItoD = Function::Create(ItoDFunc, GlobalValue::ExternalLinkage, | |
| 1063 "UItoD", TheModule); | |
| 1064 | |
| 1065 BItoD = Function::Create(ItoDFunc, GlobalValue::ExternalLinkage, | |
| 1066 "BItoD", TheModule); | |
| 1067 } | |
| 1068 | |
| 1069 bool ExpandI64::runOnModule(Module &M) { | |
| 1070 TheModule = &M; | |
| 1071 DL = &M.getDataLayout(); | |
| 1072 Splits.clear(); | |
| 1073 Changed = false; | |
| 1074 | |
| 1075 // pre pass - legalize functions | |
| 1076 for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E; ) { | |
| 1077 Function *Func = Iter++; | |
| 1078 ensureLegalFunc(Func); | |
| 1079 } | |
| 1080 | |
| 1081 // first pass - split | |
| 1082 DeadVec Dead; | |
| 1083 for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E; ++Iter) { | |
| 1084 Function *Func = Iter; | |
| 1085 if (Func->isDeclaration()) { | |
| 1086 continue; | |
| 1087 } | |
| 1088 | |
| 1089 // Walk the body of the function. We use reverse postorder so that we visit | |
| 1090 // all operands of an instruction before the instruction itself. The | |
| 1091 // exception to this is PHI nodes, which we put on a list and handle below. | |
| 1092 ReversePostOrderTraversal<Function*> RPOT(Func); | |
| 1093 for (ReversePostOrderTraversal<Function*>::rpo_iterator RI = RPOT.begin(), | |
| 1094 RE = RPOT.end(); RI != RE; ++RI) { | |
| 1095 BasicBlock *BB = *RI; | |
| 1096 for (BasicBlock::iterator Iter = BB->begin(), E = BB->end(); | |
| 1097 Iter != E; ) { | |
| 1098 Instruction *I = Iter++; | |
| 1099 if (!isLegalInstruction(I)) { | |
| 1100 if (splitInst(I)) { | |
| 1101 Changed = true; | |
| 1102 Dead.push_back(I); | |
| 1103 } | |
| 1104 } | |
| 1105 } | |
| 1106 } | |
| 1107 | |
| 1108 // Fix up PHI node operands. | |
| 1109 while (!Phis.empty()) { | |
| 1110 PHINode *PN = Phis.pop_back_val(); | |
| 1111 ChunksVec OutputChunks = getChunks(PN); | |
| 1112 for (unsigned j = 0, je = PN->getNumIncomingValues(); j != je; ++j) { | |
| 1113 Value *Op = PN->getIncomingValue(j); | |
| 1114 ChunksVec InputChunks = getChunks(Op, true); | |
| 1115 for (unsigned k = 0, ke = OutputChunks.size(); k != ke; ++k) { | |
| 1116 PHINode *NewPN = cast<PHINode>(OutputChunks[k]); | |
| 1117 NewPN->addIncoming(InputChunks[k], PN->getIncomingBlock(j)); | |
| 1118 } | |
| 1119 } | |
| 1120 PN->dropAllReferences(); | |
| 1121 } | |
| 1122 | |
| 1123 // Delete instructions which were replaced. We do this after the full walk | |
| 1124 // of the instructions so that all uses are replaced first. | |
| 1125 while (!Dead.empty()) { | |
| 1126 Instruction *D = Dead.pop_back_val(); | |
| 1127 D->eraseFromParent(); | |
| 1128 } | |
| 1129 | |
| 1130 // Apply basic block changes to phis, now that phis are all processed (and i
llegal phis erased) | |
| 1131 for (unsigned i = 0; i < PhiBlockChanges.size(); i++) { | |
| 1132 PhiBlockChange &Change = PhiBlockChanges[i]; | |
| 1133 for (BasicBlock::iterator I = Change.DD->begin(); I != Change.DD->end(); +
+I) { | |
| 1134 PHINode *Phi = dyn_cast<PHINode>(I); | |
| 1135 if (!Phi) break; | |
| 1136 int Index = Phi->getBasicBlockIndex(Change.SwitchBB); | |
| 1137 assert(Index >= 0); | |
| 1138 Phi->addIncoming(Phi->getIncomingValue(Index), Change.NewBB); | |
| 1139 } | |
| 1140 } | |
| 1141 PhiBlockChanges.clear(); | |
| 1142 | |
| 1143 // We only visited blocks found by a DFS walk from the entry, so we haven't | |
| 1144 // visited any unreachable blocks, and they may still contain illegal | |
| 1145 // instructions at this point. Being unreachable, they can simply be deleted
. | |
| 1146 removeUnreachableBlocks(*Func); | |
| 1147 } | |
| 1148 | |
| 1149 // post pass - clean up illegal functions that were legalized. We do this | |
| 1150 // after the full walk of the functions so that all uses are replaced first. | |
| 1151 for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E; ) { | |
| 1152 Function *Func = Iter++; | |
| 1153 removeIllegalFunc(Func); | |
| 1154 } | |
| 1155 | |
| 1156 return Changed; | |
| 1157 } | |
| 1158 | |
| 1159 ModulePass *llvm::createExpandI64Pass() { | |
| 1160 return new ExpandI64(); | |
| 1161 } | |
| OLD | NEW |