LLVM: lib/SandboxIR/Tracker.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

15

17

18#ifndef NDEBUG

19

20std::string IRSnapshotChecker::dumpIR(const llvm::Function &F) const {

22 raw_string_ostream SS(Result);

23 F.print(SS, nullptr);

25}

26

27IRSnapshotChecker::ContextSnapshot IRSnapshotChecker::takeSnapshot() const {

28 ContextSnapshot Result;

29 for (const auto &Entry : Ctx.LLVMModuleToModuleMap)

30 for (const auto &F : *Entry.first) {

31 FunctionSnapshot Snapshot;

33 Snapshot.TextualIR = dumpIR(F);

35 }

37}

38

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";

48 continue;

49 }

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";

56 }

57 }

58

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";

65 }

66 }

67 return DifferenceFound;

68}

69

71

73 ContextSnapshot CurrContextSnapshot = takeSnapshot();

74 if (diff(OrigContextSnapshot, CurrContextSnapshot)) {

76 "Original and current IR differ! Probably a checkpointing bug.");

77 }

78}

79

84

89#endif

90

92 : PHI(PHI), RemovedIdx(RemovedIdx) {

93 RemovedV = PHI->getIncomingValue(RemovedIdx);

94 RemovedBB = PHI->getIncomingBlock(RemovedIdx);

95}

96

98

99

100 unsigned NumIncoming = PHI->getNumIncomingValues();

101 if (NumIncoming == 0) {

102 PHI->addIncoming(RemovedV, RemovedBB);

103 return;

104 }

105

106

107 unsigned LastIdx = NumIncoming - 1;

108 PHI->addIncoming(PHI->getIncomingValue(LastIdx),

109 PHI->getIncomingBlock(LastIdx));

110 for (unsigned Idx = LastIdx; Idx > RemovedIdx; --Idx) {

111 auto *PrevV = PHI->getIncomingValue(Idx - 1);

112 auto *PrevBB = PHI->getIncomingBlock(Idx - 1);

113 PHI->setIncomingValue(Idx, PrevV);

114 PHI->setIncomingBlock(Idx, PrevBB);

115 }

116 PHI->setIncomingValue(RemovedIdx, RemovedV);

117 PHI->setIncomingBlock(RemovedIdx, RemovedBB);

118}

119

120#ifndef NDEBUG

125#endif

126

128 : PHI(PHI), Idx(PHI->getNumIncomingValues()) {}

129

131

132#ifndef NDEBUG

137#endif

138

140 assert(Changes.empty() && "You must accept or revert changes!");

141}

142

144 : ErasedIPtr(std::move(ErasedIPtr)) {

146 auto LLVMInstrs = I->getLLVMInstrs();

147

148 for (auto *LLVMI : reverse(LLVMInstrs)) {

150 Operands.reserve(LLVMI->getNumOperands());

151 for (auto [OpNum, Use] : enumerate(LLVMI->operands()))

153 InstrData.push_back({Operands, LLVMI});

154 }

156 [](const auto &D0, const auto &D1) {

157 return D0.LLVMI->comesBefore(D1.LLVMI);

158 }) &&

159 "Expected reverse program order!");

161 if (BotLLVMI->getNextNode() != nullptr)

162 NextLLVMIOrBB = BotLLVMI->getNextNode();

163 else

164 NextLLVMIOrBB = BotLLVMI->getParent();

165}

166

168 for (const auto &IData : InstrData)

169 IData.LLVMI->deleteValue();

170}

171

173

174 auto [Operands, BotLLVMI] = InstrData[0];

176 BotLLVMI->insertBefore(NextLLVMI->getIterator());

177 } else {

179 BotLLVMI->insertInto(LLVMBB, LLVMBB->end());

180 }

181 for (auto [OpNum, Op] : enumerate(Operands))

182 BotLLVMI->setOperand(OpNum, Op);

183

184

185 for (auto [Operands, LLVMI] : drop_begin(InstrData)) {

186 LLVMI->insertBefore(BotLLVMI->getIterator());

187 for (auto [OpNum, Op] : enumerate(Operands))

188 LLVMI->setOperand(OpNum, Op);

189 BotLLVMI = LLVMI;

190 }

191 Tracker.getContext().registerValue(std::move(ErasedIPtr));

192}

193

194#ifndef NDEBUG

199#endif

200

202 if (auto *NextI = RemovedI->getNextNode())

203 NextInstrOrBB = NextI;

204 else

205 NextInstrOrBB = RemovedI->getParent();

206}

207

210 RemovedI->insertBefore(NextI);

211 } else {

213 RemovedI->insertInto(BB, BB->end());

214 }

215}

216

217#ifndef NDEBUG

222#endif

223

225 : CSI(CSI), HandlerIdx(CSI->getNumHandlers()) {}

226

228

229

231 LLVMCSI->removeHandler(LLVMCSI->handler_begin() + HandlerIdx);

232}

233

235 for (const auto &C : Switch->cases())

236 Cases.push_back({C.getCaseValue(), C.getCaseSuccessor()});

237}

238

240

241

242

243

244

245

246 unsigned NumCases = Switch->getNumCases();

247 for (unsigned I = 0; I < NumCases; ++I)

248 Switch->removeCase(Switch->case_begin());

249 for (auto &Case : Cases)

250 Switch->addCase(Case.Val, Case.Dest);

251}

252

253#ifndef NDEBUG

258#endif

259

261 auto It = Switch->findCaseValue(Val);

262 Switch->removeCase(It);

263}

264

265#ifndef NDEBUG

270#endif

271

273 if (auto *NextI = MovedI->getNextNode())

274 NextInstrOrBB = NextI;

275 else

276 NextInstrOrBB = MovedI->getParent();

277}

278

