mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-28 23:17:10 +00:00
IR: Make Metadata::print() reliable and useful
Replumb the `AsmWriter` so that `Metadata::print()` is generally useful. (Similarly change `Metadata::printAsOperand()`.) - `SlotTracker` now has a mode where all metadata will be correctly numbered when initializing a `Module`. Normally, `Metadata` only referenced from within `Function`s gets numbered when the `Function` is incorporated. - `Metadata::print()` and `Metadata::printAsOperand()` (and `Metadata::dump()`) now take an optional `Module` argument. When provided, `SlotTracker` is initialized with the new mode, and the numbering will be complete and consistent for all calls to `print()`. - `Value::print()` uses the new `SlotTracker` mode when printing intrinsics with `MDNode` operands, `MetadataAsValue` operands, or the bodies of functions. Thus, metadata numbering will be consistent between calls to `Metadata::print()` and `Value::print()`. - `Metadata::print()` (and `Metadata::dump()`) now print the full definition of `MDNode`s: !5 = !{!6, !"abc", !7} This matches behaviour for `Value::print()`, which includes the name of instructions. - Updated call sites in `Verifier` to call `print()` instead of `printAsOperand()`. All this, so that `Verifier` can print out useful failure messages that involve `Metadata` for PR22777. Note that `Metadata::printAsOperand()` previously took an optional `bool` and `Module` operand. The former was cargo-culted from `Value::printAsOperand()` and wasn't doing anything useful. The latter didn't give consistent results (without the new `SlotTracker` mode). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232275 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -221,7 +221,7 @@ TEST_F(MDNodeTest, Print) {
|
||||
std::string Expected;
|
||||
{
|
||||
raw_string_ostream OS(Expected);
|
||||
OS << "!{";
|
||||
OS << "<" << (void *)N << "> = !{";
|
||||
C->printAsOperand(OS);
|
||||
OS << ", ";
|
||||
S->printAsOperand(OS);
|
||||
@@ -241,6 +241,89 @@ TEST_F(MDNodeTest, Print) {
|
||||
EXPECT_EQ(Expected, Actual);
|
||||
}
|
||||
|
||||
#define EXPECT_PRINTER_EQ(EXPECTED, PRINT) \
|
||||
do { \
|
||||
std::string Actual_; \
|
||||
raw_string_ostream OS(Actual_); \
|
||||
PRINT; \
|
||||
OS.flush(); \
|
||||
std::string Expected_(EXPECTED); \
|
||||
EXPECT_EQ(Expected_, Actual_); \
|
||||
} while (false)
|
||||
|
||||
TEST_F(MDNodeTest, PrintFromModule) {
|
||||
Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 7);
|
||||
MDString *S = MDString::get(Context, "foo");
|
||||
MDNode *N0 = getNode();
|
||||
MDNode *N1 = getNode(N0);
|
||||
MDNode *N2 = getNode(N0, N1);
|
||||
|
||||
Metadata *Args[] = {ConstantAsMetadata::get(C), S, nullptr, N0, N1, N2};
|
||||
MDNode *N = MDNode::get(Context, Args);
|
||||
Module M("test", Context);
|
||||
NamedMDNode *NMD = M.getOrInsertNamedMetadata("named");
|
||||
NMD->addOperand(N);
|
||||
|
||||
std::string Expected;
|
||||
{
|
||||
raw_string_ostream OS(Expected);
|
||||
OS << "!0 = !{";
|
||||
C->printAsOperand(OS);
|
||||
OS << ", ";
|
||||
S->printAsOperand(OS);
|
||||
OS << ", null, !1, !2, !3}";
|
||||
}
|
||||
|
||||
EXPECT_PRINTER_EQ(Expected, N->print(OS, &M));
|
||||
}
|
||||
|
||||
TEST_F(MDNodeTest, PrintFromFunction) {
|
||||
Module M("test", Context);
|
||||
auto *FTy = FunctionType::get(Type::getVoidTy(Context), false);
|
||||
auto *F0 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F0", &M);
|
||||
auto *F1 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F1", &M);
|
||||
auto *BB0 = BasicBlock::Create(Context, "entry", F0);
|
||||
auto *BB1 = BasicBlock::Create(Context, "entry", F1);
|
||||
auto *R0 = ReturnInst::Create(Context, BB0);
|
||||
auto *R1 = ReturnInst::Create(Context, BB1);
|
||||
auto *N0 = MDNode::getDistinct(Context, None);
|
||||
auto *N1 = MDNode::getDistinct(Context, None);
|
||||
R0->setMetadata("md", N0);
|
||||
R1->setMetadata("md", N1);
|
||||
|
||||
EXPECT_PRINTER_EQ("!0 = distinct !{}", N0->print(OS, &M));
|
||||
EXPECT_PRINTER_EQ("!1 = distinct !{}", N1->print(OS, &M));
|
||||
}
|
||||
|
||||
TEST_F(MDNodeTest, PrintFromMetadataAsValue) {
|
||||
Module M("test", Context);
|
||||
|
||||
auto *Intrinsic =
|
||||
Function::Create(FunctionType::get(Type::getVoidTy(Context),
|
||||
Type::getMetadataTy(Context), false),
|
||||
GlobalValue::ExternalLinkage, "llvm.intrinsic", &M);
|
||||
|
||||
auto *FTy = FunctionType::get(Type::getVoidTy(Context), false);
|
||||
auto *F0 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F0", &M);
|
||||
auto *F1 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F1", &M);
|
||||
auto *BB0 = BasicBlock::Create(Context, "entry", F0);
|
||||
auto *BB1 = BasicBlock::Create(Context, "entry", F1);
|
||||
auto *N0 = MDNode::getDistinct(Context, None);
|
||||
auto *N1 = MDNode::getDistinct(Context, None);
|
||||
auto *MAV0 = MetadataAsValue::get(Context, N0);
|
||||
auto *MAV1 = MetadataAsValue::get(Context, N1);
|
||||
CallInst::Create(Intrinsic, MAV0, "", BB0);
|
||||
CallInst::Create(Intrinsic, MAV1, "", BB1);
|
||||
|
||||
EXPECT_PRINTER_EQ("!0 = distinct !{}", MAV0->print(OS));
|
||||
EXPECT_PRINTER_EQ("!1 = distinct !{}", MAV1->print(OS));
|
||||
EXPECT_PRINTER_EQ("!0", MAV0->printAsOperand(OS, false));
|
||||
EXPECT_PRINTER_EQ("!1", MAV1->printAsOperand(OS, false));
|
||||
EXPECT_PRINTER_EQ("metadata !0", MAV0->printAsOperand(OS, true));
|
||||
EXPECT_PRINTER_EQ("metadata !1", MAV1->printAsOperand(OS, true));
|
||||
}
|
||||
#undef EXPECT_PRINTER_EQ
|
||||
|
||||
TEST_F(MDNodeTest, NullOperand) {
|
||||
// metadata !{}
|
||||
MDNode *Empty = MDNode::get(Context, None);
|
||||
|
Reference in New Issue
Block a user