1590 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/SandboxIR/Instruction.h"10#include "llvm/SandboxIR/Function.h"11 12namespace llvm::sandboxir {13 14const 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) OPC21#include "llvm/SandboxIR/Values.def"22 }23 llvm_unreachable("Unknown Opcode");24}25 26llvm::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 and33 // return its successor.34 llvm::Instruction *PrevBotI = cast<llvm::Instruction>(Prev->Val);35 return PrevBotI->getNextNode();36}37 38BBIterator Instruction::getIterator() const {39 auto *I = cast<llvm::Instruction>(Val);40 return BasicBlock::iterator(I->getParent(), I->getIterator(), &Ctx);41}42 43Instruction *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 works48 // 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 58Instruction *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 66void 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 74void 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 be85 // 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 the90 // 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 100void 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 125void 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 135void Instruction::insertAfter(Instruction *AfterI) {136 insertInto(AfterI->getParent(), std::next(AfterI->getIterator()));137}138 139void 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 161BasicBlock *Instruction::getParent() const {162 // Get the LLVM IR Instruction that this maps to, get its parent, and get the163 // 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 170bool 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 181void 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 189void 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 196void 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 203void 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 210void 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 217void 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 225void 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 233void 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 241void 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 249void 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 257void 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 264void 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 271Type *Instruction::getAccessType() const {272 return Ctx.getType(cast<llvm::Instruction>(Val)->getAccessType());273}274 275void 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 NDEBUG283void Instruction::dumpOS(raw_ostream &OS) const {284 OS << "Unimplemented! Please override dump().";285}286#endif // NDEBUG287 288VAArgInst *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 296Value *VAArgInst::getPointerOperand() {297 return Ctx.getValue(cast<llvm::VAArgInst>(Val)->getPointerOperand());298}299 300FreezeInst *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 307FenceInst *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 314void 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 322void 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 329Value *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 340void SelectInst::swapValues() {341 Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(1),342 getOperandUse(2));343 cast<llvm::SelectInst>(Val)->swapValues();344}345 346bool SelectInst::classof(const Value *From) {347 return From->getSubclassID() == ClassID::Select;348}349 350BranchInst *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 358BranchInst *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 367bool BranchInst::classof(const Value *From) {368 return From->getSubclassID() == ClassID::Br;369}370 371Value *BranchInst::getCondition() const {372 assert(isConditional() && "Cannot get condition of an uncond branch!");373 return Ctx.getValue(cast<llvm::BranchInst>(Val)->getCondition());374}375 376BasicBlock *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 383void BranchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {384 assert((Idx == 0 || Idx == 1) && "Out of bounds!");385 setOperand(2u - Idx, NewSucc);386}387 388BasicBlock *BranchInst::LLVMBBToSBBB::operator()(llvm::BasicBlock *BB) const {389 return cast<BasicBlock>(Ctx.getValue(BB));390}391const BasicBlock *392BranchInst::ConstLLVMBBToSBBB::operator()(const llvm::BasicBlock *BB) const {393 return cast<BasicBlock>(Ctx.getValue(BB));394}395 396void 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 403LoadInst *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 413bool LoadInst::classof(const Value *From) {414 return From->getSubclassID() == ClassID::Load;415}416 417Value *LoadInst::getPointerOperand() const {418 return Ctx.getValue(cast<llvm::LoadInst>(Val)->getPointerOperand());419}420 421void 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 428StoreInst *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 437bool StoreInst::classof(const Value *From) {438 return From->getSubclassID() == ClassID::Store;439}440 441Value *StoreInst::getValueOperand() const {442 return Ctx.getValue(cast<llvm::StoreInst>(Val)->getValueOperand());443}444 445Value *StoreInst::getPointerOperand() const {446 return Ctx.getValue(cast<llvm::StoreInst>(Val)->getPointerOperand());447}448 449UnreachableInst *UnreachableInst::create(InsertPosition Pos, Context &Ctx) {450 auto &Builder = setInsertPos(Pos);451 llvm::UnreachableInst *NewUI = Builder.CreateUnreachable();452 return Ctx.createUnreachableInst(NewUI);453}454 455bool UnreachableInst::classof(const Value *From) {456 return From->getSubclassID() == ClassID::Unreachable;457}458 459ReturnInst *ReturnInst::createCommon(Value *RetVal, IRBuilder<> &Builder,460 Context &Ctx) {461 llvm::ReturnInst *NewRI;462 if (RetVal != nullptr)463 NewRI = Builder.CreateRet(RetVal->Val);464 else465 NewRI = Builder.CreateRetVoid();466 return Ctx.createReturnInst(NewRI);467}468 469ReturnInst *ReturnInst::create(Value *RetVal, InsertPosition Pos,470 Context &Ctx) {471 auto &Builder = setInsertPos(Pos);472 return createCommon(RetVal, Builder, Ctx);473}474 475Value *ReturnInst::getReturnValue() const {476 auto *LLVMRetVal = cast<llvm::ReturnInst>(Val)->getReturnValue();477 return LLVMRetVal != nullptr ? Ctx.getValue(LLVMRetVal) : nullptr;478}479 480FunctionType *CallBase::getFunctionType() const {481 return cast<FunctionType>(482 Ctx.getType(cast<llvm::CallBase>(Val)->getFunctionType()));483}484 485Value *CallBase::getCalledOperand() const {486 return Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledOperand());487}488 489Use 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 494Function *CallBase::getCalledFunction() const {495 return cast_or_null<Function>(496 Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledFunction()));497}498Function *CallBase::getCaller() {499 return cast<Function>(Ctx.getValue(cast<llvm::CallBase>(Val)->getCaller()));500}501 502void CallBase::setCalledFunction(Function *F) {503 // F's function type is private, so we rely on `setCalledFunction()` to update504 // it. But even though we are calling `setCalledFunction()` we also need to505 // track this change at the SandboxIR level, which is why we call506 // `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 515CallInst *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 528InvokeInst *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 544BasicBlock *InvokeInst::getNormalDest() const {545 return cast<BasicBlock>(546 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getNormalDest()));547}548BasicBlock *InvokeInst::getUnwindDest() const {549 return cast<BasicBlock>(550 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getUnwindDest()));551}552void InvokeInst::setNormalDest(BasicBlock *BB) {553 setOperand(1, BB);554 assert(getNormalDest() == BB && "LLVM IR uses a different operan index!");555}556void InvokeInst::setUnwindDest(BasicBlock *BB) {557 setOperand(2, BB);558 assert(getUnwindDest() == BB && "LLVM IR uses a different operan index!");559}560LandingPadInst *InvokeInst::getLandingPadInst() const {561 return cast<LandingPadInst>(562 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getLandingPadInst()));563 ;564}565BasicBlock *InvokeInst::getSuccessor(unsigned SuccIdx) const {566 return cast<BasicBlock>(567 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getSuccessor(SuccIdx)));568}569 570CallBrInst *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 593Value *CallBrInst::getIndirectDestLabel(unsigned Idx) const {594 return Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDestLabel(Idx));595}596Value *CallBrInst::getIndirectDestLabelUse(unsigned Idx) const {597 return Ctx.getValue(598 cast<llvm::CallBrInst>(Val)->getIndirectDestLabelUse(Idx));599}600BasicBlock *CallBrInst::getDefaultDest() const {601 return cast<BasicBlock>(602 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getDefaultDest()));603}604BasicBlock *CallBrInst::getIndirectDest(unsigned Idx) const {605 return cast<BasicBlock>(606 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDest(Idx)));607}608llvm::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}615void 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}621void 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}629BasicBlock *CallBrInst::getSuccessor(unsigned Idx) const {630 return cast<BasicBlock>(631 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getSuccessor(Idx)));632}633 634LandingPadInst *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 643void 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 650Constant *LandingPadInst::getClause(unsigned Idx) const {651 return cast<Constant>(652 Ctx.getValue(cast<llvm::LandingPadInst>(Val)->getClause(Idx)));653}654 655Value *FuncletPadInst::getParentPad() const {656 return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getParentPad());657}658 659void 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 666Value *FuncletPadInst::getArgOperand(unsigned Idx) const {667 return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getArgOperand(Idx));668}669 670void 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 678CatchSwitchInst *CatchPadInst::getCatchSwitch() const {679 return cast<CatchSwitchInst>(680 Ctx.getValue(cast<llvm::CatchPadInst>(Val)->getCatchSwitch()));681}682 683CatchPadInst *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 696CleanupPadInst *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 709CatchReturnInst *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 717CatchPadInst *CatchReturnInst::getCatchPad() const {718 return cast<CatchPadInst>(719 Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getCatchPad()));720}721 722void 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 730BasicBlock *CatchReturnInst::getSuccessor() const {731 return cast<BasicBlock>(732 Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getSuccessor()));733}734 735void 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 743Value *CatchReturnInst::getCatchSwitchParentPad() const {744 return Ctx.getValue(745 cast<llvm::CatchReturnInst>(Val)->getCatchSwitchParentPad());746}747 748CleanupReturnInst *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 759CleanupPadInst *CleanupReturnInst::getCleanupPad() const {760 return cast<CleanupPadInst>(761 Ctx.getValue(cast<llvm::CleanupReturnInst>(Val)->getCleanupPad()));762}763 764void 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 773BasicBlock *CleanupReturnInst::getUnwindDest() const {774 return cast_or_null<BasicBlock>(775 Ctx.getValue(cast<llvm::CleanupReturnInst>(Val)->getUnwindDest()));776}777 778void 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 787Value *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 803Type *GetElementPtrInst::getSourceElementType() const {804 return Ctx.getType(805 cast<llvm::GetElementPtrInst>(Val)->getSourceElementType());806}807 808Type *GetElementPtrInst::getResultElementType() const {809 return Ctx.getType(810 cast<llvm::GetElementPtrInst>(Val)->getResultElementType());811}812 813Value *GetElementPtrInst::getPointerOperand() const {814 return Ctx.getValue(cast<llvm::GetElementPtrInst>(Val)->getPointerOperand());815}816 817Type *GetElementPtrInst::getPointerOperandType() const {818 return Ctx.getType(819 cast<llvm::GetElementPtrInst>(Val)->getPointerOperandType());820}821 822BasicBlock *PHINode::LLVMBBToBB::operator()(llvm::BasicBlock *LLVMBB) const {823 return cast<BasicBlock>(Ctx.getValue(LLVMBB));824}825 826PHINode *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 834bool PHINode::classof(const Value *From) {835 return From->getSubclassID() == ClassID::PHI;836}837 838Value *PHINode::getIncomingValue(unsigned Idx) const {839 return Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingValue(Idx));840}841void 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}848BasicBlock *PHINode::getIncomingBlock(unsigned Idx) const {849 return cast<BasicBlock>(850 Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingBlock(Idx)));851}852BasicBlock *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}857void 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}868void 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}875Value *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}883Value *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}893int PHINode::getBasicBlockIndex(const BasicBlock *BB) const {894 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);895 return cast<llvm::PHINode>(Val)->getBasicBlockIndex(LLVMBB);896}897Value *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}903Value *PHINode::hasConstantValue() const {904 llvm::Value *LLVMV = cast<llvm::PHINode>(Val)->hasConstantValue();905 return LLVMV != nullptr ? Ctx.getValue(LLVMV) : nullptr;906}907void 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}914void PHINode::removeIncomingValueIf(function_ref<bool(unsigned)> Predicate) {915 // Avoid duplicate tracking by going through this->removeIncomingValue here at916 // the expense of some performance. Copy PHI::removeIncomingValueIf more917 // directly if performance becomes an issue.918 919 // Removing the element at index X, moves the element previously at X + 1920 // 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 929Value *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 941Value *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 951Type *CmpInst::makeCmpResultType(Type *OpndType) {952 if (auto *VT = dyn_cast<VectorType>(OpndType)) {953 // TODO: Cleanup when we have more complete support for954 // sandboxir::VectorType955 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 962void 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 969void CmpInst::swapOperands() {970 if (ICmpInst *IC = dyn_cast<ICmpInst>(this))971 IC->swapOperands();972 else973 cast<FCmpInst>(this)->swapOperands();974}975 976void ICmpInst::swapOperands() {977 Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);978 cast<llvm::ICmpInst>(Val)->swapOperands();979}980 981void FCmpInst::swapOperands() {982 Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);983 cast<llvm::FCmpInst>(Val)->swapOperands();984}985 986#ifndef NDEBUG987void CmpInst::dumpOS(raw_ostream &OS) const {988 dumpCommonPrefix(OS);989 dumpCommonSuffix(OS);990}991 992void CmpInst::dump() const {993 dumpOS(dbgs());994 dbgs() << "\n";995}996#endif // NDEBUG997 998static 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::PtrToAddr:1011 return static_cast<llvm::Instruction::CastOps>(1012 llvm::Instruction::PtrToAddr);1013 case Instruction::Opcode::PtrToInt:1014 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::PtrToInt);1015 case Instruction::Opcode::IntToPtr:1016 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::IntToPtr);1017 case Instruction::Opcode::SIToFP:1018 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SIToFP);1019 case Instruction::Opcode::UIToFP:1020 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::UIToFP);1021 case Instruction::Opcode::Trunc:1022 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::Trunc);1023 case Instruction::Opcode::FPTrunc:1024 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPTrunc);1025 case Instruction::Opcode::BitCast:1026 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::BitCast);1027 case Instruction::Opcode::AddrSpaceCast:1028 return static_cast<llvm::Instruction::CastOps>(1029 llvm::Instruction::AddrSpaceCast);1030 default:1031 llvm_unreachable("Opcode not suitable for CastInst!");1032 }1033}1034 1035/// \Returns the LLVM opcode that corresponds to \p Opc.1036static llvm::Instruction::UnaryOps getLLVMUnaryOp(Instruction::Opcode Opc) {1037 switch (Opc) {1038 case Instruction::Opcode::FNeg:1039 return static_cast<llvm::Instruction::UnaryOps>(llvm::Instruction::FNeg);1040 default:1041 llvm_unreachable("Not a unary op!");1042 }1043}1044 1045CatchSwitchInst *CatchSwitchInst::create(Value *ParentPad, BasicBlock *UnwindBB,1046 unsigned NumHandlers,1047 InsertPosition Pos, Context &Ctx,1048 const Twine &Name) {1049 auto &Builder = setInsertPos(Pos);1050 llvm::CatchSwitchInst *LLVMCSI = Builder.CreateCatchSwitch(1051 ParentPad->Val, cast<llvm::BasicBlock>(UnwindBB->Val), NumHandlers, Name);1052 return Ctx.createCatchSwitchInst(LLVMCSI);1053}1054 1055Value *CatchSwitchInst::getParentPad() const {1056 return Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getParentPad());1057}1058 1059void CatchSwitchInst::setParentPad(Value *ParentPad) {1060 Ctx.getTracker()1061 .emplaceIfTracking<GenericSetter<&CatchSwitchInst::getParentPad,1062 &CatchSwitchInst::setParentPad>>(this);1063 cast<llvm::CatchSwitchInst>(Val)->setParentPad(ParentPad->Val);1064}1065 1066BasicBlock *CatchSwitchInst::getUnwindDest() const {1067 return cast_or_null<BasicBlock>(1068 Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getUnwindDest()));1069}1070 1071void CatchSwitchInst::setUnwindDest(BasicBlock *UnwindDest) {1072 Ctx.getTracker()1073 .emplaceIfTracking<GenericSetter<&CatchSwitchInst::getUnwindDest,1074 &CatchSwitchInst::setUnwindDest>>(this);1075 cast<llvm::CatchSwitchInst>(Val)->setUnwindDest(1076 cast<llvm::BasicBlock>(UnwindDest->Val));1077}1078 1079void CatchSwitchInst::addHandler(BasicBlock *Dest) {1080 Ctx.getTracker().emplaceIfTracking<CatchSwitchAddHandler>(this);1081 cast<llvm::CatchSwitchInst>(Val)->addHandler(1082 cast<llvm::BasicBlock>(Dest->Val));1083}1084 1085ResumeInst *ResumeInst::create(Value *Exn, InsertPosition Pos, Context &Ctx) {1086 auto &Builder = setInsertPos(Pos);1087 auto *LLVMI = cast<llvm::ResumeInst>(Builder.CreateResume(Exn->Val));1088 return Ctx.createResumeInst(LLVMI);1089}1090 1091Value *ResumeInst::getValue() const {1092 return Ctx.getValue(cast<llvm::ResumeInst>(Val)->getValue());1093}1094 1095SwitchInst *SwitchInst::create(Value *V, BasicBlock *Dest, unsigned NumCases,1096 InsertPosition Pos, Context &Ctx,1097 const Twine &Name) {1098 auto &Builder = setInsertPos(Pos);1099 llvm::SwitchInst *LLVMSwitch =1100 Builder.CreateSwitch(V->Val, cast<llvm::BasicBlock>(Dest->Val), NumCases);1101 return Ctx.createSwitchInst(LLVMSwitch);1102}1103 1104Value *SwitchInst::getCondition() const {1105 return Ctx.getValue(cast<llvm::SwitchInst>(Val)->getCondition());1106}1107 1108void SwitchInst::setCondition(Value *V) {1109 Ctx.getTracker()1110 .emplaceIfTracking<1111 GenericSetter<&SwitchInst::getCondition, &SwitchInst::setCondition>>(1112 this);1113 cast<llvm::SwitchInst>(Val)->setCondition(V->Val);1114}1115 1116BasicBlock *SwitchInst::getDefaultDest() const {1117 return cast<BasicBlock>(1118 Ctx.getValue(cast<llvm::SwitchInst>(Val)->getDefaultDest()));1119}1120 1121void SwitchInst::setDefaultDest(BasicBlock *DefaultCase) {1122 Ctx.getTracker()1123 .emplaceIfTracking<GenericSetter<&SwitchInst::getDefaultDest,1124 &SwitchInst::setDefaultDest>>(this);1125 cast<llvm::SwitchInst>(Val)->setDefaultDest(1126 cast<llvm::BasicBlock>(DefaultCase->Val));1127}1128 1129template <typename LLVMCaseItT, typename BlockT, typename ConstT>1130ConstT *1131SwitchInst::CaseHandleImpl<LLVMCaseItT, BlockT, ConstT>::getCaseValue() const {1132 const auto &LLVMCaseHandle = *LLVMCaseIt;1133 auto *LLVMC = Ctx.getValue(LLVMCaseHandle.getCaseValue());1134 return cast<ConstT>(LLVMC);1135}1136 1137template <typename LLVMCaseItT, typename BlockT, typename ConstT>1138BlockT *1139SwitchInst::CaseHandleImpl<LLVMCaseItT, BlockT, ConstT>::getCaseSuccessor()1140 const {1141 const auto &LLVMCaseHandle = *LLVMCaseIt;1142 auto *LLVMBB = LLVMCaseHandle.getCaseSuccessor();1143 return cast<BlockT>(Ctx.getValue(LLVMBB));1144}1145 1146template class SwitchInst::CaseHandleImpl<llvm::SwitchInst::CaseIt, BasicBlock,1147 ConstantInt>;1148template class SwitchInst::CaseItImpl<llvm::SwitchInst::CaseIt, BasicBlock,1149 ConstantInt>;1150template class SwitchInst::CaseHandleImpl<llvm::SwitchInst::ConstCaseIt,1151 const BasicBlock, const ConstantInt>;1152template class SwitchInst::CaseItImpl<llvm::SwitchInst::ConstCaseIt,1153 const BasicBlock, const ConstantInt>;1154 1155ConstantInt *SwitchInst::findCaseDest(BasicBlock *BB) {1156 auto *LLVMC = cast<llvm::SwitchInst>(Val)->findCaseDest(1157 cast<llvm::BasicBlock>(BB->Val));1158 return LLVMC != nullptr ? cast<ConstantInt>(Ctx.getValue(LLVMC)) : nullptr;1159}1160 1161void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {1162 Ctx.getTracker().emplaceIfTracking<SwitchAddCase>(this, OnVal);1163 // TODO: Track this!1164 cast<llvm::SwitchInst>(Val)->addCase(cast<llvm::ConstantInt>(OnVal->Val),1165 cast<llvm::BasicBlock>(Dest->Val));1166}1167 1168SwitchInst::CaseIt SwitchInst::removeCase(CaseIt It) {1169 Ctx.getTracker().emplaceIfTracking<SwitchRemoveCase>(this);1170 1171 auto *LLVMSwitch = cast<llvm::SwitchInst>(Val);1172 unsigned CaseNum = It - case_begin();1173 llvm::SwitchInst::CaseIt LLVMIt(LLVMSwitch, CaseNum);1174 auto LLVMCaseIt = LLVMSwitch->removeCase(LLVMIt);1175 unsigned Num = LLVMCaseIt - LLVMSwitch->case_begin();1176 return CaseIt(this, Num);1177}1178 1179BasicBlock *SwitchInst::getSuccessor(unsigned Idx) const {1180 return cast<BasicBlock>(1181 Ctx.getValue(cast<llvm::SwitchInst>(Val)->getSuccessor(Idx)));1182}1183 1184void SwitchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {1185 Ctx.getTracker()1186 .emplaceIfTracking<GenericSetterWithIdx<&SwitchInst::getSuccessor,1187 &SwitchInst::setSuccessor>>(this,1188 Idx);1189 cast<llvm::SwitchInst>(Val)->setSuccessor(1190 Idx, cast<llvm::BasicBlock>(NewSucc->Val));1191}1192 1193Value *UnaryOperator::create(Instruction::Opcode Op, Value *OpV,1194 InsertPosition Pos, Context &Ctx,1195 const Twine &Name) {1196 auto &Builder = setInsertPos(Pos);1197 auto *NewLLVMV = Builder.CreateUnOp(getLLVMUnaryOp(Op), OpV->Val, Name);1198 if (auto *NewUnOpV = dyn_cast<llvm::UnaryOperator>(NewLLVMV)) {1199 return Ctx.createUnaryOperator(NewUnOpV);1200 }1201 assert(isa<llvm::Constant>(NewLLVMV) && "Expected constant");1202 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewLLVMV));1203}1204 1205Value *UnaryOperator::createWithCopiedFlags(Instruction::Opcode Op, Value *OpV,1206 Value *CopyFrom, InsertPosition Pos,1207 Context &Ctx, const Twine &Name) {1208 auto *NewV = create(Op, OpV, Pos, Ctx, Name);1209 if (auto *UnI = dyn_cast<llvm::UnaryOperator>(NewV->Val))1210 UnI->copyIRFlags(CopyFrom->Val);1211 return NewV;1212}1213 1214/// \Returns the LLVM opcode that corresponds to \p Opc.1215static llvm::Instruction::BinaryOps getLLVMBinaryOp(Instruction::Opcode Opc) {1216 switch (Opc) {1217 case Instruction::Opcode::Add:1218 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Add);1219 case Instruction::Opcode::FAdd:1220 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FAdd);1221 case Instruction::Opcode::Sub:1222 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Sub);1223 case Instruction::Opcode::FSub:1224 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FSub);1225 case Instruction::Opcode::Mul:1226 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Mul);1227 case Instruction::Opcode::FMul:1228 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FMul);1229 case Instruction::Opcode::UDiv:1230 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::UDiv);1231 case Instruction::Opcode::SDiv:1232 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SDiv);1233 case Instruction::Opcode::FDiv:1234 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FDiv);1235 case Instruction::Opcode::URem:1236 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::URem);1237 case Instruction::Opcode::SRem:1238 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SRem);1239 case Instruction::Opcode::FRem:1240 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FRem);1241 case Instruction::Opcode::Shl:1242 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Shl);1243 case Instruction::Opcode::LShr:1244 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::LShr);1245 case Instruction::Opcode::AShr:1246 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::AShr);1247 case Instruction::Opcode::And:1248 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::And);1249 case Instruction::Opcode::Or:1250 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Or);1251 case Instruction::Opcode::Xor:1252 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Xor);1253 default:1254 llvm_unreachable("Not a binary op!");1255 }1256}1257Value *BinaryOperator::create(Instruction::Opcode Op, Value *LHS, Value *RHS,1258 InsertPosition Pos, Context &Ctx,1259 const Twine &Name) {1260 auto &Builder = setInsertPos(Pos);1261 llvm::Value *NewV =1262 Builder.CreateBinOp(getLLVMBinaryOp(Op), LHS->Val, RHS->Val, Name);1263 if (auto *NewBinOp = dyn_cast<llvm::BinaryOperator>(NewV))1264 return Ctx.createBinaryOperator(NewBinOp);1265 assert(isa<llvm::Constant>(NewV) && "Expected constant");1266 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));1267}1268 1269Value *BinaryOperator::createWithCopiedFlags(Instruction::Opcode Op, Value *LHS,1270 Value *RHS, Value *CopyFrom,1271 InsertPosition Pos, Context &Ctx,1272 const Twine &Name) {1273 1274 Value *NewV = create(Op, LHS, RHS, Pos, Ctx, Name);1275 if (auto *NewBO = dyn_cast<BinaryOperator>(NewV))1276 cast<llvm::BinaryOperator>(NewBO->Val)->copyIRFlags(CopyFrom->Val);1277 return NewV;1278}1279 1280void PossiblyDisjointInst::setIsDisjoint(bool B) {1281 Ctx.getTracker()1282 .emplaceIfTracking<GenericSetter<&PossiblyDisjointInst::isDisjoint,1283 &PossiblyDisjointInst::setIsDisjoint>>(1284 this);1285 cast<llvm::PossiblyDisjointInst>(Val)->setIsDisjoint(B);1286}1287 1288void AtomicRMWInst::setAlignment(Align Align) {1289 Ctx.getTracker()1290 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getAlign,1291 &AtomicRMWInst::setAlignment>>(this);1292 cast<llvm::AtomicRMWInst>(Val)->setAlignment(Align);1293}1294 1295void AtomicRMWInst::setVolatile(bool V) {1296 Ctx.getTracker()1297 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::isVolatile,1298 &AtomicRMWInst::setVolatile>>(this);1299 cast<llvm::AtomicRMWInst>(Val)->setVolatile(V);1300}1301 1302void AtomicRMWInst::setOrdering(AtomicOrdering Ordering) {1303 Ctx.getTracker()1304 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getOrdering,1305 &AtomicRMWInst::setOrdering>>(this);1306 cast<llvm::AtomicRMWInst>(Val)->setOrdering(Ordering);1307}1308 1309void AtomicRMWInst::setSyncScopeID(SyncScope::ID SSID) {1310 Ctx.getTracker()1311 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getSyncScopeID,1312 &AtomicRMWInst::setSyncScopeID>>(this);1313 cast<llvm::AtomicRMWInst>(Val)->setSyncScopeID(SSID);1314}1315 1316Value *AtomicRMWInst::getPointerOperand() {1317 return Ctx.getValue(cast<llvm::AtomicRMWInst>(Val)->getPointerOperand());1318}1319 1320Value *AtomicRMWInst::getValOperand() {1321 return Ctx.getValue(cast<llvm::AtomicRMWInst>(Val)->getValOperand());1322}1323 1324AtomicRMWInst *AtomicRMWInst::create(BinOp Op, Value *Ptr, Value *Val,1325 MaybeAlign Align, AtomicOrdering Ordering,1326 InsertPosition Pos, Context &Ctx,1327 SyncScope::ID SSID, const Twine &Name) {1328 auto &Builder = setInsertPos(Pos);1329 auto *LLVMAtomicRMW =1330 Builder.CreateAtomicRMW(Op, Ptr->Val, Val->Val, Align, Ordering, SSID);1331 LLVMAtomicRMW->setName(Name);1332 return Ctx.createAtomicRMWInst(LLVMAtomicRMW);1333}1334 1335void AtomicCmpXchgInst::setSyncScopeID(SyncScope::ID SSID) {1336 Ctx.getTracker()1337 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSyncScopeID,1338 &AtomicCmpXchgInst::setSyncScopeID>>(1339 this);1340 cast<llvm::AtomicCmpXchgInst>(Val)->setSyncScopeID(SSID);1341}1342 1343Value *AtomicCmpXchgInst::getPointerOperand() {1344 return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getPointerOperand());1345}1346 1347Value *AtomicCmpXchgInst::getCompareOperand() {1348 return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getCompareOperand());1349}1350 1351Value *AtomicCmpXchgInst::getNewValOperand() {1352 return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getNewValOperand());1353}1354 1355AtomicCmpXchgInst *1356AtomicCmpXchgInst::create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,1357 AtomicOrdering SuccessOrdering,1358 AtomicOrdering FailureOrdering, InsertPosition Pos,1359 Context &Ctx, SyncScope::ID SSID, const Twine &Name) {1360 auto &Builder = setInsertPos(Pos);1361 auto *LLVMAtomicCmpXchg =1362 Builder.CreateAtomicCmpXchg(Ptr->Val, Cmp->Val, New->Val, Align,1363 SuccessOrdering, FailureOrdering, SSID);1364 LLVMAtomicCmpXchg->setName(Name);1365 return Ctx.createAtomicCmpXchgInst(LLVMAtomicCmpXchg);1366}1367 1368void AtomicCmpXchgInst::setAlignment(Align Align) {1369 Ctx.getTracker()1370 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getAlign,1371 &AtomicCmpXchgInst::setAlignment>>(this);1372 cast<llvm::AtomicCmpXchgInst>(Val)->setAlignment(Align);1373}1374 1375void AtomicCmpXchgInst::setVolatile(bool V) {1376 Ctx.getTracker()1377 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isVolatile,1378 &AtomicCmpXchgInst::setVolatile>>(this);1379 cast<llvm::AtomicCmpXchgInst>(Val)->setVolatile(V);1380}1381 1382void AtomicCmpXchgInst::setWeak(bool IsWeak) {1383 Ctx.getTracker()1384 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isWeak,1385 &AtomicCmpXchgInst::setWeak>>(this);1386 cast<llvm::AtomicCmpXchgInst>(Val)->setWeak(IsWeak);1387}1388 1389void AtomicCmpXchgInst::setSuccessOrdering(AtomicOrdering Ordering) {1390 Ctx.getTracker()1391 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSuccessOrdering,1392 &AtomicCmpXchgInst::setSuccessOrdering>>(1393 this);1394 cast<llvm::AtomicCmpXchgInst>(Val)->setSuccessOrdering(Ordering);1395}1396 1397void AtomicCmpXchgInst::setFailureOrdering(AtomicOrdering Ordering) {1398 Ctx.getTracker()1399 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getFailureOrdering,1400 &AtomicCmpXchgInst::setFailureOrdering>>(1401 this);1402 cast<llvm::AtomicCmpXchgInst>(Val)->setFailureOrdering(Ordering);1403}1404 1405AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace, InsertPosition Pos,1406 Context &Ctx, Value *ArraySize,1407 const Twine &Name) {1408 auto &Builder = setInsertPos(Pos);1409 auto *NewAlloca =1410 Builder.CreateAlloca(Ty->LLVMTy, AddrSpace, ArraySize->Val, Name);1411 return Ctx.createAllocaInst(NewAlloca);1412}1413 1414Type *AllocaInst::getAllocatedType() const {1415 return Ctx.getType(cast<llvm::AllocaInst>(Val)->getAllocatedType());1416}1417 1418void AllocaInst::setAllocatedType(Type *Ty) {1419 Ctx.getTracker()1420 .emplaceIfTracking<GenericSetter<&AllocaInst::getAllocatedType,1421 &AllocaInst::setAllocatedType>>(this);1422 cast<llvm::AllocaInst>(Val)->setAllocatedType(Ty->LLVMTy);1423}1424 1425void AllocaInst::setAlignment(Align Align) {1426 Ctx.getTracker()1427 .emplaceIfTracking<1428 GenericSetter<&AllocaInst::getAlign, &AllocaInst::setAlignment>>(1429 this);1430 cast<llvm::AllocaInst>(Val)->setAlignment(Align);1431}1432 1433void AllocaInst::setUsedWithInAlloca(bool V) {1434 Ctx.getTracker()1435 .emplaceIfTracking<GenericSetter<&AllocaInst::isUsedWithInAlloca,1436 &AllocaInst::setUsedWithInAlloca>>(this);1437 cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V);1438}1439 1440Value *AllocaInst::getArraySize() {1441 return Ctx.getValue(cast<llvm::AllocaInst>(Val)->getArraySize());1442}1443 1444PointerType *AllocaInst::getType() const {1445 return cast<PointerType>(Ctx.getType(cast<llvm::AllocaInst>(Val)->getType()));1446}1447 1448Value *CastInst::create(Type *DestTy, Opcode Op, Value *Operand,1449 InsertPosition Pos, Context &Ctx, const Twine &Name) {1450 assert(getLLVMCastOp(Op) && "Opcode not suitable for CastInst!");1451 auto &Builder = setInsertPos(Pos);1452 auto *NewV =1453 Builder.CreateCast(getLLVMCastOp(Op), Operand->Val, DestTy->LLVMTy, Name);1454 if (auto *NewCI = dyn_cast<llvm::CastInst>(NewV))1455 return Ctx.createCastInst(NewCI);1456 assert(isa<llvm::Constant>(NewV) && "Expected constant");1457 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));1458}1459 1460bool CastInst::classof(const Value *From) {1461 return From->getSubclassID() == ClassID::Cast;1462}1463 1464Type *CastInst::getSrcTy() const {1465 return Ctx.getType(cast<llvm::CastInst>(Val)->getSrcTy());1466}1467 1468Type *CastInst::getDestTy() const {1469 return Ctx.getType(cast<llvm::CastInst>(Val)->getDestTy());1470}1471 1472void PossiblyNonNegInst::setNonNeg(bool B) {1473 Ctx.getTracker()1474 .emplaceIfTracking<GenericSetter<&PossiblyNonNegInst::hasNonNeg,1475 &PossiblyNonNegInst::setNonNeg>>(this);1476 cast<llvm::PossiblyNonNegInst>(Val)->setNonNeg(B);1477}1478 1479Value *InsertElementInst::create(Value *Vec, Value *NewElt, Value *Idx,1480 InsertPosition Pos, Context &Ctx,1481 const Twine &Name) {1482 auto &Builder = Instruction::setInsertPos(Pos);1483 llvm::Value *NewV =1484 Builder.CreateInsertElement(Vec->Val, NewElt->Val, Idx->Val, Name);1485 if (auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))1486 return Ctx.createInsertElementInst(NewInsert);1487 assert(isa<llvm::Constant>(NewV) && "Expected constant");1488 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));1489}1490 1491Value *ExtractElementInst::create(Value *Vec, Value *Idx, InsertPosition Pos,1492 Context &Ctx, const Twine &Name) {1493 auto &Builder = setInsertPos(Pos);1494 llvm::Value *NewV = Builder.CreateExtractElement(Vec->Val, Idx->Val, Name);1495 if (auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))1496 return Ctx.createExtractElementInst(NewExtract);1497 assert(isa<llvm::Constant>(NewV) && "Expected constant");1498 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));1499}1500 1501Value *ShuffleVectorInst::create(Value *V1, Value *V2, Value *Mask,1502 InsertPosition Pos, Context &Ctx,1503 const Twine &Name) {1504 auto &Builder = setInsertPos(Pos);1505 llvm::Value *NewV =1506 Builder.CreateShuffleVector(V1->Val, V2->Val, Mask->Val, Name);1507 if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV))1508 return Ctx.createShuffleVectorInst(NewShuffle);1509 assert(isa<llvm::Constant>(NewV) && "Expected constant");1510 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));1511}1512 1513Value *ShuffleVectorInst::create(Value *V1, Value *V2, ArrayRef<int> Mask,1514 InsertPosition Pos, Context &Ctx,1515 const Twine &Name) {1516 auto &Builder = setInsertPos(Pos);1517 llvm::Value *NewV = Builder.CreateShuffleVector(V1->Val, V2->Val, Mask, Name);1518 if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV))1519 return Ctx.createShuffleVectorInst(NewShuffle);1520 assert(isa<llvm::Constant>(NewV) && "Expected constant");1521 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));1522}1523 1524void ShuffleVectorInst::setShuffleMask(ArrayRef<int> Mask) {1525 Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this);1526 cast<llvm::ShuffleVectorInst>(Val)->setShuffleMask(Mask);1527}1528 1529VectorType *ShuffleVectorInst::getType() const {1530 return cast<VectorType>(1531 Ctx.getType(cast<llvm::ShuffleVectorInst>(Val)->getType()));1532}1533 1534void ShuffleVectorInst::commute() {1535 Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this);1536 Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(0),1537 getOperandUse(1));1538 cast<llvm::ShuffleVectorInst>(Val)->commute();1539}1540 1541Constant *ShuffleVectorInst::getShuffleMaskForBitcode() const {1542 return Ctx.getOrCreateConstant(1543 cast<llvm::ShuffleVectorInst>(Val)->getShuffleMaskForBitcode());1544}1545 1546Constant *ShuffleVectorInst::convertShuffleMaskForBitcode(ArrayRef<int> Mask,1547 Type *ResultTy) {1548 return ResultTy->getContext().getOrCreateConstant(1549 llvm::ShuffleVectorInst::convertShuffleMaskForBitcode(Mask,1550 ResultTy->LLVMTy));1551}1552 1553VectorType *ExtractElementInst::getVectorOperandType() const {1554 return cast<VectorType>(Ctx.getType(getVectorOperand()->getType()->LLVMTy));1555}1556 1557Value *ExtractValueInst::create(Value *Agg, ArrayRef<unsigned> Idxs,1558 InsertPosition Pos, Context &Ctx,1559 const Twine &Name) {1560 auto &Builder = setInsertPos(Pos);1561 llvm::Value *NewV = Builder.CreateExtractValue(Agg->Val, Idxs, Name);1562 if (auto *NewExtractValueInst = dyn_cast<llvm::ExtractValueInst>(NewV))1563 return Ctx.createExtractValueInst(NewExtractValueInst);1564 assert(isa<llvm::Constant>(NewV) && "Expected constant");1565 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));1566}1567 1568Type *ExtractValueInst::getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs) {1569 auto *LLVMTy = llvm::ExtractValueInst::getIndexedType(Agg->LLVMTy, Idxs);1570 return Agg->getContext().getType(LLVMTy);1571}1572 1573Value *InsertValueInst::create(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,1574 InsertPosition Pos, Context &Ctx,1575 const Twine &Name) {1576 auto &Builder = setInsertPos(Pos);1577 llvm::Value *NewV = Builder.CreateInsertValue(Agg->Val, Val->Val, Idxs, Name);1578 if (auto *NewInsertValueInst = dyn_cast<llvm::InsertValueInst>(NewV))1579 return Ctx.createInsertValueInst(NewInsertValueInst);1580 assert(isa<llvm::Constant>(NewV) && "Expected constant");1581 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));1582}1583 1584ConstantTokenNone *ConstantTokenNone::get(Context &Ctx) {1585 auto *LLVMC = llvm::ConstantTokenNone::get(Ctx.LLVMCtx);1586 return cast<ConstantTokenNone>(Ctx.getOrCreateConstant(LLVMC));1587}1588 1589} // namespace llvm::sandboxir1590