summaryrefslogtreecommitdiff
path: root/unittests/IR/ValueTest.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-06-27 00:38:26 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-06-27 00:38:26 +0000
commit2a5fda92b4ed2ddbaa03e1e6bb2107d8fe7f2cea (patch)
tree64bdab92b42ee5cb49d82c9235bdc59d826f9f87 /unittests/IR/ValueTest.cpp
parente92934e0781bd87151abe20afe3a9dbbb31818b8 (diff)
IR: Expose ModuleSlotTracker in Value::print()
Allow callers of `Value::print()` and `Metadata::print()` to pass in a `ModuleSlotTracker`. This allows them to pay only once for calculating module-level slots (such as Metadata). This is related to PR23865, where there was a huge cost for `MachineFunction::print()`. Although I don't have a *particular* user in mind for this new code, I have hit big slowdowns before when running `opt -debug`, and I think this will be useful. Going forward, if someone hits a big slowdown with `print()` statements, they can create a `ModuleSlotTracker` and send it through. Similarly, adding support to `Value::dump()` and `Metadata::dump()` should be trivial. I added unit tests to be sure the `print()` functions actually behave the same way with and without the slot tracker. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240867 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests/IR/ValueTest.cpp')
-rw-r--r--unittests/IR/ValueTest.cpp69
1 files changed, 69 insertions, 0 deletions
diff --git a/unittests/IR/ValueTest.cpp b/unittests/IR/ValueTest.cpp
index 4dd0c2c36cf..32d66a1b472 100644
--- a/unittests/IR/ValueTest.cpp
+++ b/unittests/IR/ValueTest.cpp
@@ -11,6 +11,7 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
@@ -106,4 +107,72 @@ TEST(GlobalTest, AlignDeath) {
#endif
#endif
+TEST(ValueTest, printSlots) {
+ // Check that Value::print() and Value::printAsOperand() work with and
+ // without a slot tracker.
+ 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"
+ " 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 &BB = F->getEntryBlock();
+ ASSERT_EQ(3u, BB.size());
+
+ Instruction *I0 = BB.begin();
+ ASSERT_TRUE(I0);
+ Instruction *I1 = ++BB.begin();
+ ASSERT_TRUE(I1);
+
+ ModuleSlotTracker MST(M.get());
+
+#define CHECK_PRINT(INST, STR) \
+ do { \
+ { \
+ std::string S; \
+ raw_string_ostream OS(S); \
+ INST->print(OS); \
+ EXPECT_EQ(STR, OS.str()); \
+ } \
+ { \
+ std::string S; \
+ raw_string_ostream OS(S); \
+ INST->print(OS, MST); \
+ EXPECT_EQ(STR, OS.str()); \
+ } \
+ } while (false)
+ CHECK_PRINT(I0, " %0 = add i32 %y, 1");
+ CHECK_PRINT(I1, " %1 = add i32 %y, 1");
+#undef CHECK_PRINT
+
+#define CHECK_PRINT_AS_OPERAND(INST, TYPE, STR) \
+ do { \
+ { \
+ std::string S; \
+ raw_string_ostream OS(S); \
+ INST->printAsOperand(OS, TYPE); \
+ EXPECT_EQ(StringRef(STR), StringRef(OS.str())); \
+ } \
+ { \
+ std::string S; \
+ raw_string_ostream OS(S); \
+ INST->printAsOperand(OS, TYPE, MST); \
+ EXPECT_EQ(StringRef(STR), StringRef(OS.str())); \
+ } \
+ } while (false)
+ CHECK_PRINT_AS_OPERAND(I0, false, "%0");
+ CHECK_PRINT_AS_OPERAND(I1, false, "%1");
+ CHECK_PRINT_AS_OPERAND(I0, true, "i32 %0");
+ CHECK_PRINT_AS_OPERAND(I1, true, "i32 %1");
+#undef CHECK_PRINT_AS_OPERAND
+}
+
} // end anonymous namespace