[llvm] r271348 - Add support for metadata attachments for global variables.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Tue May 31 16:01:54 PDT 2016


Author: pcc
Date: Tue May 31 18:01:54 2016
New Revision: 271348

URL: http://llvm.org/viewvc/llvm-project?rev=271348&view=rev
Log:
Add support for metadata attachments for global variables.

This patch adds an IR, assembly and bitcode representation for metadata
attachments for globals. Future patches will port existing features to use
these new attachments.

Differential Revision: http://reviews.llvm.org/D20074

Modified:
    llvm/trunk/docs/BitCodeFormat.rst
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
    llvm/trunk/include/llvm/IR/Function.h
    llvm/trunk/include/llvm/IR/GlobalObject.h
    llvm/trunk/include/llvm/IR/GlobalVariable.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
    llvm/trunk/lib/IR/Function.cpp
    llvm/trunk/lib/IR/Globals.cpp
    llvm/trunk/lib/IR/LLVMContextImpl.h
    llvm/trunk/lib/IR/Metadata.cpp
    llvm/trunk/test/Assembler/metadata.ll

Modified: llvm/trunk/docs/BitCodeFormat.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/BitCodeFormat.rst?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/docs/BitCodeFormat.rst (original)
+++ llvm/trunk/docs/BitCodeFormat.rst Tue May 31 18:01:54 2016
@@ -856,6 +856,16 @@ be one ``GCNAME`` record for each garbag
 ``gc`` attributes within the module. These records can be referenced by 1-based
 index in the *gc* fields of ``FUNCTION`` records.
 
+MODULE_CODE_GLOBALVAR_ATTACHMENT Record
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``[GLOBALVAR_ATTACHMENT, valueid, n x [id, mdnode]]``
+
+The ``GLOBALVAR_ATTACHMENT`` record (code 19) describes the metadata
+attachments for a global variable. The ``valueid`` is the value index for
+the global variable, and the remaining fields are pairs of metadata name
+indices and metadata node indices.
+
 .. _PARAMATTR_BLOCK:
 
 PARAMATTR_BLOCK Contents

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Tue May 31 18:01:54 2016
@@ -619,7 +619,8 @@ assume that the globals are densely pack
 iterate over them as an array, alignment padding would break this
 iteration. The maximum alignment is ``1 << 29``.
 
-Globals can also have a :ref:`DLL storage class <dllstorageclass>`.
+Globals can also have a :ref:`DLL storage class <dllstorageclass>` and
+an optional list of attached :ref:`metadata <metadata>`,
 
 Variables and aliases can have a
 :ref:`Thread Local Storage Model <tls_model>`.
@@ -630,7 +631,7 @@ Syntax::
                          [unnamed_addr] [AddrSpace] [ExternallyInitialized]
                          <global | constant> <Type> [<InitializerConstant>]
                          [, section "name"] [, comdat [($name)]]
-                         [, align <Alignment>]
+                         [, align <Alignment>] (, !name !N)*
 
 For example, the following defines a global in a numbered address space
 with an initializer, section, and alignment:

Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original)
+++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Tue May 31 18:01:54 2016
@@ -113,6 +113,9 @@ enum ModuleCodes {
 
   // IFUNC: [ifunc value type, addrspace, resolver val#, linkage, visibility]
   MODULE_CODE_IFUNC = 18,
+
+  // GLOBALVAR_ATTACHMENT: [valueid, n x [id, mdnode]]
+  MODULE_CODE_GLOBALVAR_ATTACHMENT = 19,
 };
 
 /// PARAMATTR blocks have code for defining a parameter attribute set.

Modified: llvm/trunk/include/llvm/IR/Function.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Function.h?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Function.h (original)
+++ llvm/trunk/include/llvm/IR/Function.h Tue May 31 18:01:54 2016
@@ -72,13 +72,8 @@ private:
   /// Bits from GlobalObject::GlobalObjectSubclassData.
   enum {
     /// Whether this function is materializable.
-    IsMaterializableBit = 1 << 0,
-    HasMetadataHashEntryBit = 1 << 1
+    IsMaterializableBit = 0,
   };
