brintos

brintos / llvm-project-archived public Read only

0
0
Text · 60.4 KiB · 9ae4c98 Raw
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