32 for (
const auto &
F : *
Entry.first) {
33 FunctionSnapshot Snapshot;
35 Snapshot.TextualIR = dumpIR(
F);
41bool IRSnapshotChecker::diff(
const ContextSnapshot &Orig,
42 const ContextSnapshot &Curr)
const {
43 bool DifferenceFound =
false;
44 for (
const auto &[
F, OrigFS] : Orig) {
45 auto CurrFSIt = Curr.find(
F);
46 if (CurrFSIt == Curr.end()) {
47 DifferenceFound =
true;
48 dbgs() <<
"Function " <<
F->getName() <<
" not found in current IR.\n";
49 dbgs() << OrigFS.TextualIR <<
"\n";
52 const FunctionSnapshot &CurrFS = CurrFSIt->second;
53 if (OrigFS.Hash != CurrFS.Hash) {
54 DifferenceFound =
true;
55 dbgs() <<
"Found IR difference in Function " <<
F->getName() <<
"\n";
56 dbgs() <<
"Original:\n" << OrigFS.TextualIR <<
"\n";
57 dbgs() <<
"Current:\n" << CurrFS.TextualIR <<
"\n";
61 for (
const auto &[
F, CurrFS] : Curr) {
62 if (!Orig.contains(
F)) {
63 DifferenceFound =
true;
64 dbgs() <<
"Function " <<
F->getName()
65 <<
" found in current IR but not in original snapshot.\n";
66 dbgs() << CurrFS.TextualIR <<
"\n";
69 return DifferenceFound;
76 if (diff(OrigContextSnapshot, CurrContextSnapshot)) {
78 "Original and current IR differ! Probably a checkpointing bug.");
94 :
PHI(
PHI), RemovedIdx(RemovedIdx) {
95 RemovedV =
PHI->getIncomingValue(RemovedIdx);
96 RemovedBB =
PHI->getIncomingBlock(RemovedIdx);
103 if (NumIncoming == 0) {
109 unsigned LastIdx = NumIncoming - 1;
112 for (
unsigned Idx = LastIdx;
Idx > RemovedIdx; --
Idx) {
142 assert(Changes.empty() &&
"You must accept or revert changes!");
146 : ErasedIPtr(
std::
move(ErasedIPtr)) {
147 auto *
I = cast<Instruction>(this->ErasedIPtr.get());
148 auto LLVMInstrs =
I->getLLVMInstrs();
150 for (
auto *LLVMI :
reverse(LLVMInstrs)) {
152 Operands.reserve(LLVMI->getNumOperands());
158 [](
const auto &D0,
const auto &D1) {
159 return D0.LLVMI->comesBefore(D1.LLVMI);
161 "Expected reverse program order!");
162 auto *BotLLVMI = cast<llvm::Instruction>(
I->Val);
163 if (BotLLVMI->getNextNode() !=
nullptr)
164 NextLLVMIOrBB = BotLLVMI->getNextNode();
166 NextLLVMIOrBB = BotLLVMI->getParent();
170 for (
const auto &IData : InstrData)
171 IData.LLVMI->deleteValue();
176 auto [
Operands, BotLLVMI] = InstrData[0];
177 if (
auto *NextLLVMI = dyn_cast<llvm::Instruction *>(NextLLVMIOrBB)) {
178 BotLLVMI->insertBefore(NextLLVMI);
180 auto *LLVMBB = cast<llvm::BasicBlock *>(NextLLVMIOrBB);
181 BotLLVMI->insertInto(LLVMBB, LLVMBB->end());
184 BotLLVMI->setOperand(OpNum,
Op);
188 LLVMI->insertBefore(BotLLVMI);
190 LLVMI->setOperand(OpNum,
Op);
205 NextInstrOrBB = NextI;
211 if (
auto *NextI = dyn_cast<Instruction *>(NextInstrOrBB)) {
214 auto *BB = cast<BasicBlock *>(NextInstrOrBB);
227 : CSI(CSI), HandlerIdx(CSI->getNumHandlers()) {}
232 auto *LLVMCSI = cast<llvm::CatchSwitchInst>(CSI->
Val);
233 LLVMCSI->removeHandler(LLVMCSI->handler_begin() + HandlerIdx);
237 for (
const auto &
C : Switch->cases())
238 Cases.
push_back({
C.getCaseValue(),
C.getCaseSuccessor()});
249 for (
unsigned I = 0;
I < NumCases; ++
I)
251 for (
auto &Case : Cases)
252 Switch->
addCase(Case.Val, Case.Dest);
276 NextInstrOrBB = NextI;
282 if (
auto *NextI = dyn_cast<Instruction *>(NextInstrOrBB)) {
285 auto *BB = cast<BasicBlock *>(NextInstrOrBB);
318 : SVI(SVI), PrevMask(SVI->getShuffleMask()) {}
343#if !defined(NDEBUG) && defined(EXPENSIVE_CHECKS)
344 SnapshotChecker.
save();
351 for (
auto &Change :
reverse(Changes))
352 Change->revert(*
this);
354#if !defined(NDEBUG) && defined(EXPENSIVE_CHECKS)
362 for (
auto &Change : Changes)
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
Module.h This file contains the declarations for the Module class.
mir Rename Register Operands
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
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.
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 ...
void moveBefore(BasicBlock &BB, const BBIterator &WhereIt)
Move this instruction to WhereIt.
void insertInto(BasicBlock *BB, const BBIterator &WhereIt)
Insert this detached instruction into BB at WhereIt.
Instruction * getNextNode() const
\Returns the next sandboxir::Instruction in the block, or nullptr if at the end of the block.
void removeFromParent()
Detach this from its parent BasicBlock without deleting it.
void insertBefore(Instruction *BeforeI)
Insert this detached instruction before BeforeI.
void eraseFromParent()
Detach this Value from its parent and delete it.
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
Value * getIncomingValue(unsigned Idx) const
void setIncomingBlock(unsigned Idx, BasicBlock *BB)
Value * removeIncomingValue(unsigned Idx)
void setIncomingValue(unsigned Idx, Value *V)
BasicBlock * getIncomingBlock(unsigned Idx) const
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
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)
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
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
void revert()
Stops tracking and reverts to saved state.
void save()
Turns on IR tracking.
Context & getContext() const
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::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)
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.
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.