diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/docs/BitCodeFormat.rst | 10 | ||||
| -rw-r--r-- | llvm/docs/LangRef.rst | 5 | ||||
| -rw-r--r-- | llvm/include/llvm/Bitcode/LLVMBitCodes.h | 3 | ||||
| -rw-r--r-- | llvm/include/llvm/IR/Function.h | 45 | ||||
| -rw-r--r-- | llvm/include/llvm/IR/GlobalObject.h | 54 | ||||
| -rw-r--r-- | llvm/include/llvm/IR/GlobalVariable.h | 4 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 24 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.h | 1 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 39 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 42 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 16 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Writer/ValueEnumerator.h | 4 | ||||
| -rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 15 | ||||
| -rw-r--r-- | llvm/lib/IR/Function.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/IR/Globals.cpp | 10 | ||||
| -rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 4 | ||||
| -rw-r--r-- | llvm/lib/IR/Metadata.cpp | 26 | ||||
| -rw-r--r-- | llvm/test/Assembler/metadata.ll | 19 | 
18 files changed, 217 insertions, 110 deletions
diff --git a/llvm/docs/BitCodeFormat.rst b/llvm/docs/BitCodeFormat.rst index edab66ead64..ac051c49bc8 100644 --- a/llvm/docs/BitCodeFormat.rst +++ b/llvm/docs/BitCodeFormat.rst @@ -856,6 +856,16 @@ be one ``GCNAME`` record for each garbage collector name referenced in function  ``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 diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 4882ac106b8..2a1c7a00049 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -619,7 +619,8 @@ assume that the globals are densely packed in their section and try to  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: diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index c1d5fb5f469..a134e8ca3bc 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -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. diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index 6aeddab4311..dd21f2d723c 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -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 <> diff --git a/llvm/include/llvm/IR/GlobalObject.h b/llvm/include/llvm/IR/GlobalObject.h index 2171d6e71cb..038fda9218c 100644 --- a/llvm/include/llvm/IR/GlobalObject.h +++ b/llvm/include/llvm/IR/GlobalObject.h @@ -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 diff --git a/llvm/include/llvm/IR/GlobalVariable.h b/llvm/include/llvm/IR/GlobalVariable.h index fd08fe005ea..7bc528775dd 100644 --- a/llvm/include/llvm/IR/GlobalVariable.h +++ b/llvm/include/llvm/IR/GlobalVariable.h @@ -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; diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 3f9ea5766bd..09d012d5375 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -891,6 +891,9 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,        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(Instruction &Inst) {    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;  } diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index cffea25485a..7c32f2c7fac 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -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> diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 2cd1297d902..55c0d064938 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -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::parseModule(uint64_t ResumeBit,        }        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::parseIdentificationBlock() {    }  } +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::parseMetadataAttachment(Function &F) {          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;        } diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index ec3ecb2287e..d65e924507c 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -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::writeFunctionMetadata(const Function &F) {    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);    } diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 6bf95b12d80..6051173eed6 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -344,6 +344,11 @@ ValueEnumerator::ValueEnumerator(const Module &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::EnumerateNamedMDNode(const NamedMDNode *MD) {      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( diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/llvm/lib/Bitcode/Writer/ValueEnumerator.h index bff2de70b3e..34d33fc418b 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.h +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.h @@ -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);    ///} diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index ec975c77c96..c5002dc8c2f 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -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 GlobalVariable *GV) {    if (GV->getAlignment())      Out << ", align " << GV->getAlignment(); +  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs; +  GV->getAllMetadata(MDs); +  printMetadataAttachments(MDs, ", "); +    printInfoComment(*GV);  } diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index c8741964564..815922593e5 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -218,11 +218,13 @@ bool Argument::hasAttribute(Attribute::AttrKind Kind) const {  //===----------------------------------------------------------------------===//  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 { diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp index 3bf3cc25455..d151b9c5dc2 100644 --- a/llvm/lib/IR/Globals.cpp +++ b/llvm/lib/IR/Globals.cpp @@ -81,13 +81,13 @@ void GlobalObject::setAlignment(unsigned Align) {  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(const GlobalValue *Src) {    }  } +void GlobalVariable::dropAllReferences() { +  User::dropAllReferences(); +  clearMetadata(); +}  //===----------------------------------------------------------------------===//  // GlobalIndirectSymbol Implementation diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 7d7be4492c7..02af08ac4f9 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -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 diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp index 9435cd2ec35..a77565cf087 100644 --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -1281,24 +1281,24 @@ void Instruction::clearMetadataHashEntries() {    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 KindID, MDNode *MD) {    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(ArrayRef<unsigned> KnownIDs) {    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(ArrayRef<unsigned> KnownIDs) {      clearMetadata();  } -void Function::clearMetadata() { +void GlobalObject::clearMetadata() {    if (!hasMetadata())      return; -  getContext().pImpl->FunctionMetadata.erase(this); +  getContext().pImpl->GlobalObjectMetadata.erase(this);    setHasMetadataHashEntry(false);  } diff --git a/llvm/test/Assembler/metadata.ll b/llvm/test/Assembler/metadata.ll index ba7065d16f4..2fe26be47de 100644 --- a/llvm/test/Assembler/metadata.ll +++ b/llvm/test/Assembler/metadata.ll @@ -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]+]] +@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)  | 

