diff options
-rw-r--r-- | llvm/include/llvm/IR/ModuleSlotTracker.h | 8 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 5 | ||||
-rw-r--r-- | llvm/unittests/IR/ValueTest.cpp | 60 |
3 files changed, 73 insertions, 0 deletions
diff --git a/llvm/include/llvm/IR/ModuleSlotTracker.h b/llvm/include/llvm/IR/ModuleSlotTracker.h index c37dcecf8e4..49730a66bdf 100644 --- a/llvm/include/llvm/IR/ModuleSlotTracker.h +++ b/llvm/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/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index ec4370970ba..823916e7690 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/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/llvm/unittests/IR/ValueTest.cpp b/llvm/unittests/IR/ValueTest.cpp index 32d66a1b472..7a4c2f696f7 100644 --- a/llvm/unittests/IR/ValueTest.cpp +++ b/llvm/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<Module> 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<Module> 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 |