1 //===- Instruction.cpp - The Instructions of Sandbox IR -------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/SandboxIR/Instruction.h" 10 #include "llvm/SandboxIR/Function.h" 11 12 namespace llvm::sandboxir { 13 14 const char *Instruction::getOpcodeName(Opcode Opc) { 15 switch (Opc) { 16 #define OP(OPC) \ 17 case Opcode::OPC: \ 18 return #OPC; 19 #define OPCODES(...) __VA_ARGS__ 20 #define DEF_INSTR(ID, OPC, CLASS) OPC 21 #include "llvm/SandboxIR/Values.def" 22 } 23 llvm_unreachable("Unknown Opcode"); 24 } 25 26 llvm::Instruction *Instruction::getTopmostLLVMInstruction() const { 27 Instruction *Prev = getPrevNode(); 28 if (Prev == nullptr) { 29 // If at top of the BB, return the first BB instruction. 30 return &*cast<llvm::BasicBlock>(getParent()->Val)->begin(); 31 } 32 // Else get the Previous sandbox IR instruction's bottom IR instruction and 33 // return its successor. 34 llvm::Instruction *PrevBotI = cast<llvm::Instruction>(Prev->Val); 35 return PrevBotI->getNextNode(); 36 } 37 38 BBIterator Instruction::getIterator() const { 39 auto *I = cast<llvm::Instruction>(Val); 40 return BasicBlock::iterator(I->getParent(), I->getIterator(), &Ctx); 41 } 42 43 Instruction *Instruction::getNextNode() const { 44 assert(getParent() != nullptr && "Detached!"); 45 assert(getIterator() != getParent()->end() && "Already at end!"); 46 // `Val` is the bottom-most LLVM IR instruction. Get the next in the chain, 47 // and get the corresponding sandboxir Instruction that maps to it. This works 48 // even for SandboxIR Instructions that map to more than one LLVM Instruction. 49 auto *LLVMI = cast<llvm::Instruction>(Val); 50 assert(LLVMI->getParent() != nullptr && "LLVM IR instr is detached!"); 51 auto *NextLLVMI = LLVMI->getNextNode(); 52 auto *NextI = cast_or_null<Instruction>(Ctx.getValue(NextLLVMI)); 53 if (NextI == nullptr) 54 return nullptr; 55 return NextI; 56 } 57 58 Instruction *Instruction::getPrevNode() const { 59 assert(getParent() != nullptr && "Detached!"); 60 auto It = getIterator(); 61 if (It != getParent()->begin()) 62 return std::prev(getIterator()).get(); 63 return nullptr; 64 } 65 66 void Instruction::removeFromParent() { 67 Ctx.getTracker().emplaceIfTracking<RemoveFromParent>(this); 68 69 // Detach all the LLVM IR instructions from their parent BB. 70 for (llvm::Instruction *I : getLLVMInstrs()) 71 I->removeFromParent(); 72 } 73 74 void Instruction::eraseFromParent() { 75 assert(users().empty() && "Still connected to users, can't erase!"); 76 77 Ctx.runEraseInstrCallbacks(this); 78 std::unique_ptr<Value> Detached = Ctx.detach(this); 79 auto LLVMInstrs = getLLVMInstrs(); 80 81 auto &Tracker = Ctx.getTracker(); 82 if (Tracker.isTracking()) { 83 Tracker.track(std::make_unique<EraseFromParent>(std::move(Detached))); 84 // We don't actually delete the IR instruction, because then it would be 85 // impossible to bring it back from the dead at the same memory location. 86 // Instead we remove it from its BB and track its current location. 87 for (llvm::Instruction *I : LLVMInstrs) 88 I->removeFromParent(); 89 // TODO: Multi-instructions need special treatment because some of the 90 // references are internal to the instruction. 91 for (llvm::Instruction *I : LLVMInstrs) 92 I->dropAllReferences(); 93 } else { 94 // Erase in reverse to avoid erasing nstructions with attached uses. 95 for (llvm::Instruction *I : reverse(LLVMInstrs)) 96 I->eraseFromParent(); 97 } 98 } 99 100 void Instruction::moveBefore(BasicBlock &BB, const BBIterator &WhereIt) { 101 if (std::next(getIterator()) == WhereIt) 102 // Destination is same as origin, nothing to do. 103 return; 104 105 Ctx.runMoveInstrCallbacks(this, WhereIt); 106 Ctx.getTracker().emplaceIfTracking<MoveInstr>(this); 107 108 auto *LLVMBB = cast<llvm::BasicBlock>(BB.Val); 109 llvm::BasicBlock::iterator It; 110 if (WhereIt == BB.end()) { 111 It = LLVMBB->end(); 112 } else { 113 Instruction *WhereI = &*WhereIt; 114 It = WhereI->getTopmostLLVMInstruction()->getIterator(); 115 } 116 // TODO: Move this to the verifier of sandboxir::Instruction. 117 assert(is_sorted(getLLVMInstrs(), 118 [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) && 119 "Expected program order!"); 120 // Do the actual move in LLVM IR. 121 for (auto *I : getLLVMInstrs()) 122 I->moveBefore(*LLVMBB, It); 123 } 124 125 void Instruction::insertBefore(Instruction *BeforeI) { 126 llvm::Instruction *BeforeTopI = BeforeI->getTopmostLLVMInstruction(); 127 128 Ctx.getTracker().emplaceIfTracking<InsertIntoBB>(this); 129 130 // Insert the LLVM IR Instructions in program order. 131 for (llvm::Instruction *I : getLLVMInstrs()) 132 I->insertBefore(BeforeTopI->getIterator()); 133 } 134 135 void Instruction::insertAfter(Instruction *AfterI) { 136 insertInto(AfterI->getParent(), std::next(AfterI->getIterator())); 137 } 138 139 void Instruction::insertInto(BasicBlock *BB, const BBIterator &WhereIt) { 140 llvm::BasicBlock *LLVMBB = cast<llvm::BasicBlock>(BB->Val); 141 llvm::Instruction *LLVMBeforeI; 142 llvm::BasicBlock::iterator LLVMBeforeIt; 143 Instruction *BeforeI; 144 if (WhereIt != BB->end()) { 145 BeforeI = &*WhereIt; 146 LLVMBeforeI = BeforeI->getTopmostLLVMInstruction(); 147 LLVMBeforeIt = LLVMBeforeI->getIterator(); 148 } else { 149 BeforeI = nullptr; 150 LLVMBeforeI = nullptr; 151 LLVMBeforeIt = LLVMBB->end(); 152 } 153 154 Ctx.getTracker().emplaceIfTracking<InsertIntoBB>(this); 155 156 // Insert the LLVM IR Instructions in program order. 157 for (llvm::Instruction *I : getLLVMInstrs()) 158 I->insertInto(LLVMBB, LLVMBeforeIt); 159 } 160 161 BasicBlock *Instruction::getParent() const { 162 // Get the LLVM IR Instruction that this maps to, get its parent, and get the 163 // corresponding sandboxir::BasicBlock by looking it up in sandboxir::Context. 164 auto *BB = cast<llvm::Instruction>(Val)->getParent(); 165 if (BB == nullptr) 166 return nullptr; 167 return cast<BasicBlock>(Ctx.getValue(BB)); 168 } 169 170 bool Instruction::classof(const sandboxir::Value *From) { 171 switch (From->getSubclassID()) { 172 #define DEF_INSTR(ID, OPC, CLASS) \ 173 case ClassID::ID: \ 174 return true; 175 #include "llvm/SandboxIR/Values.def" 176 default: 177 return false; 178 } 179 } 180 181 void Instruction::setHasNoUnsignedWrap(bool B) { 182 Ctx.getTracker() 183 .emplaceIfTracking<GenericSetter<&Instruction::hasNoUnsignedWrap, 184 &Instruction::setHasNoUnsignedWrap>>( 185 this); 186 cast<llvm::Instruction>(Val)->setHasNoUnsignedWrap(B); 187 } 188 189 void Instruction::setHasNoSignedWrap(bool B) { 190 Ctx.getTracker() 191 .emplaceIfTracking<GenericSetter<&Instruction::hasNoSignedWrap, 192 &Instruction::setHasNoSignedWrap>>(this); 193 cast<llvm::Instruction>(Val)->setHasNoSignedWrap(B); 194 } 195 196 void Instruction::setFast(bool B) { 197 Ctx.getTracker() 198 .emplaceIfTracking< 199 GenericSetter<&Instruction::isFast, &Instruction::setFast>>(this); 200 cast<llvm::Instruction>(Val)->setFast(B); 201 } 202 203 void Instruction::setIsExact(bool B) { 204 Ctx.getTracker() 205 .emplaceIfTracking< 206 GenericSetter<&Instruction::isExact, &Instruction::setIsExact>>(this); 207 cast<llvm::Instruction>(Val)->setIsExact(B); 208 } 209 210 void Instruction::setHasAllowReassoc(bool B) { 211 Ctx.getTracker() 212 .emplaceIfTracking<GenericSetter<&Instruction::hasAllowReassoc, 213 &Instruction::setHasAllowReassoc>>(this); 214 cast<llvm::Instruction>(Val)->setHasAllowReassoc(B); 215 } 216 217 void Instruction::setHasNoNaNs(bool B) { 218 Ctx.getTracker() 219 .emplaceIfTracking< 220 GenericSetter<&Instruction::hasNoNaNs, &Instruction::setHasNoNaNs>>( 221 this); 222 cast<llvm::Instruction>(Val)->setHasNoNaNs(B); 223 } 224 225 void Instruction::setHasNoInfs(bool B) { 226 Ctx.getTracker() 227 .emplaceIfTracking< 228 GenericSetter<&Instruction::hasNoInfs, &Instruction::setHasNoInfs>>( 229 this); 230 cast<llvm::Instruction>(Val)->setHasNoInfs(B); 231 } 232 233 void Instruction::setHasNoSignedZeros(bool B) { 234 Ctx.getTracker() 235 .emplaceIfTracking<GenericSetter<&Instruction::hasNoSignedZeros, 236 &Instruction::setHasNoSignedZeros>>( 237 this); 238 cast<llvm::Instruction>(Val)->setHasNoSignedZeros(B); 239 } 240 241 void Instruction::setHasAllowReciprocal(bool B) { 242 Ctx.getTracker() 243 .emplaceIfTracking<GenericSetter<&Instruction::hasAllowReciprocal, 244 &Instruction::setHasAllowReciprocal>>( 245 this); 246 cast<llvm::Instruction>(Val)->setHasAllowReciprocal(B); 247 } 248 249 void Instruction::setHasAllowContract(bool B) { 250 Ctx.getTracker() 251 .emplaceIfTracking<GenericSetter<&Instruction::hasAllowContract, 252 &Instruction::setHasAllowContract>>( 253 this); 254 cast<llvm::Instruction>(Val)->setHasAllowContract(B); 255 } 256 257 void Instruction::setFastMathFlags(FastMathFlags FMF) { 258 Ctx.getTracker() 259 .emplaceIfTracking<GenericSetter<&Instruction::getFastMathFlags, 260 &Instruction::copyFastMathFlags>>(this); 261 cast<llvm::Instruction>(Val)->setFastMathFlags(FMF); 262 } 263 264 void Instruction::copyFastMathFlags(FastMathFlags FMF) { 265 Ctx.getTracker() 266 .emplaceIfTracking<GenericSetter<&Instruction::getFastMathFlags, 267 &Instruction::copyFastMathFlags>>(this); 268 cast<llvm::Instruction>(Val)->copyFastMathFlags(FMF); 269 } 270 271 Type *Instruction::getAccessType() const { 272 return Ctx.getType(cast<llvm::Instruction>(Val)->getAccessType()); 273 } 274 275 void Instruction::setHasApproxFunc(bool B) { 276 Ctx.getTracker() 277 .emplaceIfTracking<GenericSetter<&Instruction::hasApproxFunc, 278 &Instruction::setHasApproxFunc>>(this); 279 cast<llvm::Instruction>(Val)->setHasApproxFunc(B); 280 } 281 282 #ifndef NDEBUG 283 void Instruction::dumpOS(raw_ostream &OS) const { 284 OS << "Unimplemented! Please override dump()."; 285 } 286 #endif // NDEBUG 287 288 VAArgInst *VAArgInst::create(Value *List, Type *Ty, InsertPosition Pos, 289 Context &Ctx, const Twine &Name) { 290 auto &Builder = setInsertPos(Pos); 291 auto *LLVMI = 292 cast<llvm::VAArgInst>(Builder.CreateVAArg(List->Val, Ty->LLVMTy, Name)); 293 return Ctx.createVAArgInst(LLVMI); 294 } 295 296 Value *VAArgInst::getPointerOperand() { 297 return Ctx.getValue(cast<llvm::VAArgInst>(Val)->getPointerOperand()); 298 } 299 300 FreezeInst *FreezeInst::create(Value *V, InsertPosition Pos, Context &Ctx, 301 const Twine &Name) { 302 auto &Builder = setInsertPos(Pos); 303 auto *LLVMI = cast<llvm::FreezeInst>(Builder.CreateFreeze(V->Val, Name)); 304 return Ctx.createFreezeInst(LLVMI); 305 } 306 307 FenceInst *FenceInst::create(AtomicOrdering Ordering, InsertPosition Pos, 308 Context &Ctx, SyncScope::ID SSID) { 309 auto &Builder = Instruction::setInsertPos(Pos); 310 llvm::FenceInst *LLVMI = Builder.CreateFence(Ordering, SSID); 311 return Ctx.createFenceInst(LLVMI); 312 } 313 314 void FenceInst::setOrdering(AtomicOrdering Ordering) { 315 Ctx.getTracker() 316 .emplaceIfTracking< 317 GenericSetter<&FenceInst::getOrdering, &FenceInst::setOrdering>>( 318 this); 319 cast<llvm::FenceInst>(Val)->setOrdering(Ordering); 320 } 321 322 void FenceInst::setSyncScopeID(SyncScope::ID SSID) { 323 Ctx.getTracker() 324 .emplaceIfTracking<GenericSetter<&FenceInst::getSyncScopeID, 325 &FenceInst::setSyncScopeID>>(this); 326 cast<llvm::FenceInst>(Val)->setSyncScopeID(SSID); 327 } 328 329 Value *SelectInst::create(Value *Cond, Value *True, Value *False, 330 InsertPosition Pos, Context &Ctx, const Twine &Name) { 331 auto &Builder = Instruction::setInsertPos(Pos); 332 llvm::Value *NewV = 333 Builder.CreateSelect(Cond->Val, True->Val, False->Val, Name); 334 if (auto *NewSI = dyn_cast<llvm::SelectInst>(NewV)) 335 return Ctx.createSelectInst(NewSI); 336 assert(isa<llvm::Constant>(NewV) && "Expected constant"); 337 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV)); 338 } 339 340 void SelectInst::swapValues() { 341 Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(1), 342 getOperandUse(2)); 343 cast<llvm::SelectInst>(Val)->swapValues(); 344 } 345 346 bool SelectInst::classof(const Value *From) { 347 return From->getSubclassID() == ClassID::Select; 348 } 349 350 BranchInst *BranchInst::create(BasicBlock *IfTrue, InsertPosition Pos, 351 Context &Ctx) { 352 auto &Builder = setInsertPos(Pos); 353 llvm::BranchInst *NewBr = 354 Builder.CreateBr(cast<llvm::BasicBlock>(IfTrue->Val)); 355 return Ctx.createBranchInst(NewBr); 356 } 357 358 BranchInst *BranchInst::create(BasicBlock *IfTrue, BasicBlock *IfFalse, 359 Value *Cond, InsertPosition Pos, Context &Ctx) { 360 auto &Builder = setInsertPos(Pos); 361 llvm::BranchInst *NewBr = 362 Builder.CreateCondBr(Cond->Val, cast<llvm::BasicBlock>(IfTrue->Val), 363 cast<llvm::BasicBlock>(IfFalse->Val)); 364 return Ctx.createBranchInst(NewBr); 365 } 366 367 bool BranchInst::classof(const Value *From) { 368 return From->getSubclassID() == ClassID::Br; 369 } 370 371 Value *BranchInst::getCondition() const { 372 assert(isConditional() && "Cannot get condition of an uncond branch!"); 373 return Ctx.getValue(cast<llvm::BranchInst>(Val)->getCondition()); 374 } 375 376 BasicBlock *BranchInst::getSuccessor(unsigned SuccIdx) const { 377 assert(SuccIdx < getNumSuccessors() && 378 "Successor # out of range for Branch!"); 379 return cast_or_null<BasicBlock>( 380 Ctx.getValue(cast<llvm::BranchInst>(Val)->getSuccessor(SuccIdx))); 381 } 382 383 void BranchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) { 384 assert((Idx == 0 || Idx == 1) && "Out of bounds!"); 385 setOperand(2u - Idx, NewSucc); 386 } 387 388 BasicBlock *BranchInst::LLVMBBToSBBB::operator()(llvm::BasicBlock *BB) const { 389 return cast<BasicBlock>(Ctx.getValue(BB)); 390 } 391 const BasicBlock * 392 BranchInst::ConstLLVMBBToSBBB::operator()(const llvm::BasicBlock *BB) const { 393 return cast<BasicBlock>(Ctx.getValue(BB)); 394 } 395 396 void LoadInst::setVolatile(bool V) { 397 Ctx.getTracker() 398 .emplaceIfTracking< 399 GenericSetter<&LoadInst::isVolatile, &LoadInst::setVolatile>>(this); 400 cast<llvm::LoadInst>(Val)->setVolatile(V); 401 } 402 403 LoadInst *LoadInst::create(Type *Ty, Value *Ptr, MaybeAlign Align, 404 InsertPosition Pos, bool IsVolatile, Context &Ctx, 405 const Twine &Name) { 406 auto &Builder = setInsertPos(Pos); 407 auto *NewLI = 408 Builder.CreateAlignedLoad(Ty->LLVMTy, Ptr->Val, Align, IsVolatile, Name); 409 auto *NewSBI = Ctx.createLoadInst(NewLI); 410 return NewSBI; 411 } 412 413 bool LoadInst::classof(const Value *From) { 414 return From->getSubclassID() == ClassID::Load; 415 } 416 417 Value *LoadInst::getPointerOperand() const { 418 return Ctx.getValue(cast<llvm::LoadInst>(Val)->getPointerOperand()); 419 } 420 421 void StoreInst::setVolatile(bool V) { 422 Ctx.getTracker() 423 .emplaceIfTracking< 424 GenericSetter<&StoreInst::isVolatile, &StoreInst::setVolatile>>(this); 425 cast<llvm::StoreInst>(Val)->setVolatile(V); 426 } 427 428 StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align, 429 InsertPosition Pos, bool IsVolatile, 430 Context &Ctx) { 431 auto &Builder = setInsertPos(Pos); 432 auto *NewSI = Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, IsVolatile); 433 auto *NewSBI = Ctx.createStoreInst(NewSI); 434 return NewSBI; 435 } 436 437 bool StoreInst::classof(const Value *From) { 438 return From->getSubclassID() == ClassID::Store; 439 } 440 441 Value *StoreInst::getValueOperand() const { 442 return Ctx.getValue(cast<llvm::StoreInst>(Val)->getValueOperand()); 443 } 444 445 Value *StoreInst::getPointerOperand() const { 446 return Ctx.getValue(cast<llvm::StoreInst>(Val)->getPointerOperand()); 447 } 448 449 UnreachableInst *UnreachableInst::create(InsertPosition Pos, Context &Ctx) { 450 auto &Builder = setInsertPos(Pos); 451 llvm::UnreachableInst *NewUI = Builder.CreateUnreachable(); 452 return Ctx.createUnreachableInst(NewUI); 453 } 454 455 bool UnreachableInst::classof(const Value *From) { 456 return From->getSubclassID() == ClassID::Unreachable; 457 } 458 459 ReturnInst *ReturnInst::createCommon(Value *RetVal, IRBuilder<> &Builder, 460 Context &Ctx) { 461 llvm::ReturnInst *NewRI; 462 if (RetVal != nullptr) 463 NewRI = Builder.CreateRet(RetVal->Val); 464 else 465 NewRI = Builder.CreateRetVoid(); 466 return Ctx.createReturnInst(NewRI); 467 } 468 469 ReturnInst *ReturnInst::create(Value *RetVal, InsertPosition Pos, 470 Context &Ctx) { 471 auto &Builder = setInsertPos(Pos); 472 return createCommon(RetVal, Builder, Ctx); 473 } 474 475 Value *ReturnInst::getReturnValue() const { 476 auto *LLVMRetVal = cast<llvm::ReturnInst>(Val)->getReturnValue(); 477 return LLVMRetVal != nullptr ? Ctx.getValue(LLVMRetVal) : nullptr; 478 } 479 480 FunctionType *CallBase::getFunctionType() const { 481 return cast<FunctionType>( 482 Ctx.getType(cast<llvm::CallBase>(Val)->getFunctionType())); 483 } 484 485 Value *CallBase::getCalledOperand() const { 486 return Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledOperand()); 487 } 488 489 Use CallBase::getCalledOperandUse() const { 490 llvm::Use *LLVMUse = &cast<llvm::CallBase>(Val)->getCalledOperandUse(); 491 return Use(LLVMUse, cast<User>(Ctx.getValue(LLVMUse->getUser())), Ctx); 492 } 493 494 Function *CallBase::getCalledFunction() const { 495 return cast_or_null<Function>( 496 Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledFunction())); 497 } 498 Function *CallBase::getCaller() { 499 return cast<Function>(Ctx.getValue(cast<llvm::CallBase>(Val)->getCaller())); 500 } 501 502 void CallBase::setCalledFunction(Function *F) { 503 // F's function type is private, so we rely on `setCalledFunction()` to update 504 // it. But even though we are calling `setCalledFunction()` we also need to 505 // track this change at the SandboxIR level, which is why we call 506 // `setCalledOperand()` here. 507 // Note: This may break if `setCalledFunction()` early returns if `F` 508 // is already set, but we do have a unit test for it. 509 setCalledOperand(F); 510 cast<llvm::CallBase>(Val)->setCalledFunction( 511 cast<llvm::FunctionType>(F->getFunctionType()->LLVMTy), 512 cast<llvm::Function>(F->Val)); 513 } 514 515 CallInst *CallInst::create(FunctionType *FTy, Value *Func, 516 ArrayRef<Value *> Args, InsertPosition Pos, 517 Context &Ctx, const Twine &NameStr) { 518 auto &Builder = setInsertPos(Pos); 519 SmallVector<llvm::Value *> LLVMArgs; 520 LLVMArgs.reserve(Args.size()); 521 for (Value *Arg : Args) 522 LLVMArgs.push_back(Arg->Val); 523 llvm::CallInst *NewCI = Builder.CreateCall( 524 cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val, LLVMArgs, NameStr); 525 return Ctx.createCallInst(NewCI); 526 } 527 528 InvokeInst *InvokeInst::create(FunctionType *FTy, Value *Func, 529 BasicBlock *IfNormal, BasicBlock *IfException, 530 ArrayRef<Value *> Args, InsertPosition Pos, 531 Context &Ctx, const Twine &NameStr) { 532 auto &Builder = setInsertPos(Pos); 533 SmallVector<llvm::Value *> LLVMArgs; 534 LLVMArgs.reserve(Args.size()); 535 for (Value *Arg : Args) 536 LLVMArgs.push_back(Arg->Val); 537 llvm::InvokeInst *Invoke = Builder.CreateInvoke( 538 cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val, 539 cast<llvm::BasicBlock>(IfNormal->Val), 540 cast<llvm::BasicBlock>(IfException->Val), LLVMArgs, NameStr); 541 return Ctx.createInvokeInst(Invoke); 542 } 543 544 BasicBlock *InvokeInst::getNormalDest() const { 545 return cast<BasicBlock>( 546 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getNormalDest())); 547 } 548 BasicBlock *InvokeInst::getUnwindDest() const { 549 return cast<BasicBlock>( 550 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getUnwindDest())); 551 } 552 void InvokeInst::setNormalDest(BasicBlock *BB) { 553 setOperand(1, BB); 554 assert(getNormalDest() == BB && "LLVM IR uses a different operan index!"); 555 } 556 void InvokeInst::setUnwindDest(BasicBlock *BB) { 557 setOperand(2, BB); 558 assert(getUnwindDest() == BB && "LLVM IR uses a different operan index!"); 559 } 560 LandingPadInst *InvokeInst::getLandingPadInst() const { 561 return cast<LandingPadInst>( 562 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getLandingPadInst())); 563 ; 564 } 565 BasicBlock *InvokeInst::getSuccessor(unsigned SuccIdx) const { 566 return cast<BasicBlock>( 567 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getSuccessor(SuccIdx))); 568 } 569 570 CallBrInst *CallBrInst::create(FunctionType *FTy, Value *Func, 571 BasicBlock *DefaultDest, 572 ArrayRef<BasicBlock *> IndirectDests, 573 ArrayRef<Value *> Args, InsertPosition Pos, 574 Context &Ctx, const Twine &NameStr) { 575 auto &Builder = setInsertPos(Pos); 576 SmallVector<llvm::BasicBlock *> LLVMIndirectDests; 577 LLVMIndirectDests.reserve(IndirectDests.size()); 578 for (BasicBlock *IndDest : IndirectDests) 579 LLVMIndirectDests.push_back(cast<llvm::BasicBlock>(IndDest->Val)); 580 581 SmallVector<llvm::Value *> LLVMArgs; 582 LLVMArgs.reserve(Args.size()); 583 for (Value *Arg : Args) 584 LLVMArgs.push_back(Arg->Val); 585 586 llvm::CallBrInst *CallBr = 587 Builder.CreateCallBr(cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val, 588 cast<llvm::BasicBlock>(DefaultDest->Val), 589 LLVMIndirectDests, LLVMArgs, NameStr); 590 return Ctx.createCallBrInst(CallBr); 591 } 592 593 Value *CallBrInst::getIndirectDestLabel(unsigned Idx) const { 594 return Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDestLabel(Idx)); 595 } 596 Value *CallBrInst::getIndirectDestLabelUse(unsigned Idx) const { 597 return Ctx.getValue( 598 cast<llvm::CallBrInst>(Val)->getIndirectDestLabelUse(Idx)); 599 } 600 BasicBlock *CallBrInst::getDefaultDest() const { 601 return cast<BasicBlock>( 602 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getDefaultDest())); 603 } 604 BasicBlock *CallBrInst::getIndirectDest(unsigned Idx) const { 605 return cast<BasicBlock>( 606 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDest(Idx))); 607 } 608 llvm::SmallVector<BasicBlock *, 16> CallBrInst::getIndirectDests() const { 609 SmallVector<BasicBlock *, 16> BBs; 610 for (llvm::BasicBlock *LLVMBB : 611 cast<llvm::CallBrInst>(Val)->getIndirectDests()) 612 BBs.push_back(cast<BasicBlock>(Ctx.getValue(LLVMBB))); 613 return BBs; 614 } 615 void CallBrInst::setDefaultDest(BasicBlock *BB) { 616 Ctx.getTracker() 617 .emplaceIfTracking<GenericSetter<&CallBrInst::getDefaultDest, 618 &CallBrInst::setDefaultDest>>(this); 619 cast<llvm::CallBrInst>(Val)->setDefaultDest(cast<llvm::BasicBlock>(BB->Val)); 620 } 621 void CallBrInst::setIndirectDest(unsigned Idx, BasicBlock *BB) { 622 Ctx.getTracker() 623 .emplaceIfTracking<GenericSetterWithIdx<&CallBrInst::getIndirectDest, 624 &CallBrInst::setIndirectDest>>( 625 this, Idx); 626 cast<llvm::CallBrInst>(Val)->setIndirectDest(Idx, 627 cast<llvm::BasicBlock>(BB->Val)); 628 } 629 BasicBlock *CallBrInst::getSuccessor(unsigned Idx) const { 630 return cast<BasicBlock>( 631 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getSuccessor(Idx))); 632 } 633 634 LandingPadInst *LandingPadInst::create(Type *RetTy, unsigned NumReservedClauses, 635 InsertPosition Pos, Context &Ctx, 636 const Twine &Name) { 637 auto &Builder = setInsertPos(Pos); 638 llvm::LandingPadInst *LLVMI = 639 Builder.CreateLandingPad(RetTy->LLVMTy, NumReservedClauses, Name); 640 return Ctx.createLandingPadInst(LLVMI); 641 } 642 643 void LandingPadInst::setCleanup(bool V) { 644 Ctx.getTracker() 645 .emplaceIfTracking<GenericSetter<&LandingPadInst::isCleanup, 646 &LandingPadInst::setCleanup>>(this); 647 cast<llvm::LandingPadInst>(Val)->setCleanup(V); 648 } 649 650 Constant *LandingPadInst::getClause(unsigned Idx) const { 651 return cast<Constant>( 652 Ctx.getValue(cast<llvm::LandingPadInst>(Val)->getClause(Idx))); 653 } 654 655 Value *FuncletPadInst::getParentPad() const { 656 return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getParentPad()); 657 } 658 659 void FuncletPadInst::setParentPad(Value *ParentPad) { 660 Ctx.getTracker() 661 .emplaceIfTracking<GenericSetter<&FuncletPadInst::getParentPad, 662 &FuncletPadInst::setParentPad>>(this); 663 cast<llvm::FuncletPadInst>(Val)->setParentPad(ParentPad->Val); 664 } 665 666 Value *FuncletPadInst::getArgOperand(unsigned Idx) const { 667 return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getArgOperand(Idx)); 668 } 669 670 void FuncletPadInst::setArgOperand(unsigned Idx, Value *V) { 671 Ctx.getTracker() 672 .emplaceIfTracking<GenericSetterWithIdx<&FuncletPadInst::getArgOperand, 673 &FuncletPadInst::setArgOperand>>( 674 this, Idx); 675 cast<llvm::FuncletPadInst>(Val)->setArgOperand(Idx, V->Val); 676 } 677 678 CatchSwitchInst *CatchPadInst::getCatchSwitch() const { 679 return cast<CatchSwitchInst>( 680 Ctx.getValue(cast<llvm::CatchPadInst>(Val)->getCatchSwitch())); 681 } 682 683 CatchPadInst *CatchPadInst::create(Value *ParentPad, ArrayRef<Value *> Args, 684 InsertPosition Pos, Context &Ctx, 685 const Twine &Name) { 686 auto &Builder = setInsertPos(Pos); 687 SmallVector<llvm::Value *> LLVMArgs; 688 LLVMArgs.reserve(Args.size()); 689 for (auto *Arg : Args) 690 LLVMArgs.push_back(Arg->Val); 691 llvm::CatchPadInst *LLVMI = 692 Builder.CreateCatchPad(ParentPad->Val, LLVMArgs, Name); 693 return Ctx.createCatchPadInst(LLVMI); 694 } 695 696 CleanupPadInst *CleanupPadInst::create(Value *ParentPad, ArrayRef<Value *> Args, 697 InsertPosition Pos, Context &Ctx, 698 const Twine &Name) { 699 auto &Builder = setInsertPos(Pos); 700 SmallVector<llvm::Value *> LLVMArgs; 701 LLVMArgs.reserve(Args.size()); 702 for (auto *Arg : Args) 703 LLVMArgs.push_back(Arg->Val); 704 llvm::CleanupPadInst *LLVMI = 705 Builder.CreateCleanupPad(ParentPad->Val, LLVMArgs, Name); 706 return Ctx.createCleanupPadInst(LLVMI); 707 } 708 709 CatchReturnInst *CatchReturnInst::create(CatchPadInst *CatchPad, BasicBlock *BB, 710 InsertPosition Pos, Context &Ctx) { 711 auto &Builder = setInsertPos(Pos); 712 llvm::CatchReturnInst *LLVMI = Builder.CreateCatchRet( 713 cast<llvm::CatchPadInst>(CatchPad->Val), cast<llvm::BasicBlock>(BB->Val)); 714 return Ctx.createCatchReturnInst(LLVMI); 715 } 716 717 CatchPadInst *CatchReturnInst::getCatchPad() const { 718 return cast<CatchPadInst>( 719 Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getCatchPad())); 720 } 721 722 void CatchReturnInst::setCatchPad(CatchPadInst *CatchPad) { 723 Ctx.getTracker() 724 .emplaceIfTracking<GenericSetter<&CatchReturnInst::getCatchPad, 725 &CatchReturnInst::setCatchPad>>(this); 726 cast<llvm::CatchReturnInst>(Val)->setCatchPad( 727 cast<llvm::CatchPadInst>(CatchPad->Val)); 728 } 729 730 BasicBlock *CatchReturnInst::getSuccessor() const { 731 return cast<BasicBlock>( 732 Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getSuccessor())); 733 } 734 735 void CatchReturnInst::setSuccessor(BasicBlock *NewSucc) { 736 Ctx.getTracker() 737 .emplaceIfTracking<GenericSetter<&CatchReturnInst::getSuccessor, 738 &CatchReturnInst::setSuccessor>>(this); 739 cast<llvm::CatchReturnInst>(Val)->setSuccessor( 740 cast<llvm::BasicBlock>(NewSucc->Val)); 741 } 742 743 Value *CatchReturnInst::getCatchSwitchParentPad() const { 744 return Ctx.getValue( 745 cast<llvm::CatchReturnInst>(Val)->getCatchSwitchParentPad()); 746 } 747 748 CleanupReturnInst *CleanupReturnInst::create(CleanupPadInst *CleanupPad, 749 BasicBlock *UnwindBB, 750 InsertPosition Pos, Context &Ctx) { 751 auto &Builder = setInsertPos(Pos); 752 auto *LLVMUnwindBB = 753 UnwindBB != nullptr ? cast<llvm::BasicBlock>(UnwindBB->Val) : nullptr; 754 llvm::CleanupReturnInst *LLVMI = Builder.CreateCleanupRet( 755 cast<llvm::CleanupPadInst>(CleanupPad->Val), LLVMUnwindBB); 756 return Ctx.createCleanupReturnInst(LLVMI); 757 } 758 759 CleanupPadInst *CleanupReturnInst::getCleanupPad() const { 760 return cast<CleanupPadInst>( 761 Ctx.getValue(cast<llvm::CleanupReturnInst>(Val)->getCleanupPad())); 762 } 763 764 void CleanupReturnInst::setCleanupPad(CleanupPadInst *CleanupPad) { 765 Ctx.getTracker() 766 .emplaceIfTracking<GenericSetter<&CleanupReturnInst::getCleanupPad, 767 &CleanupReturnInst::setCleanupPad>>( 768 this); 769 cast<llvm::CleanupReturnInst>(Val)->setCleanupPad( 770 cast<llvm::CleanupPadInst>(CleanupPad->Val)); 771 } 772 773 BasicBlock *CleanupReturnInst::getUnwindDest() const { 774 return cast_or_null<BasicBlock>( 775 Ctx.getValue(cast<llvm::CleanupReturnInst>(Val)->getUnwindDest())); 776 } 777 778 void CleanupReturnInst::setUnwindDest(BasicBlock *NewDest) { 779 Ctx.getTracker() 780 .emplaceIfTracking<GenericSetter<&CleanupReturnInst::getUnwindDest, 781 &CleanupReturnInst::setUnwindDest>>( 782 this); 783 cast<llvm::CleanupReturnInst>(Val)->setUnwindDest( 784 cast<llvm::BasicBlock>(NewDest->Val)); 785 } 786 787 Value *GetElementPtrInst::create(Type *Ty, Value *Ptr, 788 ArrayRef<Value *> IdxList, InsertPosition Pos, 789 Context &Ctx, const Twine &NameStr) { 790 auto &Builder = setInsertPos(Pos); 791 SmallVector<llvm::Value *> LLVMIdxList; 792 LLVMIdxList.reserve(IdxList.size()); 793 for (Value *Idx : IdxList) 794 LLVMIdxList.push_back(Idx->Val); 795 llvm::Value *NewV = 796 Builder.CreateGEP(Ty->LLVMTy, Ptr->Val, LLVMIdxList, NameStr); 797 if (auto *NewGEP = dyn_cast<llvm::GetElementPtrInst>(NewV)) 798 return Ctx.createGetElementPtrInst(NewGEP); 799 assert(isa<llvm::Constant>(NewV) && "Expected constant"); 800 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV)); 801 } 802 803 Type *GetElementPtrInst::getSourceElementType() const { 804 return Ctx.getType( 805 cast<llvm::GetElementPtrInst>(Val)->getSourceElementType()); 806 } 807 808 Type *GetElementPtrInst::getResultElementType() const { 809 return Ctx.getType( 810 cast<llvm::GetElementPtrInst>(Val)->getResultElementType()); 811 } 812 813 Value *GetElementPtrInst::getPointerOperand() const { 814 return Ctx.getValue(cast<llvm::GetElementPtrInst>(Val)->getPointerOperand()); 815 } 816 817 Type *GetElementPtrInst::getPointerOperandType() const { 818 return Ctx.getType( 819 cast<llvm::GetElementPtrInst>(Val)->getPointerOperandType()); 820 } 821 822 BasicBlock *PHINode::LLVMBBToBB::operator()(llvm::BasicBlock *LLVMBB) const { 823 return cast<BasicBlock>(Ctx.getValue(LLVMBB)); 824 } 825 826 PHINode *PHINode::create(Type *Ty, unsigned NumReservedValues, 827 InsertPosition Pos, Context &Ctx, const Twine &Name) { 828 auto &Builder = setInsertPos(Pos); 829 llvm::PHINode *NewPHI = 830 Builder.CreatePHI(Ty->LLVMTy, NumReservedValues, Name); 831 return Ctx.createPHINode(NewPHI); 832 } 833 834 bool PHINode::classof(const Value *From) { 835 return From->getSubclassID() == ClassID::PHI; 836 } 837 838 Value *PHINode::getIncomingValue(unsigned Idx) const { 839 return Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingValue(Idx)); 840 } 841 void PHINode::setIncomingValue(unsigned Idx, Value *V) { 842 Ctx.getTracker() 843 .emplaceIfTracking<GenericSetterWithIdx<&PHINode::getIncomingValue, 844 &PHINode::setIncomingValue>>(this, 845 Idx); 846 cast<llvm::PHINode>(Val)->setIncomingValue(Idx, V->Val); 847 } 848 BasicBlock *PHINode::getIncomingBlock(unsigned Idx) const { 849 return cast<BasicBlock>( 850 Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingBlock(Idx))); 851 } 852 BasicBlock *PHINode::getIncomingBlock(const Use &U) const { 853 llvm::Use *LLVMUse = U.LLVMUse; 854 llvm::BasicBlock *BB = cast<llvm::PHINode>(Val)->getIncomingBlock(*LLVMUse); 855 return cast<BasicBlock>(Ctx.getValue(BB)); 856 } 857 void PHINode::setIncomingBlock(unsigned Idx, BasicBlock *BB) { 858 // Helper to disambiguate PHINode::getIncomingBlock(unsigned). 859 constexpr BasicBlock *(PHINode::*GetIncomingBlockFn)(unsigned) const = 860 &PHINode::getIncomingBlock; 861 Ctx.getTracker() 862 .emplaceIfTracking< 863 GenericSetterWithIdx<GetIncomingBlockFn, &PHINode::setIncomingBlock>>( 864 this, Idx); 865 cast<llvm::PHINode>(Val)->setIncomingBlock(Idx, 866 cast<llvm::BasicBlock>(BB->Val)); 867 } 868 void PHINode::addIncoming(Value *V, BasicBlock *BB) { 869 auto &Tracker = Ctx.getTracker(); 870 Tracker.emplaceIfTracking<PHIAddIncoming>(this); 871 872 cast<llvm::PHINode>(Val)->addIncoming(V->Val, 873 cast<llvm::BasicBlock>(BB->Val)); 874 } 875 Value *PHINode::removeIncomingValue(unsigned Idx) { 876 auto &Tracker = Ctx.getTracker(); 877 Tracker.emplaceIfTracking<PHIRemoveIncoming>(this, Idx); 878 llvm::Value *LLVMV = 879 cast<llvm::PHINode>(Val)->removeIncomingValue(Idx, 880 /*DeletePHIIfEmpty=*/false); 881 return Ctx.getValue(LLVMV); 882 } 883 Value *PHINode::removeIncomingValue(BasicBlock *BB) { 884 auto &Tracker = Ctx.getTracker(); 885 Tracker.emplaceIfTracking<PHIRemoveIncoming>(this, getBasicBlockIndex(BB)); 886 887 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val); 888 llvm::Value *LLVMV = 889 cast<llvm::PHINode>(Val)->removeIncomingValue(LLVMBB, 890 /*DeletePHIIfEmpty=*/false); 891 return Ctx.getValue(LLVMV); 892 } 893 int PHINode::getBasicBlockIndex(const BasicBlock *BB) const { 894 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val); 895 return cast<llvm::PHINode>(Val)->getBasicBlockIndex(LLVMBB); 896 } 897 Value *PHINode::getIncomingValueForBlock(const BasicBlock *BB) const { 898 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val); 899 llvm::Value *LLVMV = 900 cast<llvm::PHINode>(Val)->getIncomingValueForBlock(LLVMBB); 901 return Ctx.getValue(LLVMV); 902 } 903 Value *PHINode::hasConstantValue() const { 904 llvm::Value *LLVMV = cast<llvm::PHINode>(Val)->hasConstantValue(); 905 return LLVMV != nullptr ? Ctx.getValue(LLVMV) : nullptr; 906 } 907 void PHINode::replaceIncomingBlockWith(const BasicBlock *Old, BasicBlock *New) { 908 assert(New && Old && "Sandbox IR PHI node got a null basic block!"); 909 for (unsigned Idx = 0, NumOps = cast<llvm::PHINode>(Val)->getNumOperands(); 910 Idx != NumOps; ++Idx) 911 if (getIncomingBlock(Idx) == Old) 912 setIncomingBlock(Idx, New); 913 } 914 void PHINode::removeIncomingValueIf(function_ref<bool(unsigned)> Predicate) { 915 // Avoid duplicate tracking by going through this->removeIncomingValue here at 916 // the expense of some performance. Copy PHI::removeIncomingValueIf more 917 // directly if performance becomes an issue. 918 919 // Removing the element at index X, moves the element previously at X + 1 920 // to X. Working from the end avoids complications from that. 921 unsigned Idx = getNumIncomingValues(); 922 while (Idx > 0) { 923 if (Predicate(Idx - 1)) 924 removeIncomingValue(Idx - 1); 925 --Idx; 926 } 927 } 928 929 Value *CmpInst::create(Predicate P, Value *S1, Value *S2, InsertPosition Pos, 930 Context &Ctx, const Twine &Name) { 931 auto &Builder = setInsertPos(Pos); 932 auto *LLVMV = Builder.CreateCmp(P, S1->Val, S2->Val, Name); 933 // It may have been folded into a constant. 934 if (auto *LLVMC = dyn_cast<llvm::Constant>(LLVMV)) 935 return Ctx.getOrCreateConstant(LLVMC); 936 if (isa<llvm::ICmpInst>(LLVMV)) 937 return Ctx.createICmpInst(cast<llvm::ICmpInst>(LLVMV)); 938 return Ctx.createFCmpInst(cast<llvm::FCmpInst>(LLVMV)); 939 } 940 941 Value *CmpInst::createWithCopiedFlags(Predicate P, Value *S1, Value *S2, 942 const Instruction *F, InsertPosition Pos, 943 Context &Ctx, const Twine &Name) { 944 Value *V = create(P, S1, S2, Pos, Ctx, Name); 945 if (auto *C = dyn_cast<Constant>(V)) 946 return C; 947 cast<llvm::CmpInst>(V->Val)->copyIRFlags(F->Val); 948 return V; 949 } 950 951 Type *CmpInst::makeCmpResultType(Type *OpndType) { 952 if (auto *VT = dyn_cast<VectorType>(OpndType)) { 953 // TODO: Cleanup when we have more complete support for 954 // sandboxir::VectorType 955 return OpndType->getContext().getType(llvm::VectorType::get( 956 llvm::Type::getInt1Ty(OpndType->getContext().LLVMCtx), 957 cast<llvm::VectorType>(VT->LLVMTy)->getElementCount())); 958 } 959 return Type::getInt1Ty(OpndType->getContext()); 960 } 961 962 void CmpInst::setPredicate(Predicate P) { 963 Ctx.getTracker() 964 .emplaceIfTracking< 965 GenericSetter<&CmpInst::getPredicate, &CmpInst::setPredicate>>(this); 966 cast<llvm::CmpInst>(Val)->setPredicate(P); 967 } 968 969 void CmpInst::swapOperands() { 970 if (ICmpInst *IC = dyn_cast<ICmpInst>(this)) 971 IC->swapOperands(); 972 else 973 cast<FCmpInst>(this)->swapOperands(); 974 } 975 976 void ICmpInst::swapOperands() { 977 Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this); 978 cast<llvm::ICmpInst>(Val)->swapOperands(); 979 } 980 981 void FCmpInst::swapOperands() { 982 Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this); 983 cast<llvm::FCmpInst>(Val)->swapOperands(); 984 } 985 986 #ifndef NDEBUG 987 void CmpInst::dumpOS(raw_ostream &OS) const { 988 dumpCommonPrefix(OS); 989 dumpCommonSuffix(OS); 990 } 991 992 void CmpInst::dump() const { 993 dumpOS(dbgs()); 994 dbgs() << "\n"; 995 } 996 #endif // NDEBUG 997 998 static llvm::Instruction::CastOps getLLVMCastOp(Instruction::Opcode Opc) { 999 switch (Opc) { 1000 case Instruction::Opcode::ZExt: 1001 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::ZExt); 1002 case Instruction::Opcode::SExt: 1003 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SExt); 1004 case Instruction::Opcode::FPToUI: 1005 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToUI); 1006 case Instruction::Opcode::FPToSI: 1007 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToSI); 1008 case Instruction::Opcode::FPExt: 1009 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPExt); 1010 case Instruction::Opcode::PtrToInt: 1011 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::PtrToInt); 1012 case Instruction::Opcode::IntToPtr: 1013 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::IntToPtr); 1014 case Instruction::Opcode::SIToFP: 1015 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SIToFP); 1016 case Instruction::Opcode::UIToFP: 1017 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::UIToFP); 1018 case Instruction::Opcode::Trunc: 1019 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::Trunc); 1020 case Instruction::Opcode::FPTrunc: 1021 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPTrunc); 1022 case Instruction::Opcode::BitCast: 1023 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::BitCast); 1024 case Instruction::Opcode::AddrSpaceCast: 1025 return static_cast<llvm::Instruction::CastOps>( 1026 llvm::Instruction::AddrSpaceCast); 1027 default: 1028 llvm_unreachable("Opcode not suitable for CastInst!"); 1029 } 1030 } 1031 1032 /// \Returns the LLVM opcode that corresponds to \p Opc. 1033 static llvm::Instruction::UnaryOps getLLVMUnaryOp(Instruction::Opcode Opc) { 1034 switch (Opc) { 1035 case Instruction::Opcode::FNeg: 1036 return static_cast<llvm::Instruction::UnaryOps>(llvm::Instruction::FNeg); 1037 default: 1038 llvm_unreachable("Not a unary op!"); 1039 } 1040 } 1041 1042 CatchSwitchInst *CatchSwitchInst::create(Value *ParentPad, BasicBlock *UnwindBB, 1043 unsigned NumHandlers, 1044 InsertPosition Pos, Context &Ctx, 1045 const Twine &Name) { 1046 auto &Builder = setInsertPos(Pos); 1047 llvm::CatchSwitchInst *LLVMCSI = Builder.CreateCatchSwitch( 1048 ParentPad->Val, cast<llvm::BasicBlock>(UnwindBB->Val), NumHandlers, Name); 1049 return Ctx.createCatchSwitchInst(LLVMCSI); 1050 } 1051 1052 Value *CatchSwitchInst::getParentPad() const { 1053 return Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getParentPad()); 1054 } 1055 1056 void CatchSwitchInst::setParentPad(Value *ParentPad) { 1057 Ctx.getTracker() 1058 .emplaceIfTracking<GenericSetter<&CatchSwitchInst::getParentPad, 1059 &CatchSwitchInst::setParentPad>>(this); 1060 cast<llvm::CatchSwitchInst>(Val)->setParentPad(ParentPad->Val); 1061 } 1062 1063 BasicBlock *CatchSwitchInst::getUnwindDest() const { 1064 return cast_or_null<BasicBlock>( 1065 Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getUnwindDest())); 1066 } 1067 1068 void CatchSwitchInst::setUnwindDest(BasicBlock *UnwindDest) { 1069 Ctx.getTracker() 1070 .emplaceIfTracking<GenericSetter<&CatchSwitchInst::getUnwindDest, 1071 &CatchSwitchInst::setUnwindDest>>(this); 1072 cast<llvm::CatchSwitchInst>(Val)->setUnwindDest( 1073 cast<llvm::BasicBlock>(UnwindDest->Val)); 1074 } 1075 1076 void CatchSwitchInst::addHandler(BasicBlock *Dest) { 1077 Ctx.getTracker().emplaceIfTracking<CatchSwitchAddHandler>(this); 1078 cast<llvm::CatchSwitchInst>(Val)->addHandler( 1079 cast<llvm::BasicBlock>(Dest->Val)); 1080 } 1081 1082 ResumeInst *ResumeInst::create(Value *Exn, InsertPosition Pos, Context &Ctx) { 1083 auto &Builder = setInsertPos(Pos); 1084 auto *LLVMI = cast<llvm::ResumeInst>(Builder.CreateResume(Exn->Val)); 1085 return Ctx.createResumeInst(LLVMI); 1086 } 1087 1088 Value *ResumeInst::getValue() const { 1089 return Ctx.getValue(cast<llvm::ResumeInst>(Val)->getValue()); 1090 } 1091 1092 SwitchInst *SwitchInst::create(Value *V, BasicBlock *Dest, unsigned NumCases, 1093 InsertPosition Pos, Context &Ctx, 1094 const Twine &Name) { 1095 auto &Builder = setInsertPos(Pos); 1096 llvm::SwitchInst *LLVMSwitch = 1097 Builder.CreateSwitch(V->Val, cast<llvm::BasicBlock>(Dest->Val), NumCases); 1098 return Ctx.createSwitchInst(LLVMSwitch); 1099 } 1100 1101 Value *SwitchInst::getCondition() const { 1102 return Ctx.getValue(cast<llvm::SwitchInst>(Val)->getCondition()); 1103 } 1104 1105 void SwitchInst::setCondition(Value *V) { 1106 Ctx.getTracker() 1107 .emplaceIfTracking< 1108 GenericSetter<&SwitchInst::getCondition, &SwitchInst::setCondition>>( 1109 this); 1110 cast<llvm::SwitchInst>(Val)->setCondition(V->Val); 1111 } 1112 1113 BasicBlock *SwitchInst::getDefaultDest() const { 1114 return cast<BasicBlock>( 1115 Ctx.getValue(cast<llvm::SwitchInst>(Val)->getDefaultDest())); 1116 } 1117 1118 void SwitchInst::setDefaultDest(BasicBlock *DefaultCase) { 1119 Ctx.getTracker() 1120 .emplaceIfTracking<GenericSetter<&SwitchInst::getDefaultDest, 1121 &SwitchInst::setDefaultDest>>(this); 1122 cast<llvm::SwitchInst>(Val)->setDefaultDest( 1123 cast<llvm::BasicBlock>(DefaultCase->Val)); 1124 } 1125 ConstantInt *SwitchInst::findCaseDest(BasicBlock *BB) { 1126 auto *LLVMC = cast<llvm::SwitchInst>(Val)->findCaseDest( 1127 cast<llvm::BasicBlock>(BB->Val)); 1128 return LLVMC != nullptr ? cast<ConstantInt>(Ctx.getValue(LLVMC)) : nullptr; 1129 } 1130 1131 void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) { 1132 Ctx.getTracker().emplaceIfTracking<SwitchAddCase>(this, OnVal); 1133 // TODO: Track this! 1134 cast<llvm::SwitchInst>(Val)->addCase(cast<llvm::ConstantInt>(OnVal->Val), 1135 cast<llvm::BasicBlock>(Dest->Val)); 1136 } 1137 1138 SwitchInst::CaseIt SwitchInst::removeCase(CaseIt It) { 1139 Ctx.getTracker().emplaceIfTracking<SwitchRemoveCase>(this); 1140 1141 auto *LLVMSwitch = cast<llvm::SwitchInst>(Val); 1142 unsigned CaseNum = It - case_begin(); 1143 llvm::SwitchInst::CaseIt LLVMIt(LLVMSwitch, CaseNum); 1144 auto LLVMCaseIt = LLVMSwitch->removeCase(LLVMIt); 1145 unsigned Num = LLVMCaseIt - LLVMSwitch->case_begin(); 1146 return CaseIt(this, Num); 1147 } 1148 1149 BasicBlock *SwitchInst::getSuccessor(unsigned Idx) const { 1150 return cast<BasicBlock>( 1151 Ctx.getValue(cast<llvm::SwitchInst>(Val)->getSuccessor(Idx))); 1152 } 1153 1154 void SwitchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) { 1155 Ctx.getTracker() 1156 .emplaceIfTracking<GenericSetterWithIdx<&SwitchInst::getSuccessor, 1157 &SwitchInst::setSuccessor>>(this, 1158 Idx); 1159 cast<llvm::SwitchInst>(Val)->setSuccessor( 1160 Idx, cast<llvm::BasicBlock>(NewSucc->Val)); 1161 } 1162 1163 Value *UnaryOperator::create(Instruction::Opcode Op, Value *OpV, 1164 InsertPosition Pos, Context &Ctx, 1165 const Twine &Name) { 1166 auto &Builder = setInsertPos(Pos); 1167 auto *NewLLVMV = Builder.CreateUnOp(getLLVMUnaryOp(Op), OpV->Val, Name); 1168 if (auto *NewUnOpV = dyn_cast<llvm::UnaryOperator>(NewLLVMV)) { 1169 return Ctx.createUnaryOperator(NewUnOpV); 1170 } 1171 assert(isa<llvm::Constant>(NewLLVMV) && "Expected constant"); 1172 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewLLVMV)); 1173 } 1174 1175 Value *UnaryOperator::createWithCopiedFlags(Instruction::Opcode Op, Value *OpV, 1176 Value *CopyFrom, InsertPosition Pos, 1177 Context &Ctx, const Twine &Name) { 1178 auto *NewV = create(Op, OpV, Pos, Ctx, Name); 1179 if (auto *UnI = dyn_cast<llvm::UnaryOperator>(NewV->Val)) 1180 UnI->copyIRFlags(CopyFrom->Val); 1181 return NewV; 1182 } 1183 1184 /// \Returns the LLVM opcode that corresponds to \p Opc. 1185 static llvm::Instruction::BinaryOps getLLVMBinaryOp(Instruction::Opcode Opc) { 1186 switch (Opc) { 1187 case Instruction::Opcode::Add: 1188 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Add); 1189 case Instruction::Opcode::FAdd: 1190 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FAdd); 1191 case Instruction::Opcode::Sub: 1192 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Sub); 1193 case Instruction::Opcode::FSub: 1194 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FSub); 1195 case Instruction::Opcode::Mul: 1196 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Mul); 1197 case Instruction::Opcode::FMul: 1198 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FMul); 1199 case Instruction::Opcode::UDiv: 1200 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::UDiv); 1201 case Instruction::Opcode::SDiv: 1202 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SDiv); 1203 case Instruction::Opcode::FDiv: 1204 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FDiv); 1205 case Instruction::Opcode::URem: 1206 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::URem); 1207 case Instruction::Opcode::SRem: 1208 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SRem); 1209 case Instruction::Opcode::FRem: 1210 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FRem); 1211 case Instruction::Opcode::Shl: 1212 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Shl); 1213 case Instruction::Opcode::LShr: 1214 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::LShr); 1215 case Instruction::Opcode::AShr: 1216 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::AShr); 1217 case Instruction::Opcode::And: 1218 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::And); 1219 case Instruction::Opcode::Or: 1220 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Or); 1221 case Instruction::Opcode::Xor: 1222 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Xor); 1223 default: 1224 llvm_unreachable("Not a binary op!"); 1225 } 1226 } 1227 Value *BinaryOperator::create(Instruction::Opcode Op, Value *LHS, Value *RHS, 1228 InsertPosition Pos, Context &Ctx, 1229 const Twine &Name) { 1230 auto &Builder = setInsertPos(Pos); 1231 llvm::Value *NewV = 1232 Builder.CreateBinOp(getLLVMBinaryOp(Op), LHS->Val, RHS->Val, Name); 1233 if (auto *NewBinOp = dyn_cast<llvm::BinaryOperator>(NewV)) 1234 return Ctx.createBinaryOperator(NewBinOp); 1235 assert(isa<llvm::Constant>(NewV) && "Expected constant"); 1236 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV)); 1237 } 1238 1239 Value *BinaryOperator::createWithCopiedFlags(Instruction::Opcode Op, Value *LHS, 1240 Value *RHS, Value *CopyFrom, 1241 InsertPosition Pos, Context &Ctx, 1242 const Twine &Name) { 1243 1244 Value *NewV = create(Op, LHS, RHS, Pos, Ctx, Name); 1245 if (auto *NewBO = dyn_cast<BinaryOperator>(NewV)) 1246 cast<llvm::BinaryOperator>(NewBO->Val)->copyIRFlags(CopyFrom->Val); 1247 return NewV; 1248 } 1249 1250 void PossiblyDisjointInst::setIsDisjoint(bool B) { 1251 Ctx.getTracker() 1252 .emplaceIfTracking<GenericSetter<&PossiblyDisjointInst::isDisjoint, 1253 &PossiblyDisjointInst::setIsDisjoint>>( 1254 this); 1255 cast<llvm::PossiblyDisjointInst>(Val)->setIsDisjoint(B); 1256 } 1257 1258 void AtomicRMWInst::setAlignment(Align Align) { 1259 Ctx.getTracker() 1260 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getAlign, 1261 &AtomicRMWInst::setAlignment>>(this); 1262 cast<llvm::AtomicRMWInst>(Val)->setAlignment(Align); 1263 } 1264 1265 void AtomicRMWInst::setVolatile(bool V) { 1266 Ctx.getTracker() 1267 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::isVolatile, 1268 &AtomicRMWInst::setVolatile>>(this); 1269 cast<llvm::AtomicRMWInst>(Val)->setVolatile(V); 1270 } 1271 1272 void AtomicRMWInst::setOrdering(AtomicOrdering Ordering) { 1273 Ctx.getTracker() 1274 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getOrdering, 1275 &AtomicRMWInst::setOrdering>>(this); 1276 cast<llvm::AtomicRMWInst>(Val)->setOrdering(Ordering); 1277 } 1278 1279 void AtomicRMWInst::setSyncScopeID(SyncScope::ID SSID) { 1280 Ctx.getTracker() 1281 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getSyncScopeID, 1282 &AtomicRMWInst::setSyncScopeID>>(this); 1283 cast<llvm::AtomicRMWInst>(Val)->setSyncScopeID(SSID); 1284 } 1285 1286 Value *AtomicRMWInst::getPointerOperand() { 1287 return Ctx.getValue(cast<llvm::AtomicRMWInst>(Val)->getPointerOperand()); 1288 } 1289 1290 Value *AtomicRMWInst::getValOperand() { 1291 return Ctx.getValue(cast<llvm::AtomicRMWInst>(Val)->getValOperand()); 1292 } 1293 1294 AtomicRMWInst *AtomicRMWInst::create(BinOp Op, Value *Ptr, Value *Val, 1295 MaybeAlign Align, AtomicOrdering Ordering, 1296 InsertPosition Pos, Context &Ctx, 1297 SyncScope::ID SSID, const Twine &Name) { 1298 auto &Builder = setInsertPos(Pos); 1299 auto *LLVMAtomicRMW = 1300 Builder.CreateAtomicRMW(Op, Ptr->Val, Val->Val, Align, Ordering, SSID); 1301 LLVMAtomicRMW->setName(Name); 1302 return Ctx.createAtomicRMWInst(LLVMAtomicRMW); 1303 } 1304 1305 void AtomicCmpXchgInst::setSyncScopeID(SyncScope::ID SSID) { 1306 Ctx.getTracker() 1307 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSyncScopeID, 1308 &AtomicCmpXchgInst::setSyncScopeID>>( 1309 this); 1310 cast<llvm::AtomicCmpXchgInst>(Val)->setSyncScopeID(SSID); 1311 } 1312 1313 Value *AtomicCmpXchgInst::getPointerOperand() { 1314 return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getPointerOperand()); 1315 } 1316 1317 Value *AtomicCmpXchgInst::getCompareOperand() { 1318 return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getCompareOperand()); 1319 } 1320 1321 Value *AtomicCmpXchgInst::getNewValOperand() { 1322 return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getNewValOperand()); 1323 } 1324 1325 AtomicCmpXchgInst * 1326 AtomicCmpXchgInst::create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align, 1327 AtomicOrdering SuccessOrdering, 1328 AtomicOrdering FailureOrdering, InsertPosition Pos, 1329 Context &Ctx, SyncScope::ID SSID, const Twine &Name) { 1330 auto &Builder = setInsertPos(Pos); 1331 auto *LLVMAtomicCmpXchg = 1332 Builder.CreateAtomicCmpXchg(Ptr->Val, Cmp->Val, New->Val, Align, 1333 SuccessOrdering, FailureOrdering, SSID); 1334 LLVMAtomicCmpXchg->setName(Name); 1335 return Ctx.createAtomicCmpXchgInst(LLVMAtomicCmpXchg); 1336 } 1337 1338 void AtomicCmpXchgInst::setAlignment(Align Align) { 1339 Ctx.getTracker() 1340 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getAlign, 1341 &AtomicCmpXchgInst::setAlignment>>(this); 1342 cast<llvm::AtomicCmpXchgInst>(Val)->setAlignment(Align); 1343 } 1344 1345 void AtomicCmpXchgInst::setVolatile(bool V) { 1346 Ctx.getTracker() 1347 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isVolatile, 1348 &AtomicCmpXchgInst::setVolatile>>(this); 1349 cast<llvm::AtomicCmpXchgInst>(Val)->setVolatile(V); 1350 } 1351 1352 void AtomicCmpXchgInst::setWeak(bool IsWeak) { 1353 Ctx.getTracker() 1354 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isWeak, 1355 &AtomicCmpXchgInst::setWeak>>(this); 1356 cast<llvm::AtomicCmpXchgInst>(Val)->setWeak(IsWeak); 1357 } 1358 1359 void AtomicCmpXchgInst::setSuccessOrdering(AtomicOrdering Ordering) { 1360 Ctx.getTracker() 1361 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSuccessOrdering, 1362 &AtomicCmpXchgInst::setSuccessOrdering>>( 1363 this); 1364 cast<llvm::AtomicCmpXchgInst>(Val)->setSuccessOrdering(Ordering); 1365 } 1366 1367 void AtomicCmpXchgInst::setFailureOrdering(AtomicOrdering Ordering) { 1368 Ctx.getTracker() 1369 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getFailureOrdering, 1370 &AtomicCmpXchgInst::setFailureOrdering>>( 1371 this); 1372 cast<llvm::AtomicCmpXchgInst>(Val)->setFailureOrdering(Ordering); 1373 } 1374 1375 AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace, InsertPosition Pos, 1376 Context &Ctx, Value *ArraySize, 1377 const Twine &Name) { 1378 auto &Builder = setInsertPos(Pos); 1379 auto *NewAlloca = 1380 Builder.CreateAlloca(Ty->LLVMTy, AddrSpace, ArraySize->Val, Name); 1381 return Ctx.createAllocaInst(NewAlloca); 1382 } 1383 1384 Type *AllocaInst::getAllocatedType() const { 1385 return Ctx.getType(cast<llvm::AllocaInst>(Val)->getAllocatedType()); 1386 } 1387 1388 void AllocaInst::setAllocatedType(Type *Ty) { 1389 Ctx.getTracker() 1390 .emplaceIfTracking<GenericSetter<&AllocaInst::getAllocatedType, 1391 &AllocaInst::setAllocatedType>>(this); 1392 cast<llvm::AllocaInst>(Val)->setAllocatedType(Ty->LLVMTy); 1393 } 1394 1395 void AllocaInst::setAlignment(Align Align) { 1396 Ctx.getTracker() 1397 .emplaceIfTracking< 1398 GenericSetter<&AllocaInst::getAlign, &AllocaInst::setAlignment>>( 1399 this); 1400 cast<llvm::AllocaInst>(Val)->setAlignment(Align); 1401 } 1402 1403 void AllocaInst::setUsedWithInAlloca(bool V) { 1404 Ctx.getTracker() 1405 .emplaceIfTracking<GenericSetter<&AllocaInst::isUsedWithInAlloca, 1406 &AllocaInst::setUsedWithInAlloca>>(this); 1407 cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V); 1408 } 1409 1410 Value *AllocaInst::getArraySize() { 1411 return Ctx.getValue(cast<llvm::AllocaInst>(Val)->getArraySize()); 1412 } 1413 1414 PointerType *AllocaInst::getType() const { 1415 return cast<PointerType>(Ctx.getType(cast<llvm::AllocaInst>(Val)->getType())); 1416 } 1417 1418 Value *CastInst::create(Type *DestTy, Opcode Op, Value *Operand, 1419 InsertPosition Pos, Context &Ctx, const Twine &Name) { 1420 assert(getLLVMCastOp(Op) && "Opcode not suitable for CastInst!"); 1421 auto &Builder = setInsertPos(Pos); 1422 auto *NewV = 1423 Builder.CreateCast(getLLVMCastOp(Op), Operand->Val, DestTy->LLVMTy, Name); 1424 if (auto *NewCI = dyn_cast<llvm::CastInst>(NewV)) 1425 return Ctx.createCastInst(NewCI); 1426 assert(isa<llvm::Constant>(NewV) && "Expected constant"); 1427 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV)); 1428 } 1429 1430 bool CastInst::classof(const Value *From) { 1431 return From->getSubclassID() == ClassID::Cast; 1432 } 1433 1434 Type *CastInst::getSrcTy() const { 1435 return Ctx.getType(cast<llvm::CastInst>(Val)->getSrcTy()); 1436 } 1437 1438 Type *CastInst::getDestTy() const { 1439 return Ctx.getType(cast<llvm::CastInst>(Val)->getDestTy()); 1440 } 1441 1442 void PossiblyNonNegInst::setNonNeg(bool B) { 1443 Ctx.getTracker() 1444 .emplaceIfTracking<GenericSetter<&PossiblyNonNegInst::hasNonNeg, 1445 &PossiblyNonNegInst::setNonNeg>>(this); 1446 cast<llvm::PossiblyNonNegInst>(Val)->setNonNeg(B); 1447 } 1448 1449 Value *InsertElementInst::create(Value *Vec, Value *NewElt, Value *Idx, 1450 InsertPosition Pos, Context &Ctx, 1451 const Twine &Name) { 1452 auto &Builder = Instruction::setInsertPos(Pos); 1453 llvm::Value *NewV = 1454 Builder.CreateInsertElement(Vec->Val, NewElt->Val, Idx->Val, Name); 1455 if (auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV)) 1456 return Ctx.createInsertElementInst(NewInsert); 1457 assert(isa<llvm::Constant>(NewV) && "Expected constant"); 1458 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV)); 1459 } 1460 1461 Value *ExtractElementInst::create(Value *Vec, Value *Idx, InsertPosition Pos, 1462 Context &Ctx, const Twine &Name) { 1463 auto &Builder = setInsertPos(Pos); 1464 llvm::Value *NewV = Builder.CreateExtractElement(Vec->Val, Idx->Val, Name); 1465 if (auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV)) 1466 return Ctx.createExtractElementInst(NewExtract); 1467 assert(isa<llvm::Constant>(NewV) && "Expected constant"); 1468 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV)); 1469 } 1470 1471 Value *ShuffleVectorInst::create(Value *V1, Value *V2, Value *Mask, 1472 InsertPosition Pos, Context &Ctx, 1473 const Twine &Name) { 1474 auto &Builder = setInsertPos(Pos); 1475 llvm::Value *NewV = 1476 Builder.CreateShuffleVector(V1->Val, V2->Val, Mask->Val, Name); 1477 if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV)) 1478 return Ctx.createShuffleVectorInst(NewShuffle); 1479 assert(isa<llvm::Constant>(NewV) && "Expected constant"); 1480 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV)); 1481 } 1482 1483 Value *ShuffleVectorInst::create(Value *V1, Value *V2, ArrayRef<int> Mask, 1484 InsertPosition Pos, Context &Ctx, 1485 const Twine &Name) { 1486 auto &Builder = setInsertPos(Pos); 1487 llvm::Value *NewV = Builder.CreateShuffleVector(V1->Val, V2->Val, Mask, Name); 1488 if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV)) 1489 return Ctx.createShuffleVectorInst(NewShuffle); 1490 assert(isa<llvm::Constant>(NewV) && "Expected constant"); 1491 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV)); 1492 } 1493 1494 void ShuffleVectorInst::setShuffleMask(ArrayRef<int> Mask) { 1495 Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this); 1496 cast<llvm::ShuffleVectorInst>(Val)->setShuffleMask(Mask); 1497 } 1498 1499 VectorType *ShuffleVectorInst::getType() const { 1500 return cast<VectorType>( 1501 Ctx.getType(cast<llvm::ShuffleVectorInst>(Val)->getType())); 1502 } 1503 1504 void ShuffleVectorInst::commute() { 1505 Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this); 1506 Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(0), 1507 getOperandUse(1)); 1508 cast<llvm::ShuffleVectorInst>(Val)->commute(); 1509 } 1510 1511 Constant *ShuffleVectorInst::getShuffleMaskForBitcode() const { 1512 return Ctx.getOrCreateConstant( 1513 cast<llvm::ShuffleVectorInst>(Val)->getShuffleMaskForBitcode()); 1514 } 1515 1516 Constant *ShuffleVectorInst::convertShuffleMaskForBitcode(ArrayRef<int> Mask, 1517 Type *ResultTy) { 1518 return ResultTy->getContext().getOrCreateConstant( 1519 llvm::ShuffleVectorInst::convertShuffleMaskForBitcode(Mask, 1520 ResultTy->LLVMTy)); 1521 } 1522 1523 VectorType *ExtractElementInst::getVectorOperandType() const { 1524 return cast<VectorType>(Ctx.getType(getVectorOperand()->getType()->LLVMTy)); 1525 } 1526 1527 Value *ExtractValueInst::create(Value *Agg, ArrayRef<unsigned> Idxs, 1528 InsertPosition Pos, Context &Ctx, 1529 const Twine &Name) { 1530 auto &Builder = setInsertPos(Pos); 1531 llvm::Value *NewV = Builder.CreateExtractValue(Agg->Val, Idxs, Name); 1532 if (auto *NewExtractValueInst = dyn_cast<llvm::ExtractValueInst>(NewV)) 1533 return Ctx.createExtractValueInst(NewExtractValueInst); 1534 assert(isa<llvm::Constant>(NewV) && "Expected constant"); 1535 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV)); 1536 } 1537 1538 Type *ExtractValueInst::getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs) { 1539 auto *LLVMTy = llvm::ExtractValueInst::getIndexedType(Agg->LLVMTy, Idxs); 1540 return Agg->getContext().getType(LLVMTy); 1541 } 1542 1543 Value *InsertValueInst::create(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs, 1544 InsertPosition Pos, Context &Ctx, 1545 const Twine &Name) { 1546 auto &Builder = setInsertPos(Pos); 1547 llvm::Value *NewV = Builder.CreateInsertValue(Agg->Val, Val->Val, Idxs, Name); 1548 if (auto *NewInsertValueInst = dyn_cast<llvm::InsertValueInst>(NewV)) 1549 return Ctx.createInsertValueInst(NewInsertValueInst); 1550 assert(isa<llvm::Constant>(NewV) && "Expected constant"); 1551 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV)); 1552 } 1553 1554 ConstantTokenNone *ConstantTokenNone::get(Context &Ctx) { 1555 auto *LLVMC = llvm::ConstantTokenNone::get(Ctx.LLVMCtx); 1556 return cast<ConstantTokenNone>(Ctx.getOrCreateConstant(LLVMC)); 1557 } 1558 1559 } // namespace llvm::sandboxir 1560