26 if (LLVMUse ==
nullptr)
27 OS <<
"<null> LLVM Use! ";
58 assert(
Use.LLVMUse !=
nullptr &&
"Already at end!");
68 assert(LLVMUse !=
nullptr &&
"Already at end!");
69 LLVMUse = LLVMUse->getNext();
70 if (LLVMUse ==
nullptr) {
75 auto *LLVMUser = LLVMUse->getUser();
76 Use.Usr = cast_or_null<sandboxir::User>(Ctx->getValue(LLVMUser));
81 : SubclassID(SubclassID), Val(Val), Ctx(Ctx) {
100 bool AtEnd = UseBegin == UseEnd;
101 llvm::Use *LLVMUse = AtEnd ? nullptr : &*UseBegin;
104 : cast_or_null<sandboxir::User>(
Ctx.
getValue(&*LLVMUse->getUser()));
116 OtherVal, [&ShouldReplace,
this](
llvm::Use &LLVMUse) ->
bool {
120 Use UseToReplace(&LLVMUse, DstU,
Ctx);
121 if (!ShouldReplace(UseToReplace))
132 "Replacing with Value of different type!");
144 std::stringstream SS;
145 SS <<
"SB" <<
UID <<
".";
154 OS.indent(2) <<
"Val: ";
195 assert(isa<llvm::User>(
Val) &&
"Non-users have no operands!");
198 LLVMUse = &cast<llvm::User>(
Val)->getOperandUse(OpIdx);
200 LLVMUse = cast<llvm::User>(
Val)->op_end();
201 return Use(LLVMUse,
const_cast<User *
>(
this),
Ctx);
207 "Use not found in this SBUser's operands!");
212 switch (
From->getSubclassID()) {
213#define DEF_VALUE(ID, CLASS)
214#define DEF_USER(ID, CLASS) \
217#define DEF_INSTR(ID, OPC, CLASS) \
220#include "llvm/SandboxIR/SandboxIRValues.def"
227 assert(isa<llvm::User>(
Val) &&
"No operands!");
232 cast<llvm::User>(
Val)->setOperand(OperandIdx, Operand->
Val);
245 return cast<llvm::User>(
Val)->replaceUsesOfWith(FromV->
Val, ToV->
Val);
256 auto ItE = BB->
end();
257 assert(It != ItE &&
"Already at end!");
263 assert(Num > 0 &&
"Bad getNumOfIRInstrs()");
264 It = std::next(It, Num - 1);
270 if (It == BB->
end()) {
276 assert(Num > 0 &&
"Bad getNumOfIRInstrs()");
277 assert(std::prev(It, Num - 1) != BB->
begin() &&
"Already at begin!");
278 It = std::prev(It, Num);
284#define DEF_VALUE(ID, CLASS)
285#define DEF_USER(ID, CLASS)
289#define DEF_INSTR(ID, OPC, CLASS) OPC
290#include "llvm/SandboxIR/SandboxIRValues.def"
297 if (Prev ==
nullptr) {
299 return &*cast<llvm::BasicBlock>(
getParent()->
Val)->begin();
308 auto *
I = cast<llvm::Instruction>(
Val);
318 auto *LLVMI = cast<llvm::Instruction>(
Val);
319 assert(LLVMI->getParent() !=
nullptr &&
"LLVM IR instr is detached!");
320 auto *NextLLVMI = LLVMI->getNextNode();
321 auto *NextI = cast_or_null<Instruction>(
Ctx.
getValue(NextLLVMI));
322 if (NextI ==
nullptr)
342 I->removeFromParent();
346 assert(
users().empty() &&
"Still connected to users, can't erase!");
347 std::unique_ptr<Value> Detached =
Ctx.
detach(
this);
353 std::make_unique<EraseFromParent>(std::move(Detached),
Tracker));
358 I->removeFromParent();
362 I->dropAllReferences();
366 I->eraseFromParent();
379 auto *LLVMBB = cast<llvm::BasicBlock>(BB.
Val);
381 if (WhereIt == BB.
end()) {
389 [](
auto *I1,
auto *I2) {
return I1->comesBefore(I2); }) &&
390 "Expected program order!");
393 I->moveBefore(*LLVMBB, It);
400 [](
auto *I1,
auto *I2) {
return I1->comesBefore(I2); }) &&
401 "Expected program order!");
404 I->insertBefore(BeforeTopI);
415 if (WhereIt != BB->
end()) {
420 LLVMBeforeI =
nullptr;
421 LLVMBeforeIt = LLVMBB->
end();
425 I->insertInto(LLVMBB, LLVMBeforeIt);
438 switch (
From->getSubclassID()) {
439#define DEF_INSTR(ID, OPC, CLASS) \
442#include "llvm/SandboxIR/SandboxIRValues.def"
450 OS <<
"Unimplemented! Please override dump().";
463 Builder.SetInsertPoint(BeforeIR);
464 auto *NewLI = Builder.CreateAlignedLoad(Ty,
Ptr->Val,
Align,
474 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->
Val));
475 auto *NewLI = Builder.CreateAlignedLoad(Ty,
Ptr->Val,
Align,
482 return From->getSubclassID() == ClassID::Load;
521 auto *
F = cast<llvm::Function>(
Val);
522 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
526 auto *SBArg = cast_or_null<Argument>(Ctx.getValue(&LLVMArg));
527 if (SBArg == nullptr)
530 SBArg->printAsOperand(OS);
532 [&] { OS <<
", "; });
538 auto *LLVMF = cast<llvm::Function>(
Val);
542 auto *BB = cast_or_null<BasicBlock>(
Ctx.
getValue(&LLVMBB));
548 [&
OS] {
OS <<
"\n"; });
559 return cast_or_null<Instruction>(Ctx->
getValue(&*It));
563 std::unique_ptr<Value> Erased;
566 auto *Val = It->second.release();
567 Erased = std::unique_ptr<Value>(Val);
574 assert(V->getSubclassID() != Value::ClassID::Constant &&
575 "Can't detach a constant!");
576 assert(V->getSubclassID() != Value::ClassID::User &&
"Can't detach a user!");
581 assert(VPtr->getSubclassID() != Value::ClassID::User &&
582 "Can't register a user!");
583 Value *V = VPtr.get();
584 [[maybe_unused]]
auto Pair =
586 assert(Pair.second &&
"Already exists!");
592 auto It = Pair.first;
594 return It->second.get();
596 if (
auto *
C = dyn_cast<llvm::Constant>(LLVMV)) {
597 It->second = std::unique_ptr<Constant>(
new Constant(
C, *
this));
598 auto *NewC = It->second.get();
603 if (
auto *Arg = dyn_cast<llvm::Argument>(LLVMV)) {
604 It->second = std::unique_ptr<Argument>(
new Argument(Arg, *
this));
605 return It->second.get();
607 if (
auto *BB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
608 assert(isa<BlockAddress>(U) &&
609 "This won't create a SBBB, don't call this function directly!");
614 assert(isa<llvm::Instruction>(LLVMV) &&
"Expected Instruction");
616 switch (cast<llvm::Instruction>(LLVMV)->
getOpcode()) {
617 case llvm::Instruction::Load: {
618 auto *LLVMLd = cast<llvm::LoadInst>(LLVMV);
619 It->second = std::unique_ptr<LoadInst>(
new LoadInst(LLVMLd, *
this));
620 return It->second.get();
626 It->second = std::unique_ptr<OpaqueInst>(
627 new OpaqueInst(cast<llvm::Instruction>(LLVMV), *
this));
628 return It->second.get();
633 auto NewBBPtr = std::unique_ptr<BasicBlock>(
new BasicBlock(LLVMBB, *
this));
634 auto *BB = cast<BasicBlock>(
registerValue(std::move(NewBBPtr)));
636 BB->buildBasicBlockFromLLVMIR(LLVMBB);
641 auto NewPtr = std::unique_ptr<LoadInst>(
new LoadInst(LI, *
this));
648 return It->second.get();
654 auto NewFPtr = std::unique_ptr<Function>(
new Function(
F, *
this));
656 for (
auto &Arg :
F->args())
661 auto *SBF = cast<Function>(
registerValue(std::move(NewFPtr)));
666 auto *BB = cast<llvm::BasicBlock>(
Val);
667 auto *
F = BB->getParent();
680 if (isa<llvm::BasicBlock>(
Op))
683 if (isa<llvm::MetadataAsValue>(
Op))
686 if (isa<llvm::InlineAsm>(
Op))
691#if !defined(NDEBUG) && defined(SBVEC_EXPENSIVE_CHECKS)
701 assert(V !=
nullptr &&
"No SandboxIR for BB->begin()!");
702 auto *
I = cast<Instruction>(V);
703 unsigned Num =
I->getNumOfIRInstrs();
704 assert(Num >= 1u &&
"Bad getNumOfIRInstrs()");
705 It = std::next(It, Num - 1);
713 return cast_or_null<Instruction>(TerminatorV);
717 auto *BB = cast<llvm::BasicBlock>(
Val);
718 assert(!BB->empty() &&
"Empty block!");
719 auto *SBI = cast<Instruction>(
getContext().getValue(&*BB->begin()));
720 assert(SBI !=
nullptr &&
"Expected Instr!");
725 auto *BB = cast<llvm::BasicBlock>(
Val);
726 assert(!BB->empty() &&
"Empty block!");
727 auto *SBI = cast<Instruction>(
getContext().getValue(&*BB->rbegin()));
728 assert(SBI !=
nullptr &&
"Expected Instr!");
744 OS <<
"<Crash-proof mode!>\n";
749 OS << IRef <<
" *** No SandboxIR ***\n";
751 auto *SBI = dyn_cast<Instruction>(SBV);
752 if (SBI ==
nullptr) {
753 OS << IRef <<
" *** Not a SBInstruction!!! ***\n";
755 if (Visited.
insert(SBI).second)
761 for (
auto &SBI : *
this) {
BlockVerifier::State From
This file contains the declarations for the subclasses of Constant, which represent the different fla...
ppc ctr loops PowerPC CTR Loops Verify
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
This class represents an incoming formal argument to a Function.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
InstListType::iterator iterator
Instruction iterators...
This class represents an Operation in the Expression.
Implements a dense probed hash-table based set.
const char * getOpcodeName() const
An instruction for reading from 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.
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.
Argument of a sandboxir::Function.
void printAsOperand(raw_ostream &OS) const
LLVM_DUMP_METHOD void dump() const final
Iterator for Instructions in a `BasicBlock.
BBIterator & operator++()
BBIterator & operator--()
Contains a list of sandboxir::Instruction's.
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
LLVM_DUMP_METHOD void dump() const final
LLVM_DUMP_METHOD void dump() const override
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...
auto & getLLVMIRBuilder()
std::unique_ptr< Value > detach(Value *V)
Remove SBV from all SandboxIR maps and stop owning it.
BasicBlock * createBasicBlock(llvm::BasicBlock *BB)
Create a sandboxir::BasicBlock for an existing LLVM IR BB.
LoadInst * createLoadInst(llvm::LoadInst *LI)
std::unique_ptr< Value > detachLLVMValue(llvm::Value *V)
Remove V from the maps and returns the unique_ptr.
Value * getOrCreateValue(llvm::Value *LLVMV)
Get or create a sandboxir::Value for an existing LLVM IR LLVMV.
friend class BasicBlock
Various leaf nodes.
size_t getNumValues() const
\Returns the number of values registered with Context.
void dumpNameAndArgs(raw_ostream &OS) const
LLVM_DUMP_METHOD void dump() const final
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.
LLVM_DUMP_METHOD void dump() const override
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.
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.
static bool classof(const Value *From)
For isa/dyn_cast.
LLVM_DUMP_METHOD void dump() const override
static LoadInst * create(Type *Ty, Value *Ptr, MaybeAlign Align, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
Value * getPointerOperand() const
An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to an OpaqueInstr.
LLVM_DUMP_METHOD void dump() const override
Iterator for the Use edges of a User's operands.
value_type operator*() const
OperandUseIterator & operator++()
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.
Represents a Def-use/Use-def edge in SandboxIR.
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::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).
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 are tuples (A,...
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.