From 3aa342be500a55c3bbee302f3a8db937eaa2c241 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 16 Oct 2013 01:49:05 +0000 Subject: Add support for metadata representing .ident directives. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192764 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/AsmPrinter.h | 2 ++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 18 ++++++++++++++++++ lib/IR/Verifier.cpp | 20 ++++++++++++++++++++ test/CodeGen/X86/ident-metadata.ll | 9 +++++++++ test/Verifier/ident-meta1.ll | 12 ++++++++++++ test/Verifier/ident-meta2.ll | 13 +++++++++++++ test/Verifier/ident-meta3.ll | 10 ++++++++++ 7 files changed, 84 insertions(+) create mode 100644 test/CodeGen/X86/ident-metadata.ll create mode 100644 test/Verifier/ident-meta1.ll create mode 100644 test/Verifier/ident-meta2.ll create mode 100644 test/Verifier/ident-meta3.ll diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 997f5f3c10..d6a6ab4698 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -491,6 +491,8 @@ namespace llvm { const MachineBasicBlock *MBB, unsigned uid) const; void EmitLLVMUsedList(const ConstantArray *InitList); + /// Emit llvm.ident metadata in an '.ident' directive. + void EmitModuleIdents(Module &M); void EmitXXStructorList(const Constant *List, bool isCtor); GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C); }; diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 60f1bfffb2..0fe341a243 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -953,6 +953,9 @@ bool AsmPrinter::doFinalization(Module &M) { if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I)) MP->finishAssembly(*this); + // Emit llvm.ident metadata in an '.ident' directive. + EmitModuleIdents(M); + // If we don't have any trampolines, then we don't require stack memory // to be executable. Some targets have a directive to declare this. Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline"); @@ -1332,6 +1335,21 @@ void AsmPrinter::EmitXXStructorList(const Constant *List, bool isCtor) { } } +void AsmPrinter::EmitModuleIdents(Module &M) { + if (!MAI->hasIdentDirective()) + return; + + if (const NamedMDNode *NMD = M.getNamedMetadata("llvm.ident")) { + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + const MDNode *N = NMD->getOperand(i); + assert(N->getNumOperands() == 1 && + "llvm.ident metadata entry can have only one operand"); + const MDString *S = cast(N->getOperand(0)); + OutStreamer.EmitIdent(S->getString()); + } + } +} + //===--------------------------------------------------------------------===// // Emission and print routines // diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index c7559c1bf9..7d657def32 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -216,6 +216,7 @@ namespace { visitNamedMDNode(*I); visitModuleFlags(M); + visitModuleIdents(M); // Verify Debug Info. verifyDebugInfo(M); @@ -260,6 +261,7 @@ namespace { void visitGlobalAlias(GlobalAlias &GA); void visitNamedMDNode(NamedMDNode &NMD); void visitMDNode(MDNode &MD, Function *F); + void visitModuleIdents(Module &M); void visitModuleFlags(Module &M); void visitModuleFlag(MDNode *Op, DenseMap &SeenIDs, SmallVectorImpl &Requirements); @@ -613,6 +615,24 @@ void Verifier::visitMDNode(MDNode &MD, Function *F) { } } +void Verifier::visitModuleIdents(Module &M) { + const NamedMDNode *Idents = M.getNamedMetadata("llvm.ident"); + if (!Idents) + return; + + // llvm.ident takes a list of metadata entry. Each entry has only one string. + // Scan each llvm.ident entry and make sure that this requirement is met. + for (unsigned i = 0, e = Idents->getNumOperands(); i != e; ++i) { + const MDNode *N = Idents->getOperand(i); + Assert1(N->getNumOperands() == 1, + "incorrect number of operands in llvm.ident metadata", N); + Assert1(isa(N->getOperand(0)), + ("invalid value for llvm.ident metadata entry operand" + "(the operand should be a string)"), + N->getOperand(0)); + } +} + void Verifier::visitModuleFlags(Module &M) { const NamedMDNode *Flags = M.getModuleFlagsMetadata(); if (!Flags) return; diff --git a/test/CodeGen/X86/ident-metadata.ll b/test/CodeGen/X86/ident-metadata.ll new file mode 100644 index 0000000000..211d882694 --- /dev/null +++ b/test/CodeGen/X86/ident-metadata.ll @@ -0,0 +1,9 @@ +; RUN: llc -march=x86 < %s | FileCheck %s +; Verify that llvm.ident metadata is emitted as .ident +; directives in assembly files, and in the .comment section in ELF object files. + +; CHECK: .ident "clang version x.x" +; CHECK-NEXT: .ident "something else" +!llvm.ident = !{!0, !1} +!0 = metadata !{metadata !"clang version x.x"} +!1 = metadata !{metadata !"something else"} diff --git a/test/Verifier/ident-meta1.ll b/test/Verifier/ident-meta1.ll new file mode 100644 index 0000000000..fb247a8c5e --- /dev/null +++ b/test/Verifier/ident-meta1.ll @@ -0,0 +1,12 @@ +; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s +; Verify that llvm.ident is properly structured. +; llvm.ident takes a list of metadata entries. +; Each metadata entry can have only one string. + +!llvm.ident = !{!0, !1} +!0 = metadata !{metadata !"version string"} +!1 = metadata !{metadata !"string1", metadata !"string2"} +; CHECK: assembly parsed, but does not verify as correct! +; CHECK-NEXT: incorrect number of operands in llvm.ident metadata +; CHECK-NEXT: metadata !1 + diff --git a/test/Verifier/ident-meta2.ll b/test/Verifier/ident-meta2.ll new file mode 100644 index 0000000000..e86f18adc0 --- /dev/null +++ b/test/Verifier/ident-meta2.ll @@ -0,0 +1,13 @@ +; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s +; Verify that llvm.ident is properly structured. +; llvm.ident takes a list of metadata entries. +; Each metadata entry can contain one string only. + +!llvm.ident = !{!0, !1, !2, !3} +!0 = metadata !{metadata !"str1"} +!1 = metadata !{metadata !"str2"} +!2 = metadata !{metadata !"str3"} +!3 = metadata !{i32 1} +; CHECK: assembly parsed, but does not verify as correct! +; CHECK-NEXT: invalid value for llvm.ident metadata entry operand(the operand should be a string) +; CHECK-NEXT: i32 1 diff --git a/test/Verifier/ident-meta3.ll b/test/Verifier/ident-meta3.ll new file mode 100644 index 0000000000..a847b46216 --- /dev/null +++ b/test/Verifier/ident-meta3.ll @@ -0,0 +1,10 @@ +; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s +; Verify that llvm.ident is properly structured. +; llvm.ident takes a list of metadata entries. +; Each metadata entry can contain one string only. + +!llvm.ident = !{!0} +!0 = metadata !{metadata !{metadata !"nested metadata"}} +; CHECK: assembly parsed, but does not verify as correct! +; CHECK-NEXT: invalid value for llvm.ident metadata entry operand(the operand should be a string) +; CHECK-NEXT: metadata !1 -- cgit v1.2.3