281 MovedI->moveBefore(NextI);

282 } else {

284 MovedI->moveBefore(*BB, BB->end());

285 }

286}

287

288#ifndef NDEBUG

293#endif

294

296

298

299#ifndef NDEBUG

304#endif

305

307

308#ifndef NDEBUG

313#endif

314

316 : SVI(SVI), PrevMask(SVI->getShuffleMask()) {}

317

319 SVI->setShuffleMask(PrevMask);

320}

321

322#ifndef NDEBUG

327#endif

328

330

332#ifndef NDEBUG

337#endif

338

341#if !defined(NDEBUG) && defined(EXPENSIVE_CHECKS)

342 SnapshotChecker.save();

343#endif

344}

345

349 for (auto &Change : reverse(Changes))

350 Change->revert(*this);

351 Changes.clear();

352#if !defined(NDEBUG) && defined(EXPENSIVE_CHECKS)

353 SnapshotChecker.expectNoDiff();

354#endif

356}

357

361 for (auto &Change : Changes)

362 Change->accept();

363 Changes.clear();

364}

365

366#ifndef NDEBUG

368 for (auto [Idx, ChangePtr] : enumerate(Changes)) {

369 OS << Idx << ". ";

370 ChangePtr->dump(OS);

371 OS << "\n";

372 }

373}

378#endif

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

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.

This class implements an extremely fast bulk output stream that can only output to a stream.

void revert(Tracker &Tracker) final

This runs when changes get reverted.

Definition Tracker.cpp:227

CatchSwitchAddHandler(CatchSwitchInst *CSI)

Definition Tracker.cpp:224

void revert(Tracker &Tracker) final

This runs when changes get reverted.

Definition Tracker.cpp:331

CmpSwapOperands(CmpInst *Cmp)

Definition Tracker.cpp:329

LLVM_DUMP_METHOD void dump() const final

Definition Tracker.cpp:333

LLVM_DUMP_METHOD void dump() const final

Definition Tracker.cpp:309

void revert(Tracker &Tracker) final

This runs when changes get reverted.

Definition Tracker.cpp:306

void accept() final

This runs when changes get accepted.

Definition Tracker.cpp:167

LLVM_DUMP_METHOD void dump() const final

Definition Tracker.cpp:195

void revert(Tracker &Tracker) final

This runs when changes get reverted.

Definition Tracker.cpp:172

EraseFromParent(std::unique_ptr< sandboxir::Value > &&IPtr)

Definition Tracker.cpp:143

LLVM_ABI_FOR_TEST void expectNoDiff()

Checks current state against saved state, crashes if different.

Definition Tracker.cpp:72

LLVM_ABI_FOR_TEST void save()

Saves a snapshot of the current state.

Definition Tracker.cpp:70

LLVM_DUMP_METHOD void dump() const final

Definition Tracker.cpp:300

InsertIntoBB(Instruction *InsertedI)

Definition Tracker.cpp:297

void revert(Tracker &Tracker) final

This runs when changes get reverted.

Definition Tracker.cpp:295

A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...

LLVM_DUMP_METHOD void dump() const final

Definition Tracker.cpp:289

MoveInstr(sandboxir::Instruction *I)

Definition Tracker.cpp:272

void revert(Tracker &Tracker) final

This runs when changes get reverted.

Definition Tracker.cpp:279

PHIAddIncoming(PHINode *PHI)

Definition Tracker.cpp:127

void revert(Tracker &Tracker) final

This runs when changes get reverted.

Definition Tracker.cpp:130

LLVM_DUMP_METHOD void dump() const final

Definition Tracker.cpp:133

LLVM_DUMP_METHOD void dump() const final

Definition Tracker.cpp:121

PHIRemoveIncoming(PHINode *PHI, unsigned RemovedIdx)

Definition Tracker.cpp:91

void revert(Tracker &Tracker) final

This runs when changes get reverted.

Definition Tracker.cpp:97

void revert(Tracker &Tracker) final

This runs when changes get reverted.

Definition Tracker.cpp:208

RemoveFromParent(Instruction *RemovedI)

Definition Tracker.cpp:201

LLVM_DUMP_METHOD void dump() const final

Definition Tracker.cpp:218

ShuffleVectorSetMask(ShuffleVectorInst *SVI)

Definition Tracker.cpp:315

LLVM_DUMP_METHOD void dump() const final

Definition Tracker.cpp:323

void revert(Tracker &Tracker) final

This runs when changes get reverted.

Definition Tracker.cpp:318

void revert(Tracker &Tracker) final

This runs when changes get reverted.

Definition Tracker.cpp:260

LLVM_DUMP_METHOD void dump() const final

Definition Tracker.cpp:266

LLVM_DUMP_METHOD void dump() const final

Definition Tracker.cpp:254

SwitchRemoveCase(SwitchInst *Switch)

Definition Tracker.cpp:234

void revert(Tracker &Tracker) final

This runs when changes get reverted.

Definition Tracker.cpp:239

LLVM_ABI ~Tracker()

Definition Tracker.cpp:139

LLVM_ABI void revert()

Stops tracking and reverts to saved state.

Definition Tracker.cpp:346

LLVM_ABI void save()

Turns on IR tracking.

Definition Tracker.cpp:339

LLVM_ABI void accept()

Stops tracking and accept changes.

Definition Tracker.cpp:358

LLVM_DUMP_METHOD void dump() const

Definition Tracker.cpp:374

LLVM_DUMP_METHOD void dump() const final

Definition Tracker.cpp:80

LLVM_DUMP_METHOD void dump() const final

Definition Tracker.cpp:85

Represents a Def-use/Use-def edge in SandboxIR.

LLVM_ABI Value * get() const

#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,...

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

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...

DWARFExpression::Operation Op

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

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.