X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FIR%2FDebugInfo.cpp;h=deeaae7d5de2a90e3d3539062afbb9b08eb964b0;hb=415561b6e077fb4dda5d59c699829c9e7d39e08e;hp=60904c2b356b2cf780a91ad4ab9207904777f2a0;hpb=666a51320e75d3a3fc1b38c0b683496b40f49c18;p=oota-llvm.git diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index 60904c2b356..deeaae7d5de 100644 --- a/lib/IR/DebugInfo.cpp +++ b/lib/IR/DebugInfo.cpp @@ -52,7 +52,7 @@ bool DIDescriptor::Verify() const { DIImportedEntity(DbgNode).Verify() || DIExpression(DbgNode).Verify()); } -static Value *getField(const MDNode *DbgNode, unsigned Elt) { +static Metadata *getField(const MDNode *DbgNode, unsigned Elt) { if (!DbgNode || Elt >= DbgNode->getNumOperands()) return nullptr; return DbgNode->getOperand(Elt); @@ -73,25 +73,17 @@ StringRef DIDescriptor::getStringField(unsigned Elt) const { } uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const { - if (!DbgNode) - return 0; - - if (Elt < DbgNode->getNumOperands()) - if (ConstantInt *CI = - dyn_cast_or_null(DbgNode->getOperand(Elt))) + if (auto *C = getConstantField(Elt)) + if (ConstantInt *CI = dyn_cast(C)) return CI->getZExtValue(); return 0; } int64_t DIDescriptor::getInt64Field(unsigned Elt) const { - if (!DbgNode) - return 0; - - if (Elt < DbgNode->getNumOperands()) - if (ConstantInt *CI = - dyn_cast_or_null(DbgNode->getOperand(Elt))) - return CI->getSExtValue(); + if (auto *C = getConstantField(Elt)) + if (ConstantInt *CI = dyn_cast(C)) + return CI->getZExtValue(); return 0; } @@ -102,12 +94,7 @@ DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const { } GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const { - if (!DbgNode) - return nullptr; - - if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null(DbgNode->getOperand(Elt)); - return nullptr; + return dyn_cast_or_null(getConstantField(Elt)); } Constant *DIDescriptor::getConstantField(unsigned Elt) const { @@ -115,17 +102,14 @@ Constant *DIDescriptor::getConstantField(unsigned Elt) const { return nullptr; if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null(DbgNode->getOperand(Elt)); + if (auto *C = + dyn_cast_or_null(DbgNode->getOperand(Elt))) + return C->getValue(); return nullptr; } Function *DIDescriptor::getFunctionField(unsigned Elt) const { - if (!DbgNode) - return nullptr; - - if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null(DbgNode->getOperand(Elt)); - return nullptr; + return dyn_cast_or_null(getConstantField(Elt)); } void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) { @@ -134,7 +118,7 @@ void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) { if (Elt < DbgNode->getNumOperands()) { MDNode *Node = const_cast(DbgNode); - Node->replaceOperandWith(Elt, F); + Node->replaceOperandWith(Elt, F ? ConstantAsMetadata::get(F) : nullptr); } } @@ -163,18 +147,32 @@ uint64_t DIExpression::getElement(unsigned Idx) const { return getHeaderFieldAs(I); } -bool DIExpression::isVariablePiece() const { - return getNumElements() && getElement(0) == dwarf::DW_OP_piece; +bool DIExpression::isBitPiece() const { + unsigned N = getNumElements(); + return N >=3 && getElement(N-3) == dwarf::DW_OP_bit_piece; +} + +uint64_t DIExpression::getBitPieceOffset() const { + assert(isBitPiece() && "not a piece"); + return getElement(getNumElements()-2); +} + +uint64_t DIExpression::getBitPieceSize() const { + assert(isBitPiece() && "not a piece"); + return getElement(getNumElements()-1); +} + +DIExpression::iterator DIExpression::begin() const { + return DIExpression::iterator(*this); } -uint64_t DIExpression::getPieceOffset() const { - assert(isVariablePiece()); - return getElement(1); +DIExpression::iterator DIExpression::end() const { + return DIExpression::iterator(); } -uint64_t DIExpression::getPieceSize() const { - assert(isVariablePiece()); - return getElement(2); +DIExpression::Operand DIExpression::Operand::getNext() const { + iterator it(I); + return *(++it); } //===----------------------------------------------------------------------===// @@ -182,7 +180,7 @@ uint64_t DIExpression::getPieceSize() const { //===----------------------------------------------------------------------===// bool DIDescriptor::isSubroutineType() const { - return isCompositeType() && getTag() == dwarf::DW_TAG_subroutine_type; + return DbgNode && getTag() == dwarf::DW_TAG_subroutine_type; } bool DIDescriptor::isBasicType() const { @@ -256,8 +254,7 @@ bool DIDescriptor::isSubprogram() const { } bool DIDescriptor::isGlobalVariable() const { - return DbgNode && (getTag() == dwarf::DW_TAG_variable || - getTag() == dwarf::DW_TAG_constant); + return DbgNode && getTag() == dwarf::DW_TAG_variable; } bool DIDescriptor::isScope() const { @@ -347,27 +344,25 @@ void DIDescriptor::replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D) { // itself. const MDNode *DN = D; if (DbgNode == DN) { - SmallVector Ops(DbgNode->getNumOperands()); + SmallVector Ops(DbgNode->getNumOperands()); for (size_t i = 0; i != Ops.size(); ++i) Ops[i] = DbgNode->getOperand(i); DN = MDNode::get(VMContext, Ops); } - MDNode *Node = const_cast(DbgNode); - const Value *V = cast_or_null(DN); - Node->replaceAllUsesWith(const_cast(V)); + assert(DbgNode->isTemporary() && "Expected temporary node"); + auto *Node = const_cast(DbgNode); + Node->replaceAllUsesWith(const_cast(DN)); MDNode::deleteTemporary(Node); DbgNode = DN; } void DIDescriptor::replaceAllUsesWith(MDNode *D) { - assert(DbgNode && "Trying to replace an unverified type!"); assert(DbgNode != D && "This replacement should always happen"); - MDNode *Node = const_cast(DbgNode); - const MDNode *DN = D; - const Value *V = cast_or_null(DN); - Node->replaceAllUsesWith(const_cast(V)); + assert(DbgNode->isTemporary() && "Expected temporary node"); + auto *Node = const_cast(DbgNode); + Node->replaceAllUsesWith(D); MDNode::deleteTemporary(Node); } @@ -398,7 +393,7 @@ bool DIObjCProperty::Verify() const { static bool fieldIsMDNode(const MDNode *DbgNode, unsigned Elt) { // FIXME: This function should return true, if the field is null or the field // is indeed a MDNode: return !Fld || isa(Fld). - Value *Fld = getField(DbgNode, Elt); + Metadata *Fld = getField(DbgNode, Elt); if (Fld && isa(Fld) && !cast(Fld)->getString().empty()) return false; return true; @@ -406,36 +401,38 @@ static bool fieldIsMDNode(const MDNode *DbgNode, unsigned Elt) { /// \brief Check if a field at position Elt of a MDNode is a MDString. static bool fieldIsMDString(const MDNode *DbgNode, unsigned Elt) { - Value *Fld = getField(DbgNode, Elt); + Metadata *Fld = getField(DbgNode, Elt); return !Fld || isa(Fld); } /// \brief Check if a value can be a reference to a type. -static bool isTypeRef(const Value *Val) { - return !Val || - (isa(Val) && !cast(Val)->getString().empty()) || - (isa(Val) && DIType(cast(Val)).isType()); +static bool isTypeRef(const Metadata *MD) { + if (!MD) + return true; + if (auto *S = dyn_cast(MD)) + return !S->getString().empty(); + if (auto *N = dyn_cast(MD)) + return DIType(N).isType(); + return false; } /// \brief Check if referenced field might be a type. static bool fieldIsTypeRef(const MDNode *DbgNode, unsigned Elt) { - Value *Fld = getField(DbgNode, Elt); - return isTypeRef(Fld); + return isTypeRef(dyn_cast_or_null(getField(DbgNode, Elt))); } /// \brief Check if a value can be a ScopeRef. -static bool isScopeRef(const Value *Val) { - return !Val || - (isa(Val) && !cast(Val)->getString().empty()) || - // Not checking for Val->isScope() here, because it would work - // only for lexical scopes and not all subclasses of DIScope. - isa(Val); +static bool isScopeRef(const Metadata *MD) { + if (!MD) + return true; + if (auto *S = dyn_cast(MD)) + return !S->getString().empty(); + return isa(MD); } /// \brief Check if a field at position Elt of a MDNode can be a ScopeRef. static bool fieldIsScopeRef(const MDNode *DbgNode, unsigned Elt) { - Value *Fld = getField(DbgNode, Elt); - return isScopeRef(Fld); + return isScopeRef(dyn_cast_or_null(getField(DbgNode, Elt))); } bool DIType::Verify() const { @@ -531,7 +528,6 @@ bool DISubprogram::Verify() const { // If a DISubprogram has an llvm::Function*, then scope chains from all // instructions within the function should lead to this DISubprogram. if (auto *F = getFunction()) { - LLVMContext &Ctxt = F->getContext(); for (auto &BB : *F) { for (auto &I : BB) { DebugLoc DL = I.getDebugLoc(); @@ -541,15 +537,19 @@ bool DISubprogram::Verify() const { MDNode *Scope = nullptr; MDNode *IA = nullptr; // walk the inlined-at scopes - while (DL.getScopeAndInlinedAt(Scope, IA, F->getContext()), IA) + while ((IA = DL.getInlinedAt())) DL = DebugLoc::getFromDILocation(IA); - DL.getScopeAndInlinedAt(Scope, IA, Ctxt); + DL.getScopeAndInlinedAt(Scope, IA); + if (!Scope) + return false; assert(!IA); while (!DIDescriptor(Scope).isSubprogram()) { DILexicalBlockFile D(Scope); Scope = D.isLexicalBlockFile() ? D.getScope() - : DebugLoc::getFromDILexicalBlock(Scope).getScope(Ctxt); + : DebugLoc::getFromDILexicalBlock(Scope).getScope(); + if (!Scope) + return false; } if (!DISubprogram(Scope).describes(F)) return false; @@ -607,14 +607,29 @@ bool DIExpression::Verify() const { if (!DbgNode) return true; - return isExpression() && DbgNode->getNumOperands() == 1; + if (!(isExpression() && DbgNode->getNumOperands() == 1)) + return false; + + for (auto Op : *this) + switch (Op) { + case DW_OP_bit_piece: + // Must be the last element of the expression. + return std::distance(Op.getBase(), DIHeaderFieldIterator()) == 3; + case DW_OP_plus: + if (std::distance(Op.getBase(), DIHeaderFieldIterator()) < 2) + return false; + break; + case DW_OP_deref: + break; + default: + // Other operators are not yet supported by the backend. + return false; + } + return true; } bool DILocation::Verify() const { - if (!DbgNode) - return false; - - return DbgNode->getNumOperands() == 4; + return DbgNode && isa(DbgNode); } bool DINameSpace::Verify() const { @@ -676,19 +691,19 @@ MDString *DICompositeType::getIdentifier() const { static void VerifySubsetOf(const MDNode *LHS, const MDNode *RHS) { for (unsigned i = 0; i != LHS->getNumOperands(); ++i) { // Skip the 'empty' list (that's a single i32 0, rather than truly empty). - if (i == 0 && isa(LHS->getOperand(i))) + if (i == 0 && mdconst::hasa(LHS->getOperand(i))) continue; const MDNode *E = cast(LHS->getOperand(i)); bool found = false; for (unsigned j = 0; !found && j != RHS->getNumOperands(); ++j) - found = E == RHS->getOperand(j); + found = (E == cast(RHS->getOperand(j))); assert(found && "Losing a member during member list replacement"); } } #endif void DICompositeType::setArraysHelper(MDNode *Elements, MDNode *TParams) { - TrackingVH N(*this); + TrackingMDNodeRef N(*this); if (Elements) { #ifndef NDEBUG // Check that the new list of members contains all the old members as well. @@ -712,7 +727,7 @@ DIScopeRef DIScope::getRef() const { } void DICompositeType::setContainingType(DICompositeType ContainingType) { - TrackingVH N(*this); + TrackingMDNodeRef N(*this); N->replaceOperandWith(5, ContainingType.getRef()); DbgNode = N; } @@ -746,8 +761,8 @@ DIArray DISubprogram::getVariables() const { return DIArray(getNodeField(DbgNode, 8)); } -Value *DITemplateValueParameter::getValue() const { - return getField(DbgNode, 3); +Metadata *DITemplateValueParameter::getValue() const { + return DbgNode->getOperand(3); } DIScopeRef DIScope::getContext() const { @@ -849,16 +864,12 @@ void DICompileUnit::replaceGlobalVariables(DIArray GlobalVariables) { DILocation DILocation::copyWithNewScope(LLVMContext &Ctx, DILexicalBlockFile NewScope) { - SmallVector Elts; assert(Verify()); - for (unsigned I = 0; I < DbgNode->getNumOperands(); ++I) { - if (I != 2) - Elts.push_back(DbgNode->getOperand(I)); - else - Elts.push_back(NewScope); - } - MDNode *NewDIL = MDNode::get(Ctx, Elts); - return DILocation(NewDIL); + assert(NewScope && "Expected valid scope"); + + const auto *Old = cast(DbgNode); + return DILocation(MDLocation::get(Ctx, Old->getLine(), Old->getColumn(), + NewScope, Old->getInlinedAt())); } unsigned DILocation::computeNewDiscriminator(LLVMContext &Ctx) { @@ -873,7 +884,7 @@ DIVariable llvm::createInlinedVariable(MDNode *DV, MDNode *InlinedScope, return cleanseInlinedVariable(DV, VMContext); // Insert inlined scope. - SmallVector Elts; + SmallVector Elts; for (unsigned I = 0, E = DIVariableInlinedAtIndex; I != E; ++I) Elts.push_back(DV->getOperand(I)); Elts.push_back(InlinedScope); @@ -889,7 +900,7 @@ DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) { return DIVariable(DV); // Remove inlined scope. - SmallVector Elts; + SmallVector Elts; for (unsigned I = 0, E = DIVariableInlinedAtIndex; I != E; ++I) Elts.push_back(DV->getOperand(I)); @@ -921,7 +932,7 @@ DISubprogram llvm::getDISubprogram(const Function *F) { if (Inst == BB.end()) continue; DebugLoc DLoc = Inst->getDebugLoc(); - const MDNode *Scope = DLoc.getScopeNode(F->getParent()->getContext()); + const MDNode *Scope = DLoc.getScopeNode(); DISubprogram Subprogram = getDISubprogram(Scope); return Subprogram.describes(F) ? Subprogram : DISubprogram(); } @@ -1125,7 +1136,7 @@ void DebugInfoFinder::processDeclare(const Module &M, if (!DV.isVariable()) return; - if (!NodesSeen.insert(DV)) + if (!NodesSeen.insert(DV).second) return; processScope(DIVariable(N).getContext()); processType(DIVariable(N).getType().resolve(TypeIdentifierMap)); @@ -1141,7 +1152,7 @@ void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) { if (!DV.isVariable()) return; - if (!NodesSeen.insert(DV)) + if (!NodesSeen.insert(DV).second) return; processScope(DIVariable(N).getContext()); processType(DIVariable(N).getType().resolve(TypeIdentifierMap)); @@ -1151,7 +1162,7 @@ bool DebugInfoFinder::addType(DIType DT) { if (!DT) return false; - if (!NodesSeen.insert(DT)) + if (!NodesSeen.insert(DT).second) return false; TYs.push_back(DT); @@ -1161,7 +1172,7 @@ bool DebugInfoFinder::addType(DIType DT) { bool DebugInfoFinder::addCompileUnit(DICompileUnit CU) { if (!CU) return false; - if (!NodesSeen.insert(CU)) + if (!NodesSeen.insert(CU).second) return false; CUs.push_back(CU); @@ -1172,7 +1183,7 @@ bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable DIG) { if (!DIG) return false; - if (!NodesSeen.insert(DIG)) + if (!NodesSeen.insert(DIG).second) return false; GVs.push_back(DIG); @@ -1183,7 +1194,7 @@ bool DebugInfoFinder::addSubprogram(DISubprogram SP) { if (!SP) return false; - if (!NodesSeen.insert(SP)) + if (!NodesSeen.insert(SP).second) return false; SPs.push_back(SP); @@ -1197,7 +1208,7 @@ bool DebugInfoFinder::addScope(DIScope Scope) { // as null for now. if (Scope->getNumOperands() == 0) return false; - if (!NodesSeen.insert(Scope)) + if (!NodesSeen.insert(Scope).second) return false; Scopes.push_back(Scope); return true; @@ -1399,24 +1410,22 @@ void DIVariable::printInternal(raw_ostream &OS) const { } void DIExpression::printInternal(raw_ostream &OS) const { - for (unsigned I = 0; I < getNumElements(); ++I) { - uint64_t OpCode = getElement(I); - OS << " [" << OperationEncodingString(OpCode); - switch (OpCode) { + for (auto Op : *this) { + OS << " [" << OperationEncodingString(Op); + switch (Op) { case DW_OP_plus: { - OS << " " << getElement(++I); + OS << " " << Op.getArg(1); break; } - case DW_OP_piece: { - unsigned Offset = getElement(++I); - unsigned Size = getElement(++I); - OS << " offset=" << Offset << ", size=" << Size; + case DW_OP_bit_piece: { + OS << " offset=" << Op.getArg(1) << ", size=" << Op.getArg(2); break; } + case DW_OP_deref: + // No arguments. + break; default: - // Else bail out early. This may be a line table entry. - OS << "Unknown]"; - return; + llvm_unreachable("unhandled operation"); } OS << "]"; } @@ -1465,19 +1474,19 @@ void DIVariable::printExtendedName(raw_ostream &OS) const { } } -template <> DIRef::DIRef(const Value *V) : Val(V) { +template <> DIRef::DIRef(const Metadata *V) : Val(V) { assert(isScopeRef(V) && "DIScopeRef should be a MDString or MDNode"); } -template <> DIRef::DIRef(const Value *V) : Val(V) { +template <> DIRef::DIRef(const Metadata *V) : Val(V) { assert(isTypeRef(V) && "DITypeRef should be a MDString or MDNode"); } template <> DIScopeRef DIDescriptor::getFieldAs(unsigned Elt) const { - return DIScopeRef(getField(DbgNode, Elt)); + return DIScopeRef(cast_or_null(getField(DbgNode, Elt))); } template <> DITypeRef DIDescriptor::getFieldAs(unsigned Elt) const { - return DITypeRef(getField(DbgNode, Elt)); + return DITypeRef(cast_or_null(getField(DbgNode, Elt))); } bool llvm::StripDebugInfo(Module &M) { @@ -1528,10 +1537,10 @@ bool llvm::StripDebugInfo(Module &M) { } unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) { - Value *Val = M.getModuleFlag("Debug Info Version"); - if (!Val) - return 0; - return cast(Val)->getZExtValue(); + if (auto *Val = mdconst::dyn_extract_or_null( + M.getModuleFlag("Debug Info Version"))) + return Val->getZExtValue(); + return 0; } llvm::DenseMap