Skip to content

Commit 95b366c

Browse files
[SandboxIR] Add setVolatile function to LoadInst and StoreInst (#101759)
This patch adds sandboxir::LoadInst::setVolatile() and sandboxir::StoreInst::setVolatile() and the corresponding tracking class.
1 parent ed5b0e1 commit 95b366c

File tree

6 files changed

+123
-1
lines changed

6 files changed

+123
-1
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,8 @@ class LoadInst final : public UnaryInstruction {
870870
public:
871871
/// Return true if this is a load from a volatile memory location.
872872
bool isVolatile() const { return cast<llvm::LoadInst>(Val)->isVolatile(); }
873-
873+
/// Specify whether this is a volatile load or not.
874+
void setVolatile(bool V);
874875
unsigned getUseOperandNo(const Use &Use) const final {
875876
return getUseOperandNoDefault(Use);
876877
}
@@ -919,6 +920,8 @@ class StoreInst final : public Instruction {
919920
public:
920921
/// Return true if this is a store from a volatile memory location.
921922
bool isVolatile() const { return cast<llvm::StoreInst>(Val)->isVolatile(); }
923+
/// Specify whether this is a volatile store or not.
924+
void setVolatile(bool V);
922925
unsigned getUseOperandNo(const Use &Use) const final {
923926
return getUseOperandNoDefault(Use);
924927
}

llvm/include/llvm/SandboxIR/Tracker.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ namespace llvm::sandboxir {
5454

5555
class BasicBlock;
5656
class CallBrInst;
57+
class LoadInst;
58+
class StoreInst;
5759
class Instruction;
5860
class Tracker;
5961

@@ -271,6 +273,25 @@ class CallBrInstSetIndirectDest : public IRChangeBase {
271273
#endif
272274
};
273275

276+
class SetVolatile : public IRChangeBase {
277+
/// This holds the properties of whether LoadInst or StoreInst was volatile
278+
bool WasVolatile;
279+
/// This could either be StoreInst or LoadInst
280+
PointerUnion<StoreInst *, LoadInst *> StoreOrLoad;
281+
282+
public:
283+
SetVolatile(Instruction *I, Tracker &Tracker);
284+
void revert() final;
285+
void accept() final {}
286+
#ifndef NDEBUG
287+
void dump(raw_ostream &OS) const final {
288+
dumpCommon(OS);
289+
OS << "SetVolatile";
290+
}
291+
LLVM_DUMP_METHOD void dump() const final;
292+
#endif
293+
};
294+
274295
class MoveInstr : public IRChangeBase {
275296
/// The instruction that moved.
276297
Instruction *MovedI;

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,13 @@ void BranchInst::dump() const {
610610
}
611611
#endif // NDEBUG
612612

613+
void LoadInst::setVolatile(bool V) {
614+
auto &Tracker = Ctx.getTracker();
615+
if (Tracker.isTracking())
616+
Tracker.track(std::make_unique<SetVolatile>(this, Tracker));
617+
cast<llvm::LoadInst>(Val)->setVolatile(V);
618+
}
619+
613620
LoadInst *LoadInst::create(Type *Ty, Value *Ptr, MaybeAlign Align,
614621
Instruction *InsertBefore, Context &Ctx,
615622
const Twine &Name) {
@@ -664,6 +671,14 @@ void LoadInst::dump() const {
664671
dbgs() << "\n";
665672
}
666673
#endif // NDEBUG
674+
675+
void StoreInst::setVolatile(bool V) {
676+
auto &Tracker = Ctx.getTracker();
677+
if (Tracker.isTracking())
678+
Tracker.track(std::make_unique<SetVolatile>(this, Tracker));
679+
cast<llvm::StoreInst>(Val)->setVolatile(V);
680+
}
681+
667682
StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align,
668683
Instruction *InsertBefore, Context &Ctx) {
669684
return create(V, Ptr, Align, InsertBefore, /*IsVolatile=*/false, Ctx);

llvm/lib/SandboxIR/Tracker.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,35 @@ void CallBrInstSetIndirectDest::dump() const {
235235
}
236236
#endif
237237

238+
SetVolatile::SetVolatile(Instruction *I, Tracker &Tracker)
239+
: IRChangeBase(Tracker) {
240+
if (auto *Load = dyn_cast<LoadInst>(I)) {
241+
WasVolatile = Load->isVolatile();
242+
StoreOrLoad = Load;
243+
} else if (auto *Store = dyn_cast<StoreInst>(I)) {
244+
WasVolatile = Store->isVolatile();
245+
StoreOrLoad = Store;
246+
} else {
247+
llvm_unreachable("Expected LoadInst or StoreInst");
248+
}
249+
}
250+
251+
void SetVolatile::revert() {
252+
if (auto *Load = StoreOrLoad.dyn_cast<LoadInst *>()) {
253+
Load->setVolatile(WasVolatile);
254+
} else if (auto *Store = StoreOrLoad.dyn_cast<StoreInst *>()) {
255+
Store->setVolatile(WasVolatile);
256+
} else {
257+
llvm_unreachable("Expected LoadInst or StoreInst");
258+
}
259+
}
260+
#ifndef NDEBUG
261+
void SetVolatile::dump() const {
262+
dump(dbgs());
263+
dbgs() << "\n";
264+
}
265+
#endif
266+
238267
MoveInstr::MoveInstr(Instruction *MovedI, Tracker &Tracker)
239268
: IRChangeBase(Tracker), MovedI(MovedI) {
240269
if (auto *NextI = MovedI->getNextNode())

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,7 @@ define void @foo(ptr %arg0, ptr %arg1) {
754754
EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Ld));
755755
auto *VLd = cast<sandboxir::LoadInst>(&*It++);
756756
auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
757+
bool OrigVolatileValue;
757758

758759
// Check isVolatile()
759760
EXPECT_FALSE(Ld->isVolatile());
@@ -768,6 +769,11 @@ define void @foo(ptr %arg0, ptr %arg1) {
768769
sandboxir::LoadInst::create(Ld->getType(), Arg1, Align(8),
769770
/*InsertBefore=*/Ret, Ctx, "NewLd");
770771
EXPECT_FALSE(NewLd->isVolatile());
772+
OrigVolatileValue = NewLd->isVolatile();
773+
NewLd->setVolatile(true);
774+
EXPECT_TRUE(NewLd->isVolatile());
775+
NewLd->setVolatile(OrigVolatileValue);
776+
EXPECT_FALSE(NewLd->isVolatile());
771777
EXPECT_EQ(NewLd->getType(), Ld->getType());
772778
EXPECT_EQ(NewLd->getPointerOperand(), Arg1);
773779
EXPECT_EQ(NewLd->getAlign(), 8);
@@ -778,6 +784,11 @@ define void @foo(ptr %arg0, ptr %arg1) {
778784
/*InsertBefore=*/Ret,
779785
/*IsVolatile=*/true, Ctx, "NewVLd");
780786

787+
EXPECT_TRUE(NewVLd->isVolatile());
788+
OrigVolatileValue = NewVLd->isVolatile();
789+
NewVLd->setVolatile(false);
790+
EXPECT_FALSE(NewVLd->isVolatile());
791+
NewVLd->setVolatile(OrigVolatileValue);
781792
EXPECT_TRUE(NewVLd->isVolatile());
782793
EXPECT_EQ(NewVLd->getName(), "NewVLd");
783794
// Check create(InsertAtEnd)
@@ -823,6 +834,7 @@ define void @foo(i8 %val, ptr %ptr) {
823834
auto *St = cast<sandboxir::StoreInst>(&*It++);
824835
auto *VSt = cast<sandboxir::StoreInst>(&*It++);
825836
auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
837+
bool OrigVolatileValue;
826838

827839
// Check that the StoreInst has been created correctly.
828840
EXPECT_FALSE(St->isVolatile());
@@ -837,6 +849,11 @@ define void @foo(i8 %val, ptr %ptr) {
837849
sandboxir::StoreInst::create(Val, Ptr, Align(8),
838850
/*InsertBefore=*/Ret, Ctx);
839851
EXPECT_FALSE(NewSt->isVolatile());
852+
OrigVolatileValue = NewSt->isVolatile();
853+
NewSt->setVolatile(true);
854+
EXPECT_TRUE(NewSt->isVolatile());
855+
NewSt->setVolatile(OrigVolatileValue);
856+
EXPECT_FALSE(NewSt->isVolatile());
840857
EXPECT_EQ(NewSt->getType(), St->getType());
841858
EXPECT_EQ(NewSt->getValueOperand(), Val);
842859
EXPECT_EQ(NewSt->getPointerOperand(), Ptr);
@@ -848,6 +865,11 @@ define void @foo(i8 %val, ptr %ptr) {
848865
/*InsertBefore=*/Ret,
849866
/*IsVolatile=*/true, Ctx);
850867
EXPECT_TRUE(NewVSt->isVolatile());
868+
OrigVolatileValue = NewVSt->isVolatile();
869+
NewVSt->setVolatile(false);
870+
EXPECT_FALSE(NewVSt->isVolatile());
871+
NewVSt->setVolatile(OrigVolatileValue);
872+
EXPECT_TRUE(NewVSt->isVolatile());
851873
EXPECT_EQ(NewVSt->getType(), VSt->getType());
852874
EXPECT_EQ(NewVSt->getValueOperand(), Val);
853875
EXPECT_EQ(NewVSt->getPointerOperand(), Ptr);

llvm/unittests/SandboxIR/TrackerTest.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,3 +708,35 @@ define void @foo(i8 %arg0, i8 %arg1, i8 %arg2) {
708708
EXPECT_EQ(PHI->getIncomingBlock(1), BB1);
709709
EXPECT_EQ(PHI->getIncomingValue(1), Arg1);
710710
}
711+
712+
TEST_F(TrackerTest, SetVolatile) {
713+
parseIR(C, R"IR(
714+
define void @foo(ptr %arg0, i8 %val) {
715+
%ld = load i8, ptr %arg0, align 64
716+
store i8 %val, ptr %arg0, align 64
717+
ret void
718+
}
719+
)IR");
720+
Function &LLVMF = *M->getFunction("foo");
721+
sandboxir::Context Ctx(C);
722+
723+
auto *F = Ctx.createFunction(&LLVMF);
724+
auto *BB = &*F->begin();
725+
auto It = BB->begin();
726+
auto *Load = cast<sandboxir::LoadInst>(&*It++);
727+
auto *Store = cast<sandboxir::StoreInst>(&*It++);
728+
729+
EXPECT_FALSE(Load->isVolatile());
730+
Ctx.save();
731+
Load->setVolatile(true);
732+
EXPECT_TRUE(Load->isVolatile());
733+
Ctx.revert();
734+
EXPECT_FALSE(Load->isVolatile());
735+
736+
EXPECT_FALSE(Store->isVolatile());
737+
Ctx.save();
738+
Store->setVolatile(true);
739+
EXPECT_TRUE(Store->isVolatile());
740+
Ctx.revert();
741+
EXPECT_FALSE(Store->isVolatile());
742+
}

0 commit comments

Comments
 (0)