mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +00:00 
			
		
		
		
	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
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user