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:
1244 if (WhereIt != WhereBB->
end())
1249 Builder.
CreateSwitch(V->Val, cast<llvm::BasicBlock>(Dest->
Val), NumCases);
1262 cast<llvm::SwitchInst>(
Val)->setCondition(V->Val);
1266 return cast<BasicBlock>(
1274 cast<llvm::SwitchInst>(
Val)->setDefaultDest(
1275 cast<llvm::BasicBlock>(DefaultCase->
Val));
1278 auto *LLVMC = cast<llvm::SwitchInst>(
Val)->findCaseDest(
1279 cast<llvm::BasicBlock>(BB->
Val));
1280 return LLVMC !=
nullptr ? cast<ConstantInt>(
Ctx.
getValue(LLVMC)) :
nullptr;
1286 cast<llvm::SwitchInst>(
Val)->addCase(cast<llvm::ConstantInt>(OnVal->
Val),
1287 cast<llvm::BasicBlock>(Dest->
Val));
1293 this, Case.getCaseValue(), Case.getCaseSuccessor());
1298 auto LLVMCaseIt =
LLVMSwitch->removeCase(LLVMIt);
1299 unsigned Num = LLVMCaseIt -
LLVMSwitch->case_begin();
1300 return CaseIt(
this, Num);
1304 return cast<BasicBlock>(
1313 cast<llvm::SwitchInst>(
Val)->setSuccessor(
1314 Idx, cast<llvm::BasicBlock>(NewSucc->
Val));
1321 if (WhereIt == WhereBB->
end())
1326 if (
auto *NewUnOpV = dyn_cast<llvm::UnaryOperator>(NewLLVMV)) {
1329 assert(isa<llvm::Constant>(NewLLVMV) &&
"Expected constant");
1351 if (
auto *UnI = dyn_cast<llvm::UnaryOperator>(NewV->Val))
1352 UnI->copyIRFlags(CopyFrom->
Val);
1375 case Instruction::Opcode::Add:
1377 case Instruction::Opcode::FAdd:
1379 case Instruction::Opcode::Sub:
1381 case Instruction::Opcode::FSub:
1383 case Instruction::Opcode::Mul:
1385 case Instruction::Opcode::FMul:
1387 case Instruction::Opcode::UDiv:
1389 case Instruction::Opcode::SDiv:
1391 case Instruction::Opcode::FDiv:
1393 case Instruction::Opcode::URem:
1395 case Instruction::Opcode::SRem:
1397 case Instruction::Opcode::FRem:
1399 case Instruction::Opcode::Shl:
1401 case Instruction::Opcode::LShr:
1403 case Instruction::Opcode::AShr:
1405 case Instruction::Opcode::And:
1407 case Instruction::Opcode::Or:
1409 case Instruction::Opcode::Xor:
1419 if (WhereIt == WhereBB->
end())
1425 if (
auto *NewBinOp = dyn_cast<llvm::BinaryOperator>(NewV))
1427 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1451 if (
auto *NewBO = dyn_cast<BinaryOperator>(NewV))
1452 cast<llvm::BinaryOperator>(NewBO->Val)->copyIRFlags(CopyFrom->
Val);
1477 cast<llvm::AtomicRMWInst>(
Val)->setAlignment(
Align);
1484 cast<llvm::AtomicRMWInst>(
Val)->setVolatile(V);
1491 cast<llvm::AtomicRMWInst>(
Val)->setOrdering(Ordering);
1498 cast<llvm::AtomicRMWInst>(
Val)->setSyncScopeID(SSID);
1515 if (WhereIt == WhereBB->
end())
1546 cast<llvm::AtomicCmpXchgInst>(
Val)->setSyncScopeID(SSID);
1568 if (WhereIt == WhereBB->
end())
1574 SuccessOrdering, FailureOrdering, SSID);
1586 return create(
Ptr, Cmp, New,
Align, SuccessOrdering, FailureOrdering,
1598 return create(
Ptr, Cmp, New,
Align, SuccessOrdering, FailureOrdering,
1599 InsertAtEnd->
end(), InsertAtEnd,
Ctx, SSID,
Name);
1606 cast<llvm::AtomicCmpXchgInst>(
Val)->setAlignment(
Align);
1613 cast<llvm::AtomicCmpXchgInst>(
Val)->setVolatile(V);
1620 cast<llvm::AtomicCmpXchgInst>(
Val)->setWeak(IsWeak);
1628 cast<llvm::AtomicCmpXchgInst>(
Val)->setSuccessOrdering(Ordering);
1636 cast<llvm::AtomicCmpXchgInst>(
Val)->setFailureOrdering(Ordering);
1643 if (WhereIt == WhereBB->
end())
1661 return create(Ty, AddrSpace, InsertAtEnd->
end(), InsertAtEnd,
Ctx, ArraySize,
1669 cast<llvm::AllocaInst>(
Val)->setAllocatedType(Ty);
1677 cast<llvm::AllocaInst>(
Val)->setAlignment(
Align);
1684 cast<llvm::AllocaInst>(
Val)->setUsedWithInAlloca(V);
1696 if (WhereIt == WhereBB->
end())
1702 if (
auto *NewCI = dyn_cast<llvm::CastInst>(NewV))
1704 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1718 return create(DestTy,
Op, Operand, InsertAtEnd->
end(), InsertAtEnd,
Ctx,
1723 return From->getSubclassID() == ClassID::Cast;
1733 if (
auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1735 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1746 if (
auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1748 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1758 if (
auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1760 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1770 if (
auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1772 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1785 auto *LLVMC = llvm::ConstantInt::get(Ty, V, IsSigned);
1791 auto *
F = cast<llvm::Function>(
Val);
1792 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
1796 auto *SBArg = cast_or_null<Argument>(Ctx.getValue(&LLVMArg));
1797 if (SBArg == nullptr)
1800 SBArg->printAsOperand(OS);
1802 [&] { OS <<
", "; });
1808 auto *LLVMF = cast<llvm::Function>(
Val);
1812 auto *BB = cast_or_null<BasicBlock>(
Ctx.
getValue(&LLVMBB));
1818 [&
OS] {
OS <<
"\n"; });
1825 return cast_or_null<Instruction>(Ctx->
getValue(&*It));
1829 std::unique_ptr<Value> Erased;
1832 auto *Val = It->second.release();
1833 Erased = std::unique_ptr<Value>(Val);
1840 assert(V->getSubclassID() != Value::ClassID::Constant &&
1841 "Can't detach a constant!");
1842 assert(V->getSubclassID() != Value::ClassID::User &&
"Can't detach a user!");
1847 assert(VPtr->getSubclassID() != Value::ClassID::User &&
1848 "Can't register a user!");
1854 if (
auto *
I = dyn_cast<Instruction>(VPtr.get()))
1857 Value *V = VPtr.get();
1858 [[maybe_unused]]
auto Pair =
1860 assert(Pair.second &&
"Already exists!");
1866 auto It = Pair.first;
1868 return It->second.get();
1870 if (
auto *
C = dyn_cast<llvm::Constant>(LLVMV)) {
1871 if (
auto *CI = dyn_cast<llvm::ConstantInt>(
C)) {
1872 It->second = std::unique_ptr<ConstantInt>(
new ConstantInt(CI, *
this));
1873 return It->second.get();
1875 if (
auto *
F = dyn_cast<llvm::Function>(LLVMV))
1876 It->second = std::unique_ptr<Function>(
new Function(
F, *
this));
1878 It->second = std::unique_ptr<Constant>(
new Constant(
C, *
this));
1879 auto *NewC = It->second.get();
1884 if (
auto *Arg = dyn_cast<llvm::Argument>(LLVMV)) {
1885 It->second = std::unique_ptr<Argument>(
new Argument(Arg, *
this));
1886 return It->second.get();
1888 if (
auto *BB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
1889 assert(isa<BlockAddress>(U) &&
1890 "This won't create a SBBB, don't call this function directly!");
1895 assert(isa<llvm::Instruction>(LLVMV) &&
"Expected Instruction");
1897 switch (cast<llvm::Instruction>(LLVMV)->
getOpcode()) {
1898 case llvm::Instruction::Select: {
1899 auto *LLVMSel = cast<llvm::SelectInst>(LLVMV);
1900 It->second = std::unique_ptr<SelectInst>(
new SelectInst(LLVMSel, *
this));
1901 return It->second.get();
1903 case llvm::Instruction::ExtractElement: {
1904 auto *LLVMIns = cast<llvm::ExtractElementInst>(LLVMV);
1905 It->second = std::unique_ptr<ExtractElementInst>(
1907 return It->second.get();
1909 case llvm::Instruction::InsertElement: {
1910 auto *LLVMIns = cast<llvm::InsertElementInst>(LLVMV);
1911 It->second = std::unique_ptr<InsertElementInst>(
1913 return It->second.get();
1915 case llvm::Instruction::Br: {
1916 auto *
LLVMBr = cast<llvm::BranchInst>(LLVMV);
1918 return It->second.get();
1920 case llvm::Instruction::Load: {
1921 auto *LLVMLd = cast<llvm::LoadInst>(LLVMV);
1922 It->second = std::unique_ptr<LoadInst>(
new LoadInst(LLVMLd, *
this));
1923 return It->second.get();
1925 case llvm::Instruction::Store: {
1926 auto *LLVMSt = cast<llvm::StoreInst>(LLVMV);
1927 It->second = std::unique_ptr<StoreInst>(
new StoreInst(LLVMSt, *
this));
1928 return It->second.get();
1930 case llvm::Instruction::Ret: {
1931 auto *
LLVMRet = cast<llvm::ReturnInst>(LLVMV);
1933 return It->second.get();
1935 case llvm::Instruction::Call: {
1936 auto *
LLVMCall = cast<llvm::CallInst>(LLVMV);
1938 return It->second.get();
1940 case llvm::Instruction::Invoke: {
1941 auto *
LLVMInvoke = cast<llvm::InvokeInst>(LLVMV);
1943 return It->second.get();
1945 case llvm::Instruction::CallBr: {
1946 auto *
LLVMCallBr = cast<llvm::CallBrInst>(LLVMV);
1948 return It->second.get();
1950 case llvm::Instruction::GetElementPtr: {
1951 auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
1952 It->second = std::unique_ptr<GetElementPtrInst>(
1954 return It->second.get();
1956 case llvm::Instruction::Switch: {
1957 auto *LLVMSwitchInst = cast<llvm::SwitchInst>(LLVMV);
1959 std::unique_ptr<SwitchInst>(
new SwitchInst(LLVMSwitchInst, *
this));
1960 return It->second.get();
1962 case llvm::Instruction::FNeg: {
1963 auto *LLVMUnaryOperator = cast<llvm::UnaryOperator>(LLVMV);
1964 It->second = std::unique_ptr<UnaryOperator>(
1966 return It->second.get();
1968 case llvm::Instruction::Add:
1969 case llvm::Instruction::FAdd:
1970 case llvm::Instruction::Sub:
1971 case llvm::Instruction::FSub:
1972 case llvm::Instruction::Mul:
1973 case llvm::Instruction::FMul:
1974 case llvm::Instruction::UDiv:
1975 case llvm::Instruction::SDiv:
1976 case llvm::Instruction::FDiv:
1977 case llvm::Instruction::URem:
1978 case llvm::Instruction::SRem:
1979 case llvm::Instruction::FRem:
1980 case llvm::Instruction::Shl:
1981 case llvm::Instruction::LShr:
1982 case llvm::Instruction::AShr:
1983 case llvm::Instruction::And:
1984 case llvm::Instruction::Or:
1985 case llvm::Instruction::Xor: {
1986 auto *LLVMBinaryOperator = cast<llvm::BinaryOperator>(LLVMV);
1987 It->second = std::unique_ptr<BinaryOperator>(
1989 return It->second.get();
1991 case llvm::Instruction::AtomicRMW: {
1995 return It->second.get();
1997 case llvm::Instruction::AtomicCmpXchg: {
1999 It->second = std::unique_ptr<AtomicCmpXchgInst>(
2001 return It->second.get();
2003 case llvm::Instruction::Alloca: {
2004 auto *
LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
2006 return It->second.get();
2008 case llvm::Instruction::ZExt:
2009 case llvm::Instruction::SExt:
2010 case llvm::Instruction::FPToUI:
2011 case llvm::Instruction::FPToSI:
2012 case llvm::Instruction::FPExt:
2013 case llvm::Instruction::PtrToInt:
2014 case llvm::Instruction::IntToPtr:
2015 case llvm::Instruction::SIToFP:
2016 case llvm::Instruction::UIToFP:
2017 case llvm::Instruction::Trunc:
2018 case llvm::Instruction::FPTrunc:
2019 case llvm::Instruction::BitCast:
2020 case llvm::Instruction::AddrSpaceCast: {
2021 auto *LLVMCast = cast<llvm::CastInst>(LLVMV);
2022 It->second = std::unique_ptr<CastInst>(
new CastInst(LLVMCast, *
this));
2023 return It->second.get();
2025 case llvm::Instruction::PHI: {
2026 auto *LLVMPhi = cast<llvm::PHINode>(LLVMV);
2027 It->second = std::unique_ptr<PHINode>(
new PHINode(LLVMPhi, *
this));
2028 return It->second.get();
2030 case llvm::Instruction::Unreachable: {
2032 It->second = std::unique_ptr<UnreachableInst>(
2034 return It->second.get();
2040 It->second = std::unique_ptr<OpaqueInst>(
2041 new OpaqueInst(cast<llvm::Instruction>(LLVMV), *
this));
2042 return It->second.get();
2047 auto NewBBPtr = std::unique_ptr<BasicBlock>(
new BasicBlock(LLVMBB, *
this));
2048 auto *BB = cast<BasicBlock>(
registerValue(std::move(NewBBPtr)));
2050 BB->buildBasicBlockFromLLVMIR(LLVMBB);
2055 auto NewPtr = std::unique_ptr<SelectInst>(
new SelectInst(SI, *
this));
2063 return cast<ExtractElementInst>(
registerValue(std::move(NewPtr)));
2070 return cast<InsertElementInst>(
registerValue(std::move(NewPtr)));
2074 auto NewPtr = std::unique_ptr<BranchInst>(
new BranchInst(BI, *
this));
2079 auto NewPtr = std::unique_ptr<LoadInst>(
new LoadInst(LI, *
this));
2084 auto NewPtr = std::unique_ptr<StoreInst>(
new StoreInst(SI, *
this));
2089 auto NewPtr = std::unique_ptr<ReturnInst>(
new ReturnInst(
I, *
this));
2094 auto NewPtr = std::unique_ptr<CallInst>(
new CallInst(
I, *
this));
2099 auto NewPtr = std::unique_ptr<InvokeInst>(
new InvokeInst(
I, *
this));
2104 auto NewPtr = std::unique_ptr<CallBrInst>(
new CallBrInst(
I, *
this));
2111 return cast<UnreachableInst>(
registerValue(std::move(NewPtr)));
2118 return cast<GetElementPtrInst>(
registerValue(std::move(NewPtr)));
2121 auto NewPtr = std::unique_ptr<SwitchInst>(
new SwitchInst(
I, *
this));
2125 auto NewPtr = std::unique_ptr<UnaryOperator>(
new UnaryOperator(
I, *
this));
2126 return cast<UnaryOperator>(
registerValue(std::move(NewPtr)));
2129 auto NewPtr = std::unique_ptr<BinaryOperator>(
new BinaryOperator(
I, *
this));
2130 return cast<BinaryOperator>(
registerValue(std::move(NewPtr)));
2133 auto NewPtr = std::unique_ptr<AtomicRMWInst>(
new AtomicRMWInst(
I, *
this));
2134 return cast<AtomicRMWInst>(
registerValue(std::move(NewPtr)));
2140 return cast<AtomicCmpXchgInst>(
registerValue(std::move(NewPtr)));
2143 auto NewPtr = std::unique_ptr<AllocaInst>(
new AllocaInst(
I, *
this));
2147 auto NewPtr = std::unique_ptr<CastInst>(
new CastInst(
I, *
this));
2151 auto NewPtr = std::unique_ptr<PHINode>(
new PHINode(
I, *
this));
2158 return It->second.get();
2164 auto NewFPtr = std::unique_ptr<Function>(
new Function(
F, *
this));
2165 auto *SBF = cast<Function>(
registerValue(std::move(NewFPtr)));
2167 for (
auto &Arg :
F->args())
2176 auto *BB = cast<llvm::BasicBlock>(
Val);
2177 auto *
F = BB->getParent();
2190 if (isa<llvm::BasicBlock>(
Op))
2193 if (isa<llvm::MetadataAsValue>(
Op))
2196 if (isa<llvm::InlineAsm>(
Op))
2201#if !defined(NDEBUG) && defined(SBVEC_EXPENSIVE_CHECKS)
2211 assert(V !=
nullptr &&
"No SandboxIR for BB->begin()!");
2212 auto *
I = cast<Instruction>(V);
2213 unsigned Num =
I->getNumOfIRInstrs();
2214 assert(Num >= 1u &&
"Bad getNumOfIRInstrs()");
2215 It = std::next(It, Num - 1);
2223 return cast_or_null<Instruction>(TerminatorV);
2227 auto *BB = cast<llvm::BasicBlock>(
Val);
2228 assert(!BB->empty() &&
"Empty block!");
2229 auto *SBI = cast<Instruction>(
getContext().getValue(&*BB->begin()));
2230 assert(SBI !=
nullptr &&
"Expected Instr!");
2235 auto *BB = cast<llvm::BasicBlock>(
Val);
2236 assert(!BB->empty() &&
"Empty block!");
2237 auto *SBI = cast<Instruction>(
getContext().getValue(&*BB->rbegin()));
2238 assert(SBI !=
nullptr &&
"Expected Instr!");
2254 OS <<
"<Crash-proof mode!>\n";
2259 OS << IRef <<
" *** No SandboxIR ***\n";
2261 auto *SBI = dyn_cast<Instruction>(SBV);
2262 if (SBI ==
nullptr) {
2263 OS << IRef <<
" *** Not a SBInstruction!!! ***\n";
2265 if (Visited.
insert(SBI).second)
2271 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())
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.
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)
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.