-  void setGlobalObjectBit(unsigned Mask, bool Value) {
-    setGlobalObjectSubClassData((~Mask & getGlobalObjectSubClassData()) |
-                                (Value ? Mask : 0u));
-  }
 
   friend class SymbolTableListTraits<Function>;
 
@@ -614,35 +609,6 @@ public:
   /// setjmp or other function that gcc recognizes as "returning twice".
   bool callsFunctionThatReturnsTwice() const;
 
-  /// \brief Check if this has any metadata.
-  bool hasMetadata() const { return hasMetadataHashEntry(); }
-
-  /// \brief Get the current metadata attachment, if any.
-  ///
-  /// Returns \c nullptr if such an attachment is missing.
-  /// @{
-  MDNode *getMetadata(unsigned KindID) const;
-  MDNode *getMetadata(StringRef Kind) const;
-  /// @}
-
-  /// \brief Set a particular kind of metadata attachment.
-  ///
-  /// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or
-  /// replacing it if it already exists.
-  /// @{
-  void setMetadata(unsigned KindID, MDNode *MD);
-  void setMetadata(StringRef Kind, MDNode *MD);
-  /// @}
-
-  /// \brief Get all current metadata attachments.
-  void
-  getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const;
-
-  /// \brief Drop metadata not in the given list.
-  ///
-  /// Drop all metadata from \c this not included in \c KnownIDs.
-  void dropUnknownMetadata(ArrayRef<unsigned> KnownIDs);
-
   /// \brief Set the attached subprogram.
   ///
   /// Calls \a setMetadata() with \a LLVMContext::MD_dbg.
@@ -664,15 +630,6 @@ private:
     Value::setValueSubclassData(D);
   }
   void setValueSubclassDataBit(unsigned Bit, bool On);
-
-  bool hasMetadataHashEntry() const {
-    return getGlobalObjectSubClassData() & HasMetadataHashEntryBit;
-  }
-  void setHasMetadataHashEntry(bool HasEntry) {
-    setGlobalObjectBit(HasMetadataHashEntryBit, HasEntry);
-  }
-
-  void clearMetadata();
 };
 
 template <>

Modified: llvm/trunk/include/llvm/IR/GlobalObject.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GlobalObject.h?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/GlobalObject.h (original)
+++ llvm/trunk/include/llvm/IR/GlobalObject.h Tue May 31 18:01:54 2016
@@ -20,6 +20,7 @@
 
 namespace llvm {
 class Comdat;
+class MDNode;
 class Module;
 
 class GlobalObject : public GlobalValue {
@@ -36,12 +37,19 @@ protected:
 
   std::string Section;     // Section to emit this into, empty means default
   Comdat *ObjComdat;
-  static const unsigned AlignmentBits = 5;
+  enum {
+    LastAlignmentBit = 4,
+    HasMetadataHashEntryBit,
+
+    GlobalObjectBits,
+  };
   static const unsigned GlobalObjectSubClassDataBits =
-      GlobalValueSubClassDataBits - AlignmentBits;
+      GlobalValueSubClassDataBits - GlobalObjectBits;
 
 private:
+  static const unsigned AlignmentBits = LastAlignmentBit + 1;
   static const unsigned AlignmentMask = (1 << AlignmentBits) - 1;
+  static const unsigned GlobalObjectMask = (1 << GlobalObjectBits) - 1;
 
 public:
   unsigned getAlignment() const {
@@ -63,6 +71,35 @@ public:
   Comdat *getComdat() { return ObjComdat; }
   void setComdat(Comdat *C) { ObjComdat = C; }
 
+  /// Check if this has any metadata.
+  bool hasMetadata() const { return hasMetadataHashEntry(); }
+
+  /// Get the current metadata attachment, if any.
+  ///
+  /// Returns \c nullptr if such an attachment is missing.
+  /// @{
+  MDNode *getMetadata(unsigned KindID) const;
+  MDNode *getMetadata(StringRef Kind) const;
+  /// @}
+
+  /// Set a particular kind of metadata attachment.
+  ///
+  /// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or
+  /// replacing it if it already exists.
+  /// @{
+  void setMetadata(unsigned KindID, MDNode *MD);
+  void setMetadata(StringRef Kind, MDNode *MD);
+  /// @}
+
+  /// Get all current metadata attachments.
+  void
+  getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const;
+
+  /// Drop metadata not in the given list.
+  ///
+  /// Drop all metadata from \c this not included in \c KnownIDs.
+  void dropUnknownMetadata(ArrayRef<unsigned> KnownIDs);
+
   void copyAttributesFrom(const GlobalValue *Src) override;
 
   // Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -70,6 +107,19 @@ public:
     return V->getValueID() == Value::FunctionVal ||
            V->getValueID() == Value::GlobalVariableVal;
   }
+
+protected:
+  void clearMetadata();
+
+private:
+  bool hasMetadataHashEntry() const {
+    return getGlobalValueSubClassData() & (1 << HasMetadataHashEntryBit);
+  }
+  void setHasMetadataHashEntry(bool HasEntry) {
+    unsigned Mask = 1 << HasMetadataHashEntryBit;
+    setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) |
+                               (HasEntry ? Mask : 0u));
+  }
 };
 
 } // End llvm namespace

