Unverified Commit e77af7e1 authored by Stephen Tozer's avatar Stephen Tozer Committed by GitHub
Browse files

[DebugInfo] Make DIArgList inherit from Metadata and always unique (#72147)

This patch changes the `DIArgList` class's inheritance from `MDNode` to
`Metadata, ReplaceableMetadataImpl`, and ensures that it is always
unique, i.e. a distinct DIArgList should never be produced.

This should not result in any changes to IR or bitcode parsing and
printing, as the format for DIArgList is unchanged, and the order in which it
appears should also be identical. As a minor note, this patch also fixes
a gap in the verifier, where the ValueAsMetadata operands to a DIArgList
would not be visited.
parent e5e71aff
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -548,6 +548,7 @@ namespace llvm {
    bool parseMetadataAsValue(Value *&V, PerFunctionState &PFS);
    bool parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
                              PerFunctionState *PFS);
    bool parseDIArgList(Metadata *&MD, PerFunctionState *PFS);
    bool parseMetadata(Metadata *&MD, PerFunctionState *PFS);
    bool parseMDTuple(MDNode *&MD, bool IsDistinct = false);
    bool parseMDNode(MDNode *&N);
@@ -569,8 +570,6 @@ namespace llvm {
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS)                                  \
  bool parse##CLASS(MDNode *&Result, bool IsDistinct);
#include "llvm/IR/Metadata.def"
    bool parseDIArgList(MDNode *&Result, bool IsDistinct,
                        PerFunctionState *PFS);

    // Function Parsing.
    struct ArgInfo {
+10 −21
Original line number Diff line number Diff line
@@ -3753,51 +3753,40 @@ public:

/// List of ValueAsMetadata, to be used as an argument to a dbg.value
/// intrinsic.
class DIArgList : public MDNode {
class DIArgList : public Metadata, ReplaceableMetadataImpl {
  friend class ReplaceableMetadataImpl;
  friend class LLVMContextImpl;
  friend class MDNode;
  using iterator = SmallVectorImpl<ValueAsMetadata *>::iterator;

  SmallVector<ValueAsMetadata *, 4> Args;

  DIArgList(LLVMContext &C, StorageType Storage,
            ArrayRef<ValueAsMetadata *> Args)
      : MDNode(C, DIArgListKind, Storage, std::nullopt),
  DIArgList(LLVMContext &Context, ArrayRef<ValueAsMetadata *> Args)
      : Metadata(DIArgListKind, Uniqued), ReplaceableMetadataImpl(Context),
        Args(Args.begin(), Args.end()) {
    track();
  }
  ~DIArgList() { untrack(); }

  static DIArgList *getImpl(LLVMContext &Context,
                            ArrayRef<ValueAsMetadata *> Args,
                            StorageType Storage, bool ShouldCreate = true);

  TempDIArgList cloneImpl() const {
    return getTemporary(getContext(), getArgs());
  }

  void track();
  void untrack();
  void dropAllReferences();
  void dropAllReferences(bool Untrack);

public:
  DEFINE_MDNODE_GET(DIArgList, (ArrayRef<ValueAsMetadata *> Args), (Args))

  TempDIArgList clone() const { return cloneImpl(); }
  static DIArgList *get(LLVMContext &Context, ArrayRef<ValueAsMetadata *> Args);

  ArrayRef<ValueAsMetadata *> getArgs() const { return Args; }

  iterator args_begin() { return Args.begin(); }
  iterator args_end() { return Args.end(); }

  ReplaceableMetadataImpl *getReplaceableUses() {
    return Context.getReplaceableUses();
  }

  static bool classof(const Metadata *MD) {
    return MD->getMetadataID() == DIArgListKind;
  }

  SmallVector<DPValue *> getAllDPValueUsers() {
    return ReplaceableMetadataImpl::getAllDPValueUsers();
  }

  void handleChangedOperand(void *Ref, Metadata *New);
};

+1 −1
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ HANDLE_METADATA_BRANCH(ValueAsMetadata)
HANDLE_METADATA_LEAF(ConstantAsMetadata)
HANDLE_METADATA_LEAF(LocalAsMetadata)
HANDLE_METADATA_LEAF(DistinctMDOperandPlaceholder)
HANDLE_METADATA_LEAF(DIArgList)
HANDLE_MDNODE_BRANCH(MDNode)
HANDLE_MDNODE_LEAF_UNIQUABLE(MDTuple)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocation)
@@ -115,7 +116,6 @@ HANDLE_SPECIALIZED_MDNODE_BRANCH(DIMacroNode)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacro)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacroFile)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DICommonBlock)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIArgList)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIStringType)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGenericSubrange)

+1 −4
Original line number Diff line number Diff line
@@ -1037,7 +1037,6 @@ struct TempMDNodeDeleter {
class MDNode : public Metadata {
  friend class ReplaceableMetadataImpl;
  friend class LLVMContextImpl;
  friend class DIArgList;

  /// The header that is coallocated with an MDNode along with its "small"
  /// operands. It is located immediately before the main body of the node.
@@ -1220,9 +1219,7 @@ public:
  bool isDistinct() const { return Storage == Distinct; }
  bool isTemporary() const { return Storage == Temporary; }

  bool isReplaceable() const {
    return isTemporary() || getMetadataID() == DIArgListKind;
  }
  bool isReplaceable() const { return isTemporary(); }

  /// RAUW a temporary.
  ///
+9 −9
Original line number Diff line number Diff line
@@ -5486,13 +5486,9 @@ bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
  return false;
}

bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct) {
  return parseDIArgList(Result, IsDistinct, nullptr);
}
/// ParseDIArgList:
///   ::= !DIArgList(i32 7, i64 %0)
bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct,
                              PerFunctionState *PFS) {
bool LLParser::parseDIArgList(Metadata *&MD, PerFunctionState *PFS) {
  assert(PFS && "Expected valid function state");
  assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
  Lex.Lex();
@@ -5512,7 +5508,7 @@ bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct,
  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  Result = GET_OR_DISTINCT(DIArgList, (Context, Args));
  MD = DIArgList::get(Context, Args);
  return false;
}

@@ -5626,13 +5622,17 @@ bool LLParser::parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
///  ::= !DILocation(...)
bool LLParser::parseMetadata(Metadata *&MD, PerFunctionState *PFS) {
  if (Lex.getKind() == lltok::MetadataVar) {
    MDNode *N;
    // DIArgLists are a special case, as they are a list of ValueAsMetadata and
    // so parsing this requires a Function State.
    if (Lex.getStrVal() == "DIArgList") {
      if (parseDIArgList(N, false, PFS))
      Metadata *AL;
      if (parseDIArgList(AL, PFS))
        return true;
    } else if (parseSpecializedMDNode(N)) {
      MD = AL;
      return false;
    }
    MDNode *N;
    if (parseSpecializedMDNode(N)) {
      return true;
    }
    MD = N;
Loading