29 LLVMUse->swap(*OtherUse.LLVMUse);
35 if (LLVMUse ==
nullptr)
36 OS <<
"<null> LLVM Use! ";
67 assert(
Use.LLVMUse !=
nullptr &&
"Already at end!");
77 assert(LLVMUse !=
nullptr &&
"Already at end!");
78 LLVMUse = LLVMUse->getNext();
79 if (LLVMUse ==
nullptr) {
84 auto *LLVMUser = LLVMUse->getUser();
85 Use.Usr = cast_or_null<sandboxir::User>(Ctx->getValue(LLVMUser));
104 int OtherOpNo =
Other.Use.getOperandNo();
105 return ThisOpNo - OtherOpNo;
109 : SubclassID(SubclassID), Val(Val), Ctx(Ctx) {
128 bool AtEnd = UseBegin == UseEnd;
129 llvm::Use *LLVMUse = AtEnd ? nullptr : &*UseBegin;
132 : cast_or_null<sandboxir::User>(
Ctx.
getValue(&*LLVMUse->getUser()));
144 OtherVal, [&ShouldReplace,
this](
llvm::Use &LLVMUse) ->
bool {
148 Use UseToReplace(&LLVMUse, DstU,
Ctx);
149 if (!ShouldReplace(UseToReplace))
158 "Replacing with Value of different type!");
170 std::stringstream SS;
171 SS <<
"SB" <<
UID <<
".";
180 OS.indent(2) <<
"Val: ";
222 assert(isa<llvm::User>(
Val) &&
"Non-users have no operands!");
225 LLVMUse = &cast<llvm::User>(
Val)->getOperandUse(OpIdx);
227 LLVMUse = cast<llvm::User>(
Val)->op_end();
228 return Use(LLVMUse,
const_cast<User *
>(
this),
Ctx);
234 "Use not found in this SBUser's operands!");
239 switch (
From->getSubclassID()) {
240#define DEF_VALUE(ID, CLASS)
241#define DEF_USER(ID, CLASS) \
244#define DEF_INSTR(ID, OPC, CLASS) \
247#include "llvm/SandboxIR/SandboxIRValues.def"
254 assert(isa<llvm::User>(
Val) &&
"No operands!");
257 cast<llvm::User>(
Val)->setOperand(OperandIdx, Operand->
Val);
270 return cast<llvm::User>(
Val)->replaceUsesOfWith(FromV->
Val, ToV->
Val);
281 auto ItE = BB->
end();
282 assert(It != ItE &&
"Already at end!");
288 assert(Num > 0 &&
"Bad getNumOfIRInstrs()");
289 It = std::next(It, Num - 1);
295 if (It == BB->
end()) {
301 assert(Num > 0 &&
"Bad getNumOfIRInstrs()");
302 assert(std::prev(It, Num - 1) != BB->
begin() &&
"Already at begin!");
303 It = std::prev(It, Num);
312#define OPCODES(...) __VA_ARGS__
313#define DEF_INSTR(ID, OPC, CLASS) OPC
314#include "llvm/SandboxIR/SandboxIRValues.def"
321 if (Prev ==
nullptr) {
323 return &*cast<llvm::BasicBlock>(
getParent()->
Val)->begin();
332 auto *
I = cast<llvm::Instruction>(
Val);
342 auto *LLVMI = cast<llvm::Instruction>(
Val);
343 assert(LLVMI->getParent() !=
nullptr &&
"LLVM IR instr is detached!");
344 auto *NextLLVMI = LLVMI->getNextNode();
345 auto *NextI = cast_or_null<Instruction>(
Ctx.
getValue(NextLLVMI));
346 if (NextI ==
nullptr)
364 I->removeFromParent();
368 assert(
users().empty() &&
"Still connected to users, can't erase!");
369 std::unique_ptr<Value> Detached =
Ctx.
detach(
this);
374 Tracker.
track(std::make_unique<EraseFromParent>(std::move(Detached)));
379 I->removeFromParent();
383 I->dropAllReferences();
387 I->eraseFromParent();
398 auto *LLVMBB = cast<llvm::BasicBlock>(BB.
Val);
400 if (WhereIt == BB.
end()) {
408 [](
auto *I1,
auto *I2) {
return I1->comesBefore(I2); }) &&
409 "Expected program order!");
412 I->moveBefore(*LLVMBB, It);
419 [](
auto *I1,
auto *I2) {
return I1->comesBefore(I2); }) &&
420 "Expected program order!");
426 I->insertBefore(BeforeTopI);
438 if (WhereIt != BB->
end()) {
444 LLVMBeforeI =
nullptr;
445 LLVMBeforeIt = LLVMBB->
end();
452 I->insertInto(LLVMBB, LLVMBeforeIt);
465 switch (
From->getSubclassID()) {
466#define DEF_INSTR(ID, OPC, CLASS) \
469#include "llvm/SandboxIR/SandboxIRValues.def"
480 cast<llvm::Instruction>(
Val)->setHasNoUnsignedWrap(
B);
487 cast<llvm::Instruction>(
Val)->setHasNoSignedWrap(
B);
494 cast<llvm::Instruction>(
Val)->setFast(
B);
501 cast<llvm::Instruction>(
Val)->setIsExact(
B);
508 cast<llvm::Instruction>(
Val)->setHasAllowReassoc(
B);
516 cast<llvm::Instruction>(
Val)->setHasNoNaNs(
B);
524 cast<llvm::Instruction>(
Val)->setHasNoInfs(
B);
532 cast<llvm::Instruction>(
Val)->setHasNoSignedZeros(
B);
540 cast<llvm::Instruction>(
Val)->setHasAllowReciprocal(
B);
548 cast<llvm::Instruction>(
Val)->setHasAllowContract(
B);
555 cast<llvm::Instruction>(
Val)->setFastMathFlags(FMF);
562 cast<llvm::Instruction>(
Val)->copyFastMathFlags(FMF);
569 cast<llvm::Instruction>(
Val)->setHasApproxFunc(
B);
574 OS <<
"Unimplemented! Please override dump().";
583 if (
auto *NewSI = dyn_cast<llvm::SelectInst>(NewV))
585 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
595 return createCommon(
Cond, True, False,
Name, Builder,
Ctx);
601 auto *IRInsertAtEnd = cast<llvm::BasicBlock>(InsertAtEnd->
Val);
604 return createCommon(
Cond, True, False,
Name, Builder,
Ctx);
608 return From->getSubclassID() == ClassID::Select;
617 Builder.
CreateBr(cast<llvm::BasicBlock>(IfTrue->
Val));
626 Builder.
CreateBr(cast<llvm::BasicBlock>(IfTrue->
Val));
638 cast<llvm::BasicBlock>(IfFalse->
Val));
649 cast<llvm::BasicBlock>(IfFalse->
Val));
654 return From->getSubclassID() == ClassID::Br;
664 "Successor # out of range for Branch!");
665 return cast_or_null<BasicBlock>(
666 Ctx.
getValue(cast<llvm::BranchInst>(
Val)->getSuccessor(SuccIdx)));
675 return cast<BasicBlock>(Ctx.
getValue(BB));
678BranchInst::ConstLLVMBBToSBBB::operator()(
const llvm::BasicBlock *BB)
const {
679 return cast<BasicBlock>(Ctx.
getValue(BB));
686 cast<llvm::LoadInst>(
Val)->setVolatile(V);
725 return From->getSubclassID() == ClassID::Load;
736 cast<llvm::StoreInst>(
Val)->setVolatile(V);
763 auto *InsertAtEndIR = cast<llvm::BasicBlock>(InsertAtEnd->
Val);
772 return From->getSubclassID() == ClassID::Store;
801 return From->getSubclassID() == ClassID::Unreachable;
807 if (RetVal !=
nullptr)
819 return createCommon(RetVal, Builder,
Ctx);
826 return createCommon(RetVal, Builder,
Ctx);
830 auto *LLVMRetVal = cast<llvm::ReturnInst>(
Val)->getReturnValue();
831 return LLVMRetVal !=
nullptr ?
Ctx.
getValue(LLVMRetVal) :
nullptr;
839 llvm::Use *LLVMUse = &cast<llvm::CallBase>(
Val)->getCalledOperandUse();
844 return cast_or_null<Function>(
848 return cast<Function>(
Ctx.
getValue(cast<llvm::CallBase>(
Val)->getCaller()));
859 cast<llvm::CallBase>(
Val)->setCalledFunction(
F->getFunctionType(),
860 cast<llvm::Function>(
F->Val));
866 const Twine &NameStr) {
868 if (WhereIt != WhereBB->
end())
874 for (
Value *Arg : Args)
898 const Twine &NameStr) {
900 if (WhereIt != WhereBB->
end())
906 for (
Value *Arg : Args)
909 FTy, Func->Val, cast<llvm::BasicBlock>(IfNormal->
Val),
910 cast<llvm::BasicBlock>(IfException->
Val), LLVMArgs, NameStr);
918 const Twine &NameStr) {
919 return create(FTy, Func, IfNormal, IfException, Args,
928 return create(FTy, Func, IfNormal, IfException, Args, InsertAtEnd->
end(),
929 InsertAtEnd,
Ctx, NameStr);
933 return cast<BasicBlock>(
937 return cast<BasicBlock>(
949 return cast<Instruction>(
954 return cast<BasicBlock>(
955 Ctx.
getValue(cast<llvm::InvokeInst>(
Val)->getSuccessor(SuccIdx)));
963 const Twine &NameStr) {
965 if (WhereIt != WhereBB->
end())
973 LLVMIndirectDests.
push_back(cast<llvm::BasicBlock>(IndDest->Val));
977 for (
Value *Arg : Args)
981 FTy, Func->Val, cast<llvm::BasicBlock>(DefaultDest->
Val),
982 LLVMIndirectDests, LLVMArgs, NameStr);
991 const Twine &NameStr) {
992 return create(FTy, Func, DefaultDest, IndirectDests, Args,
1001 return create(FTy, Func, DefaultDest, IndirectDests, Args, InsertAtEnd->
end(),
1002 InsertAtEnd,
Ctx, NameStr);
1013 return cast<BasicBlock>(
1017 return cast<BasicBlock>(
1031 cast<llvm::CallBrInst>(
Val)->setDefaultDest(cast<llvm::BasicBlock>(BB->
Val));
1038 cast<llvm::CallBrInst>(
Val)->setIndirectDest(
Idx,
1039 cast<llvm::BasicBlock>(BB->
Val));
1042 return cast<BasicBlock>(
1050 const Twine &NameStr) {
1052 if (WhereIt != WhereBB->
end())
1061 if (
auto *NewGEP = dyn_cast<llvm::GetElementPtrInst>(NewV))
1063 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1070 const Twine &NameStr) {
1079 const Twine &NameStr) {
1081 InsertAtEnd,
Ctx, NameStr);
1089 return cast<BasicBlock>(Ctx.
getValue(LLVMBB));
1101 return From->getSubclassID() == ClassID::PHI;
1112 cast<llvm::PHINode>(
Val)->setIncomingValue(
Idx, V->Val);
1115 return cast<BasicBlock>(
1131 cast<llvm::PHINode>(
Val)->setIncomingBlock(
Idx,
1132 cast<llvm::BasicBlock>(BB->
Val));
1138 cast<llvm::PHINode>(
Val)->addIncoming(V->Val,
1139 cast<llvm::BasicBlock>(BB->
Val));
1145 cast<llvm::PHINode>(
Val)->removeIncomingValue(
Idx,
1153 auto *LLVMBB = cast<llvm::BasicBlock>(BB->
Val);
1155 cast<llvm::PHINode>(
Val)->removeIncomingValue(LLVMBB,
1160 auto *LLVMBB = cast<llvm::BasicBlock>(BB->
Val);
1161 return cast<llvm::PHINode>(
Val)->getBasicBlockIndex(LLVMBB);
1164 auto *LLVMBB = cast<llvm::BasicBlock>(BB->
Val);
1166 cast<llvm::PHINode>(
Val)->getIncomingValueForBlock(LLVMBB);
1170 llvm::Value *LLVMV = cast<llvm::PHINode>(
Val)->hasConstantValue();
1171 return LLVMV !=
nullptr ?
Ctx.
getValue(LLVMV) :
nullptr;
1174 assert(New && Old &&
"Sandbox IR PHI node got a null basic block!");
1189 if (Predicate(
Idx - 1))
1197 case Instruction::Opcode::ZExt:
1199 case Instruction::Opcode::SExt:
1201 case Instruction::Opcode::FPToUI:
1203 case Instruction::Opcode::FPToSI:
1205 case Instruction::Opcode::FPExt:
1207 case Instruction::Opcode::PtrToInt:
1209 case Instruction::Opcode::IntToPtr:
1211 case Instruction::Opcode::SIToFP:
1213 case Instruction::Opcode::UIToFP:
1215 case Instruction::Opcode::Trunc:
1217 case Instruction::Opcode::FPTrunc:
1219 case Instruction::Opcode::BitCast:
1221 case Instruction::Opcode::AddrSpaceCast:
1223 llvm::Instruction::AddrSpaceCast);
1232 case Instruction::Opcode::FNeg:
1240 unsigned NumHandlers,
1245 if (WhereIt != WhereBB->
end())
1250 ParentPad->
Val, cast<llvm::BasicBlock>(UnwindBB->
Val), NumHandlers,
Name);
1262 cast<llvm::CatchSwitchInst>(
Val)->setParentPad(ParentPad->
Val);
1266 return cast_or_null<BasicBlock>(
1267 Ctx.
getValue(cast<llvm::CatchSwitchInst>(
Val)->getUnwindDest()));
1274 cast<llvm::CatchSwitchInst>(
Val)->setUnwindDest(
1275 cast<llvm::BasicBlock>(UnwindDest->
Val));
1280 cast<llvm::CatchSwitchInst>(
Val)->addHandler(
1281 cast<llvm::BasicBlock>(Dest->
Val));
1289 if (WhereIt != WhereBB->
end())
1294 Builder.
CreateSwitch(V->Val, cast<llvm::BasicBlock>(Dest->
Val), NumCases);
1307 cast<llvm::SwitchInst>(
Val)->setCondition(V->Val);
1311 return cast<BasicBlock>(
1319 cast<llvm::SwitchInst>(
Val)->setDefaultDest(
1320 cast<llvm::BasicBlock>(DefaultCase->
Val));
1323 auto *LLVMC = cast<llvm::SwitchInst>(
Val)->findCaseDest(
1324 cast<llvm::BasicBlock>(BB->
Val));
1325 return LLVMC !=
nullptr ? cast<ConstantInt>(
Ctx.
getValue(LLVMC)) :
nullptr;
1331 cast<llvm::SwitchInst>(
Val)->addCase(cast<llvm::ConstantInt>(OnVal->
Val),
1332 cast<llvm::BasicBlock>(Dest->
Val));
1338 this, Case.getCaseValue(), Case.getCaseSuccessor());
1343 auto LLVMCaseIt =
LLVMSwitch->removeCase(LLVMIt);
1344 unsigned Num = LLVMCaseIt -
LLVMSwitch->case_begin();
1345 return CaseIt(
this, Num);
1349 return cast<BasicBlock>(
1358 cast<llvm::SwitchInst>(
Val)->setSuccessor(
1359 Idx, cast<llvm::BasicBlock>(NewSucc->
Val));
1366 if (WhereIt == WhereBB->
end())
1371 if (
auto *NewUnOpV = dyn_cast<llvm::UnaryOperator>(NewLLVMV)) {
1374 assert(isa<llvm::Constant>(NewLLVMV) &&
"Expected constant");
1396 if (
auto *UnI = dyn_cast<llvm::UnaryOperator>(NewV->Val))
1397 UnI->copyIRFlags(CopyFrom->
Val);
1420 case Instruction::Opcode::Add:
1422 case Instruction::Opcode::FAdd:
1424 case Instruction::Opcode::Sub:
1426 case Instruction::Opcode::FSub:
1428 case Instruction::Opcode::Mul:
1430 case Instruction::Opcode::FMul:
1432 case Instruction::Opcode::UDiv:
1434 case Instruction::Opcode::SDiv:
1436 case Instruction::Opcode::FDiv:
1438 case Instruction::Opcode::URem:
1440 case Instruction::Opcode::SRem:
1442 case Instruction::Opcode::FRem:
1444 case Instruction::Opcode::Shl:
1446 case Instruction::Opcode::LShr:
1448 case Instruction::Opcode::AShr:
1450 case Instruction::Opcode::And:
1452 case Instruction::Opcode::Or:
1454 case Instruction::Opcode::Xor:
1464 if (WhereIt == WhereBB->
end())
1470 if (
auto *NewBinOp = dyn_cast<llvm::BinaryOperator>(NewV))
1472 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1496 if (
auto *NewBO = dyn_cast<BinaryOperator>(NewV))
1497 cast<llvm::BinaryOperator>(NewBO->Val)->copyIRFlags(CopyFrom->
Val);
1522 cast<llvm::AtomicRMWInst>(
Val)->setAlignment(
Align);
1529 cast<llvm::AtomicRMWInst>(
Val)->setVolatile(V);
1536 cast<llvm::AtomicRMWInst>(
Val)->setOrdering(Ordering);
1543 cast<llvm::AtomicRMWInst>(
Val)->setSyncScopeID(SSID);
1560 if (WhereIt == WhereBB->
end())
1591 cast<llvm::AtomicCmpXchgInst>(
Val)->setSyncScopeID(SSID);
1613 if (WhereIt == WhereBB->
end())
1619 SuccessOrdering, FailureOrdering, SSID);
1631 return create(
Ptr, Cmp, New,
Align, SuccessOrdering, FailureOrdering,
1643 return create(
Ptr, Cmp, New,
Align, SuccessOrdering, FailureOrdering,
1644 InsertAtEnd->
end(), InsertAtEnd,
Ctx, SSID,
Name);
1651 cast<llvm::AtomicCmpXchgInst>(
Val)->setAlignment(
Align);
1658 cast<llvm::AtomicCmpXchgInst>(
Val)->setVolatile(V);
1665 cast<llvm::AtomicCmpXchgInst>(
Val)->setWeak(IsWeak);
1673 cast<llvm::AtomicCmpXchgInst>(
Val)->setSuccessOrdering(Ordering);
1681 cast<llvm::AtomicCmpXchgInst>(
Val)->setFailureOrdering(Ordering);
1688 if (WhereIt == WhereBB->
end())
1706 return create(Ty, AddrSpace, InsertAtEnd->
end(), InsertAtEnd,
Ctx, ArraySize,
1714 cast<llvm::AllocaInst>(
Val)->setAllocatedType(Ty);
1722 cast<llvm::AllocaInst>(
Val)->setAlignment(
Align);
1729 cast<llvm::AllocaInst>(
Val)->setUsedWithInAlloca(V);
1741 if (WhereIt == WhereBB->
end())
1747 if (
auto *NewCI = dyn_cast<llvm::CastInst>(NewV))
1749 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1763 return create(DestTy,
Op, Operand, InsertAtEnd->
end(), InsertAtEnd,
Ctx,
1768 return From->getSubclassID() == ClassID::Cast;
1778 if (
auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1780 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1791 if (
auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1793 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1803 if (
auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1805 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1815 if (
auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1817 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1830 auto *LLVMC = llvm::ConstantInt::get(Ty, V, IsSigned);
1836 auto *
F = cast<llvm::Function>(
Val);
1837 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
1841 auto *SBArg = cast_or_null<Argument>(Ctx.getValue(&LLVMArg));
1842 if (SBArg == nullptr)
1845 SBArg->printAsOperand(OS);
1847 [&] { OS <<
", "; });
1853 auto *LLVMF = cast<llvm::Function>(
Val);
1857 auto *BB = cast_or_null<BasicBlock>(
Ctx.
getValue(&LLVMBB));
1863 [&
OS] {
OS <<
"\n"; });
1870 return cast_or_null<Instruction>(Ctx->
getValue(&*It));
1874 std::unique_ptr<Value> Erased;
1877 auto *Val = It->second.release();
1878 Erased = std::unique_ptr<Value>(Val);
1885 assert(V->getSubclassID() != Value::ClassID::Constant &&
1886 "Can't detach a constant!");
1887 assert(V->getSubclassID() != Value::ClassID::User &&
"Can't detach a user!");
1892 assert(VPtr->getSubclassID() != Value::ClassID::User &&
1893 "Can't register a user!");
1899 if (
auto *
I = dyn_cast<Instruction>(VPtr.get()))
1902 Value *V = VPtr.get();
1903 [[maybe_unused]]
auto Pair =
1905 assert(Pair.second &&
"Already exists!");
1911 auto It = Pair.first;
1913 return It->second.get();
1915 if (
auto *
C = dyn_cast<llvm::Constant>(LLVMV)) {
1916 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C)) {
1917 It->second = std::unique_ptr<ConstantInt>(
new ConstantInt(CI, *
this));
1918 return It->second.get();
1920 if (
auto *
F = dyn_cast<llvm::Function>(LLVMV))
1921 It->second = std::unique_ptr<Function>(
new Function(
F, *
this));
1923 It->second = std::unique_ptr<Constant>(
new Constant(
C, *
this));
1924 auto *NewC = It->second.get();
1929 if (
auto *Arg = dyn_cast<llvm::Argument>(LLVMV)) {
1930 It->second = std::unique_ptr<Argument>(
new Argument(Arg, *
this));
1931 return It->second.get();
1933 if (
auto *BB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
1934 assert(isa<BlockAddress>(U) &&
1935 "This won't create a SBBB, don't call this function directly!");
1940 assert(isa<llvm::Instruction>(LLVMV) &&
"Expected Instruction");
1942 switch (cast<llvm::Instruction>(LLVMV)->
getOpcode()) {
1943 case llvm::Instruction::Select: {
1944 auto *LLVMSel = cast<llvm::SelectInst>(LLVMV);
1945 It->second = std::unique_ptr<SelectInst>(
new SelectInst(LLVMSel, *
this));
1946 return It->second.get();
1948 case llvm::Instruction::ExtractElement: {
1949 auto *LLVMIns = cast<llvm::ExtractElementInst>(LLVMV);
1950 It->second = std::unique_ptr<ExtractElementInst>(
1952 return It->second.get();
1954 case llvm::Instruction::InsertElement: {
1955 auto *LLVMIns = cast<llvm::InsertElementInst>(LLVMV);
1956 It->second = std::unique_ptr<InsertElementInst>(
1958 return It->second.get();
1960 case llvm::Instruction::Br: {
1961 auto *
LLVMBr = cast<llvm::BranchInst>(LLVMV);
1963 return It->second.get();
1965 case llvm::Instruction::Load: {
1966 auto *LLVMLd = cast<llvm::LoadInst>(LLVMV);
1967 It->second = std::unique_ptr<LoadInst>(
new LoadInst(LLVMLd, *
this));
1968 return It->second.get();
1970 case llvm::Instruction::Store: {
1971 auto *LLVMSt = cast<llvm::StoreInst>(LLVMV);
1972 It->second = std::unique_ptr<StoreInst>(
new StoreInst(LLVMSt, *
this));
1973 return It->second.get();
1975 case llvm::Instruction::Ret: {
1976 auto *
LLVMRet = cast<llvm::ReturnInst>(LLVMV);
1978 return It->second.get();
1980 case llvm::Instruction::Call: {
1981 auto *
LLVMCall = cast<llvm::CallInst>(LLVMV);
1983 return It->second.get();
1985 case llvm::Instruction::Invoke: {
1986 auto *
LLVMInvoke = cast<llvm::InvokeInst>(LLVMV);
1988 return It->second.get();
1990 case llvm::Instruction::CallBr: {
1991 auto *
LLVMCallBr = cast<llvm::CallBrInst>(LLVMV);
1993 return It->second.get();
1995 case llvm::Instruction::GetElementPtr: {
1996 auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
1997 It->second = std::unique_ptr<GetElementPtrInst>(
1999 return It->second.get();
2001 case llvm::Instruction::CatchSwitch: {
2002 auto *LLVMCatchSwitchInst = cast<llvm::CatchSwitchInst>(LLVMV);
2003 It->second = std::unique_ptr<CatchSwitchInst>(
2005 return It->second.get();
2007 case llvm::Instruction::Switch: {
2008 auto *LLVMSwitchInst = cast<llvm::SwitchInst>(LLVMV);
2010 std::unique_ptr<SwitchInst>(
new SwitchInst(LLVMSwitchInst, *
this));
2011 return It->second.get();
2013 case llvm::Instruction::FNeg: {
2014 auto *LLVMUnaryOperator = cast<llvm::UnaryOperator>(LLVMV);
2015 It->second = std::unique_ptr<UnaryOperator>(
2017 return It->second.get();
2019 case llvm::Instruction::Add:
2020 case llvm::Instruction::FAdd:
2021 case llvm::Instruction::Sub:
2022 case llvm::Instruction::FSub:
2023 case llvm::Instruction::Mul:
2024 case llvm::Instruction::FMul:
2025 case llvm::Instruction::UDiv:
2026 case llvm::Instruction::SDiv:
2027 case llvm::Instruction::FDiv:
2028 case llvm::Instruction::URem:
2029 case llvm::Instruction::SRem:
2030 case llvm::Instruction::FRem:
2031 case llvm::Instruction::Shl:
2032 case llvm::Instruction::LShr:
2033 case llvm::Instruction::AShr:
2034 case llvm::Instruction::And:
2035 case llvm::Instruction::Or:
2036 case llvm::Instruction::Xor: {
2037 auto *LLVMBinaryOperator = cast<llvm::BinaryOperator>(LLVMV);
2038 It->second = std::unique_ptr<BinaryOperator>(
2040 return It->second.get();
2042 case llvm::Instruction::AtomicRMW: {
2046 return It->second.get();
2048 case llvm::Instruction::AtomicCmpXchg: {
2050 It->second = std::unique_ptr<AtomicCmpXchgInst>(
2052 return It->second.get();
2054 case llvm::Instruction::Alloca: {
2055 auto *
LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
2057 return It->second.get();
2059 case llvm::Instruction::ZExt:
2060 case llvm::Instruction::SExt:
2061 case llvm::Instruction::FPToUI:
2062 case llvm::Instruction::FPToSI:
2063 case llvm::Instruction::FPExt:
2064 case llvm::Instruction::PtrToInt:
2065 case llvm::Instruction::IntToPtr:
2066 case llvm::Instruction::SIToFP:
2067 case llvm::Instruction::UIToFP:
2068 case llvm::Instruction::Trunc:
2069 case llvm::Instruction::FPTrunc:
2070 case llvm::Instruction::BitCast:
2071 case llvm::Instruction::AddrSpaceCast: {
2072 auto *LLVMCast = cast<llvm::CastInst>(LLVMV);
2073 It->second = std::unique_ptr<CastInst>(
new CastInst(LLVMCast, *
this));
2074 return It->second.get();
2076 case llvm::Instruction::PHI: {
2077 auto *LLVMPhi = cast<llvm::PHINode>(LLVMV);
2078 It->second = std::unique_ptr<PHINode>(
new PHINode(LLVMPhi, *
this));
2079 return It->second.get();
2081 case llvm::Instruction::Unreachable: {
2083 It->second = std::unique_ptr<UnreachableInst>(
2085 return It->second.get();
2091 It->second = std::unique_ptr<OpaqueInst>(
2092 new OpaqueInst(cast<llvm::Instruction>(LLVMV), *
this));
2093 return It->second.get();
2098 auto NewBBPtr = std::unique_ptr<BasicBlock>(
new BasicBlock(LLVMBB, *
this));
2099 auto *BB = cast<BasicBlock>(
registerValue(std::move(NewBBPtr)));
2101 BB->buildBasicBlockFromLLVMIR(LLVMBB);
2106 auto NewPtr = std::unique_ptr<SelectInst>(
new SelectInst(SI, *
this));
2114 return cast<ExtractElementInst>(
registerValue(std::move(NewPtr)));
2121 return cast<InsertElementInst>(
registerValue(std::move(NewPtr)));
2125 auto NewPtr = std::unique_ptr<BranchInst>(
new BranchInst(BI, *
this));
2130 auto NewPtr = std::unique_ptr<LoadInst>(
new LoadInst(LI, *
this));
2135 auto NewPtr = std::unique_ptr<StoreInst>(
new StoreInst(SI, *
this));
2140 auto NewPtr = std::unique_ptr<ReturnInst>(
new ReturnInst(
I, *
this));
2145 auto NewPtr = std::unique_ptr<CallInst>(
new CallInst(
I, *
this));
2150 auto NewPtr = std::unique_ptr<InvokeInst>(
new InvokeInst(
I, *
this));
2155 auto NewPtr = std::unique_ptr<CallBrInst>(
new CallBrInst(
I, *
this));
2162 return cast<UnreachableInst>(
registerValue(std::move(NewPtr)));
2169 return cast<GetElementPtrInst>(
registerValue(std::move(NewPtr)));
2172 auto NewPtr = std::unique_ptr<CatchSwitchInst>(
new CatchSwitchInst(
I, *
this));
2173 return cast<CatchSwitchInst>(
registerValue(std::move(NewPtr)));
2176 auto NewPtr = std::unique_ptr<SwitchInst>(
new SwitchInst(
I, *
this));
2180 auto NewPtr = std::unique_ptr<UnaryOperator>(
new UnaryOperator(
I, *
this));
2181 return cast<UnaryOperator>(
registerValue(std::move(NewPtr)));
2184 auto NewPtr = std::unique_ptr<BinaryOperator>(
new BinaryOperator(
I, *
this));
2185 return cast<BinaryOperator>(
registerValue(std::move(NewPtr)));
2188 auto NewPtr = std::unique_ptr<AtomicRMWInst>(
new AtomicRMWInst(
I, *
this));
2189 return cast<AtomicRMWInst>(
registerValue(std::move(NewPtr)));
2195 return cast<AtomicCmpXchgInst>(
registerValue(std::move(NewPtr)));
2198 auto NewPtr = std::unique_ptr<AllocaInst>(
new AllocaInst(
I, *
this));
2202 auto NewPtr = std::unique_ptr<CastInst>(
new CastInst(
I, *
this));
2206 auto NewPtr = std::unique_ptr<PHINode>(
new PHINode(
I, *
this));
2213 return It->second.get();
2219 auto NewFPtr = std::unique_ptr<Function>(
new Function(
F, *
this));
2220 auto *SBF = cast<Function>(
registerValue(std::move(NewFPtr)));
2222 for (
auto &Arg :
F->args())
2231 auto *BB = cast<llvm::BasicBlock>(
Val);
2232 auto *
F = BB->getParent();
2245 if (isa<llvm::BasicBlock>(
Op))
2248 if (isa<llvm::MetadataAsValue>(
Op))
2251 if (isa<llvm::InlineAsm>(
Op))
2256#if !defined(NDEBUG) && defined(SBVEC_EXPENSIVE_CHECKS)
2266 assert(V !=
nullptr &&
"No SandboxIR for BB->begin()!");
2267 auto *
I = cast<Instruction>(V);
2268 unsigned Num =
I->getNumOfIRInstrs();
2269 assert(Num >= 1u &&
"Bad getNumOfIRInstrs()");
2270 It = std::next(It, Num - 1);
2278 return cast_or_null<Instruction>(TerminatorV);
2282 auto *BB = cast<llvm::BasicBlock>(
Val);
2283 assert(!BB->empty() &&
"Empty block!");
2284 auto *SBI = cast<Instruction>(
getContext().getValue(&*BB->begin()));
2285 assert(SBI !=
nullptr &&
"Expected Instr!");
2290 auto *BB = cast<llvm::BasicBlock>(
Val);
2291 assert(!BB->empty() &&
"Empty block!");
2292 auto *SBI = cast<Instruction>(
getContext().getValue(&*BB->rbegin()));
2293 assert(SBI !=
nullptr &&
"Expected Instr!");
2309 OS <<
"<Crash-proof mode!>\n";
2314 OS << IRef <<
" *** No SandboxIR ***\n";
2316 auto *SBI = dyn_cast<Instruction>(SBV);
2317 if (SBI ==
nullptr) {
2318 OS << IRef <<
" *** Not a SBInstruction!!! ***\n";
2320 if (Visited.
insert(SBI).second)
2326 for (
auto &SBI : *
this) {
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
ppc ctr loops PowerPC CTR Loops Verify
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static llvm::Instruction::CastOps getLLVMCastOp(Instruction::Opcode Opc)
static llvm::Instruction::UnaryOps getLLVMUnaryOp(Instruction::Opcode Opc)
\Returns the LLVM opcode that corresponds to Opc.
static llvm::Instruction::BinaryOps getLLVMBinaryOp(Instruction::Opcode Opc)
\Returns the LLVM opcode that corresponds to Opc.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
an instruction to allocate memory on the stack
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
InstListType::iterator iterator
Instruction iterators...
Conditional or Unconditional Branch instruction.
CallBr instruction, tracking function calls that may not return control but instead transfer it to a ...
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
This class represents an Operation in the Expression.
Implements a dense probed hash-table based set.
Convenience struct for specifying and reasoning about fast-math flags.
Class to represent function types.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
CallBrInst * CreateCallBr(FunctionType *Ty, Value *Callee, BasicBlock *DefaultDest, ArrayRef< BasicBlock * > IndirectDests, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="")
Create a callbr instruction.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
AtomicCmpXchgInst * CreateAtomicCmpXchg(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SyncScope::ID SSID=SyncScope::System)
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
UnreachableInst * CreateUnreachable()
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
InvokeInst * CreateInvoke(FunctionType *Ty, Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef< Value * > Args, ArrayRef< OperandBundleDef > OpBundles, const Twine &Name="")
Create an invoke instruction.
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
CatchSwitchInst * CreateCatchSwitch(Value *ParentPad, BasicBlock *UnwindBB, unsigned NumHandlers, const Twine &Name="")
Value * CreateUnOp(Instruction::UnaryOps Opc, Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)
SwitchInst * CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases=10, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a switch instruction with the specified value, default dest, and with a hint for the number of...
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
ReturnInst * CreateRetVoid()
Create a 'ret void' instruction.
AtomicRMWInst * CreateAtomicRMW(AtomicRMWInst::BinOp Op, Value *Ptr, Value *Val, MaybeAlign Align, AtomicOrdering Ordering, SyncScope::ID SSID=SyncScope::System)
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
BranchInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
This instruction inserts a single (scalar) element into a VectorType value.
const char * getOpcodeName() const
An instruction for reading from memory.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
Return a value (possibly void), from a function.
This class represents the LLVM 'select' instruction.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
LLVM Value Representation.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
void replaceUsesWithIf(Value *New, llvm::function_ref< bool(Use &U)> ShouldReplace)
Go through the uses list for this definition and make each use point to "V" if the callback ShouldRep...
StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
An efficient, type-erasing, non-owning reference to a callable.
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
This class implements an extremely fast bulk output stream that can only output to a stream.
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
Value * getArraySize()
Get the number of elements allocated.
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
void setAlignment(Align Align)
void setUsedWithInAlloca(bool V)
Specify whether this alloca is used to represent the arguments to a call.
static AllocaInst * create(Type *Ty, unsigned AddrSpace, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, Value *ArraySize=nullptr, const Twine &Name="")
void setAllocatedType(Type *Ty)
for use only in special circumstances that need to generically transform a whole instruction (eg: IR ...
Argument of a sandboxir::Function.
void dumpOS(raw_ostream &OS) const final
void printAsOperand(raw_ostream &OS) const
void setSyncScopeID(SyncScope::ID SSID)
void setVolatile(bool V)
Specify whether this is a volatile cmpxchg.
Value * getCompareOperand()
void setAlignment(Align Align)
Value * getPointerOperand()
void setSuccessOrdering(AtomicOrdering Ordering)
Value * getNewValOperand()
static AtomicCmpXchgInst * create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, SyncScope::ID SSID=SyncScope::System, const Twine &Name="")
AtomicOrdering getFailureOrdering() const
void setWeak(bool IsWeak)
bool isVolatile() const
Return true if this is a cmpxchg from a volatile memory location.
AtomicOrdering getSuccessOrdering() const
void setFailureOrdering(AtomicOrdering Ordering)
SyncScope::ID getSyncScopeID() const
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
bool isWeak() const
Return true if this cmpxchg may spuriously fail.
Value * getPointerOperand()
static AtomicRMWInst * create(BinOp Op, Value *Ptr, Value *Val, MaybeAlign Align, AtomicOrdering Ordering, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, SyncScope::ID SSID=SyncScope::System, const Twine &Name="")
SyncScope::ID getSyncScopeID() const
void setAlignment(Align Align)
void setSyncScopeID(SyncScope::ID SSID)
void setOrdering(AtomicOrdering Ordering)
AtomicOrdering getOrdering() const
Iterator for Instructions in a `BasicBlock.
BBIterator & operator++()
BBIterator & operator--()
Contains a list of sandboxir::Instruction's.
void dumpOS(raw_ostream &OS) const final
void verify() const final
Should crash if there is something wrong with the instruction.
Function * getParent() const
Instruction & front() const
Instruction * getTerminator() const
Context & getContext() const
Instruction & back() const
static Value * create(Instruction::Opcode Op, Value *LHS, Value *RHS, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
static Value * createWithCopiedFlags(Instruction::Opcode Op, Value *LHS, Value *RHS, Value *CopyFrom, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
unsigned getNumSuccessors() const
static bool classof(const Value *From)
For isa/dyn_cast.
bool isConditional() const
void setSuccessor(unsigned Idx, BasicBlock *NewSucc)
BasicBlock * getSuccessor(unsigned SuccIdx) const
static BranchInst * create(BasicBlock *IfTrue, Instruction *InsertBefore, Context &Ctx)
Value * getCondition() const
void setCalledFunction(Function *F)
Function * getCalledFunction() const
void setCalledOperand(Value *V)
Value * getCalledOperand() const
Use getCalledOperandUse() const
static CallBrInst * create(FunctionType *FTy, Value *Func, BasicBlock *DefaultDest, ArrayRef< BasicBlock * > IndirectDests, ArrayRef< Value * > Args, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &NameStr="")
BasicBlock * getIndirectDest(unsigned Idx) const
void setDefaultDest(BasicBlock *BB)
Value * getIndirectDestLabel(unsigned Idx) const
Value * getIndirectDestLabelUse(unsigned Idx) const
SmallVector< BasicBlock *, 16 > getIndirectDests() const
BasicBlock * getDefaultDest() const
BasicBlock * getSuccessor(unsigned Idx) const
void setIndirectDest(unsigned Idx, BasicBlock *BB)
static CallInst * create(FunctionType *FTy, Value *Func, ArrayRef< Value * > Args, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &NameStr="")
static Value * create(Type *DestTy, Opcode Op, Value *Operand, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
static bool classof(const Value *From)
For isa/dyn_cast.
void setParentPad(Value *ParentPad)
static CatchSwitchInst * create(Value *ParentPad, BasicBlock *UnwindBB, unsigned NumHandlers, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
void addHandler(BasicBlock *Dest)
Value * getParentPad() const
void setUnwindDest(BasicBlock *UnwindDest)
BasicBlock * getUnwindDest() const
static ConstantInt * get(Type *Ty, uint64_t V, Context &Ctx, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
void dumpOS(raw_ostream &OS) const override
CallBrInst * createCallBrInst(llvm::CallBrInst *I)
GetElementPtrInst * createGetElementPtrInst(llvm::GetElementPtrInst *I)
DenseMap< llvm::Value *, std::unique_ptr< sandboxir::Value > > LLVMValueToValueMap
Maps LLVM Value to the corresponding sandboxir::Value.
Value * registerValue(std::unique_ptr< Value > &&VPtr)
Take ownership of VPtr and store it in LLVMValueToValueMap.
sandboxir::Value * getValue(llvm::Value *V) const
Argument * getOrCreateArgument(llvm::Argument *LLVMArg)
Get or create a sandboxir::Argument for an existing LLVM IR LLVMArg.
Function * createFunction(llvm::Function *F)
Create a sandboxir::Function for an existing LLVM IR F, including all blocks and instructions.
Value * getOrCreateValueInternal(llvm::Value *V, llvm::User *U=nullptr)
This is the actual function that creates sandboxir values for V, and among others handles all instruc...
friend ExtractElementInst
auto & getLLVMIRBuilder()
std::unique_ptr< Value > detach(Value *V)
Remove SBV from all SandboxIR maps and stop owning it.
SwitchInst * createSwitchInst(llvm::SwitchInst *I)
UnreachableInst * createUnreachableInst(llvm::UnreachableInst *UI)
BranchInst * createBranchInst(llvm::BranchInst *I)
Constant * getOrCreateConstant(llvm::Constant *LLVMC)
Get or create a sandboxir::Constant from an existing LLVM IR LLVMC.
BasicBlock * createBasicBlock(llvm::BasicBlock *BB)
Create a sandboxir::BasicBlock for an existing LLVM IR BB.
UnaryOperator * createUnaryOperator(llvm::UnaryOperator *I)
ExtractElementInst * createExtractElementInst(llvm::ExtractElementInst *EEI)
LoadInst * createLoadInst(llvm::LoadInst *LI)
AllocaInst * createAllocaInst(llvm::AllocaInst *I)
CallInst * createCallInst(llvm::CallInst *I)
AtomicRMWInst * createAtomicRMWInst(llvm::AtomicRMWInst *I)
std::unique_ptr< Value > detachLLVMValue(llvm::Value *V)
Remove V from the maps and returns the unique_ptr.
StoreInst * createStoreInst(llvm::StoreInst *SI)
Value * getOrCreateValue(llvm::Value *LLVMV)
Get or create a sandboxir::Value for an existing LLVM IR LLVMV.
InsertElementInst * createInsertElementInst(llvm::InsertElementInst *IEI)
AtomicCmpXchgInst * createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I)
CatchSwitchInst * createCatchSwitchInst(llvm::CatchSwitchInst *I)
ReturnInst * createReturnInst(llvm::ReturnInst *I)
PHINode * createPHINode(llvm::PHINode *I)
SelectInst * createSelectInst(llvm::SelectInst *SI)
CastInst * createCastInst(llvm::CastInst *I)
BinaryOperator * createBinaryOperator(llvm::BinaryOperator *I)
friend class BasicBlock
Various leaf nodes.
InvokeInst * createInvokeInst(llvm::InvokeInst *I)
size_t getNumValues() const
\Returns the number of values registered with Context.
static Value * create(Value *Vec, Value *Idx, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
void dumpNameAndArgs(raw_ostream &OS) const
void dumpOS(raw_ostream &OS) const final
Similar to GenericSetter but the setters/getters have an index as their first argument.
This class can be used for tracking most instruction setters.
Value * getPointerOperand() const
static Value * create(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &NameStr="")
static Value * create(Value *Vec, Value *NewElt, Value *Idx, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...
bool hasNoUnsignedWrap() const
Determine whether the no signed wrap flag is set.
BBIterator getIterator() const
\Returns a BasicBlock::iterator for this Instruction.
void removeFromParent()
Detach this from its parent BasicBlock without deleting it.
bool hasAllowReassoc() const
Determine whether the allow-reassociation flag is set.
virtual unsigned getNumOfIRInstrs() const =0
This is used by BasicBlock::iterator.
bool hasNoSignedZeros() const
Determine whether the no-signed-zeros flag is set.
void copyFastMathFlags(FastMathFlags FMF)
Convenience function for transferring all fast-math flag values to this instruction,...
void setHasNoSignedZeros(bool B)
Set or clear the no-signed-zeros flag on this instruction, which must be an operator which supports t...
static bool classof(const sandboxir::Value *From)
For isa/dyn_cast.
bool hasAllowContract() const
Determine whether the allow-contract flag is set.
void setHasAllowContract(bool B)
Set or clear the allow-contract flag on this instruction, which must be an operator which supports th...
void setIsExact(bool B=true)
Set or clear the exact flag on this instruction, which must be an operator which supports this flag.
bool hasApproxFunc() const
Determine whether the approximate-math-functions flag is set.
bool hasNoSignedWrap() const
Determine whether the no signed wrap flag is set.
void setHasNoNaNs(bool B)
Set or clear the no-nans flag on this instruction, which must be an operator which supports this flag...
void insertInto(BasicBlock *BB, const BBIterator &WhereIt)
Insert this detached instruction into BB at WhereIt.
void setHasApproxFunc(bool B)
Set or clear the approximate-math-functions flag on this instruction, which must be an operator which...
void setHasAllowReassoc(bool B)
Set or clear the reassociation flag on this instruction, which must be an operator which supports thi...
void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
void eraseFromParent()
Detach this Value from its parent and delete it.
Instruction * getNextNode() const
\Returns the next sandboxir::Instruction in the block, or nullptr if at the end of the block.
void moveBefore(BasicBlock &BB, const BBIterator &WhereIt)
Move this instruction to WhereIt.
llvm::Instruction * getTopmostLLVMInstruction() const
A SandboxIR Instruction may map to multiple LLVM IR Instruction.
void setHasNoInfs(bool B)
Set or clear the no-infs flag on this instruction, which must be an operator which supports this flag...
void insertAfter(Instruction *AfterI)
Insert this detached instruction after AfterI.
virtual SmallVector< llvm::Instruction *, 1 > getLLVMInstrs() const =0
\Returns the LLVM IR Instructions that this SandboxIR maps to in program order.
void dumpOS(raw_ostream &OS) const override
Instruction * getPrevNode() const
\Returns the previous sandboxir::Instruction in the block, or nullptr if at the beginning of the bloc...
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
void setHasNoSignedWrap(bool B=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
void setHasAllowReciprocal(bool B)
Set or clear the allow-reciprocal flag on this instruction, which must be an operator which supports ...
bool hasAllowReciprocal() const
Determine whether the allow-reciprocal flag is set.
void setFast(bool B)
Set or clear all fast-math-flags on this instruction, which must be an operator which supports this f...
void setHasNoUnsignedWrap(bool B=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
void insertBefore(Instruction *BeforeI)
Insert this detached instruction before BeforeI.
BasicBlock * getParent() const
\Returns the BasicBlock containing this Instruction, or null if it is detached.
Instruction * getLandingPadInst() const
BasicBlock * getSuccessor(unsigned SuccIdx) const
void setNormalDest(BasicBlock *BB)
static InvokeInst * create(FunctionType *FTy, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value * > Args, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &NameStr="")
void setUnwindDest(BasicBlock *BB)
BasicBlock * getNormalDest() const
BasicBlock * getUnwindDest() const
static bool classof(const Value *From)
For isa/dyn_cast.
static LoadInst * create(Type *Ty, Value *Ptr, MaybeAlign Align, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
void setVolatile(bool V)
Specify whether this is a volatile load or not.
Value * getPointerOperand() const
An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to an OpaqueInstr.
Iterator for the Use edges of a User's operands.
OperandUseIterator()=default
value_type operator*() const
OperandUseIterator operator+(unsigned Num) const
OperandUseIterator operator-(unsigned Num) const
OperandUseIterator & operator++()
static bool classof(const Value *From)
For isa/dyn_cast.
void setIncomingBlock(unsigned Idx, BasicBlock *BB)
void replaceIncomingBlockWith(const BasicBlock *Old, BasicBlock *New)
void setIncomingValue(unsigned Idx, Value *V)
unsigned getNumIncomingValues() const
void addIncoming(Value *V, BasicBlock *BB)
int getBasicBlockIndex(const BasicBlock *BB) const
Value * removeIncomingValue(unsigned Idx)
void removeIncomingValueIf(function_ref< bool(unsigned)> Predicate)
Value * hasConstantValue() const
Value * getIncomingValueForBlock(const BasicBlock *BB) const
BasicBlock * getIncomingBlock(unsigned Idx) const
static PHINode * create(Type *Ty, unsigned NumReservedValues, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
Value * getIncomingValue(unsigned Idx) const
Value * getReturnValue() const
\Returns null if there is no return value.
static ReturnInst * create(Value *RetVal, Instruction *InsertBefore, Context &Ctx)
static Value * create(Value *Cond, Value *True, Value *False, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
static bool classof(const Value *From)
For isa/dyn_cast.
static bool classof(const Value *From)
For isa/dyn_cast.
void setVolatile(bool V)
Specify whether this is a volatile store or not.
static StoreInst * create(Value *V, Value *Ptr, MaybeAlign Align, Instruction *InsertBefore, Context &Ctx)
Value * getPointerOperand() const
Value * getValueOperand() const
BasicBlock * getSuccessor(unsigned Idx) const
void setSuccessor(unsigned Idx, BasicBlock *NewSucc)
void setDefaultDest(BasicBlock *DefaultCase)
CaseIt case_begin()
Returns a read/write iterator that points to the first case in the SwitchInst.
void addCase(ConstantInt *OnVal, BasicBlock *Dest)
llvm::SwitchInst::CaseIteratorImpl< CaseHandle > CaseIt
BasicBlock * getDefaultDest() const
void setCondition(Value *V)
static SwitchInst * create(Value *V, BasicBlock *Dest, unsigned NumCases, BasicBlock::iterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
Value * getCondition() const
ConstantInt * findCaseDest(BasicBlock *BB)
CaseIt removeCase(CaseIt It)
This method removes the specified case and its successor from the switch instruction.
The tracker collects all the change objects and implements the main API for saving / reverting / acce...
bool isTracking() const
\Returns true if the tracker is recording changes.
void track(std::unique_ptr< IRChangeBase > &&Change)
Record Change and take ownership.
bool emplaceIfTracking(ArgsT... Args)
A convenience wrapper for track() that constructs and tracks the Change object if tracking is enabled...
static Value * create(Instruction::Opcode Op, Value *OpV, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
static Value * createWithCopiedFlags(Instruction::Opcode Op, Value *OpV, Value *CopyFrom, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
static bool classof(const Value *From)
static UnreachableInst * create(Instruction *InsertBefore, Context &Ctx)
Tracks the change of the source Value of a sandboxir::Use.
Tracks swapping a Use with another Use.
Represents a Def-use/Use-def edge in SandboxIR.
void dumpOS(raw_ostream &OS) const
unsigned getOperandNo() const
class User * getUser() const
Iterator for the Use edges of a Value's users.
UserUseIterator & operator++()
A sandboxir::User has operands.
virtual unsigned getUseOperandNo(const Use &Use) const =0
\Returns the operand index of Use.
static bool classof(const Value *From)
For isa/dyn_cast.
bool replaceUsesOfWith(Value *FromV, Value *ToV)
Replaces any operands that match FromV with ToV.
void verifyUserOfLLVMUse(const llvm::Use &Use) const
Use getOperandUseDefault(unsigned OpIdx, bool Verify) const
\Returns the Use edge that corresponds to OpIdx.
virtual void setOperand(unsigned OperandIdx, Value *Operand)
virtual Use getOperandUseInternal(unsigned OpIdx, bool Verify) const =0
\Returns the Use for the OpIdx'th operand.
virtual unsigned getNumOperands() const
Use getOperandUse(unsigned OpIdx) const
\Returns the operand edge for OpIdx.
void dumpCommonHeader(raw_ostream &OS) const final
A SandboxIR Value has users. This is the base class.
mapped_iterator< sandboxir::UserUseIterator, UseToUser > user_iterator
LLVM_DUMP_METHOD void dump() const
llvm::Value * Val
The LLVM Value that corresponds to this SandboxIR Value.
std::string getUid() const
Returns the unique id in the form 'SB<number>.' like 'SB1.'.
user_iterator user_begin()
void replaceAllUsesWith(Value *Other)
void dumpCommonFooter(raw_ostream &OS) const
virtual void dumpCommonHeader(raw_ostream &OS) const
UserUseIterator use_iterator
Context & Ctx
All values point to the context.
ClassID SubclassID
For isa/dyn_cast.
void dumpCommonSuffix(raw_ostream &OS) const
Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx)
iterator_range< user_iterator > users()
void replaceUsesWithIf(Value *OtherV, llvm::function_ref< bool(const Use &)> ShouldReplace)
unsigned getNumUses() const
\Returns the number of user edges (not necessarily to unique users).
unsigned UID
A unique ID used for forming the name (used for debugging).
virtual void dumpOS(raw_ostream &OS) const =0
iterator_range< use_iterator > uses()
void dumpCommonPrefix(raw_ostream &OS) const
void printAsOperandCommon(raw_ostream &OS) const
static const char * getSubclassIDStr(ClassID ID)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
void interleave(ForwardIterator begin, ForwardIterator end, UnaryFunctor each_fn, NullaryFunctor between_fn)
An STL-style algorithm similar to std::for_each that applies a second functor between every pair of e...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
constexpr size_t range_size(R &&Range)
Returns the size of the Range, i.e., the number of elements.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
AtomicOrdering
Atomic ordering for LLVM's memory model.
This struct is a compact representation of a valid (non-zero power of two) alignment.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Helper for mapped_iterator.