From 9adb2129bdee87e527f4109af37bc5d33383f6ea Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Mon, 27 Jul 2015 22:31:04 +0000 Subject: [PATCH] IR: Expose the method 'getLocalSlot' in the module slot tracker. This commit publicly exposes the method 'getLocalSlot' in the 'ModuleSlotTracker' class. This change is useful for MIR serialization, to serialize the unnamed basic block and unnamed alloca references. Reviewers: Duncan P. N. Exon Smith git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243336 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/ModuleSlotTracker.h | 8 ++++ lib/IR/AsmWriter.cpp | 5 +++ unittests/IR/ValueTest.cpp | 60 +++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/include/llvm/IR/ModuleSlotTracker.h b/include/llvm/IR/ModuleSlotTracker.h index c37dcecf8e4..49730a66bdf 100644 --- a/include/llvm/IR/ModuleSlotTracker.h +++ b/include/llvm/IR/ModuleSlotTracker.h @@ -17,6 +17,7 @@ namespace llvm { class Module; class Function; class SlotTracker; +class Value; /// Manage lifetime of a slot tracker for printing IR. /// @@ -61,6 +62,13 @@ public: /// Purge the currently incorporated function and incorporate \c F. If \c F /// is currently incorporated, this is a no-op. void incorporateFunction(const Function &F); + + /// Return the slot number of the specified local value. + /// + /// A function that defines this value should be incorporated prior to calling + /// this method. + /// Return -1 if the value is not in the function's SlotTracker. + int getLocalSlot(const Value *V); }; } // end namespace llvm diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index ec4370970ba..823916e7690 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -702,6 +702,11 @@ void ModuleSlotTracker::incorporateFunction(const Function &F) { this->F = &F; } +int ModuleSlotTracker::getLocalSlot(const Value *V) { + assert(F && "No function incorporated"); + return Machine->getLocalSlot(V); +} + static SlotTracker *createSlotTracker(const Module *M) { return new SlotTracker(M); } diff --git a/unittests/IR/ValueTest.cpp b/unittests/IR/ValueTest.cpp index 32d66a1b472..7a4c2f696f7 100644 --- a/unittests/IR/ValueTest.cpp +++ b/unittests/IR/ValueTest.cpp @@ -175,4 +175,64 @@ TEST(ValueTest, printSlots) { #undef CHECK_PRINT_AS_OPERAND } +TEST(ValueTest, getLocalSlots) { + // Verify that the getLocalSlot method returns the correct slot numbers. + LLVMContext C; + const char *ModuleString = "define void @f(i32 %x, i32 %y) {\n" + "entry:\n" + " %0 = add i32 %y, 1\n" + " %1 = add i32 %y, 1\n" + " br label %2\n" + "\n" + " ret void\n" + "}\n"; + SMDiagnostic Err; + std::unique_ptr M = parseAssemblyString(ModuleString, Err, C); + + Function *F = M->getFunction("f"); + ASSERT_TRUE(F); + ASSERT_FALSE(F->empty()); + BasicBlock &EntryBB = F->getEntryBlock(); + ASSERT_EQ(3u, EntryBB.size()); + BasicBlock *BB2 = ++F->begin(); + ASSERT_TRUE(BB2); + + Instruction *I0 = EntryBB.begin(); + ASSERT_TRUE(I0); + Instruction *I1 = ++EntryBB.begin(); + ASSERT_TRUE(I1); + + ModuleSlotTracker MST(M.get()); + MST.incorporateFunction(*F); + EXPECT_EQ(MST.getLocalSlot(I0), 0); + EXPECT_EQ(MST.getLocalSlot(I1), 1); + EXPECT_EQ(MST.getLocalSlot(&EntryBB), -1); + EXPECT_EQ(MST.getLocalSlot(BB2), 2); +} + +#if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) +TEST(ValueTest, getLocalSlotDeath) { + LLVMContext C; + const char *ModuleString = "define void @f(i32 %x, i32 %y) {\n" + "entry:\n" + " %0 = add i32 %y, 1\n" + " %1 = add i32 %y, 1\n" + " br label %2\n" + "\n" + " ret void\n" + "}\n"; + SMDiagnostic Err; + std::unique_ptr M = parseAssemblyString(ModuleString, Err, C); + + Function *F = M->getFunction("f"); + ASSERT_TRUE(F); + ASSERT_FALSE(F->empty()); + BasicBlock *BB2 = ++F->begin(); + ASSERT_TRUE(BB2); + + ModuleSlotTracker MST(M.get()); + EXPECT_DEATH(MST.getLocalSlot(BB2), "No function incorporated"); +} +#endif + } // end anonymous namespace