Skip to content

Commit 4fe33d0

Browse files
authored
[SandboxIR][NFC] GenericSetter tracker class (llvm#102260)
This patch introduces the `GenericSetter` tracker class that can be used to track and revert simple instruction setters. This patch also replaces several setter tracker classes with the generic one.
1 parent c4de358 commit 4fe33d0

File tree

3 files changed

+65
-172
lines changed

3 files changed

+65
-172
lines changed

llvm/include/llvm/SandboxIR/Tracker.h

Lines changed: 31 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -239,71 +239,45 @@ class RemoveFromParent : public IRChangeBase {
239239
#endif // NDEBUG
240240
};
241241

242-
class CallBrInstSetDefaultDest : public IRChangeBase {
243-
CallBrInst *CallBr;
244-
BasicBlock *OrigDefaultDest;
245-
246-
public:
247-
CallBrInstSetDefaultDest(CallBrInst *CallBr, Tracker &Tracker);
248-
void revert() final;
249-
void accept() final {}
250-
#ifndef NDEBUG
251-
void dump(raw_ostream &OS) const final {
252-
dumpCommon(OS);
253-
OS << "CallBrInstSetDefaultDest";
254-
}
255-
LLVM_DUMP_METHOD void dump() const final;
256-
#endif
257-
};
258-
259-
class AllocaSetAllocatedType final : public IRChangeBase {
260-
AllocaInst *Alloca;
261-
Type *OrigType;
262-
263-
public:
264-
AllocaSetAllocatedType(AllocaInst *Alloca, Tracker &Tracker);
265-
void revert() final;
266-
void accept() final {}
267-
#ifndef NDEBUG
268-
void dump(raw_ostream &OS) const final {
269-
dumpCommon(OS);
270-
OS << "AllocaSetAllocatedType";
271-
}
272-
LLVM_DUMP_METHOD void dump() const final;
273-
#endif
274-
};
275-
276-
class AllocaSetAlignment final : public IRChangeBase {
277-
AllocaInst *Alloca;
278-
Align OrigAlign;
242+
/// This class can be used for tracking most instruction setters.
243+
/// The two template arguments are:
244+
/// - GetterFn: The getter member function pointer (e.g., `&Foo::get`)
245+
/// - SetterFn: The setter member function pointer (e.g., `&Foo::set`)
246+
/// Upon construction, it saves a copy of the original value by calling the
247+
/// getter function. Revert sets the value back to the one saved, using the
248+
/// setter function provided.
249+
///
250+
/// Example:
251+
/// Tracker.track(std::make_unique<
252+
/// GenericSetter<&FooInst::get, &FooInst::set>>(I, Tracker));
253+
///
254+
template <auto GetterFn, auto SetterFn>
255+
class GenericSetter final : public IRChangeBase {
256+
/// Helper for getting the class type from the getter
257+
template <typename ClassT, typename RetT>
258+
static ClassT getClassTypeFromGetter(RetT (ClassT::*Fn)() const);
259+
template <typename ClassT, typename RetT>
260+
static ClassT getClassTypeFromGetter(RetT (ClassT::*Fn)());
261+
262+
using InstrT = decltype(getClassTypeFromGetter(GetterFn));
263+
using SavedValT = std::invoke_result_t<decltype(GetterFn), InstrT>;
264+
InstrT *I;
265+
SavedValT OrigVal;
279266

280267
public:
281-
AllocaSetAlignment(AllocaInst *Alloca, Tracker &Tracker);
282-
void revert() final;
268+
GenericSetter(InstrT *I, Tracker &Tracker)
269+
: IRChangeBase(Tracker), I(I), OrigVal((I->*GetterFn)()) {}
270+
void revert() final { (I->*SetterFn)(OrigVal); }
283271
void accept() final {}
284272
#ifndef NDEBUG
285273
void dump(raw_ostream &OS) const final {
286274
dumpCommon(OS);
287-
OS << "AllocaSetAlignment";
275+
OS << "GenericSetter";
288276
}
289-
LLVM_DUMP_METHOD void dump() const final;
290-
#endif
291-
};
292-
293-
class AllocaSetUsedWithInAlloca final : public IRChangeBase {
294-
AllocaInst *Alloca;
295-
bool Orig;
296-
297-
public:
298-
AllocaSetUsedWithInAlloca(AllocaInst *Alloca, Tracker &Tracker);
299-
void revert() final;
300-
void accept() final {}
301-
#ifndef NDEBUG
302-
void dump(raw_ostream &OS) const final {
303-
dumpCommon(OS);
304-
OS << "AllocaSetUsedWithInAlloca";
277+
LLVM_DUMP_METHOD void dump() const final {
278+
dump(dbgs());
279+
dbgs() << "\n";
305280
}
306-
LLVM_DUMP_METHOD void dump() const final;
307281
#endif
308282
};
309283

@@ -325,25 +299,6 @@ class CallBrInstSetIndirectDest : public IRChangeBase {
325299
#endif
326300
};
327301

328-
class SetVolatile : public IRChangeBase {
329-
/// This holds the properties of whether LoadInst or StoreInst was volatile
330-
bool WasVolatile;
331-
/// This could either be StoreInst or LoadInst
332-
PointerUnion<StoreInst *, LoadInst *> StoreOrLoad;
333-
334-
public:
335-
SetVolatile(Instruction *I, Tracker &Tracker);
336-
void revert() final;
337-
void accept() final {}
338-
#ifndef NDEBUG
339-
void dump(raw_ostream &OS) const final {
340-
dumpCommon(OS);
341-
OS << "SetVolatile";
342-
}
343-
LLVM_DUMP_METHOD void dump() const final;
344-
#endif
345-
};
346-
347302
class MoveInstr : public IRChangeBase {
348303
/// The instruction that moved.
349304
Instruction *MovedI;

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -626,8 +626,11 @@ void BranchInst::dump() const {
626626

627627
void LoadInst::setVolatile(bool V) {
628628
auto &Tracker = Ctx.getTracker();
629-
if (Tracker.isTracking())
630-
Tracker.track(std::make_unique<SetVolatile>(this, Tracker));
629+
if (Tracker.isTracking()) {
630+
Tracker.track(std::make_unique<
631+
GenericSetter<&LoadInst::isVolatile, &LoadInst::setVolatile>>(
632+
this, Tracker));
633+
}
631634
cast<llvm::LoadInst>(Val)->setVolatile(V);
632635
}
633636

@@ -688,8 +691,12 @@ void LoadInst::dump() const {
688691

689692
void StoreInst::setVolatile(bool V) {
690693
auto &Tracker = Ctx.getTracker();
691-
if (Tracker.isTracking())
692-
Tracker.track(std::make_unique<SetVolatile>(this, Tracker));
694+
if (Tracker.isTracking()) {
695+
Tracker.track(
696+
std::make_unique<
697+
GenericSetter<&StoreInst::isVolatile, &StoreInst::setVolatile>>(
698+
this, Tracker));
699+
}
693700
cast<llvm::StoreInst>(Val)->setVolatile(V);
694701
}
695702

@@ -1042,8 +1049,11 @@ llvm::SmallVector<BasicBlock *, 16> CallBrInst::getIndirectDests() const {
10421049
}
10431050
void CallBrInst::setDefaultDest(BasicBlock *BB) {
10441051
auto &Tracker = Ctx.getTracker();
1045-
if (Tracker.isTracking())
1046-
Tracker.track(std::make_unique<CallBrInstSetDefaultDest>(this, Tracker));
1052+
if (Tracker.isTracking()) {
1053+
Tracker.track(std::make_unique<GenericSetter<&CallBrInst::getDefaultDest,
1054+
&CallBrInst::setDefaultDest>>(
1055+
this, Tracker));
1056+
}
10471057
cast<llvm::CallBrInst>(Val)->setDefaultDest(cast<llvm::BasicBlock>(BB->Val));
10481058
}
10491059
void CallBrInst::setIndirectDest(unsigned Idx, BasicBlock *BB) {
@@ -1295,22 +1305,34 @@ AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace,
12951305

12961306
void AllocaInst::setAllocatedType(Type *Ty) {
12971307
auto &Tracker = Ctx.getTracker();
1298-
if (Tracker.isTracking())
1299-
Tracker.track(std::make_unique<AllocaSetAllocatedType>(this, Tracker));
1308+
if (Tracker.isTracking()) {
1309+
Tracker.track(
1310+
std::make_unique<GenericSetter<&AllocaInst::getAllocatedType,
1311+
&AllocaInst::setAllocatedType>>(
1312+
this, Tracker));
1313+
}
13001314
cast<llvm::AllocaInst>(Val)->setAllocatedType(Ty);
13011315
}
13021316

13031317
void AllocaInst::setAlignment(Align Align) {
13041318
auto &Tracker = Ctx.getTracker();
1305-
if (Tracker.isTracking())
1306-
Tracker.track(std::make_unique<AllocaSetAlignment>(this, Tracker));
1319+
if (Tracker.isTracking()) {
1320+
Tracker.track(
1321+
std::make_unique<
1322+
GenericSetter<&AllocaInst::getAlign, &AllocaInst::setAlignment>>(
1323+
this, Tracker));
1324+
}
13071325
cast<llvm::AllocaInst>(Val)->setAlignment(Align);
13081326
}
13091327

13101328
void AllocaInst::setUsedWithInAlloca(bool V) {
13111329
auto &Tracker = Ctx.getTracker();
1312-
if (Tracker.isTracking())
1313-
Tracker.track(std::make_unique<AllocaSetUsedWithInAlloca>(this, Tracker));
1330+
if (Tracker.isTracking()) {
1331+
Tracker.track(
1332+
std::make_unique<GenericSetter<&AllocaInst::isUsedWithInAlloca,
1333+
&AllocaInst::setUsedWithInAlloca>>(
1334+
this, Tracker));
1335+
}
13141336
cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V);
13151337
}
13161338

llvm/lib/SandboxIR/Tracker.cpp

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -204,61 +204,6 @@ void RemoveFromParent::dump() const {
204204
}
205205
#endif
206206

207-
AllocaSetAllocatedType::AllocaSetAllocatedType(AllocaInst *Alloca,
208-
Tracker &Tracker)
209-
: IRChangeBase(Tracker), Alloca(Alloca),
210-
OrigType(Alloca->getAllocatedType()) {}
211-
212-
void AllocaSetAllocatedType::revert() { Alloca->setAllocatedType(OrigType); }
213-
214-
#ifndef NDEBUG
215-
void AllocaSetAllocatedType::dump() const {
216-
dump(dbgs());
217-
dbgs() << "\n";
218-
}
219-
#endif // NDEBUG
220-
221-
AllocaSetAlignment::AllocaSetAlignment(AllocaInst *Alloca, Tracker &Tracker)
222-
: IRChangeBase(Tracker), Alloca(Alloca), OrigAlign(Alloca->getAlign()) {}
223-
224-
void AllocaSetAlignment::revert() { Alloca->setAlignment(OrigAlign); }
225-
226-
#ifndef NDEBUG
227-
void AllocaSetAlignment::dump() const {
228-
dump(dbgs());
229-
dbgs() << "\n";
230-
}
231-
#endif // NDEBUG
232-
233-
AllocaSetUsedWithInAlloca::AllocaSetUsedWithInAlloca(AllocaInst *Alloca,
234-
Tracker &Tracker)
235-
: IRChangeBase(Tracker), Alloca(Alloca),
236-
Orig(Alloca->isUsedWithInAlloca()) {}
237-
238-
void AllocaSetUsedWithInAlloca::revert() { Alloca->setUsedWithInAlloca(Orig); }
239-
240-
#ifndef NDEBUG
241-
void AllocaSetUsedWithInAlloca::dump() const {
242-
dump(dbgs());
243-
dbgs() << "\n";
244-
}
245-
#endif // NDEBUG
246-
247-
CallBrInstSetDefaultDest::CallBrInstSetDefaultDest(CallBrInst *CallBr,
248-
Tracker &Tracker)
249-
: IRChangeBase(Tracker), CallBr(CallBr) {
250-
OrigDefaultDest = CallBr->getDefaultDest();
251-
}
252-
void CallBrInstSetDefaultDest::revert() {
253-
CallBr->setDefaultDest(OrigDefaultDest);
254-
}
255-
#ifndef NDEBUG
256-
void CallBrInstSetDefaultDest::dump() const {
257-
dump(dbgs());
258-
dbgs() << "\n";
259-
}
260-
#endif
261-
262207
CallBrInstSetIndirectDest::CallBrInstSetIndirectDest(CallBrInst *CallBr,
263208
unsigned Idx,
264209
Tracker &Tracker)
@@ -275,35 +220,6 @@ void CallBrInstSetIndirectDest::dump() const {
275220
}
276221
#endif
277222

278-
SetVolatile::SetVolatile(Instruction *I, Tracker &Tracker)
279-
: IRChangeBase(Tracker) {
280-
if (auto *Load = dyn_cast<LoadInst>(I)) {
281-
WasVolatile = Load->isVolatile();
282-
StoreOrLoad = Load;
283-
} else if (auto *Store = dyn_cast<StoreInst>(I)) {
284-
WasVolatile = Store->isVolatile();
285-
StoreOrLoad = Store;
286-
} else {
287-
llvm_unreachable("Expected LoadInst or StoreInst");
288-
}
289-
}
290-
291-
void SetVolatile::revert() {
292-
if (auto *Load = StoreOrLoad.dyn_cast<LoadInst *>()) {
293-
Load->setVolatile(WasVolatile);
294-
} else if (auto *Store = StoreOrLoad.dyn_cast<StoreInst *>()) {
295-
Store->setVolatile(WasVolatile);
296-
} else {
297-
llvm_unreachable("Expected LoadInst or StoreInst");
298-
}
299-
}
300-
#ifndef NDEBUG
301-
void SetVolatile::dump() const {
302-
dump(dbgs());
303-
dbgs() << "\n";
304-
}
305-
#endif
306-
307223
MoveInstr::MoveInstr(Instruction *MovedI, Tracker &Tracker)
308224
: IRChangeBase(Tracker), MovedI(MovedI) {
309225
if (auto *NextI = MovedI->getNextNode())

0 commit comments

Comments
 (0)