30 for (
const auto &
F : *
Entry.first) {
31 FunctionSnapshot Snapshot;
33 Snapshot.TextualIR = dumpIR(
F);
39bool IRSnapshotChecker::diff(
const ContextSnapshot &Orig,
40 const ContextSnapshot &Curr)
const {
41 bool DifferenceFound =
false;
42 for (
const auto &[
F, OrigFS] : Orig) {
43 auto CurrFSIt = Curr.find(
F);
44 if (CurrFSIt == Curr.end()) {
45 DifferenceFound =
true;
46 dbgs() <<
"Function " <<
F->getName() <<
" not found in current IR.\n";
47 dbgs() << OrigFS.TextualIR <<
"\n";
50 const FunctionSnapshot &CurrFS = CurrFSIt->second;
51 if (OrigFS.Hash != CurrFS.Hash) {
52 DifferenceFound =
true;
53 dbgs() <<
"Found IR difference in Function " <<
F->getName() <<
"\n";
54 dbgs() <<
"Original:\n" << OrigFS.TextualIR <<
"\n";
55 dbgs() <<
"Current:\n" << CurrFS.TextualIR <<
"\n";
59 for (
const auto &[
F, CurrFS] : Curr) {
60 if (!Orig.contains(
F)) {
61 DifferenceFound =
true;
62 dbgs() <<
"Function " <<
F->getName()
63 <<
" found in current IR but not in original snapshot.\n";
64 dbgs() << CurrFS.TextualIR <<
"\n";
67 return DifferenceFound;
74 if (diff(OrigContextSnapshot, CurrContextSnapshot)) {
76 "Original and current IR differ! Probably a checkpointing bug.");
92 :
PHI(
PHI), RemovedIdx(RemovedIdx) {
93 RemovedV =
PHI->getIncomingValue(RemovedIdx);
94 RemovedBB =
PHI->getIncomingBlock(RemovedIdx);
101 if (NumIncoming == 0) {
107 unsigned LastIdx = NumIncoming - 1;
110 for (
unsigned Idx = LastIdx;
Idx > RemovedIdx; --
Idx) {
140 assert(Changes.empty() &&
"You must accept or revert changes!");
144 : ErasedIPtr(
std::
move(ErasedIPtr)) {
145 auto *
I = cast<Instruction>(this->ErasedIPtr.get());
146 auto LLVMInstrs =
I->getLLVMInstrs();
148 for (
auto *LLVMI :
reverse(LLVMInstrs)) {
150 Operands.reserve(LLVMI->getNumOperands());
156 [](
const auto &D0,
const auto &D1) {
157 return D0.LLVMI->comesBefore(D1.LLVMI);
159 "Expected reverse program order!");
160 auto *BotLLVMI = cast<llvm::Instruction>(
I->Val);
161 if (BotLLVMI->getNextNode() !=
nullptr)
162 NextLLVMIOrBB = BotLLVMI->getNextNode();
164 NextLLVMIOrBB = BotLLVMI->getParent();
168 for (
const auto &IData : InstrData)
169 IData.LLVMI->deleteValue();
174 auto [
Operands, BotLLVMI] = InstrData[0];
175 if (
auto *NextLLVMI = dyn_cast<llvm::Instruction *>(NextLLVMIOrBB)) {
176 BotLLVMI->insertBefore(NextLLVMI->getIterator());
178 auto *LLVMBB = cast<llvm::BasicBlock *>(NextLLVMIOrBB);
179 BotLLVMI->insertInto(LLVMBB, LLVMBB->end());
182 BotLLVMI->setOperand(OpNum,
Op);
186 LLVMI->insertBefore(BotLLVMI->getIterator());
188 LLVMI->setOperand(OpNum,
Op);
203 NextInstrOrBB = NextI;
209 if (
auto *NextI = dyn_cast<Instruction *>(NextInstrOrBB)) {
212 auto *BB = cast<BasicBlock *>(NextInstrOrBB);
225 : CSI(CSI), HandlerIdx(CSI->getNumHandlers()) {}
230 auto *LLVMCSI = cast<llvm::CatchSwitchInst>(CSI->
Val);
231 LLVMCSI->removeHandler(LLVMCSI->handler_begin() + HandlerIdx);
235 for (
const auto &
C : Switch->cases())
236 Cases.
push_back({
C.getCaseValue(),
C.getCaseSuccessor()});
247 for (
unsigned I = 0;
I < NumCases; ++
I)
249 for (
auto &Case : Cases)
250 Switch->
addCase(Case.Val, Case.Dest);
274 NextInstrOrBB = NextI;
280 if (
auto *NextI = dyn_cast<Instruction *>(NextInstrOrBB)) {
283 auto *BB = cast<BasicBlock *>(NextInstrOrBB);
316 : SVI(SVI), PrevMask(SVI->getShuffleMask()) {}
341#if !defined(NDEBUG) && defined(EXPENSIVE_CHECKS)
342 SnapshotChecker.
save();
349 for (
auto &Change :
reverse(Changes))
350 Change->revert(*
this);
352#if !defined(NDEBUG) && defined(EXPENSIVE_CHECKS)
361 for (
auto &Change : Changes)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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
mir Rename Register Operands
This class represents an Operation in the Expression.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
void revert(Tracker &Tracker) final
This runs when changes get reverted.
CatchSwitchAddHandler(CatchSwitchInst *CSI)
LLVM_ABI void swapOperands()
void revert(Tracker &Tracker) final
This runs when changes get reverted.
CmpSwapOperands(CmpInst *Cmp)
LLVM_DUMP_METHOD void dump() const final
DenseMap< llvm::Module *, std::unique_ptr< Module > > LLVMModuleToModuleMap
Maps an LLVM Module to the corresponding sandboxir::Module.
LLVM_ABI Value * registerValue(std::unique_ptr< Value > &&VPtr)
Take ownership of VPtr and store it in LLVMValueToValueMap.
LLVM_DUMP_METHOD void dump() const final
void revert(Tracker &Tracker) final
This runs when changes get reverted.
void accept() final
This runs when changes get accepted.
LLVM_DUMP_METHOD void dump() const final
void revert(Tracker &Tracker) final
This runs when changes get reverted.
EraseFromParent(std::unique_ptr< sandboxir::Value > &&IPtr)
void expectNoDiff()
Checks current state against saved state, crashes if different.
void save()
Saves a snapshot of the current state.
LLVM_DUMP_METHOD void dump() const final
InsertIntoBB(Instruction *InsertedI)
void revert(Tracker &Tracker) final
This runs when changes get reverted.
A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...
LLVM_ABI void moveBefore(BasicBlock &BB, const BBIterator &WhereIt)
Move this instruction to WhereIt.
LLVM_ABI void insertInto(BasicBlock *BB, const BBIterator &WhereIt)
Insert this detached instruction into BB at WhereIt.
LLVM_ABI Instruction * getNextNode() const
\Returns the next sandboxir::Instruction in the block, or nullptr if at the end of the block.
LLVM_ABI void removeFromParent()
Detach this from its parent BasicBlock without deleting it.
LLVM_ABI void insertBefore(Instruction *BeforeI)
Insert this detached instruction before BeforeI.
LLVM_ABI void eraseFromParent()
Detach this Value from its parent and delete it.
LLVM_ABI BasicBlock * getParent() const
\Returns the BasicBlock containing this Instruction, or null if it is detached.
LLVM_DUMP_METHOD void dump() const final
MoveInstr(sandboxir::Instruction *I)
void revert(Tracker &Tracker) final
This runs when changes get reverted.
PHIAddIncoming(PHINode *PHI)
void revert(Tracker &Tracker) final
This runs when changes get reverted.
LLVM_DUMP_METHOD void dump() const final
unsigned getNumIncomingValues() const
LLVM_ABI Value * getIncomingValue(unsigned Idx) const
LLVM_ABI void setIncomingBlock(unsigned Idx, BasicBlock *BB)
LLVM_ABI Value * removeIncomingValue(unsigned Idx)
LLVM_ABI void setIncomingValue(unsigned Idx, Value *V)
LLVM_ABI BasicBlock * getIncomingBlock(unsigned Idx) const
LLVM_ABI void addIncoming(Value *V, BasicBlock *BB)
LLVM_DUMP_METHOD void dump() const final
PHIRemoveIncoming(PHINode *PHI, unsigned RemovedIdx)
void revert(Tracker &Tracker) final
This runs when changes get reverted.
void revert(Tracker &Tracker) final
This runs when changes get reverted.
RemoveFromParent(Instruction *RemovedI)
LLVM_DUMP_METHOD void dump() const final
LLVM_ABI void setShuffleMask(ArrayRef< int > Mask)
ShuffleVectorSetMask(ShuffleVectorInst *SVI)
LLVM_DUMP_METHOD void dump() const final
void revert(Tracker &Tracker) final
This runs when changes get reverted.
void revert(Tracker &Tracker) final
This runs when changes get reverted.
LLVM_DUMP_METHOD void dump() const final
CaseIt findCaseValue(const ConstantInt *C)
LLVM_ABI void addCase(ConstantInt *OnVal, BasicBlock *Dest)
CaseIt case_begin()
Returns a read/write iterator that points to the first case in the SwitchInst.
unsigned getNumCases() const
LLVM_ABI CaseIt removeCase(CaseIt It)
This method removes the specified case and its successor from the switch instruction.
LLVM_DUMP_METHOD void dump() const final
SwitchRemoveCase(SwitchInst *Switch)
void revert(Tracker &Tracker) final
This runs when changes get reverted.
The tracker collects all the change objects and implements the main API for saving / reverting / acce...
@ Record
Tracking is disabled
@ Reverting
Tracking changes
LLVM_ABI void revert()
Stops tracking and reverts to saved state.
LLVM_ABI void save()
Turns on IR tracking.
Context & getContext() const
LLVM_ABI void accept()
Stops tracking and accept changes.
LLVM_DUMP_METHOD void dump() const
LLVM_DUMP_METHOD void dump() const final
LLVM_DUMP_METHOD void dump() const final
Represents a Def-use/Use-def edge in SandboxIR.
LLVM_ABI Value * get() const
llvm::Value * Val
The LLVM Value that corresponds to this SandboxIR Value.
#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 drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
auto reverse(ContainerTy &&C)
LLVM_ABI 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...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI stable_hash StructuralHash(const Function &F, bool DetailedHash=false)
Returns a hash of the function F.
Implement std::hash so that hash_code can be used in STL containers.