X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FDwarfCompileUnit.cpp;h=b4dba9c59236aebbe574fd7b535e68b902d63349;hb=1b279144ecc41e788f7173892dfcc89f7ee6772a;hp=63cf62c03f948900aea8ce98e3fd09d2363aa238;hpb=3ee898c624b9b2869d1e273d12d9bb8728ec236c;p=oota-llvm.git diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 63cf62c03f9..b4dba9c5923 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -1,5 +1,5 @@ #include "DwarfCompileUnit.h" - +#include "DwarfExpression.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/GlobalValue.h" @@ -10,8 +10,8 @@ #include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetSubtargetInfo.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Target/TargetSubtargetInfo.h" namespace llvm { @@ -19,7 +19,7 @@ DwarfCompileUnit::DwarfCompileUnit(unsigned UID, DICompileUnit Node, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU) : DwarfUnit(UID, dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), - Skeleton(nullptr) { + Skeleton(nullptr), LabelBegin(nullptr), BaseAddress(nullptr) { insertDIE(Node, &getUnitDie()); } @@ -283,7 +283,7 @@ void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin, // and DW_AT_high_pc attributes. If there are global variables in this // scope then create and insert DIEs for these variables. DIE &DwarfCompileUnit::updateSubprogramScopeDIE(DISubprogram SP) { - DIE *SPDie = getOrCreateSubprogramDIE(SP); + DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes()); attachLowHighPC(*SPDie, DD->getFunctionBeginSym(), DD->getFunctionEndSym()); if (!DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim( @@ -291,11 +291,12 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(DISubprogram SP) { addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr); // Only include DW_AT_frame_base in full debug info - if (getCUNode().getEmissionKind() != DIBuilder::LineTablesOnly) { + if (!includeMinimalInlineScopes()) { const TargetRegisterInfo *RI = Asm->TM.getSubtargetImpl()->getRegisterInfo(); MachineLocation Location(RI->getFrameRegister(*Asm->MF)); - addAddress(*SPDie, dwarf::DW_AT_frame_base, Location); + if (RI->isPhysicalRegister(Location.getReg())) + addAddress(*SPDie, dwarf::DW_AT_frame_base, Location); } // Add name to the name table, we do this here because we're guaranteed @@ -341,10 +342,14 @@ void DwarfCompileUnit::constructScopeDIE( // null and the children will be added to the scope DIE. createScopeChildrenDIE(Scope, Children, &ChildScopeCount); - // There is no need to emit empty lexical block DIE. - for (const auto &E : DD->findImportedEntitiesForScope(DS)) - Children.push_back( - constructImportedEntityDIE(DIImportedEntity(E.second))); + // Skip imported directives in gmlt-like data. + if (!includeMinimalInlineScopes()) { + // There is no need to emit empty lexical block DIE. + for (const auto &E : DD->findImportedEntitiesForScope(DS)) + Children.push_back( + constructImportedEntityDIE(DIImportedEntity(E.second))); + } + // If there are only other scopes as children, put them directly in the // parent instead, as this scope would serve no purpose. if (Children.size() == ChildScopeCount) { @@ -372,40 +377,46 @@ void DwarfCompileUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute, Value); } -void -DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE, - const SmallVectorImpl &Range) { +void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE, + SmallVector Range) { // Emit offset in .debug_range as a relocatable label. emitDIE will handle // emitting it appropriately. - MCSymbol *RangeSym = - Asm->GetTempSymbol("debug_ranges", DD->getNextRangeNumber()); - auto *RangeSectionSym = DD->getRangeSectionSym(); + RangeSpanList List( + Asm->GetTempSymbol("debug_ranges", DD->getNextRangeNumber()), + std::move(Range)); + // Under fission, ranges are specified by constant offsets relative to the // CU's DW_AT_GNU_ranges_base. - if (DD->useSplitDwarf()) - addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, RangeSym, RangeSectionSym); + if (isDwoUnit()) + addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), + RangeSectionSym); else - addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, RangeSym, RangeSectionSym); - - RangeSpanList List(RangeSym); - for (const InsnRange &R : Range) - List.addRange(RangeSpan(DD->getLabelBeforeInsn(R.first), - DD->getLabelAfterInsn(R.second))); + addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), + RangeSectionSym); // Add the range list to the set of ranges to be emitted. - addRangeList(std::move(List)); + (Skeleton ? Skeleton : this)->CURangeLists.push_back(std::move(List)); +} + +void DwarfCompileUnit::attachRangesOrLowHighPC( + DIE &Die, SmallVector Ranges) { + if (Ranges.size() == 1) { + const auto &single = Ranges.front(); + attachLowHighPC(Die, single.getStart(), single.getEnd()); + } else + addScopeRangeList(Die, std::move(Ranges)); } void DwarfCompileUnit::attachRangesOrLowHighPC( DIE &Die, const SmallVectorImpl &Ranges) { - assert(!Ranges.empty()); - if (Ranges.size() == 1) - attachLowHighPC(Die, DD->getLabelBeforeInsn(Ranges.front().first), - DD->getLabelAfterInsn(Ranges.front().second)); - else - addScopeRangeList(Die, Ranges); + SmallVector List; + List.reserve(Ranges.size()); + for (const InsnRange &R : Ranges) + List.push_back(RangeSpan(DD->getLabelBeforeInsn(R.first), + DD->getLabelAfterInsn(R.second))); + attachRangesOrLowHighPC(Die, std::move(List)); } // This scope represents inlined body of a function. Construct DIE to @@ -570,7 +581,8 @@ void DwarfCompileUnit::constructSubprogramScopeDIE(LexicalScope *Scope) { // If we have more than one elements and the last one is null, it is a // variadic function. if (FnArgs.getNumElements() > 1 && - !FnArgs.getElement(FnArgs.getNumElements() - 1)) + !FnArgs.getElement(FnArgs.getNumElements() - 1) && + !includeMinimalInlineScopes()) ScopeDIE.addChild(make_unique(dwarf::DW_TAG_unspecified_parameters)); } @@ -597,11 +609,13 @@ DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) { DIE *ContextDIE; + if (includeMinimalInlineScopes()) + ContextDIE = &getUnitDie(); // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with // the important distinction that the DIDescriptor is not associated with the // DIE (since the DIDescriptor will be associated with the concrete DIE, if // any). It could be refactored to some common utility function. - if (DISubprogram SPDecl = SP.getFunctionDeclaration()) { + else if (DISubprogram SPDecl = SP.getFunctionDeclaration()) { ContextDIE = &getUnitDie(); getOrCreateSubprogramDIE(SPDecl); } else @@ -613,7 +627,7 @@ DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) { &createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, DIDescriptor()); applySubprogramAttributesToDefinition(SP, *AbsDef); - if (getCUNode().getEmissionKind() != DIBuilder::LineTablesOnly) + if (!includeMinimalInlineScopes()) addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, *AbsDef)) addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); @@ -633,6 +647,8 @@ DwarfCompileUnit::constructImportedEntityDIE(const DIImportedEntity &Module) { EntityDie = getOrCreateSubprogramDIE(DISubprogram(Entity)); else if (Entity.isType()) EntityDie = getOrCreateTypeDIE(DIType(Entity)); + else if (Entity.isGlobalVariable()) + EntityDie = getOrCreateGlobalVariableDIE(DIGlobalVariable(Entity)); else EntityDie = getDIE(Entity); assert(EntityDie); @@ -654,7 +670,7 @@ void DwarfCompileUnit::finishSubprogramDefinition(DISubprogram SP) { // If this subprogram has an abstract definition, reference that addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE); } else { - if (!D && getCUNode().getEmissionKind() != DIBuilder::LineTablesOnly) + if (!D && !includeMinimalInlineScopes()) // Lazily construct the subprogram if we didn't see either concrete or // inlined versions during codegen. (except in -gmlt ^ where we want // to omit these entirely) @@ -694,5 +710,127 @@ void DwarfCompileUnit::emitHeader(const MCSymbol *ASectionSym) const { DwarfUnit::emitHeader(ASectionSym); } +/// addGlobalName - Add a new global name to the compile unit. +void DwarfCompileUnit::addGlobalName(StringRef Name, DIE &Die, + DIScope Context) { + if (includeMinimalInlineScopes()) + return; + std::string FullName = getParentContextString(Context) + Name.str(); + GlobalNames[FullName] = &Die; +} + +/// Add a new global type to the unit. +void DwarfCompileUnit::addGlobalType(DIType Ty, const DIE &Die, + DIScope Context) { + if (includeMinimalInlineScopes()) + return; + std::string FullName = getParentContextString(Context) + Ty.getName().str(); + GlobalTypes[FullName] = &Die; +} + +/// addVariableAddress - Add DW_AT_location attribute for a +/// DbgVariable based on provided MachineLocation. +void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die, + MachineLocation Location) { + if (DV.variableHasComplexAddress()) + addComplexAddress(DV, Die, dwarf::DW_AT_location, Location); + else if (DV.isBlockByrefVariable()) + addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location); + else + addAddress(Die, dwarf::DW_AT_location, Location, + DV.getVariable().isIndirect()); +} + +/// Add an address attribute to a die based on the location provided. +void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, + const MachineLocation &Location, + bool Indirect) { + DIELoc *Loc = new (DIEValueAllocator) DIELoc(); + bool validReg; + if (Location.isReg() && !Indirect) + validReg = addRegisterOpPiece(*Loc, Location.getReg()); + else + validReg = addRegisterOffset(*Loc, Location.getReg(), Location.getOffset()); + + if (!validReg) + return; + + if (!Location.isReg() && Indirect) + addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); + + // Now attach the location information to the DIE. + addBlock(Die, Attribute, Loc); +} + +/// Start with the address based on the location provided, and generate the +/// DWARF information necessary to find the actual variable given the extra +/// address information encoded in the DbgVariable, starting from the starting +/// location. Add the DWARF information to the die. +void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, + dwarf::Attribute Attribute, + const MachineLocation &Location) { + DIELoc *Loc = new (DIEValueAllocator) DIELoc(); + DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); + DIExpression Expr = DV.getExpression(); + if (Location.getOffset()) { + if (DwarfExpr.AddMachineRegIndirect(Location.getReg(), + Location.getOffset())) { + DwarfExpr.AddExpression(Expr); + assert(!DV.getVariable().isIndirect() + && "double indirection not handled"); + } + } else { + if (DwarfExpr.AddMachineRegExpression(Expr, Location.getReg())) + if (DV.getVariable().isIndirect()) + DwarfExpr.EmitOp(dwarf::DW_OP_deref); + } + + // Now attach the location information to the DIE. + addBlock(Die, Attribute, Loc); +} + +/// Add a Dwarf loclistptr attribute data and value. +void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute, + unsigned Index) { + DIEValue *Value = new (DIEValueAllocator) DIELocList(Index); + dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset + : dwarf::DW_FORM_data4; + Die.addValue(Attribute, Form, Value); +} + +void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var, + DIE &VariableDie) { + StringRef Name = Var.getName(); + if (!Name.empty()) + addString(VariableDie, dwarf::DW_AT_name, Name); + addSourceLine(VariableDie, Var.getVariable()); + addType(VariableDie, Var.getType()); + if (Var.isArtificial()) + addFlag(VariableDie, dwarf::DW_AT_artificial); +} + +/// Add a Dwarf expression attribute data and value. +void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form, + const MCExpr *Expr) { + DIEValue *Value = new (DIEValueAllocator) DIEExpr(Expr); + Die.addValue((dwarf::Attribute)0, Form, Value); +} + +void DwarfCompileUnit::applySubprogramAttributesToDefinition(DISubprogram SP, + DIE &SPDie) { + DISubprogram SPDecl = SP.getFunctionDeclaration(); + DIScope Context = resolve(SPDecl ? SPDecl.getContext() : SP.getContext()); + applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes()); + addGlobalName(SP.getName(), SPDie, Context); +} + +bool DwarfCompileUnit::isDwoUnit() const { + return DD->useSplitDwarf() && Skeleton; +} + +bool DwarfCompileUnit::includeMinimalInlineScopes() const { + return getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly || + (DD->useSplitDwarf() && !Skeleton); +} } // end llvm namespace