diff options
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp')
| -rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 184 | 
1 files changed, 147 insertions, 37 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 1dca3f0fce5b..9548ad9918c1 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -1,9 +1,8 @@  //===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===//  // -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception  //  //===----------------------------------------------------------------------===//  // @@ -18,6 +17,7 @@  #include "DwarfUnit.h"  #include "llvm/ADT/None.h"  #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h"  #include "llvm/ADT/SmallVector.h"  #include "llvm/ADT/StringRef.h"  #include "llvm/BinaryFormat/Dwarf.h" @@ -104,7 +104,7 @@ unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) {    // extend .file to support this.    unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID();    if (!File) -    return Asm->OutStreamer->EmitDwarfFileDirective(0, "", "", nullptr, None, CUID); +    return Asm->OutStreamer->EmitDwarfFileDirective(0, "", "", None, None, CUID);    return Asm->OutStreamer->EmitDwarfFileDirective(        0, File->getDirectory(), File->getFilename(), getMD5AsBytes(File),        File->getSource(), CUID); @@ -119,17 +119,19 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(    assert(GV);    auto *GVContext = GV->getScope(); -  auto *GTy = DD->resolve(GV->getType()); +  const DIType *GTy = GV->getType();    // Construct the context before querying for the existence of the DIE in    // case such construction creates the DIE. -  DIE *ContextDIE = getOrCreateContextDIE(GVContext); +  auto *CB = GVContext ? dyn_cast<DICommonBlock>(GVContext) : nullptr; +  DIE *ContextDIE = CB ? getOrCreateCommonBlock(CB, GlobalExprs) +    : getOrCreateContextDIE(GVContext);    // Add to map.    DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV);    DIScope *DeclContext;    if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) { -    DeclContext = resolve(SDMDecl->getScope()); +    DeclContext = SDMDecl->getScope();      assert(SDMDecl->isStaticMember() && "Expected static member decl");      assert(GV->isDefinition());      // We need the declaration DIE that is in the static member's class. @@ -137,7 +139,7 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(      addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);      // If the global variable's type is different from the one in the class      // member type, assume that it's more specific and also emit it. -    if (GTy != DD->resolve(SDMDecl->getBaseType())) +    if (GTy != SDMDecl->getBaseType())        addType(*VariableDIE, GTy);    } else {      DeclContext = GV->getScope(); @@ -166,8 +168,16 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(      addTemplateParams(*VariableDIE, DINodeArray(TP));    // Add location. +  addLocationAttribute(VariableDIE, GV, GlobalExprs); + +  return VariableDIE; +} + +void DwarfCompileUnit::addLocationAttribute( +    DIE *VariableDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {    bool addToAccelTable = false;    DIELoc *Loc = nullptr; +  Optional<unsigned> NVPTXAddressSpace;    std::unique_ptr<DIEDwarfExpression> DwarfExpr;    for (const auto &GE : GlobalExprs) {      const GlobalVariable *Global = GE.Var; @@ -201,8 +211,24 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(        DwarfExpr = llvm::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc);      } -    if (Expr) +    if (Expr) { +      // According to +      // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf +      // cuda-gdb requires DW_AT_address_class for all variables to be able to +      // correctly interpret address space of the variable address. +      // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef +      // sequence for the NVPTX + gdb target. +      unsigned LocalNVPTXAddressSpace; +      if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { +        const DIExpression *NewExpr = +            DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace); +        if (NewExpr != Expr) { +          Expr = NewExpr; +          NVPTXAddressSpace = LocalNVPTXAddressSpace; +        } +      }        DwarfExpr->addFragmentOffset(Expr); +    }      if (Global) {        const MCSymbol *Sym = Asm->getSymbol(Global); @@ -247,6 +273,15 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(        DwarfExpr->setMemoryLocationKind();      DwarfExpr->addExpression(Expr);    } +  if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { +    // According to +    // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf +    // cuda-gdb requires DW_AT_address_class for all variables to be able to +    // correctly interpret address space of the variable address. +    const unsigned NVPTX_ADDR_global_space = 5; +    addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1, +            NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_global_space); +  }    if (Loc)      addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize()); @@ -262,8 +297,25 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(          DD->useAllLinkageNames())        DD->addAccelName(*CUNode, GV->getLinkageName(), *VariableDIE);    } +} -  return VariableDIE; +DIE *DwarfCompileUnit::getOrCreateCommonBlock( +    const DICommonBlock *CB, ArrayRef<GlobalExpr> GlobalExprs) { +  // Construct the context before querying for the existence of the DIE in case +  // such construction creates the DIE. +  DIE *ContextDIE = getOrCreateContextDIE(CB->getScope()); + +  if (DIE *NDie = getDIE(CB)) +    return NDie; +  DIE &NDie = createAndAddDIE(dwarf::DW_TAG_common_block, *ContextDIE, CB); +  StringRef Name = CB->getName().empty() ? "_BLNK_" : CB->getName(); +  addString(NDie, dwarf::DW_AT_name, Name); +  addGlobalName(Name, NDie, CB->getScope()); +  if (CB->getFile()) +    addSourceLine(NDie, CB->getLineNo(), CB->getFile()); +  if (DIGlobalVariable *V = CB->getDecl()) +    getCU().addLocationAttribute(&NDie, V, GlobalExprs); +  return &NDie;  }  void DwarfCompileUnit::addRange(RangeSpan Range) { @@ -491,6 +543,8 @@ DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {    addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None,            getOrCreateSourceID(IA->getFile()));    addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, IA->getLine()); +  if (IA->getColumn()) +    addUInt(*ScopeDIE, dwarf::DW_AT_call_column, None, IA->getColumn());    if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4)      addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, None,              IA->getDiscriminator()); @@ -555,36 +609,27 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,      return VariableDie;    } -  // Check if variable is described by a DBG_VALUE instruction. -  if (const MachineInstr *DVInsn = DV.getMInsn()) { -    assert(DVInsn->getNumOperands() == 4); -    if (DVInsn->getOperand(0).isReg()) { -      auto RegOp = DVInsn->getOperand(0); -      auto Op1 = DVInsn->getOperand(1); -      // If the second operand is an immediate, this is an indirect value. -      assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset"); -      MachineLocation Location(RegOp.getReg(), Op1.isImm()); -      addVariableAddress(DV, *VariableDie, Location); -    } else if (DVInsn->getOperand(0).isImm()) { -      // This variable is described by a single constant. -      // Check whether it has a DIExpression. +  // Check if variable has a single location description. +  if (auto *DVal = DV.getValueLoc()) { +    if (DVal->isLocation()) +      addVariableAddress(DV, *VariableDie, DVal->getLoc()); +    else if (DVal->isInt()) {        auto *Expr = DV.getSingleExpression();        if (Expr && Expr->getNumElements()) {          DIELoc *Loc = new (DIEValueAllocator) DIELoc;          DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);          // If there is an expression, emit raw unsigned bytes.          DwarfExpr.addFragmentOffset(Expr); -        DwarfExpr.addUnsignedConstant(DVInsn->getOperand(0).getImm()); +        DwarfExpr.addUnsignedConstant(DVal->getInt());          DwarfExpr.addExpression(Expr);          addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());        } else -        addConstantValue(*VariableDie, DVInsn->getOperand(0), DV.getType()); -    } else if (DVInsn->getOperand(0).isFPImm()) -      addConstantFPValue(*VariableDie, DVInsn->getOperand(0)); -    else if (DVInsn->getOperand(0).isCImm()) -      addConstantValue(*VariableDie, DVInsn->getOperand(0).getCImm(), -                       DV.getType()); - +        addConstantValue(*VariableDie, DVal->getInt(), DV.getType()); +    } else if (DVal->isConstantFP()) { +      addConstantFPValue(*VariableDie, DVal->getConstantFP()); +    } else if (DVal->isConstantInt()) { +      addConstantValue(*VariableDie, DVal->getConstantInt(), DV.getType()); +    }      return VariableDie;    } @@ -592,6 +637,7 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,    if (!DV.hasFrameIndexExprs())      return VariableDie; +  Optional<unsigned> NVPTXAddressSpace;    DIELoc *Loc = new (DIEValueAllocator) DIELoc;    DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);    for (auto &Fragment : DV.getFrameIndexExprs()) { @@ -603,7 +649,23 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,      SmallVector<uint64_t, 8> Ops;      Ops.push_back(dwarf::DW_OP_plus_uconst);      Ops.push_back(Offset); -    Ops.append(Expr->elements_begin(), Expr->elements_end()); +    // According to +    // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf +    // cuda-gdb requires DW_AT_address_class for all variables to be able to +    // correctly interpret address space of the variable address. +    // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef +    // sequence for the NVPTX + gdb target. +    unsigned LocalNVPTXAddressSpace; +    if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { +      const DIExpression *NewExpr = +          DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace); +      if (NewExpr != Expr) { +        Expr = NewExpr; +        NVPTXAddressSpace = LocalNVPTXAddressSpace; +      } +    } +    if (Expr) +      Ops.append(Expr->elements_begin(), Expr->elements_end());      DIExpressionCursor Cursor(Ops);      DwarfExpr.setMemoryLocationKind();      if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol()) @@ -613,7 +675,19 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,            *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);      DwarfExpr.addExpression(std::move(Cursor));    } +  if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { +    // According to +    // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf +    // cuda-gdb requires DW_AT_address_class for all variables to be able to +    // correctly interpret address space of the variable address. +    const unsigned NVPTX_ADDR_local_space = 6; +    addUInt(*VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1, +            NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_local_space); +  }    addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); +  if (DwarfExpr.TagOffset) +    addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1, +            *DwarfExpr.TagOffset);    return VariableDie;  } @@ -800,7 +874,7 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(      ContextDIE = &getUnitDie();      getOrCreateSubprogramDIE(SPDecl);    } else { -    ContextDIE = getOrCreateContextDIE(resolve(SP->getScope())); +    ContextDIE = getOrCreateContextDIE(SP->getScope());      // The scope may be shared with a subprogram that has already been      // constructed in another CU, in which case we need to construct this      // subprogram in the same CU. @@ -849,7 +923,7 @@ DIE *DwarfCompileUnit::constructImportedEntityDIE(    DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag());    insertDIE(Module, IMDie);    DIE *EntityDie; -  auto *Entity = resolve(Module->getEntity()); +  auto *Entity = Module->getEntity();    if (auto *NS = dyn_cast<DINamespace>(Entity))      EntityDie = getOrCreateNameSpace(NS);    else if (auto *M = dyn_cast<DIModule>(Entity)) @@ -958,7 +1032,9 @@ bool DwarfCompileUnit::hasDwarfPubSections() const {      return true;    case DICompileUnit::DebugNameTableKind::Default:      return DD->tuneForGDB() && !includeMinimalInlineScopes() && -           !CUNode->isDebugDirectivesOnly(); +           !CUNode->isDebugDirectivesOnly() && +           DD->getAccelTableKind() != AccelTableKind::Apple && +           DD->getDwarfVersion() < 5;    }    llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum");  } @@ -1054,6 +1130,12 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,      DwarfExpr.setMemoryLocationKind();    DIExpressionCursor Cursor(DIExpr); + +  if (DIExpr->isEntryValue()) { +    DwarfExpr.setEntryValueFlag(); +    DwarfExpr.addEntryValueExpression(Cursor); +  } +    const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();    if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))      return; @@ -1112,7 +1194,7 @@ void DwarfCompileUnit::addAddressExpr(DIE &Die, dwarf::Attribute Attribute,  void DwarfCompileUnit::applySubprogramAttributesToDefinition(      const DISubprogram *SP, DIE &SPDie) {    auto *SPDecl = SP->getDeclaration(); -  auto *Context = resolve(SPDecl ? SPDecl->getScope() : SP->getScope()); +  auto *Context = SPDecl ? SPDecl->getScope() : SP->getScope();    applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes());    addGlobalName(SP->getName(), SPDie, Context);  } @@ -1121,6 +1203,10 @@ bool DwarfCompileUnit::isDwoUnit() const {    return DD->useSplitDwarf() && Skeleton;  } +void DwarfCompileUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) { +  constructTypeDIE(D, CTy); +} +  bool DwarfCompileUnit::includeMinimalInlineScopes() const {    return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly ||           (DD->useSplitDwarf() && !Skeleton); @@ -1134,3 +1220,27 @@ void DwarfCompileUnit::addAddrTableBase() {                                           : dwarf::DW_AT_GNU_addr_base,                    Label, TLOF.getDwarfAddrSection()->getBeginSymbol());  } + +void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Idx) { +  Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, dwarf::DW_FORM_udata, +               new (DIEValueAllocator) DIEBaseTypeRef(this, Idx)); +} + +void DwarfCompileUnit::createBaseTypeDIEs() { +  // Insert the base_type DIEs directly after the CU so that their offsets will +  // fit in the fixed size ULEB128 used inside the location expressions. +  // Maintain order by iterating backwards and inserting to the front of CU +  // child list. +  for (auto &Btr : reverse(ExprRefedBaseTypes)) { +    DIE &Die = getUnitDie().addChildFront( +      DIE::get(DIEValueAllocator, dwarf::DW_TAG_base_type)); +    SmallString<32> Str; +    addString(Die, dwarf::DW_AT_name, +              Twine(dwarf::AttributeEncodingString(Btr.Encoding) + +                    "_" + Twine(Btr.BitSize)).toStringRef(Str)); +    addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding); +    addUInt(Die, dwarf::DW_AT_byte_size, None, Btr.BitSize / 8); + +    Btr.Die = &Die; +  } +}  | 