Modified: llvm/trunk/include/llvm/IR/GlobalVariable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GlobalVariable.h?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/GlobalVariable.h (original)
+++ llvm/trunk/include/llvm/IR/GlobalVariable.h Tue May 31 18:01:54 2016
@@ -159,6 +159,10 @@ public:
   ///
   void eraseFromParent() override;
 
+  /// Drop all references in preparation to destroy the GlobalVariable. This
+  /// drops not only the reference to the initializer but also to any metadata.
+  void dropAllReferences();
+
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const Value *V) {
     return V->getValueID() == Value::GlobalVariableVal;

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Tue May 31 18:01:54 2016
@@ -891,6 +891,9 @@ bool LLParser::ParseGlobal(const std::st
       unsigned Alignment;
       if (ParseOptionalAlignment(Alignment)) return true;
       GV->setAlignment(Alignment);
+    } else if (Lex.getKind() == lltok::MetadataVar) {
+      if (ParseGlobalObjectMetadataAttachment(*GV))
+        return true;
     } else {
       Comdat *C;
       if (parseOptionalComdat(Name, C))
@@ -1708,17 +1711,24 @@ bool LLParser::ParseInstructionMetadata(
   return false;
 }
 
+/// ParseGlobalObjectMetadataAttachment
+///   ::= !dbg !57
+bool LLParser::ParseGlobalObjectMetadataAttachment(GlobalObject &GO) {
+  unsigned MDK;
+  MDNode *N;
+  if (ParseMetadataAttachment(MDK, N))
+    return true;
+
+  GO.setMetadata(MDK, N);
+  return false;
+}
+
 /// ParseOptionalFunctionMetadata
 ///   ::= (!dbg !57)*
 bool LLParser::ParseOptionalFunctionMetadata(Function &F) {
-  while (Lex.getKind() == lltok::MetadataVar) {
-    unsigned MDK;
-    MDNode *N;
-    if (ParseMetadataAttachment(MDK, N))
+  while (Lex.getKind() == lltok::MetadataVar)
+    if (ParseGlobalObjectMetadataAttachment(F))
       return true;
-
-    F.setMetadata(MDK, N);
-  }
   return false;
 }
 

Modified: llvm/trunk/lib/AsmParser/LLParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.h (original)
+++ llvm/trunk/lib/AsmParser/LLParser.h Tue May 31 18:01:54 2016
@@ -424,6 +424,7 @@ namespace llvm {
     bool ParseMDNodeVector(SmallVectorImpl<Metadata *> &MDs);
     bool ParseMetadataAttachment(unsigned &Kind, MDNode *&MD);
     bool ParseInstructionMetadata(Instruction &Inst);
+    bool ParseGlobalObjectMetadataAttachment(GlobalObject &GO);
     bool ParseOptionalFunctionMetadata(Function &F);
 
     template <class FieldTy>

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Tue May 31 18:01:54 2016
@@ -443,6 +443,9 @@ private:
                                        unsigned &NextMetadataNo);
   std::error_code parseMetadataKinds();
   std::error_code parseMetadataKindRecord(SmallVectorImpl<uint64_t> &Record);
+  std::error_code
+  parseGlobalObjectAttachment(GlobalObject &GO,
+                              ArrayRef<uint64_t> Record);
   std::error_code parseMetadataAttachment(Function &F);
   ErrorOr<std::string> parseModuleTriple();
   std::error_code parseUseLists();
@@ -3820,6 +3823,16 @@ std::error_code BitcodeReader::parseModu
       }
       break;
     }
