Index: llvm/include/llvm-c/DebugInfo.h =================================================================== --- llvm/include/llvm-c/DebugInfo.h +++ llvm/include/llvm-c/DebugInfo.h @@ -163,6 +163,7 @@ LLVMDILocalVariableMetadataKind, LLVMDILabelMetadataKind, LLVMDIObjCPropertyMetadataKind, + LLVMDICallSiteParamMetadataKind, LLVMDIImportedEntityMetadataKind, LLVMDIMacroMetadataKind, LLVMDIMacroFileMetadataKind, Index: llvm/include/llvm/Bitcode/LLVMBitCodes.h =================================================================== --- llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -346,7 +346,8 @@ // info. METADATA_COMMON_BLOCK = 44, // [distinct, scope, name, variable,...] METADATA_GENERIC_SUBRANGE = 45, // [distinct, count, lo, up, stride] - METADATA_ARG_LIST = 46 // [n x [type num, value num]] + METADATA_ARG_LIST = 46, // [n x [type num, value num]] + METADATA_CALL_SITE_PARAM = 47 // [distinct, argnum, expr] }; // The constants block (CONSTANTS_BLOCK_ID) describes emission for each Index: llvm/include/llvm/IR/DebugInfoMetadata.h =================================================================== --- llvm/include/llvm/IR/DebugInfoMetadata.h +++ llvm/include/llvm/IR/DebugInfoMetadata.h @@ -208,6 +208,7 @@ case DILocalVariableKind: case DILabelKind: case DIObjCPropertyKind: + case DICallSiteParamKind: case DIImportedEntityKind: case DIModuleKind: case DIGenericSubrangeKind: @@ -1588,21 +1589,24 @@ static DILocation *getImpl(LLVMContext &Context, unsigned Line, unsigned Column, Metadata *Scope, Metadata *InlinedAt, bool ImplicitCode, - StorageType Storage, bool ShouldCreate = true); + Metadata *Parameters, StorageType Storage, + bool ShouldCreate = true); static DILocation *getImpl(LLVMContext &Context, unsigned Line, unsigned Column, DILocalScope *Scope, DILocation *InlinedAt, bool ImplicitCode, - StorageType Storage, bool ShouldCreate = true) { + DINodeArray Parameters, StorageType Storage, + bool ShouldCreate = true) { return getImpl(Context, Line, Column, static_cast(Scope), - static_cast(InlinedAt), ImplicitCode, Storage, - ShouldCreate); + static_cast(InlinedAt), ImplicitCode, + Parameters.get(), Storage, ShouldCreate); } TempDILocation cloneImpl() const { // Get the raw scope/inlinedAt since it is possible to invoke this on // a DILocation containing temporary metadata. return getTemporary(getContext(), getLine(), getColumn(), getRawScope(), - getRawInlinedAt(), isImplicitCode()); + getRawInlinedAt(), isImplicitCode(), + getRawParameters()); } public: @@ -1611,13 +1615,14 @@ DEFINE_MDNODE_GET(DILocation, (unsigned Line, unsigned Column, Metadata *Scope, - Metadata *InlinedAt = nullptr, bool ImplicitCode = false), - (Line, Column, Scope, InlinedAt, ImplicitCode)) + Metadata *InlinedAt = nullptr, bool ImplicitCode = false, + Metadata *Parameters = nullptr), + (Line, Column, Scope, InlinedAt, ImplicitCode, Parameters)) DEFINE_MDNODE_GET(DILocation, (unsigned Line, unsigned Column, DILocalScope *Scope, - DILocation *InlinedAt = nullptr, - bool ImplicitCode = false), - (Line, Column, Scope, InlinedAt, ImplicitCode)) + DILocation *InlinedAt = nullptr, bool ImplicitCode = false, + DINodeArray Parameters = nullptr), + (Line, Column, Scope, InlinedAt, ImplicitCode, Parameters)) /// Return a (temporary) clone of this. TempDILocation clone() const { return cloneImpl(); } @@ -1630,6 +1635,10 @@ return cast_or_null(getRawInlinedAt()); } + DINodeArray getParameters() const { + return cast_or_null(getRawParameters()); + } + /// Check if the location corresponds to an implicit code. /// When the ImplicitCode flag is true, it means that the Instruction /// with this DILocation has been added by the front-end but it hasn't been @@ -1811,17 +1820,62 @@ } Metadata *getRawScope() const { return getOperand(0); } - Metadata *getRawInlinedAt() const { - if (getNumOperands() == 2) - return getOperand(1); - return nullptr; - } + Metadata *getRawInlinedAt() const { return getOperand(1); } + Metadata *getRawParameters() const { return getOperand(2); } static bool classof(const Metadata *MD) { return MD->getMetadataID() == DILocationKind; } }; +/// Argument value on call site. +class DICallSiteParam : public DINode { + friend class LLVMContextImpl; + friend class MDNode; + int ArgNum; + + DICallSiteParam(LLVMContext &Context, StorageType Storage, int ArgNum, + ArrayRef Ops) + : DINode(Context, DICallSiteParamKind, Storage, + dwarf::DW_TAG_call_site_parameter, Ops), + ArgNum(ArgNum) {} + ~DICallSiteParam() = default; + + static DICallSiteParam *getImpl(LLVMContext &Context, int ArgNum, + DIExpression *Expr, StorageType Storage, + bool ShouldCreate = true) { + return getImpl(Context, ArgNum, cast(Expr), Storage, + ShouldCreate); + } + + static DICallSiteParam *getImpl(LLVMContext &Context, int ArgNum, + Metadata *Expr, StorageType Storage, + bool ShouldCreate = true); + + TempDICallSiteParam cloneImpl() const { + return getTemporary(getContext(), getArgNum(), getExpression()); + } + +public: + DEFINE_MDNODE_GET(DICallSiteParam, (int ArgNum, DIExpression *Expr), + (ArgNum, Expr)) + DEFINE_MDNODE_GET(DICallSiteParam, (int ArgNum, Metadata *Expr), + (ArgNum, Expr)) + + int getArgNum() const { return ArgNum; } + + DIExpression *getExpression() const { + return cast(getRawExpression()); + } + + Metadata *getRawExpression() const { return getOperand(0); } + TempDICallSiteParam clone() const { return cloneImpl(); } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == DICallSiteParamKind; + } +}; + /// Subprogram description. class DISubprogram : public DILocalScope { friend class LLVMContextImpl; Index: llvm/include/llvm/IR/Metadata.def =================================================================== --- llvm/include/llvm/IR/Metadata.def +++ llvm/include/llvm/IR/Metadata.def @@ -109,6 +109,7 @@ HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocalVariable) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILabel) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIObjCProperty) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DICallSiteParam) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIImportedEntity) HANDLE_SPECIALIZED_MDNODE_BRANCH(DIMacroNode) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacro) Index: llvm/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/lib/AsmParser/LLParser.cpp +++ llvm/lib/AsmParser/LLParser.cpp @@ -4386,20 +4386,21 @@ /// parseDILocationFields: /// ::= !DILocation(line: 43, column: 8, scope: !5, inlinedAt: !6, -/// isImplicitCode: true) +/// isImplicitCode: true, params: !1) bool LLParser::parseDILocation(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(line, LineField, ); \ OPTIONAL(column, ColumnField, ); \ REQUIRED(scope, MDField, (/* AllowNull */ false)); \ OPTIONAL(inlinedAt, MDField, ); \ - OPTIONAL(isImplicitCode, MDBoolField, (false)); + OPTIONAL(isImplicitCode, MDBoolField, (false)); \ + OPTIONAL(params, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = - GET_OR_DISTINCT(DILocation, (Context, line.Val, column.Val, scope.Val, - inlinedAt.Val, isImplicitCode.Val)); + Result = GET_OR_DISTINCT(DILocation, + (Context, line.Val, column.Val, scope.Val, + inlinedAt.Val, isImplicitCode.Val, params.Val)); return false; } @@ -5136,6 +5137,19 @@ return false; } +/// ParseDICallSiteParam: +/// ::= !DICallSiteParam(argnum: 1, expr: !1) +bool LLParser::parseDICallSiteParam(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + OPTIONAL(argnum, MDUnsignedField, (0, INT32_MAX)); \ + OPTIONAL(expr, MDField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(DICallSiteParam, (Context, argnum.Val, expr.Val)); + return false; +} + /// parseDIImportedEntity: /// ::= !DIImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: !1, /// line: 7, name: "foo", elements: !2) Index: llvm/lib/Bitcode/Reader/MetadataLoader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -873,6 +873,7 @@ case bitc::METADATA_LABEL: case bitc::METADATA_EXPRESSION: case bitc::METADATA_OBJC_PROPERTY: + case bitc::METADATA_CALL_SITE_PARAM: case bitc::METADATA_IMPORTED_ENTITY: case bitc::METADATA_GLOBAL_VAR_EXPR: case bitc::METADATA_GENERIC_SUBRANGE: @@ -1300,7 +1301,7 @@ break; } case bitc::METADATA_LOCATION: { - if (Record.size() != 5 && Record.size() != 6) + if (Record.size() != 5 && Record.size() != 6 && Record.size() != 7) return error("Invalid record"); IsDistinct = Record[0]; @@ -1308,10 +1309,15 @@ unsigned Column = Record[2]; Metadata *Scope = getMD(Record[3]); Metadata *InlinedAt = getMDOrNull(Record[4]); - bool ImplicitCode = Record.size() == 6 && Record[5]; + bool ImplicitCode = false; + Metadata *Params = nullptr; + if (Record.size() > 5) + ImplicitCode = Record[5]; + if (Record.size() > 6) + Params = getMDOrNull(Record[6]); MetadataList.assignValue( GET_OR_DISTINCT(DILocation, (Context, Line, Column, Scope, InlinedAt, - ImplicitCode)), + ImplicitCode, Params)), NextMetadataNo); NextMetadataNo++; break; @@ -2040,6 +2046,15 @@ NextMetadataNo++; break; } + case bitc::METADATA_CALL_SITE_PARAM: { + IsDistinct = Record[0]; + MetadataList.assignValue( + GET_OR_DISTINCT(DICallSiteParam, + (Context, Record[1], getMDOrNull(Record[2]))), + NextMetadataNo); + NextMetadataNo++; + break; + } case bitc::METADATA_IMPORTED_ENTITY: { if (Record.size() < 6 && Record.size() > 8) return error("Invalid record"); Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -358,6 +358,8 @@ unsigned Abbrev); void writeDIObjCProperty(const DIObjCProperty *N, SmallVectorImpl &Record, unsigned Abbrev); + void writeDICallSiteParam(const DICallSiteParam *N, + SmallVectorImpl &Record, unsigned Abbrev); void writeDIImportedEntity(const DIImportedEntity *N, SmallVectorImpl &Record, unsigned Abbrev); @@ -1525,6 +1527,7 @@ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); return Stream.EmitAbbrev(std::move(Abbv)); } @@ -1540,6 +1543,7 @@ Record.push_back(VE.getMetadataID(N->getScope())); Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt())); Record.push_back(N->isImplicitCode()); + Record.push_back(VE.getMetadataOrNullID(N->getRawParameters())); Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev); Record.clear(); @@ -2053,6 +2057,17 @@ Record.clear(); } +void ModuleBitcodeWriter::writeDICallSiteParam( + const DICallSiteParam *N, SmallVectorImpl &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getArgNum()); + Record.push_back(VE.getMetadataOrNullID(N->getExpression())); + + Stream.EmitRecord(bitc::METADATA_CALL_SITE_PARAM, Record, Abbrev); + Record.clear(); +} + void ModuleBitcodeWriter::writeDIImportedEntity( const DIImportedEntity *N, SmallVectorImpl &Record, unsigned Abbrev) { Index: llvm/lib/IR/AsmWriter.cpp =================================================================== --- llvm/lib/IR/AsmWriter.cpp +++ llvm/lib/IR/AsmWriter.cpp @@ -1855,6 +1855,7 @@ Printer.printMetadata("inlinedAt", DL->getRawInlinedAt()); Printer.printBool("isImplicitCode", DL->isImplicitCode(), /* Default */ false); + Printer.printMetadata("params", DL->getRawParameters()); Out << ")"; } @@ -2348,6 +2349,15 @@ Out << ")"; } +static void writeDICallSiteParam(raw_ostream &Out, const DICallSiteParam *N, + AsmWriterContext &WriteCtx) { + Out << "!DICallSiteParam("; + MDFieldPrinter Printer(Out, WriteCtx); + Printer.printInt("argnum", N->getArgNum(), false); + Printer.printMetadata("expr", N->getRawExpression()); + Out << ")"; +} + static void writeDIImportedEntity(raw_ostream &Out, const DIImportedEntity *N, AsmWriterContext &WriterCtx) { Out << "!DIImportedEntity("; Index: llvm/lib/IR/DebugInfoMetadata.cpp =================================================================== --- llvm/lib/IR/DebugInfoMetadata.cpp +++ llvm/lib/IR/DebugInfoMetadata.cpp @@ -37,8 +37,8 @@ unsigned Column, ArrayRef MDs, bool ImplicitCode) : MDNode(C, DILocationKind, Storage, MDs) { - assert((MDs.size() == 1 || MDs.size() == 2) && - "Expected a scope and optional inlined-at"); + assert((MDs.size() == 1 || MDs.size() == 2 || MDs.size() == 3) && + "Expected a scope and optional inlined-at and params"); // Set line and column. assert(Column < (1u << 16) && "Expected 16-bit column"); @@ -58,14 +58,16 @@ DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line, unsigned Column, Metadata *Scope, Metadata *InlinedAt, bool ImplicitCode, - StorageType Storage, bool ShouldCreate) { + Metadata *Parameters, StorageType Storage, + bool ShouldCreate) { // Fixup column. adjustColumn(Column); if (Storage == Uniqued) { - if (auto *N = getUniqued(Context.pImpl->DILocations, - DILocationInfo::KeyTy(Line, Column, Scope, - InlinedAt, ImplicitCode))) + if (auto *N = + getUniqued(Context.pImpl->DILocations, + DILocationInfo::KeyTy(Line, Column, Scope, InlinedAt, + ImplicitCode, Parameters))) return N; if (!ShouldCreate) return nullptr; @@ -73,10 +75,18 @@ assert(ShouldCreate && "Expected non-uniqued nodes to always be created"); } - SmallVector Ops; + SmallVector Ops; Ops.push_back(Scope); if (InlinedAt) Ops.push_back(InlinedAt); + else { + Ops.push_back(nullptr); + } + if (Parameters) + Ops.push_back(Parameters); + else { + Ops.push_back(nullptr); + } return storeImpl(new (Ops.size()) DILocation(Context, Storage, Line, Column, Ops, ImplicitCode), Storage, Context.pImpl->DILocations); @@ -1607,6 +1617,14 @@ DEFINE_GETIMPL_STORE(DIObjCProperty, (Line, Attributes), Ops); } +DICallSiteParam *DICallSiteParam::getImpl(LLVMContext &Context, int ArgNum, + Metadata *Expr, + StorageType Storage, bool ShouldCreate) { + DEFINE_GETIMPL_LOOKUP(DICallSiteParam, (ArgNum, Expr)); + Metadata *Ops[] = {Expr}; + DEFINE_GETIMPL_STORE(DICallSiteParam, (ArgNum), Ops); +} + DIImportedEntity *DIImportedEntity::getImpl(LLVMContext &Context, unsigned Tag, Metadata *Scope, Metadata *Entity, Metadata *File, unsigned Line, Index: llvm/lib/IR/LLVMContextImpl.h =================================================================== --- llvm/lib/IR/LLVMContextImpl.h +++ llvm/lib/IR/LLVMContextImpl.h @@ -254,19 +254,22 @@ Metadata *Scope; Metadata *InlinedAt; bool ImplicitCode; + Metadata *Parameters; MDNodeKeyImpl(unsigned Line, unsigned Column, Metadata *Scope, - Metadata *InlinedAt, bool ImplicitCode) + Metadata *InlinedAt, bool ImplicitCode, Metadata *Parameters) : Line(Line), Column(Column), Scope(Scope), InlinedAt(InlinedAt), - ImplicitCode(ImplicitCode) {} + ImplicitCode(ImplicitCode), Parameters(Parameters) {} MDNodeKeyImpl(const DILocation *L) : Line(L->getLine()), Column(L->getColumn()), Scope(L->getRawScope()), - InlinedAt(L->getRawInlinedAt()), ImplicitCode(L->isImplicitCode()) {} + InlinedAt(L->getRawInlinedAt()), ImplicitCode(L->isImplicitCode()), + Parameters(L->getRawParameters()) {} bool isKeyOf(const DILocation *RHS) const { return Line == RHS->getLine() && Column == RHS->getColumn() && Scope == RHS->getRawScope() && InlinedAt == RHS->getRawInlinedAt() && - ImplicitCode == RHS->isImplicitCode(); + ImplicitCode == RHS->isImplicitCode() && + Parameters == RHS->getRawParameters(); } unsigned getHashValue() const { @@ -1154,6 +1157,19 @@ } }; +template <> struct MDNodeKeyImpl { + int ArgNum; + Metadata *Expr; + MDNodeKeyImpl(int ArgNum, Metadata *Expr) : ArgNum(ArgNum), Expr(Expr) {} + MDNodeKeyImpl(const DICallSiteParam *N) + : ArgNum(N->getArgNum()), Expr(N->getRawExpression()) {} + bool isKeyOf(const DICallSiteParam *RHS) const { + return ArgNum == RHS->getArgNum() && Expr == RHS->getRawExpression(); + } + + unsigned getHashValue() const { return hash_combine(ArgNum, Expr); } +}; + template <> struct MDNodeKeyImpl { unsigned Tag; Metadata *Scope; Index: llvm/lib/IR/Verifier.cpp =================================================================== --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -1485,6 +1485,10 @@ AssertDI(isa(F), "invalid file", &N, F); } +void Verifier::visitDICallSiteParam(const DICallSiteParam &N) { + AssertDI(N.getTag() == dwarf::DW_TAG_call_site_parameter, "invalid tag", &N); +} + void Verifier::visitDIImportedEntity(const DIImportedEntity &N) { AssertDI(N.getTag() == dwarf::DW_TAG_imported_module || N.getTag() == dwarf::DW_TAG_imported_declaration,