[llvm] [SandboxIR][Tracker] Track InsertIntoBB (PR #101595)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 3 09:39:01 PDT 2024
https://github.com/vporpo updated https://github.com/llvm/llvm-project/pull/101595
>From 1dbbabf95832d8bc89a0b474ae7d6844ffb0e18b Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Thu, 18 Jul 2024 15:10:15 -0700
Subject: [PATCH] [SandboxIR][Tracker] Track InsertIntoBB
This tracks the insertion of an Instruction into a BasicBlock.
---
llvm/include/llvm/SandboxIR/Tracker.h | 16 ++++++
llvm/lib/SandboxIR/SandboxIR.cpp | 14 +++++-
llvm/lib/SandboxIR/Tracker.cpp | 12 +++++
llvm/unittests/SandboxIR/TrackerTest.cpp | 63 ++++++++++++++++++++++++
4 files changed, 104 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/SandboxIR/Tracker.h b/llvm/include/llvm/SandboxIR/Tracker.h
index 238e4e9dacd34..8a963a41449ef 100644
--- a/llvm/include/llvm/SandboxIR/Tracker.h
+++ b/llvm/include/llvm/SandboxIR/Tracker.h
@@ -291,6 +291,22 @@ class MoveInstr : public IRChangeBase {
#endif // NDEBUG
};
+class InsertIntoBB final : public IRChangeBase {
+ Instruction *InsertedI = nullptr;
+
+public:
+ InsertIntoBB(Instruction *InsertedI, Tracker &Tracker);
+ void revert() final;
+ void accept() final {}
+#ifndef NDEBUG
+ void dump(raw_ostream &OS) const final {
+ dumpCommon(OS);
+ OS << "InsertIntoBB";
+ }
+ LLVM_DUMP_METHOD void dump() const final;
+#endif // NDEBUG
+};
+
/// The tracker collects all the change objects and implements the main API for
/// saving / reverting / accepting.
class Tracker {
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index a67cb2a5bb25a..2f94c83311776 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -430,6 +430,11 @@ void Instruction::insertBefore(Instruction *BeforeI) {
assert(is_sorted(getLLVMInstrs(),
[](auto *I1, auto *I2) { return I1->comesBefore(I2); }) &&
"Expected program order!");
+
+ auto &Tracker = Ctx.getTracker();
+ if (Tracker.isTracking())
+ Tracker.track(std::make_unique<InsertIntoBB>(this, Tracker));
+
// Insert the LLVM IR Instructions in program order.
for (llvm::Instruction *I : getLLVMInstrs())
I->insertBefore(BeforeTopI);
@@ -443,14 +448,21 @@ void Instruction::insertInto(BasicBlock *BB, const BBIterator &WhereIt) {
llvm::BasicBlock *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
llvm::Instruction *LLVMBeforeI;
llvm::BasicBlock::iterator LLVMBeforeIt;
+ Instruction *BeforeI;
if (WhereIt != BB->end()) {
- Instruction *BeforeI = &*WhereIt;
+ BeforeI = &*WhereIt;
LLVMBeforeI = BeforeI->getTopmostLLVMInstruction();
LLVMBeforeIt = LLVMBeforeI->getIterator();
} else {
+ BeforeI = nullptr;
LLVMBeforeI = nullptr;
LLVMBeforeIt = LLVMBB->end();
}
+
+ auto &Tracker = Ctx.getTracker();
+ if (Tracker.isTracking())
+ Tracker.track(std::make_unique<InsertIntoBB>(this, Tracker));
+
// Insert the LLVM IR Instructions in program order.
for (llvm::Instruction *I : getLLVMInstrs())
I->insertInto(LLVMBB, LLVMBeforeIt);
diff --git a/llvm/lib/SandboxIR/Tracker.cpp b/llvm/lib/SandboxIR/Tracker.cpp
index 0310160e8bf35..1f154d7de8948 100644
--- a/llvm/lib/SandboxIR/Tracker.cpp
+++ b/llvm/lib/SandboxIR/Tracker.cpp
@@ -259,6 +259,18 @@ void MoveInstr::dump() const {
}
#endif
+void InsertIntoBB::revert() { InsertedI->removeFromParent(); }
+
+InsertIntoBB::InsertIntoBB(Instruction *InsertedI, Tracker &Tracker)
+ : IRChangeBase(Tracker), InsertedI(InsertedI) {}
+
+#ifndef NDEBUG
+void InsertIntoBB::dump() const {
+ dump(dbgs());
+ dbgs() << "\n";
+}
+#endif
+
void Tracker::track(std::unique_ptr<IRChangeBase> &&Change) {
assert(State == TrackerState::Record && "The tracker should be tracking!");
Changes.push_back(std::move(Change));
diff --git a/llvm/unittests/SandboxIR/TrackerTest.cpp b/llvm/unittests/SandboxIR/TrackerTest.cpp
index d016c7793a52c..04979b45755e0 100644
--- a/llvm/unittests/SandboxIR/TrackerTest.cpp
+++ b/llvm/unittests/SandboxIR/TrackerTest.cpp
@@ -442,6 +442,69 @@ define i32 @foo(i32 %arg) {
EXPECT_EQ(It, BB->end());
}
+// TODO: Test multi-instruction patterns.
+TEST_F(TrackerTest, InsertIntoBB) {
+ parseIR(C, R"IR(
+define void @foo(i32 %arg) {
+ %add0 = add i32 %arg, %arg
+ ret void
+}
+)IR");
+ Function &LLVMF = *M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+
+ auto *F = Ctx.createFunction(&LLVMF);
+ auto *BB = &*F->begin();
+ auto It = BB->begin();
+ sandboxir::Instruction *Add0 = &*It++;
+ sandboxir::Instruction *Ret = &*It++;
+ // Detach `Add0` before we save.
+ Add0->removeFromParent();
+
+ // Check insertBefore(Instruction *) with tracking enabled.
+ Ctx.save();
+ Add0->insertBefore(Ret);
+ It = BB->begin();
+ EXPECT_EQ(&*It++, Add0);
+ EXPECT_EQ(&*It++, Ret);
+ EXPECT_EQ(It, BB->end());
+ // Check revert().
+ Ctx.revert();
+ It = BB->begin();
+ EXPECT_EQ(&*It++, Ret);
+ EXPECT_EQ(It, BB->end());
+
+ // Check insertAfter(Instruction *) with tracking enabled.
+ Ctx.save();
+ Add0->insertAfter(Ret);
+ It = BB->begin();
+ EXPECT_EQ(&*It++, Ret);
+ EXPECT_EQ(&*It++, Add0);
+ EXPECT_EQ(It, BB->end());
+ // Check revert().
+ Ctx.revert();
+ It = BB->begin();
+ EXPECT_EQ(&*It++, Ret);
+ EXPECT_EQ(It, BB->end());
+
+ // Check insertInto(BasicBlock *, BasicBlock::iterator) with tracking enabled.
+ Ctx.save();
+ Add0->insertInto(BB, Ret->getIterator());
+ It = BB->begin();
+ EXPECT_EQ(&*It++, Add0);
+ EXPECT_EQ(&*It++, Ret);
+ EXPECT_EQ(It, BB->end());
+ // Check revert().
+ Ctx.revert();
+ It = BB->begin();
+ EXPECT_EQ(&*It++, Ret);
+ EXPECT_EQ(It, BB->end());
+
+ // To make sure we don't leak memory insert `Add0` back into the BB before the
+ // end of the test.
+ Add0->insertBefore(Ret);
+}
+
TEST_F(TrackerTest, CallBaseSetters) {
parseIR(C, R"IR(
declare void @bar1(i8)
More information about the llvm-commits
mailing list