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"
477 OS <<
"Unimplemented! Please override dump().";
486 if (
auto *NewSI = dyn_cast<llvm::SelectInst>(NewV))
488 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
498 return createCommon(
Cond, True, False,
Name, Builder,
Ctx);
504 auto *IRInsertAtEnd = cast<llvm::BasicBlock>(InsertAtEnd->
Val);
507 return createCommon(
Cond, True, False,
Name, Builder,
Ctx);
511 return From->getSubclassID() == ClassID::Select;
520 Builder.
CreateBr(cast<llvm::BasicBlock>(IfTrue->
Val));
529 Builder.
CreateBr(cast<llvm::BasicBlock>(IfTrue->
Val));
541 cast<llvm::BasicBlock>(IfFalse->
Val));
552 cast<llvm::BasicBlock>(IfFalse->
Val));
557 return From->getSubclassID() == ClassID::Br;
567 "Successor # out of range for Branch!");
568 return cast_or_null<BasicBlock>(
569 Ctx.
getValue(cast<llvm::BranchInst>(
Val)->getSuccessor(SuccIdx)));
578 return cast<BasicBlock>(Ctx.
getValue(BB));
581BranchInst::ConstLLVMBBToSBBB::operator()(
const llvm::BasicBlock *BB)
const {
582 return cast<BasicBlock>(Ctx.
getValue(BB));
589 cast<llvm::LoadInst>(
Val)->setVolatile(V);
628 return From->getSubclassID() == ClassID::Load;
639 cast<llvm::StoreInst>(
Val)->setVolatile(V);
666 auto *InsertAtEndIR = cast<llvm::BasicBlock>(InsertAtEnd->
Val);
675 return From->getSubclassID() == ClassID::Store;
704 return From->getSubclassID() == ClassID::Unreachable;
710 if (RetVal !=
nullptr)
722 return createCommon(RetVal, Builder,
Ctx);
729 return createCommon(RetVal, Builder,
Ctx);
733 auto *LLVMRetVal = cast<llvm::ReturnInst>(
Val)->getReturnValue();
734 return LLVMRetVal !=
nullptr ?
Ctx.
getValue(LLVMRetVal) :
nullptr;
742 llvm::Use *LLVMUse = &cast<llvm::CallBase>(
Val)->getCalledOperandUse();
747 return cast_or_null<Function>(
751 return cast<Function>(
Ctx.
getValue(cast<llvm::CallBase>(
Val)->getCaller()));
762 cast<llvm::CallBase>(
Val)->setCalledFunction(
F->getFunctionType(),
763 cast<llvm::Function>(
F->Val));
769 const Twine &NameStr) {
771 if (WhereIt != WhereBB->
end())
777 for (
Value *Arg : Args)
801 const Twine &NameStr) {
803 if (WhereIt != WhereBB->
end())
809 for (
Value *Arg : Args)
812 FTy, Func->Val, cast<llvm::BasicBlock>(IfNormal->
Val),
813 cast<llvm::BasicBlock>(IfException->
Val), LLVMArgs, NameStr);
821 const Twine &NameStr) {
822 return create(FTy, Func, IfNormal, IfException, Args,
831 return create(FTy, Func, IfNormal, IfException, Args, InsertAtEnd->
end(),
832 InsertAtEnd,
Ctx, NameStr);
836 return cast<BasicBlock>(
840 return cast<BasicBlock>(
852 return cast<Instruction>(
857 return cast<BasicBlock>(
858 Ctx.
getValue(cast<llvm::InvokeInst>(
Val)->getSuccessor(SuccIdx)));
866 const Twine &NameStr) {
868 if (WhereIt != WhereBB->
end())
876 LLVMIndirectDests.
push_back(cast<llvm::BasicBlock>(IndDest->Val));
880 for (
Value *Arg : Args)
884 FTy, Func->Val, cast<llvm::BasicBlock>(DefaultDest->
Val),
885 LLVMIndirectDests, LLVMArgs, NameStr);
894 const Twine &NameStr) {
895 return create(FTy, Func, DefaultDest, IndirectDests, Args,
904 return create(FTy, Func, DefaultDest, IndirectDests, Args, InsertAtEnd->
end(),
905 InsertAtEnd,
Ctx, NameStr);
916 return cast<BasicBlock>(
920 return cast<BasicBlock>(
934 cast<llvm::CallBrInst>(
Val)->setDefaultDest(cast<llvm::BasicBlock>(BB->
Val));
938 cast<llvm::CallBrInst>(
Val)->setIndirectDest(
Idx,
939 cast<llvm::BasicBlock>(BB->
Val));
942 return cast<BasicBlock>(
950 const Twine &NameStr) {
952 if (WhereIt != WhereBB->
end())
961 if (
auto *NewGEP = dyn_cast<llvm::GetElementPtrInst>(NewV))
963 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
970 const Twine &NameStr) {
979 const Twine &NameStr) {
981 InsertAtEnd,
Ctx, NameStr);
989 return cast<BasicBlock>(Ctx.
getValue(LLVMBB));
1001 return From->getSubclassID() == ClassID::PHI;
1012 cast<llvm::PHINode>(
Val)->setIncomingValue(
Idx, V->Val);
1015 return cast<BasicBlock>(
1027 cast<llvm::PHINode>(
Val)->setIncomingBlock(
Idx,
1028 cast<llvm::BasicBlock>(BB->
Val));
1034 cast<llvm::PHINode>(
Val)->addIncoming(V->Val,
1035 cast<llvm::BasicBlock>(BB->
Val));
1041 cast<llvm::PHINode>(
Val)->removeIncomingValue(
Idx,
1049 auto *LLVMBB = cast<llvm::BasicBlock>(BB->
Val);
1051 cast<llvm::PHINode>(
Val)->removeIncomingValue(LLVMBB,
1056 auto *LLVMBB = cast<llvm::BasicBlock>(BB->
Val);
1057 return cast<llvm::PHINode>(
Val)->getBasicBlockIndex(LLVMBB);
1060 auto *LLVMBB = cast<llvm::BasicBlock>(BB->
Val);
1062 cast<llvm::PHINode>(
Val)->getIncomingValueForBlock(LLVMBB);
1066 llvm::Value *LLVMV = cast<llvm::PHINode>(
Val)->hasConstantValue();
1067 return LLVMV !=
nullptr ?
Ctx.
getValue(LLVMV) :
nullptr;
1070 assert(New && Old &&
"Sandbox IR PHI node got a null basic block!");
1085 if (Predicate(
Idx - 1))
1093 case Instruction::Opcode::ZExt:
1095 case Instruction::Opcode::SExt:
1097 case Instruction::Opcode::FPToUI:
1099 case Instruction::Opcode::FPToSI:
1101 case Instruction::Opcode::FPExt:
1103 case Instruction::Opcode::PtrToInt:
1105 case Instruction::Opcode::IntToPtr:
1107 case Instruction::Opcode::SIToFP:
1109 case Instruction::Opcode::UIToFP:
1111 case Instruction::Opcode::Trunc:
1113 case Instruction::Opcode::FPTrunc:
1115 case Instruction::Opcode::BitCast:
1117 case Instruction::Opcode::AddrSpaceCast:
1119 llvm::Instruction::AddrSpaceCast);
1129 if (WhereIt == WhereBB->
end())
1147 return create(Ty, AddrSpace, InsertAtEnd->
end(), InsertAtEnd,
Ctx, ArraySize,
1155 cast<llvm::AllocaInst>(
Val)->setAllocatedType(Ty);
1163 cast<llvm::AllocaInst>(
Val)->setAlignment(
Align);
1170 cast<llvm::AllocaInst>(
Val)->setUsedWithInAlloca(V);
1182 if (WhereIt == WhereBB->
end())
1188 if (
auto *NewCI = dyn_cast<llvm::CastInst>(NewV))
1190 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1204 return create(DestTy,
Op, Operand, InsertAtEnd->
end(), InsertAtEnd,
Ctx,
1209 return From->getSubclassID() == ClassID::Cast;
1219 if (
auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1221 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1232 if (
auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1234 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1244 if (
auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1246 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1256 if (
auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1258 assert(isa<llvm::Constant>(NewV) &&
"Expected constant");
1275 auto *
F = cast<llvm::Function>(
Val);
1276 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
1280 auto *SBArg = cast_or_null<Argument>(Ctx.getValue(&LLVMArg));
1281 if (SBArg == nullptr)
1284 SBArg->printAsOperand(OS);
1286 [&] { OS <<
", "; });
1292 auto *LLVMF = cast<llvm::Function>(
Val);
1296 auto *BB = cast_or_null<BasicBlock>(
Ctx.
getValue(&LLVMBB));
1302 [&
OS] {
OS <<
"\n"; });
1309 return cast_or_null<Instruction>(Ctx->
getValue(&*It));
1313 std::unique_ptr<Value> Erased;
1316 auto *Val = It->second.release();
1317 Erased = std::unique_ptr<Value>(Val);
1324 assert(V->getSubclassID() != Value::ClassID::Constant &&
1325 "Can't detach a constant!");
1326 assert(V->getSubclassID() != Value::ClassID::User &&
"Can't detach a user!");
1331 assert(VPtr->getSubclassID() != Value::ClassID::User &&
1332 "Can't register a user!");
1338 if (
auto *
I = dyn_cast<Instruction>(VPtr.get()))
1341 Value *V = VPtr.get();
1342 [[maybe_unused]]
auto Pair =
1344 assert(Pair.second &&
"Already exists!");
1350 auto It = Pair.first;
1352 return It->second.get();
1354 if (
auto *
C = dyn_cast<llvm::Constant>(LLVMV)) {
1355 if (
auto *
F = dyn_cast<llvm::Function>(LLVMV))
1356 It->second = std::unique_ptr<Function>(
new Function(
F, *
this));
1358 It->second = std::unique_ptr<Constant>(
new Constant(
C, *
this));
1359 auto *NewC = It->second.get();
1364 if (
auto *Arg = dyn_cast<llvm::Argument>(LLVMV)) {
1365 It->second = std::unique_ptr<Argument>(
new Argument(Arg, *
this));
1366 return It->second.get();
1368 if (
auto *BB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
1369 assert(isa<BlockAddress>(U) &&
1370 "This won't create a SBBB, don't call this function directly!");
1375 assert(isa<llvm::Instruction>(LLVMV) &&
"Expected Instruction");
1377 switch (cast<llvm::Instruction>(LLVMV)->
getOpcode()) {
1378 case llvm::Instruction::Select: {
1379 auto *LLVMSel = cast<llvm::SelectInst>(LLVMV);
1380 It->second = std::unique_ptr<SelectInst>(
new SelectInst(LLVMSel, *
this));
1381 return It->second.get();
1383 case llvm::Instruction::ExtractElement: {
1384 auto *LLVMIns = cast<llvm::ExtractElementInst>(LLVMV);
1385 It->second = std::unique_ptr<ExtractElementInst>(
1387 return It->second.get();
1389 case llvm::Instruction::InsertElement: {
1390 auto *LLVMIns = cast<llvm::InsertElementInst>(LLVMV);
1391 It->second = std::unique_ptr<InsertElementInst>(
1393 return It->second.get();
1395 case llvm::Instruction::Br: {
1396 auto *
LLVMBr = cast<llvm::BranchInst>(LLVMV);
1398 return It->second.get();
1400 case llvm::Instruction::Load: {
1401 auto *LLVMLd = cast<llvm::LoadInst>(LLVMV);
1402 It->second = std::unique_ptr<LoadInst>(
new LoadInst(LLVMLd, *
this));
1403 return It->second.get();
1405 case llvm::Instruction::Store: {
1406 auto *LLVMSt = cast<llvm::StoreInst>(LLVMV);
1407 It->second = std::unique_ptr<StoreInst>(
new StoreInst(LLVMSt, *
this));
1408 return It->second.get();
1410 case llvm::Instruction::Ret: {
1411 auto *
LLVMRet = cast<llvm::ReturnInst>(LLVMV);
1413 return It->second.get();
1415 case llvm::Instruction::Call: {
1416 auto *
LLVMCall = cast<llvm::CallInst>(LLVMV);
1418 return It->second.get();
1420 case llvm::Instruction::Invoke: {
1421 auto *
LLVMInvoke = cast<llvm::InvokeInst>(LLVMV);
1423 return It->second.get();
1425 case llvm::Instruction::CallBr: {
1426 auto *
LLVMCallBr = cast<llvm::CallBrInst>(LLVMV);
1428 return It->second.get();
1430 case llvm::Instruction::GetElementPtr: {
1431 auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
1432 It->second = std::unique_ptr<GetElementPtrInst>(
1434 return It->second.get();
1436 case llvm::Instruction::Alloca: {
1437 auto *
LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
1439 return It->second.get();
1441 case llvm::Instruction::ZExt:
1442 case llvm::Instruction::SExt:
1443 case llvm::Instruction::FPToUI:
1444 case llvm::Instruction::FPToSI:
1445 case llvm::Instruction::FPExt:
1446 case llvm::Instruction::PtrToInt:
1447 case llvm::Instruction::IntToPtr:
1448 case llvm::Instruction::SIToFP:
1449 case llvm::Instruction::UIToFP:
1450 case llvm::Instruction::Trunc:
1451 case llvm::Instruction::FPTrunc:
1452 case llvm::Instruction::BitCast:
1453 case llvm::Instruction::AddrSpaceCast: {
1454 auto *LLVMCast = cast<llvm::CastInst>(LLVMV);
1455 It->second = std::unique_ptr<CastInst>(
new CastInst(LLVMCast, *
this));
1456 return It->second.get();
1458 case llvm::Instruction::PHI: {
1459 auto *LLVMPhi = cast<llvm::PHINode>(LLVMV);
1460 It->second = std::unique_ptr<PHINode>(
new PHINode(LLVMPhi, *
this));
1461 return It->second.get();
1463 case llvm::Instruction::Unreachable: {
1465 It->second = std::unique_ptr<UnreachableInst>(
1467 return It->second.get();
1473 It->second = std::unique_ptr<OpaqueInst>(
1474 new OpaqueInst(cast<llvm::Instruction>(LLVMV), *
this));
1475 return It->second.get();
1480 auto NewBBPtr = std::unique_ptr<BasicBlock>(
new BasicBlock(LLVMBB, *
this));
1481 auto *BB = cast<BasicBlock>(
registerValue(std::move(NewBBPtr)));
1483 BB->buildBasicBlockFromLLVMIR(LLVMBB);
1488 auto NewPtr = std::unique_ptr<SelectInst>(
new SelectInst(SI, *
this));
1496 return cast<ExtractElementInst>(
registerValue(std::move(NewPtr)));
1503 return cast<InsertElementInst>(
registerValue(std::move(NewPtr)));
1507 auto NewPtr = std::unique_ptr<BranchInst>(
new BranchInst(BI, *
this));
1512 auto NewPtr = std::unique_ptr<LoadInst>(
new LoadInst(LI, *
this));
1517 auto NewPtr = std::unique_ptr<StoreInst>(
new StoreInst(SI, *
this));
1522 auto NewPtr = std::unique_ptr<ReturnInst>(
new ReturnInst(
I, *
this));
1527 auto NewPtr = std::unique_ptr<CallInst>(
new CallInst(
I, *
this));
1532 auto NewPtr = std::unique_ptr<InvokeInst>(
new InvokeInst(
I, *
this));
1537 auto NewPtr = std::unique_ptr<CallBrInst>(
new CallBrInst(
I, *
this));
1544 return cast<UnreachableInst>(
registerValue(std::move(NewPtr)));
1551 return cast<GetElementPtrInst>(
registerValue(std::move(NewPtr)));
1554 auto NewPtr = std::unique_ptr<AllocaInst>(
new AllocaInst(
I, *
this));
1558 auto NewPtr = std::unique_ptr<CastInst>(
new CastInst(
I, *
this));
1562 auto NewPtr = std::unique_ptr<PHINode>(
new PHINode(
I, *
this));
1569 return It->second.get();
1575 auto NewFPtr = std::unique_ptr<Function>(
new Function(
F, *
this));
1576 auto *SBF = cast<Function>(
registerValue(std::move(NewFPtr)));
1578 for (
auto &Arg :
F->args())
1587 auto *BB = cast<llvm::BasicBlock>(
Val);
1588 auto *
F = BB->getParent();
1601 if (isa<llvm::BasicBlock>(
Op))
1604 if (isa<llvm::MetadataAsValue>(
Op))
1607 if (isa<llvm::InlineAsm>(
Op))
1612#if !defined(NDEBUG) && defined(SBVEC_EXPENSIVE_CHECKS)
1622 assert(V !=
nullptr &&
"No SandboxIR for BB->begin()!");
1623 auto *
I = cast<Instruction>(V);
1624 unsigned Num =
I->getNumOfIRInstrs();
1625 assert(Num >= 1u &&
"Bad getNumOfIRInstrs()");
1626 It = std::next(It, Num - 1);
1634 return cast_or_null<Instruction>(TerminatorV);
1638 auto *BB = cast<llvm::BasicBlock>(
Val);
1639 assert(!BB->empty() &&
"Empty block!");
1640 auto *SBI = cast<Instruction>(
getContext().getValue(&*BB->begin()));
1641 assert(SBI !=
nullptr &&
"Expected Instr!");
1646 auto *BB = cast<llvm::BasicBlock>(
Val);
1647 assert(!BB->empty() &&
"Empty block!");
1648 auto *SBI = cast<Instruction>(
getContext().getValue(&*BB->rbegin()));
1649 assert(SBI !=
nullptr &&
"Expected Instr!");
1665 OS <<
"<Crash-proof mode!>\n";
1670 OS << IRef <<
" *** No SandboxIR ***\n";
1672 auto *SBI = dyn_cast<Instruction>(SBV);
1673 if (SBI ==
nullptr) {
1674 OS << IRef <<
" *** Not a SBInstruction!!! ***\n";
1676 if (Visited.
insert(SBI).second)
1682 for (
auto &SBI : *
this) {
BlockVerifier::State From
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)
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.
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 is an important base class in LLVM.
This class represents an Operation in the Expression.
Implements a dense probed hash-table based set.
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="")
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())
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.
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
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
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 Constant * createInt(Type *Ty, uint64_t V, Context &Ctx, bool IsSigned=false)
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.
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.
ExtractElementInst * createExtractElementInst(llvm::ExtractElementInst *EEI)
LoadInst * createLoadInst(llvm::LoadInst *LI)
AllocaInst * createAllocaInst(llvm::AllocaInst *I)
CallInst * createCallInst(llvm::CallInst *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)
ReturnInst * createReturnInst(llvm::ReturnInst *I)
PHINode * createPHINode(llvm::PHINode *I)
SelectInst * createSelectInst(llvm::SelectInst *SI)
CastInst * createCastInst(llvm::CastInst *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
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 ...
BBIterator getIterator() const
\Returns a BasicBlock::iterator for this Instruction.
void removeFromParent()
Detach this from its parent BasicBlock without deleting it.
virtual unsigned getNumOfIRInstrs() const =0
This is used by BasicBlock::iterator.
static bool classof(const sandboxir::Value *From)
For isa/dyn_cast.
void insertInto(BasicBlock *BB, const BBIterator &WhereIt)
Insert this detached instruction into BB at WhereIt.
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 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...
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
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 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...
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.