+    case bitc::MODULE_CODE_GLOBALVAR_ATTACHMENT: {
+      if (Record.size() % 2 == 0)
+        return error("Invalid record");
+      unsigned ValueID = Record[0];
+      if (ValueID >= ValueList.size())
+        return error("Invalid record");
+      if (auto *GV = dyn_cast<GlobalVariable>(ValueList[ValueID]))
+        parseGlobalObjectAttachment(*GV, ArrayRef<uint64_t>(Record).slice(1));
+      break;
+    }
     // FUNCTION:  [type, callingconv, isproto, linkage, paramattr,
     //             alignment, section, visibility, gc, unnamed_addr,
     //             prologuedata, dllstorageclass, comdat, prefixdata]
@@ -4144,6 +4157,21 @@ ErrorOr<std::string> BitcodeReader::pars
   }
 }
 
+std::error_code BitcodeReader::parseGlobalObjectAttachment(
+    GlobalObject &GO, ArrayRef<uint64_t> Record) {
+  assert(Record.size() % 2 == 0);
+  for (unsigned I = 0, E = Record.size(); I != E; I += 2) {
+    auto K = MDKindMap.find(Record[I]);
+    if (K == MDKindMap.end())
+      return error("Invalid ID");
+    MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[I + 1]);
+    if (!MD)
+      return error("Invalid metadata attachment");
+    GO.setMetadata(K->second, MD);
+  }
+  return std::error_code();
+}
+
 /// Parse metadata attachments.
 std::error_code BitcodeReader::parseMetadataAttachment(Function &F) {
   if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
@@ -4175,15 +4203,8 @@ std::error_code BitcodeReader::parseMeta
         return error("Invalid record");
       if (RecordLength % 2 == 0) {
         // A function attachment.
-        for (unsigned I = 0; I != RecordLength; I += 2) {
-          auto K = MDKindMap.find(Record[I]);
-          if (K == MDKindMap.end())
-            return error("Invalid ID");
-          MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[I + 1]);
-          if (!MD)
-            return error("Invalid metadata attachment");
-          F.setMetadata(K->second, MD);
-        }
+        if (std::error_code EC = parseGlobalObjectAttachment(F, Record))
+          return EC;
         continue;
       }
 

Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Tue May 31 18:01:54 2016
@@ -223,7 +223,10 @@ private:
                             SmallVectorImpl<uint64_t> &Record);
   void writeModuleMetadata();
   void writeFunctionMetadata(const Function &F);
-  void writeMetadataAttachment(const Function &F);
+  void writeFunctionMetadataAttachment(const Function &F);
+  void writeGlobalVariableMetadataAttachment(const GlobalVariable &GV);
+  void pushGlobalMetadataAttachment(SmallVectorImpl<uint64_t> &Record,
+                                    const GlobalObject &GO);
   void writeModuleMetadataStore();
   void writeOperandBundleTags();
   void writeConstants(unsigned FirstVal, unsigned LastVal, bool isGlobal);
@@ -1831,24 +1834,31 @@ void ModuleBitcodeWriter::writeFunctionM
   Stream.ExitBlock();
 }
 
