diff options
Diffstat (limited to 'llvm/lib/IR/DebugInfoMetadata.cpp')
| -rw-r--r-- | llvm/lib/IR/DebugInfoMetadata.cpp | 189 |
1 files changed, 122 insertions, 67 deletions
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 4933b6032688..51950fc937f0 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -14,9 +14,9 @@ #include "LLVMContextImpl.h" #include "MetadataImpl.h" #include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/IR/DebugProgramInstruction.h" #include "llvm/IR/Function.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Type.h" @@ -42,6 +42,11 @@ DebugVariable::DebugVariable(const DbgVariableIntrinsic *DII) Fragment(DII->getExpression()->getFragmentInfo()), InlinedAt(DII->getDebugLoc().getInlinedAt()) {} +DebugVariable::DebugVariable(const DPValue *DPV) + : Variable(DPV->getVariable()), + Fragment(DPV->getExpression()->getFragmentInfo()), + InlinedAt(DPV->getDebugLoc().getInlinedAt()) {} + DebugVariableAggregate::DebugVariableAggregate(const DbgVariableIntrinsic *DVI) : DebugVariable(DVI->getVariable(), std::nullopt, DVI->getDebugLoc()->getInlinedAt()) {} @@ -712,7 +717,9 @@ Constant *DIDerivedType::getStorageOffsetInBits() const { } Constant *DIDerivedType::getConstant() const { - assert(getTag() == dwarf::DW_TAG_member && isStaticMember()); + assert((getTag() == dwarf::DW_TAG_member || + getTag() == dwarf::DW_TAG_variable) && + isStaticMember()); if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData())) return C->getValue(); return nullptr; @@ -914,11 +921,11 @@ DICompileUnit::DICompileUnit(LLVMContext &C, StorageType Storage, bool DebugInfoForProfiling, unsigned NameTableKind, bool RangesBaseAddress, ArrayRef<Metadata *> Ops) : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops), - SourceLanguage(SourceLanguage), IsOptimized(IsOptimized), - RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind), DWOId(DWOId), - SplitDebugInlining(SplitDebugInlining), + SourceLanguage(SourceLanguage), RuntimeVersion(RuntimeVersion), + DWOId(DWOId), EmissionKind(EmissionKind), NameTableKind(NameTableKind), + IsOptimized(IsOptimized), SplitDebugInlining(SplitDebugInlining), DebugInfoForProfiling(DebugInfoForProfiling), - NameTableKind(NameTableKind), RangesBaseAddress(RangesBaseAddress) { + RangesBaseAddress(RangesBaseAddress) { assert(Storage != Uniqued); } @@ -1180,8 +1187,9 @@ DILexicalBlockFile *DILexicalBlockFile::getImpl(LLVMContext &Context, DINamespace::DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols, ArrayRef<Metadata *> Ops) - : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops), - ExportSymbols(ExportSymbols) {} + : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops) { + SubclassData1 = ExportSymbols; +} DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, bool ExportSymbols, StorageType Storage, bool ShouldCreate) { @@ -1195,8 +1203,9 @@ DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope, DICommonBlock::DICommonBlock(LLVMContext &Context, StorageType Storage, unsigned LineNo, ArrayRef<Metadata *> Ops) : DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block, - Ops), - LineNo(LineNo) {} + Ops) { + SubclassData32 = LineNo; +} DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope, Metadata *Decl, MDString *Name, Metadata *File, unsigned LineNo, @@ -1210,8 +1219,10 @@ DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope, DIModule::DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo, bool IsDecl, ArrayRef<Metadata *> Ops) - : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops), - LineNo(LineNo), IsDecl(IsDecl) {} + : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) { + SubclassData1 = IsDecl; + SubclassData32 = LineNo; +} DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *File, Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, @@ -1300,8 +1311,9 @@ DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, DIVariable::DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, signed Line, ArrayRef<Metadata *> Ops, uint32_t AlignInBits) - : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line), - AlignInBits(AlignInBits) {} + : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line) { + SubclassData32 = AlignInBits; +} std::optional<uint64_t> DIVariable::getSizeInBits() const { // This is used by the Verifier so be mindful of broken types. const Metadata *RawType = getRawType(); @@ -1327,7 +1339,9 @@ std::optional<uint64_t> DIVariable::getSizeInBits() const { DILabel::DILabel(LLVMContext &C, StorageType Storage, unsigned Line, ArrayRef<Metadata *> Ops) - : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops), Line(Line) {} + : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops) { + SubclassData32 = Line; +} DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, Metadata *File, unsigned Line, StorageType Storage, bool ShouldCreate) { @@ -1345,13 +1359,23 @@ DIExpression *DIExpression::getImpl(LLVMContext &Context, DEFINE_GETIMPL_STORE_NO_OPS(DIExpression, (Elements)); } bool DIExpression::isEntryValue() const { - return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_LLVM_entry_value; + if (auto singleLocElts = getSingleLocationExpressionElements()) { + return singleLocElts->size() > 0 && + (*singleLocElts)[0] == dwarf::DW_OP_LLVM_entry_value; + } + return false; } bool DIExpression::startsWithDeref() const { - return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref; + if (auto singleLocElts = getSingleLocationExpressionElements()) + return singleLocElts->size() > 0 && + (*singleLocElts)[0] == dwarf::DW_OP_deref; + return false; } bool DIExpression::isDeref() const { - return getNumElements() == 1 && startsWithDeref(); + if (auto singleLocElts = getSingleLocationExpressionElements()) + return singleLocElts->size() == 1 && + (*singleLocElts)[0] == dwarf::DW_OP_deref; + return false; } DIAssignID *DIAssignID::getImpl(LLVMContext &Context, StorageType Storage, @@ -1528,14 +1552,34 @@ bool DIExpression::isSingleLocationExpression() const { auto ExprOpBegin = expr_ops().begin(); auto ExprOpEnd = expr_ops().end(); - if (ExprOpBegin->getOp() == dwarf::DW_OP_LLVM_arg) + if (ExprOpBegin->getOp() == dwarf::DW_OP_LLVM_arg) { + if (ExprOpBegin->getArg(0) != 0) + return false; ++ExprOpBegin; + } return !std::any_of(ExprOpBegin, ExprOpEnd, [](auto Op) { return Op.getOp() == dwarf::DW_OP_LLVM_arg; }); } +std::optional<ArrayRef<uint64_t>> +DIExpression::getSingleLocationExpressionElements() const { + // Check for `isValid` covered by `isSingleLocationExpression`. + if (!isSingleLocationExpression()) + return std::nullopt; + + // An empty expression is already non-variadic. + if (!getNumElements()) + return ArrayRef<uint64_t>(); + + // If Expr does not have a leading DW_OP_LLVM_arg then we don't need to do + // anything. + if (getElements()[0] == dwarf::DW_OP_LLVM_arg) + return getElements().drop_front(2); + return getElements(); +} + const DIExpression * DIExpression::convertToUndefExpression(const DIExpression *Expr) { SmallVector<uint64_t, 3> UndefOps; @@ -1561,23 +1605,13 @@ DIExpression::convertToVariadicExpression(const DIExpression *Expr) { std::optional<const DIExpression *> DIExpression::convertToNonVariadicExpression(const DIExpression *Expr) { - // Check for `isValid` covered by `isSingleLocationExpression`. - if (!Expr->isSingleLocationExpression()) + if (!Expr) return std::nullopt; - // An empty expression is already non-variadic. - if (!Expr->getNumElements()) - return Expr; - - auto ElementsBegin = Expr->elements_begin(); - // If Expr does not have a leading DW_OP_LLVM_arg then we don't need to do - // anything. - if (*ElementsBegin != dwarf::DW_OP_LLVM_arg) - return Expr; + if (auto Elts = Expr->getSingleLocationExpressionElements()) + return DIExpression::get(Expr->getContext(), *Elts); - SmallVector<uint64_t> NonVariadicOps( - make_range(ElementsBegin + 2, Expr->elements_end())); - return DIExpression::get(Expr->getContext(), NonVariadicOps); + return std::nullopt; } void DIExpression::canonicalizeExpressionOps(SmallVectorImpl<uint64_t> &Ops, @@ -1648,23 +1682,29 @@ void DIExpression::appendOffset(SmallVectorImpl<uint64_t> &Ops, } bool DIExpression::extractIfOffset(int64_t &Offset) const { - if (getNumElements() == 0) { + auto SingleLocEltsOpt = getSingleLocationExpressionElements(); + if (!SingleLocEltsOpt) + return false; + auto SingleLocElts = *SingleLocEltsOpt; + + if (SingleLocElts.size() == 0) { Offset = 0; return true; } - if (getNumElements() == 2 && Elements[0] == dwarf::DW_OP_plus_uconst) { - Offset = Elements[1]; + if (SingleLocElts.size() == 2 && + SingleLocElts[0] == dwarf::DW_OP_plus_uconst) { + Offset = SingleLocElts[1]; return true; } - if (getNumElements() == 3 && Elements[0] == dwarf::DW_OP_constu) { - if (Elements[2] == dwarf::DW_OP_plus) { - Offset = Elements[1]; + if (SingleLocElts.size() == 3 && SingleLocElts[0] == dwarf::DW_OP_constu) { + if (SingleLocElts[2] == dwarf::DW_OP_plus) { + Offset = SingleLocElts[1]; return true; } - if (Elements[2] == dwarf::DW_OP_minus) { - Offset = -Elements[1]; + if (SingleLocElts[2] == dwarf::DW_OP_minus) { + Offset = -SingleLocElts[1]; return true; } } @@ -1687,18 +1727,23 @@ const DIExpression *DIExpression::extractAddressClass(const DIExpression *Expr, unsigned &AddrClass) { // FIXME: This seems fragile. Nothing that verifies that these elements // actually map to ops and not operands. + auto SingleLocEltsOpt = Expr->getSingleLocationExpressionElements(); + if (!SingleLocEltsOpt) + return nullptr; + auto SingleLocElts = *SingleLocEltsOpt; + const unsigned PatternSize = 4; - if (Expr->Elements.size() >= PatternSize && - Expr->Elements[PatternSize - 4] == dwarf::DW_OP_constu && - Expr->Elements[PatternSize - 2] == dwarf::DW_OP_swap && - Expr->Elements[PatternSize - 1] == dwarf::DW_OP_xderef) { - AddrClass = Expr->Elements[PatternSize - 3]; + if (SingleLocElts.size() >= PatternSize && + SingleLocElts[PatternSize - 4] == dwarf::DW_OP_constu && + SingleLocElts[PatternSize - 2] == dwarf::DW_OP_swap && + SingleLocElts[PatternSize - 1] == dwarf::DW_OP_xderef) { + AddrClass = SingleLocElts[PatternSize - 3]; - if (Expr->Elements.size() == PatternSize) + if (SingleLocElts.size() == PatternSize) return nullptr; - return DIExpression::get(Expr->getContext(), - ArrayRef(&*Expr->Elements.begin(), - Expr->Elements.size() - PatternSize)); + return DIExpression::get( + Expr->getContext(), + ArrayRef(&*SingleLocElts.begin(), SingleLocElts.size() - PatternSize)); } return Expr; } @@ -2076,11 +2121,14 @@ DIMacroFile *DIMacroFile::getImpl(LLVMContext &Context, unsigned MIType, DEFINE_GETIMPL_STORE(DIMacroFile, (MIType, Line), Ops); } -DIArgList *DIArgList::getImpl(LLVMContext &Context, - ArrayRef<ValueAsMetadata *> Args, - StorageType Storage, bool ShouldCreate) { - DEFINE_GETIMPL_LOOKUP(DIArgList, (Args)); - DEFINE_GETIMPL_STORE_NO_OPS(DIArgList, (Args)); +DIArgList *DIArgList::get(LLVMContext &Context, + ArrayRef<ValueAsMetadata *> Args) { + auto ExistingIt = Context.pImpl->DIArgLists.find_as(DIArgListKeyInfo(Args)); + if (ExistingIt != Context.pImpl->DIArgLists.end()) + return *ExistingIt; + DIArgList *NewArgList = new DIArgList(Context, Args); + Context.pImpl->DIArgLists.insert(NewArgList); + return NewArgList; } void DIArgList::handleChangedOperand(void *Ref, Metadata *New) { @@ -2088,12 +2136,9 @@ void DIArgList::handleChangedOperand(void *Ref, Metadata *New) { assert((!New || isa<ValueAsMetadata>(New)) && "DIArgList must be passed a ValueAsMetadata"); untrack(); - bool Uniq = isUniqued(); - if (Uniq) { - // We need to update the uniqueness once the Args are updated since they - // form the key to the DIArgLists store. - eraseFromStore(); - } + // We need to update the set storage once the Args are updated since they + // form the key to the DIArgLists store. + getContext().pImpl->DIArgLists.erase(this); ValueAsMetadata *NewVM = cast_or_null<ValueAsMetadata>(New); for (ValueAsMetadata *&VM : Args) { if (&VM == OldVMPtr) { @@ -2103,10 +2148,19 @@ void DIArgList::handleChangedOperand(void *Ref, Metadata *New) { VM = ValueAsMetadata::get(PoisonValue::get(VM->getValue()->getType())); } } - if (Uniq) { - if (uniquify() != this) - storeDistinctInContext(); + // We've changed the contents of this DIArgList, and the set storage may + // already contain a DIArgList with our new set of args; if it does, then we + // must RAUW this with the existing DIArgList, otherwise we simply insert this + // back into the set storage. + DIArgList *ExistingArgList = getUniqued(getContext().pImpl->DIArgLists, this); + if (ExistingArgList) { + replaceAllUsesWith(ExistingArgList); + // Clear this here so we don't try to untrack in the destructor. + Args.clear(); + delete this; + return; } + getContext().pImpl->DIArgLists.insert(this); track(); } void DIArgList::track() { @@ -2119,8 +2173,9 @@ void DIArgList::untrack() { if (VAM) MetadataTracking::untrack(&VAM, *VAM); } -void DIArgList::dropAllReferences() { - untrack(); +void DIArgList::dropAllReferences(bool Untrack) { + if (Untrack) + untrack(); Args.clear(); - MDNode::dropAllReferences(); + ReplaceableMetadataImpl::resolveAllUses(/* ResolveUsers */ false); } |
