[llvm] r228041 - IR: Assembly and bitcode for GenericDebugNode

Duncan P. N. Exon Smith dexonsmith at apple.com
Tue Feb 3 13:54:14 PST 2015


Author: dexonsmith
Date: Tue Feb  3 15:54:14 2015
New Revision: 228041

URL: http://llvm.org/viewvc/llvm-project?rev=228041&view=rev
Log:
IR: Assembly and bitcode for GenericDebugNode

Added:
    llvm/trunk/test/Assembler/generic-debug-node.ll
    llvm/trunk/test/Assembler/invalid-generic-debug-node-tag-missing.ll
    llvm/trunk/test/Assembler/invalid-generic-debug-node-tag-overflow.ll
Modified:
    llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/AsmParser/LLParser.h
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
    llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
    llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h
    llvm/trunk/lib/IR/AsmWriter.cpp

Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=228041&r1=228040&r2=228041&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original)
+++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Tue Feb  3 15:54:14 2015
@@ -146,7 +146,8 @@ namespace bitc {
     METADATA_OLD_NODE      = 8,   // OLD_NODE:      [n x (type num, value num)]
     METADATA_OLD_FN_NODE   = 9,   // OLD_FN_NODE:   [n x (type num, value num)]
     METADATA_NAMED_NODE    = 10,  // NAMED_NODE:    [n x mdnodes]
-    METADATA_ATTACHMENT    = 11   // [m x [value, [n x [id, mdnode]]]
+    METADATA_ATTACHMENT    = 11,  // [m x [value, [n x [id, mdnode]]]
+    METADATA_GENERIC_DEBUG = 12   // [distinct, tag, vers, header, n x md num]
   };
 
   // The constants block (CONSTANTS_BLOCK_ID) describes emission for each

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=228041&r1=228040&r2=228041&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Tue Feb  3 15:54:14 2015
@@ -2945,6 +2945,24 @@ bool LLParser::ParseMDField(LocTy Loc, S
   return false;
 }
 
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDStringField &Result) {
+  std::string S;
+  if (ParseStringConstant(S))
+    return true;
+
+  Result.assign(std::move(S));
+  return false;
+}
+
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDFieldList &Result) {
+  SmallVector<Metadata *, 4> MDs;
+  if (ParseMDNodeVector(MDs))
+    return true;
+
+  Result.assign(std::move(MDs));
+  return false;
+}
+
 template <class ParserTy>
 bool LLParser::ParseMDFieldsImplBody(ParserTy parseField) {
   do {
@@ -2990,6 +3008,7 @@ bool LLParser::ParseSpecializedMDNode(MD
     return Parse##CLASS(N, IsDistinct);
 
   DISPATCH_TO_PARSER(MDLocation);
+  DISPATCH_TO_PARSER(GenericDebugNode);
 #undef DISPATCH_TO_PARSER
 
   return TokError("expected metadata type");
@@ -3014,6 +3033,8 @@ bool LLParser::ParseSpecializedMDNode(MD
       return true;                                                             \
     VISIT_MD_FIELDS(NOP_FIELD, REQUIRE_FIELD)                                  \
   } while (false)
+#define GET_OR_DISTINCT(CLASS, ARGS)                                           \
+  (IsDistinct ? CLASS::getDistinct ARGS : CLASS::get ARGS)
 
 /// ParseMDLocationFields:
 ///   ::= !MDLocation(line: 43, column: 8, scope: !5, inlinedAt: !6)
@@ -3030,6 +3051,21 @@ bool LLParser::ParseMDLocation(MDNode *&
   Result = get(Context, line.Val, column.Val, scope.Val, inlinedAt.Val);
   return false;
 }
+
+/// ParseGenericDebugNode:
+///   ::= !GenericDebugNode(tag: 15, header: "...", operands: {...})
+bool LLParser::ParseGenericDebugNode(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
+  REQUIRED(tag, MDUnsignedField<uint32_t>, (0, ~0u >> 16));                    \
+  OPTIONAL(header, MDStringField, );                                           \
+  OPTIONAL(operands, MDFieldList, );
+  PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+  Result = GET_OR_DISTINCT(GenericDebugNode,
+                           (Context, tag.Val, header.Val, operands.Val));
+  return false;
+}
 #undef PARSE_MD_FIELD
 #undef NOP_FIELD
 #undef REQUIRE_FIELD

Modified: llvm/trunk/lib/AsmParser/LLParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=228041&r1=228040&r2=228041&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.h (original)
+++ llvm/trunk/lib/AsmParser/LLParser.h Tue Feb  3 15:54:14 2015
@@ -88,10 +88,11 @@ namespace llvm {
 
     void assign(FieldTy Val) {
       Seen = true;
-      this->Val = Val;
+      this->Val = std::move(Val);
     }
 
-    explicit MDFieldImpl(FieldTy Default) : Val(Default), Seen(false) {}
+    explicit MDFieldImpl(FieldTy Default)
+        : Val(std::move(Default)), Seen(false) {}
   };
   template <class NumTy> struct MDUnsignedField : public MDFieldImpl<NumTy> {
     typedef typename MDUnsignedField::ImplTy ImplTy;
@@ -104,6 +105,12 @@ namespace llvm {
   struct MDField : public MDFieldImpl<Metadata *> {
     MDField() : ImplTy(nullptr) {}
   };
+  struct MDStringField : public MDFieldImpl<std::string> {
+    MDStringField() : ImplTy(std::string()) {}
+  };
+  struct MDFieldList : public MDFieldImpl<SmallVector<Metadata *, 4>> {
+    MDFieldList() : ImplTy(SmallVector<Metadata *, 4>()) {}
+  };
 
   class LLParser {
   public:
@@ -421,6 +428,8 @@ namespace llvm {
     bool ParseMDField(LocTy Loc, StringRef Name,
                       MDUnsignedField<uint32_t> &Result);
     bool ParseMDField(LocTy Loc, StringRef Name, MDField &Result);
+    bool ParseMDField(LocTy Loc, StringRef Name, MDStringField &Result);
+    bool ParseMDField(LocTy Loc, StringRef Name, MDFieldList &Result);
     template <class FieldTy> bool ParseMDField(StringRef Name, FieldTy &Result);
     template <class ParserTy>
     bool ParseMDFieldsImplBody(ParserTy parseField);
@@ -428,6 +437,7 @@ namespace llvm {
     bool ParseMDFieldsImpl(ParserTy parseField, LocTy &ClosingLoc);
     bool ParseSpecializedMDNode(MDNode *&N, bool IsDistinct = false);
     bool ParseMDLocation(MDNode *&Result, bool IsDistinct);
+    bool ParseGenericDebugNode(MDNode *&Result, bool IsDistinct);
 
     // Function Parsing.
     struct ArgInfo {

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=228041&r1=228040&r2=228041&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Tue Feb  3 15:54:14 2015
@@ -1181,6 +1181,17 @@ std::error_code BitcodeReader::ParseMeta
 
   SmallVector<uint64_t, 64> Record;
 
+  auto getMDString = [&](unsigned ID) -> MDString *{
+    // This requires that the ID is not really a forward reference.  In
+    // particular, the MDString must already have been resolved.
+    if (ID)
+      return cast<MDString>(MDValueList.getValueFwdRef(ID - 1));
+    return nullptr;
+  };
+
+#define GET_OR_DISTINCT(CLASS, DISTINCT, ARGS)                                 \
+  (DISTINCT ? CLASS::getDistinct ARGS : CLASS::get ARGS)
+
   // Read all the records.
   while (1) {
     BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
@@ -1318,6 +1329,26 @@ std::error_code BitcodeReader::ParseMeta
                               NextMDValueNo++);
       break;
     }
+    case bitc::METADATA_GENERIC_DEBUG: {
+      if (Record.size() < 4)
+        return Error("Invalid record");
+
+      unsigned Tag = Record[1];
+      unsigned Version = Record[2];
+
+      if (Tag >= 1u << 16 || Version != 0)
+        return Error("Invalid record");
+
+      auto *Header = getMDString(Record[3]);
+      SmallVector<Metadata *, 8> DwarfOps;
+      for (unsigned I = 4, E = Record.size(); I != E; ++I)
+        DwarfOps.push_back(Record[I] ? MDValueList.getValueFwdRef(Record[I] - 1)
+                                     : nullptr);
+      MDValueList.AssignValue(GET_OR_DISTINCT(GenericDebugNode, Record[0],
+                                              (Context, Tag, Header, DwarfOps)),
+                              NextMDValueNo++);
+      break;
+    }
     case bitc::METADATA_STRING: {
       std::string String(Record.begin(), Record.end());
       llvm::UpgradeMDStringConstant(String);
@@ -1339,6 +1370,7 @@ std::error_code BitcodeReader::ParseMeta
     }
     }
   }
+#undef GET_OR_DISTINCT
 }
 
 /// decodeSignRotatedValue - Decode a signed value stored with the sign bit in

Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=228041&r1=228040&r2=228041&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Tue Feb  3 15:54:14 2015
@@ -792,10 +792,20 @@ static void WriteMDLocation(const MDLoca
   Record.clear();
 }
 
-static void WriteGenericDebugNode(const GenericDebugNode *,
-                                  const ValueEnumerator &, BitstreamWriter &,
-                                  SmallVectorImpl<uint64_t> &, unsigned) {
-  llvm_unreachable("unimplemented");
+static void WriteGenericDebugNode(const GenericDebugNode *N,
+                                  const ValueEnumerator &VE,
+                                  BitstreamWriter &Stream,
+                                  SmallVectorImpl<uint64_t> &Record,
+                                  unsigned Abbrev) {
+  Record.push_back(N->isDistinct());
+  Record.push_back(N->getTag());
+  Record.push_back(0); // Per-tag version field; unused for now.
+
+  for (auto &I : N->operands())
+    Record.push_back(VE.getMetadataOrNullID(I));
+
+  Stream.EmitRecord(bitc::METADATA_GENERIC_DEBUG, Record, Abbrev);
+  Record.clear();
 }
 
 static void WriteModuleMetadata(const Module *M,
@@ -833,6 +843,23 @@ static void WriteModuleMetadata(const Mo
     MDLocationAbbrev = Stream.EmitAbbrev(Abbv);
   }
 
+  unsigned GenericDebugNodeAbbrev = 0;
+  if (VE.hasGenericDebugNode()) {
+    // Abbrev for METADATA_GENERIC_DEBUG.
+    //
+    // Assume the column is usually under 128, and always output the inlined-at
+    // location (it's never more expensive than building an array size 1).
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_GENERIC_DEBUG));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    GenericDebugNodeAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
   unsigned NameAbbrev = 0;
   if (!M->named_metadata_empty()) {
     // Abbrev for METADATA_NAME.
@@ -844,7 +871,6 @@ static void WriteModuleMetadata(const Mo
   }
 
   unsigned MDTupleAbbrev = 0;
-  unsigned GenericDebugNodeAbbrev = 0;
   SmallVector<uint64_t, 64> Record;
   for (const Metadata *MD : MDs) {
     if (const MDNode *N = dyn_cast<MDNode>(MD)) {

Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=228041&r1=228040&r2=228041&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Tue Feb  3 15:54:14 2015
@@ -284,7 +284,7 @@ static bool isIntOrIntVectorValue(const
 }
 
 ValueEnumerator::ValueEnumerator(const Module &M)
-    : HasMDString(false), HasMDLocation(false) {
+    : HasMDString(false), HasMDLocation(false), HasGenericDebugNode(false) {
   if (shouldPreserveBitcodeUseListOrder())
     UseListOrders = predictUseListOrder(M);
 
@@ -544,6 +544,7 @@ void ValueEnumerator::EnumerateMetadata(
 
   HasMDString |= isa<MDString>(MD);
   HasMDLocation |= isa<MDLocation>(MD);
+  HasGenericDebugNode |= isa<GenericDebugNode>(MD);
 
   // Replace the dummy ID inserted above with the correct one.  MDValueMap may
   // have changed by inserting operands, so we need a fresh lookup here.

Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h?rev=228041&r1=228040&r2=228041&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h (original)
+++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h Tue Feb  3 15:54:14 2015
@@ -66,6 +66,7 @@ private:
   MetadataMapType MDValueMap;
   bool HasMDString;
   bool HasMDLocation;
+  bool HasGenericDebugNode;
 
   typedef DenseMap<AttributeSet, unsigned> AttributeGroupMapType;
   AttributeGroupMapType AttributeGroupMap;
@@ -120,6 +121,7 @@ public:
 
   bool hasMDString() const { return HasMDString; }
   bool hasMDLocation() const { return HasMDLocation; }
+  bool hasGenericDebugNode() const { return HasGenericDebugNode; }
 
   unsigned getTypeID(Type *T) const {
     TypeMapType::const_iterator I = TypeMap.find(T);

Modified: llvm/trunk/lib/IR/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=228041&r1=228040&r2=228041&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)
+++ llvm/trunk/lib/IR/AsmWriter.cpp Tue Feb  3 15:54:14 2015
@@ -1286,10 +1286,32 @@ raw_ostream &operator<<(raw_ostream &OS,
 }
 } // end namespace
 
-static void writeGenericDebugNode(raw_ostream &, const GenericDebugNode *,
-                                  TypePrinting *, SlotTracker *,
-                                  const Module *) {
-  llvm_unreachable("Unimplemented write");
+static void writeGenericDebugNode(raw_ostream &Out, const GenericDebugNode *N,
+                                  TypePrinting *TypePrinter,
+                                  SlotTracker *Machine, const Module *Context) {
+  Out << "!GenericDebugNode(";
+  FieldSeparator FS;
+  // Always output the line, since 0 is a relevant and important value for it.
+  Out << FS << "tag: " << N->getTag();
+  if (!N->getHeader().empty()) {
+    Out << FS << "header: \"";
+    PrintEscapedString(N->getHeader(), Out);
+    Out << "\"";
+  }
+  if (N->getNumDwarfOperands()) {
+    Out << FS << "operands: {";
+    FieldSeparator IFS;
+    for (auto &I : N->dwarf_operands()) {
+      Out << IFS;
+      if (!I) {
+        Out << "null";
+        continue;
+      }
+      WriteAsOperandInternal(Out, I, TypePrinter, Machine, Context);
+    }
+    Out << "}";
+  }
+  Out << ")";
 }
 
 static void writeMDLocation(raw_ostream &Out, const MDLocation *DL,

Added: llvm/trunk/test/Assembler/generic-debug-node.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/generic-debug-node.ll?rev=228041&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/generic-debug-node.ll (added)
+++ llvm/trunk/test/Assembler/generic-debug-node.ll Tue Feb  3 15:54:14 2015
@@ -0,0 +1,24 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+; RUN: verify-uselistorder %s
+
+; CHECK: !named = !{!0, !1, !1, !2, !2, !2, !2, !3, !4}
+!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8}
+
+; CHECK: !0 = !{}
+!0 = !{}
+
+; CHECK-NEXT: !1 = !GenericDebugNode(tag: 3, header: "some\00header", operands: {!0, !2, !2})
+!1 = !GenericDebugNode(tag: 3, header: "some\00header", operands: {!0, !3, !4})
+!2 = !GenericDebugNode(tag: 3, header: "some\00header", operands: {!{}, !3, !4})
+
+; CHECK-NEXT: !2 = !GenericDebugNode(tag: 3)
+!3 = !GenericDebugNode(tag: 3)
+!4 = !GenericDebugNode(tag: 3, header: "")
+!5 = !GenericDebugNode(tag: 3, operands: {})
+!6 = !GenericDebugNode(tag: 3, header: "", operands: {})
+
+; CHECK-NEXT: !3 = distinct !GenericDebugNode(tag: 3)
+!7 = distinct !GenericDebugNode(tag: 3)
+
+; CHECK-NEXT: !4 = !GenericDebugNode(tag: 65535)
+!8 = !GenericDebugNode(tag: 65535)

Added: llvm/trunk/test/Assembler/invalid-generic-debug-node-tag-missing.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/invalid-generic-debug-node-tag-missing.ll?rev=228041&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/invalid-generic-debug-node-tag-missing.ll (added)
+++ llvm/trunk/test/Assembler/invalid-generic-debug-node-tag-missing.ll Tue Feb  3 15:54:14 2015
@@ -0,0 +1,4 @@
+; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
+
+; CHECK: <stdin>:[[@LINE+1]]:47: error: missing required field 'tag'
+!0 = !GenericDebugNode(header: "some\00header")

Added: llvm/trunk/test/Assembler/invalid-generic-debug-node-tag-overflow.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/invalid-generic-debug-node-tag-overflow.ll?rev=228041&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/invalid-generic-debug-node-tag-overflow.ll (added)
+++ llvm/trunk/test/Assembler/invalid-generic-debug-node-tag-overflow.ll Tue Feb  3 15:54:14 2015
@@ -0,0 +1,7 @@
+; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
+
+; CHECK-NOT: error
+!0 = !GenericDebugNode(tag: 65535)
+
+; CHECK: <stdin>:[[@LINE+1]]:29: error: value for 'tag' too large, limit is 65535
+!1 = !GenericDebugNode(tag: 65536)





More information about the llvm-commits mailing list