-void ModuleBitcodeWriter::writeMetadataAttachment(const Function &F) {
+void ModuleBitcodeWriter::pushGlobalMetadataAttachment(
+    SmallVectorImpl<uint64_t> &Record, const GlobalObject &GO) {
+  // [n x [id, mdnode]]
+  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+  GO.getAllMetadata(MDs);
+  for (const auto &I : MDs) {
+    Record.push_back(I.first);
+    Record.push_back(VE.getMetadataID(I.second));
+  }
+}
+
+void ModuleBitcodeWriter::writeFunctionMetadataAttachment(const Function &F) {
   Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3);
 
   SmallVector<uint64_t, 64> Record;
 
-  // Write metadata attachments
-  // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
-  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
-  F.getAllMetadata(MDs);
-  if (!MDs.empty()) {
-    for (const auto &I : MDs) {
-      Record.push_back(I.first);
-      Record.push_back(VE.getMetadataID(I.second));
-    }
+  if (F.hasMetadata()) {
+    pushGlobalMetadataAttachment(Record, F);
     Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
     Record.clear();
   }
 
+  // Write metadata attachments
+  // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
+  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
   for (const BasicBlock &BB : F)
     for (const Instruction &I : BB) {
       MDs.clear();
@@ -2894,7 +2904,7 @@ void ModuleBitcodeWriter::writeFunction(
   writeValueSymbolTable(F.getValueSymbolTable());
 
   if (NeedsMetadataAttachment)
-    writeMetadataAttachment(F);
+    writeFunctionMetadataAttachment(F);
   if (VE.shouldPreserveUseListOrder())
     writeUseListBlock(&F);
   VE.purgeFunction();
@@ -3597,6 +3607,14 @@ void ModuleBitcodeWriter::writeModule()
   writeValueSymbolTable(M.getValueSymbolTable(),
                         /* IsModuleLevel */ true, &FunctionToBitcodeIndex);
 
+  for (const GlobalVariable &GV : M.globals())
+    if (GV.hasMetadata()) {
+      SmallVector<uint64_t, 4> Record;
+      Record.push_back(VE.getValueID(&GV));
+      pushGlobalMetadataAttachment(Record, GV);
+      Stream.EmitRecord(bitc::MODULE_CODE_GLOBALVAR_ATTACHMENT, Record);
+    }
+
   if (GenerateHash) {
     writeModuleHash(BlockStartPos);
   }

Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Tue May 31 18:01:54 2016
@@ -344,6 +344,11 @@ ValueEnumerator::ValueEnumerator(const M
   EnumerateNamedMetadata(M);
 
   SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
+  for (const GlobalVariable &GV : M.globals()) {
+    GV.getAllMetadata(MDs);
+    for (const auto &I : MDs)
+      EnumerateMetadata(&GV, I.second);
+  }
 
   // Enumerate types used by function bodies and argument lists.
   for (const Function &F : M) {
@@ -523,17 +528,18 @@ void ValueEnumerator::EnumerateNamedMDNo
     EnumerateMetadata(nullptr, MD->getOperand(i));
 }
 
-unsigned ValueEnumerator::getMetadataFunctionID(const Function *F) const {
-  return F ? getValueID(F) + 1 : 0;
+unsigned ValueEnumerator::getMetadataGlobalID(const GlobalObject *GO) const {
+  return GO ? getValueID(GO) + 1 : 0;
 }
 
-void ValueEnumerator::EnumerateMetadata(const Function *F, const Metadata *MD) {
-  EnumerateMetadata(getMetadataFunctionID(F), MD);
+void ValueEnumerator::EnumerateMetadata(const GlobalObject *GO,
+                                        const Metadata *MD) {
+  EnumerateMetadata(getMetadataGlobalID(GO), MD);
 }
 
 void ValueEnumerator::EnumerateFunctionLocalMetadata(
     const Function &F, const LocalAsMetadata *Local) {
-  EnumerateFunctionLocalMetadata(getMetadataFunctionID(&F), Local);
+  EnumerateFunctionLocalMetadata(getMetadataGlobalID(&F), Local);
 }
 
 void ValueEnumerator::dropFunctionFromMetadata(

Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h (original)
+++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h Tue May 31 18:01:54 2016
@@ -255,7 +255,7 @@ private:
   /// it's an \a MDNode.
   const MDNode *enumerateMetadataImpl(unsigned F, const Metadata *MD);
 
-  unsigned getMetadataFunctionID(const Function *F) const;
+  unsigned getMetadataGlobalID(const GlobalObject *GO) const;
 
   /// Enumerate reachable metadata in (almost) post-order.
   ///
@@ -272,7 +272,7 @@ private:
   /// \a organizeMetadata() will later partition distinct nodes ahead of
   /// uniqued ones.
   ///{
-  void EnumerateMetadata(const Function *F, const Metadata *MD);
+  void EnumerateMetadata(const GlobalObject *GO, const Metadata *MD);
   void EnumerateMetadata(unsigned F, const Metadata *MD);
   ///}
 

Modified: llvm/trunk/lib/IR/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)
+++ llvm/trunk/lib/IR/AsmWriter.cpp Tue May 31 18:01:54 2016
@@ -681,6 +681,9 @@ private:
   /// Add all of the functions arguments, basic blocks, and instructions.
   void processFunction();
 
+  /// Add the metadata directly attached to a GlobalObject.
+  void processGlobalObjectMetadata(const GlobalObject &GO);
+
   /// Add all of the metadata from a function.
   void processFunctionMetadata(const Function &F);
 
@@ -799,6 +802,7 @@ void SlotTracker::processModule() {
   for (const GlobalVariable &Var : TheModule->globals()) {
     if (!Var.hasName())
       CreateModuleSlot(&Var);
+    processGlobalObjectMetadata(Var);
   }
 
   for (const GlobalAlias &A : TheModule->aliases()) {
@@ -882,12 +886,15 @@ void SlotTracker::processFunction() {
   ST_DEBUG("end processFunction!\n");
 }
 
-void SlotTracker::processFunctionMetadata(const Function &F) {
+void SlotTracker::processGlobalObjectMetadata(const GlobalObject &GO) {
   SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
-  F.getAllMetadata(MDs);
+  GO.getAllMetadata(MDs);
   for (auto &MD : MDs)
     CreateMetadataSlot(MD.second);
+}
 
+void SlotTracker::processFunctionMetadata(const Function &F) {
+  processGlobalObjectMetadata(F);
   for (auto &BB : F) {
     for (auto &I : BB)
       processInstructionMetadata(I);
@@ -2473,6 +2480,10 @@ void AssemblyWriter::printGlobal(const G
   if (GV->getAlignment())
     Out << ", align " << GV->getAlignment();
 
+  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+  GV->getAllMetadata(MDs);
+  printMetadataAttachments(MDs, ", ");
+
   printInfoComment(*GV);
 }
 

Modified: llvm/trunk/lib/IR/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Function.cpp?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Function.cpp (original)
+++ llvm/trunk/lib/IR/Function.cpp Tue May 31 18:01:54 2016
@@ -218,11 +218,13 @@ bool Argument::hasAttribute(Attribute::A
 //===----------------------------------------------------------------------===//
 
 bool Function::isMaterializable() const {
-  return getGlobalObjectSubClassData() & IsMaterializableBit;
+  return getGlobalObjectSubClassData() & (1 << IsMaterializableBit);
 }
 
 void Function::setIsMaterializable(bool V) {
-  setGlobalObjectBit(IsMaterializableBit, V);
+  unsigned Mask = 1 << IsMaterializableBit;
+  setGlobalObjectSubClassData((~Mask & getGlobalObjectSubClassData()) |
+                              (V ? Mask : 0u));
 }
 
 LLVMContext &Function::getContext() const {

Modified: llvm/trunk/lib/IR/Globals.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Globals.cpp?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Globals.cpp (original)
+++ llvm/trunk/lib/IR/Globals.cpp Tue May 31 18:01:54 2016
@@ -81,13 +81,13 @@ void GlobalObject::setAlignment(unsigned
 
 unsigned GlobalObject::getGlobalObjectSubClassData() const {
   unsigned ValueData = getGlobalValueSubClassData();
-  return ValueData >> AlignmentBits;
+  return ValueData >> GlobalObjectBits;
 }
 
 void GlobalObject::setGlobalObjectSubClassData(unsigned Val) {
   unsigned OldData = getGlobalValueSubClassData();
-  setGlobalValueSubClassData((OldData & AlignmentMask) |
-                             (Val << AlignmentBits));
+  setGlobalValueSubClassData((OldData & GlobalObjectMask) |
+                             (Val << GlobalObjectBits));
   assert(getGlobalObjectSubClassData() == Val && "representation error");
 }
 
@@ -301,6 +301,10 @@ void GlobalVariable::copyAttributesFrom(
   }
 }
 
+void GlobalVariable::dropAllReferences() {
+  User::dropAllReferences();
+  clearMetadata();
+}
 
 //===----------------------------------------------------------------------===//
 // GlobalIndirectSymbol Implementation

Modified: llvm/trunk/lib/IR/LLVMContextImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.h (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.h Tue May 31 18:01:54 2016
@@ -1107,8 +1107,8 @@ public:
   /// Collection of per-instruction metadata used in this context.
   DenseMap<const Instruction *, MDAttachmentMap> InstructionMetadata;
 
-  /// Collection of per-function metadata used in this context.
-  DenseMap<const Function *, MDAttachmentMap> FunctionMetadata;
+  /// Collection of per-GlobalObject metadata used in this context.
+  DenseMap<const GlobalObject *, MDAttachmentMap> GlobalObjectMetadata;
 
   /// DiscriminatorTable - This table maps file:line locations to an
   /// integer representing the next DWARF path discriminator to assign to

Modified: llvm/trunk/lib/IR/Metadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Metadata.cpp?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Metadata.cpp (original)
+++ llvm/trunk/lib/IR/Metadata.cpp Tue May 31 18:01:54 2016
@@ -1281,24 +1281,24 @@ void Instruction::clearMetadataHashEntri
   setHasMetadataHashEntry(false);
 }
 
-MDNode *Function::getMetadata(unsigned KindID) const {
+MDNode *GlobalObject::getMetadata(unsigned KindID) const {
   if (!hasMetadata())
     return nullptr;
-  return getContext().pImpl->FunctionMetadata[this].lookup(KindID);
+  return getContext().pImpl->GlobalObjectMetadata[this].lookup(KindID);
 }
 
-MDNode *Function::getMetadata(StringRef Kind) const {
+MDNode *GlobalObject::getMetadata(StringRef Kind) const {
   if (!hasMetadata())
     return nullptr;
   return getMetadata(getContext().getMDKindID(Kind));
 }
 
-void Function::setMetadata(unsigned KindID, MDNode *MD) {
+void GlobalObject::setMetadata(unsigned KindID, MDNode *MD) {
   if (MD) {
     if (!hasMetadata())
       setHasMetadataHashEntry(true);
 
-    getContext().pImpl->FunctionMetadata[this].set(KindID, *MD);
+    getContext().pImpl->GlobalObjectMetadata[this].set(KindID, *MD);
     return;
   }
 
@@ -1306,29 +1306,29 @@ void Function::setMetadata(unsigned Kind
   if (!hasMetadata())
     return;
 
-  auto &Store = getContext().pImpl->FunctionMetadata[this];
+  auto &Store = getContext().pImpl->GlobalObjectMetadata[this];
   Store.erase(KindID);
   if (Store.empty())
     clearMetadata();
 }
 
-void Function::setMetadata(StringRef Kind, MDNode *MD) {
+void GlobalObject::setMetadata(StringRef Kind, MDNode *MD) {
   if (!MD && !hasMetadata())
     return;
   setMetadata(getContext().getMDKindID(Kind), MD);
 }
 
-void Function::getAllMetadata(
+void GlobalObject::getAllMetadata(
     SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const {
   MDs.clear();
 
   if (!hasMetadata())
     return;
 
-  getContext().pImpl->FunctionMetadata[this].getAll(MDs);
+  getContext().pImpl->GlobalObjectMetadata[this].getAll(MDs);
 }
 
-void Function::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) {
+void GlobalObject::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) {
   if (!hasMetadata())
     return;
   if (KnownIDs.empty()) {
@@ -1339,7 +1339,7 @@ void Function::dropUnknownMetadata(Array
   SmallSet<unsigned, 5> KnownSet;
   KnownSet.insert(KnownIDs.begin(), KnownIDs.end());
 
-  auto &Store = getContext().pImpl->FunctionMetadata[this];
+  auto &Store = getContext().pImpl->GlobalObjectMetadata[this];
   assert(!Store.empty());
 
   Store.remove_if([&KnownSet](const std::pair<unsigned, TrackingMDNodeRef> &I) {
@@ -1350,10 +1350,10 @@ void Function::dropUnknownMetadata(Array
     clearMetadata();
 }
 
-void Function::clearMetadata() {
+void GlobalObject::clearMetadata() {
   if (!hasMetadata())
     return;
-  getContext().pImpl->FunctionMetadata.erase(this);
+  getContext().pImpl->GlobalObjectMetadata.erase(this);
   setHasMetadataHashEntry(false);
 }
 

Modified: llvm/trunk/test/Assembler/metadata.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/metadata.ll?rev=271348&r1=271347&r2=271348&view=diff
==============================================================================
--- llvm/trunk/test/Assembler/metadata.ll (original)
+++ llvm/trunk/test/Assembler/metadata.ll Tue May 31 18:01:54 2016
@@ -1,8 +1,11 @@
 ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
 ; RUN: verify-uselistorder %s
 
+; CHECK: @global = global i32 0, !foo [[M2:![0-9]+]], !baz [[M3:![0-9]+]]
+ at global = global i32 0, !foo !2, !baz !3
+
 ; CHECK-LABEL: @test
-; CHECK: ret void, !bar !4, !foo !3
+; CHECK: ret void, !foo [[M0:![0-9]+]], !bar [[M1:![0-9]+]]
 define void @test() !dbg !1 {
   add i32 2, 1, !bar !0
   add i32 1, 2, !foo !1
@@ -11,24 +14,30 @@ define void @test() !dbg !1 {
   ret void, !foo !0, !bar !1
 }
 
-; CHECK-LABEL: define void @test2() !foo !5 !baz !6
+; CHECK: define void @test2() !foo [[M2]] !baz [[M3]]
 define void @test2() !foo !2 !baz !3 {
   unreachable
 }
 
-; CHECK-LABEL: define void @test3() !bar !6
-; CHECK: unreachable, !bar !7
+; CHECK: define void @test3() !bar [[M3]]
+; CHECK: unreachable, !bar [[M4:![0-9]+]]
 define void @test3() !bar !3 {
   unreachable, !bar !4
 }
 
 ; CHECK-LABEL: define void @test_attachment_name() {
-; CHECK:   unreachable, !\342abc !7
+; CHECK:   unreachable, !\342abc [[M4]]
 define void @test_attachment_name() {
   ;; Escape the first character when printing text IR, since it's a digit
   unreachable, !\34\32abc !4
 }
 
+; CHECK: [[M2]] = distinct !{}
+; CHECK: [[M3]] = distinct !{}
+; CHECK: [[M0]] = !DILocation
+; CHECK: [[M1]] = distinct !DISubprogram
+; CHECK: [[M4]] = distinct !{}
+
 !llvm.module.flags = !{!7}
 !llvm.dbg.cu = !{!5}
 !0 = !DILocation(line: 662302, column: 26, scope: !1)




More information about the llvm-commits mailing list