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