[llvm] r338390 - [DebugInfo] Generate DWARF debug information for labels.

Vlad Tsyrklevich via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 31 11:11:23 PDT 2018


This change is causing LSan failures on the ASan sanitizer bot, for example
<http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/21688/steps/check-llvm%20asan/logs/stdio>
:
FAIL: LLVM :: DebugInfo/X86/fi-piece.ll (16281 of 26964)
******************** TEST 'LLVM :: DebugInfo/X86/fi-piece.ll' FAILED
********************
Script:
--
: 'RUN: at line 1';
 /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan/bin/llc
/b/sanitizer-x86_64-linux-fast/build/llvm/test/DebugInfo/X86/fi-piece.ll
-filetype=obj -o - |
/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan/bin/llvm-dwarfdump -v
- | /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan/bin/FileCheck
/b/sanitizer-x86_64-linux-fast/build/llvm/test/DebugInfo/X86/fi-piece.ll
--
Exit Code: 1

Command Output (stderr):
--

=================================================================
==16262==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 48 byte(s) in 1 object(s) allocated from:
    #0 0x9b4b48 in malloc
/b/sanitizer-x86_64-linux-fast/build/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:88
    #1 0x5813cb2 in safe_malloc
/b/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/Support/MemAlloc.h:27:18
    #2 0x5813cb2 in llvm::SmallVectorBase::grow_pod(void*, unsigned long,
unsigned long)
/b/sanitizer-x86_64-linux-fast/build/llvm/lib/Support/SmallVector.cpp:55
    #3 0x37bf8b4 in grow_pod
/b/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/ADT/SmallVector.h:99:22
    #4 0x37bf8b4 in grow
/b/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/ADT/SmallVector.h:307
    #5 0x37bf8b4 in push_back
/b/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/ADT/SmallVector.h:312
    #6 0x37bf8b4 in llvm::DbgVariable::addMMIEntry(llvm::DbgVariable
const&)
/b/sanitizer-x86_64-linux-fast/build/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp:282
    #7 0x37d71d6 in
llvm::DwarfDebug::collectVariableInfoFromMFTable(llvm::DwarfCompileUnit&,
llvm::DenseSet<std::__1::pair<llvm::DILocalVariable const*,
llvm::DILocation const*>,
llvm::DenseMapInfo<std::__1::pair<llvm::DILocalVariable const*,
llvm::DILocation const*> > >&)
/b/sanitizer-x86_64-linux-fast/build/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp:959:15
    #8 0x37dbef3 in
llvm::DwarfDebug::collectEntityInfo(llvm::DwarfCompileUnit&,
llvm::DISubprogram const*,
llvm::DenseSet<std::__1::pair<llvm::DILocalVariable const*,
llvm::DILocation const*>,
llvm::DenseMapInfo<std::__1::pair<llvm::DILocalVariable const*,
llvm::DILocation const*> > >&)
/b/sanitizer-x86_64-linux-fast/build/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp:1212:3
    #9 0x37e156a in llvm::DwarfDebug::endFunctionImpl(llvm::MachineFunction
const*)
/b/sanitizer-x86_64-linux-fast/build/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp:1463:3
    #10 0x38e98dc in
llvm::DebugHandlerBase::endFunction(llvm::MachineFunction const*)
/b/sanitizer-x86_64-linux-fast/build/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp:304:5
    #11 0x37779a0 in llvm::AsmPrinter::EmitFunctionBody()
/b/sanitizer-x86_64-linux-fast/build/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:1208:17
    #12 0x2ad4203 in
llvm::X86AsmPrinter::runOnMachineFunction(llvm::MachineFunction&)
/b/sanitizer-x86_64-linux-fast/build/llvm/lib/Target/X86/X86AsmPrinter.cpp:78:3
    #13 0x3c6f6d5 in
llvm::MachineFunctionPass::runOnFunction(llvm::Function&)
/b/sanitizer-x86_64-linux-fast/build/llvm/lib/CodeGen/MachineFunctionPass.cpp:61:13
    #14 0x46bc25d in llvm::FPPassManager::runOnFunction(llvm::Function&)
/b/sanitizer-x86_64-linux-fast/build/llvm/lib/IR/LegacyPassManager.cpp:1586:27
    #15 0x46bc872 in llvm::FPPassManager::runOnModule(llvm::Module&)
/b/sanitizer-x86_64-linux-fast/build/llvm/lib/IR/LegacyPassManager.cpp:1609:16
    #16 0x46bd5e8 in runOnModule
/b/sanitizer-x86_64-linux-fast/build/llvm/lib/IR/LegacyPassManager.cpp:1669:27
    #17 0x46bd5e8 in llvm::legacy::PassManagerImpl::run(llvm::Module&)
/b/sanitizer-x86_64-linux-fast/build/llvm/lib/IR/LegacyPassManager.cpp:1774
    #18 0x9f2e4f in compileModule(char**, llvm::LLVMContext&)
/b/sanitizer-x86_64-linux-fast/build/llvm/tools/llc/llc.cpp:597:8
    #19 0x9ec3c0 in main
/b/sanitizer-x86_64-linux-fast/build/llvm/tools/llc/llc.cpp:351:22
    #20 0x7fdde9ea92e0 in __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x202e0)

SUMMARY: AddressSanitizer: 48 byte(s) leaked in 1 allocation(s).

I've reverted it in r338408

On Tue, Jul 31, 2018 at 7:48 AM Hsiangkai Wang via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: hsiangkai
> Date: Tue Jul 31 07:48:32 2018
> New Revision: 338390
>
> URL: http://llvm.org/viewvc/llvm-project?rev=338390&view=rev
> Log:
> [DebugInfo] Generate DWARF debug information for labels.
>
> There are two forms for label debug information in DWARF format.
>
> 1. Labels in a non-inlined function:
>
> DW_TAG_label
>   DW_AT_name
>   DW_AT_decl_file
>   DW_AT_decl_line
>   DW_AT_low_pc
>
> 2. Labels in an inlined function:
>
> DW_TAG_label
>   DW_AT_abstract_origin
>   DW_AT_low_pc
>
> We will collect label information from DBG_LABEL. Before every DBG_LABEL,
> we will generate a temporary symbol to denote the location of the label.
> The symbol could be used to get DW_AT_low_pc afterwards. So, we create a
> mapping between 'inlined label' and DBG_LABEL MachineInstr in
> DebugHandlerBase.
> The DBG_LABEL in the mapping is used to query the symbol before it.
>
> The AbstractLabels in DwarfCompileUnit is used to process labels in inlined
> functions.
>
> We also keep a mapping between scope and labels in DwarfFile to help to
> generate correct tree structure of DIEs.
>
> It also generates label debug information under global isel.
>
> Differential Revision: https://reviews.llvm.org/D45556
>
> Added:
>     llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
>       - copied, changed from r338388,
> llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
>     llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.h
>       - copied, changed from r338388,
> llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
>     llvm/trunk/test/DebugInfo/Generic/debug-label-inline.ll
>     llvm/trunk/test/DebugInfo/Generic/debug-label.ll
> Removed:
>     llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
>     llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
> Modified:
>     llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
>     llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt
>     llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h
>     llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
>     llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.cpp
>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h
>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h
>     llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
>     llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
>
> Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h?rev=338390&r1=338389&r2=338390&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
> (original)
> +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h Tue Jul
> 31 07:48:32 2018
> @@ -208,6 +208,10 @@ public:
>                                           const MDNode *Variable,
>                                           const MDNode *Expr);
>
> +  /// Build and insert a DBG_LABEL instructions specifying that \p Label
> is
> +  /// given. Convert "llvm.dbg.label Label" to "DBG_LABEL Label".
> +  MachineInstrBuilder buildDbgLabel(const MDNode *Label);
> +
>    /// Build and insert \p Res = G_FRAME_INDEX \p Idx
>    ///
>    /// G_FRAME_INDEX materializes the address of an alloca value or other
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt?rev=338390&r1=338389&r2=338390&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt Tue Jul 31 07:48:32
> 2018
> @@ -5,7 +5,7 @@ add_llvm_library(LLVMAsmPrinter
>    AsmPrinter.cpp
>    AsmPrinterDwarf.cpp
>    AsmPrinterInlineAsm.cpp
> -  DbgValueHistoryCalculator.cpp
> +  DbgEntityHistoryCalculator.cpp
>    DebugHandlerBase.cpp
>    DebugLocStream.cpp
>    DIE.cpp
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h?rev=338390&r1=338389&r2=338390&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h Tue Jul 31 07:48:32
> 2018
> @@ -14,7 +14,7 @@
>  #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
>  #define LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
>
> -#include "DbgValueHistoryCalculator.h"
> +#include "DbgEntityHistoryCalculator.h"
>  #include "DebugHandlerBase.h"
>  #include "llvm/ADT/ArrayRef.h"
>  #include "llvm/ADT/DenseMap.h"
>
> Copied: llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
> (from r338388,
> llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp)
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp?p2=llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp&p1=llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp&r1=338388&r2=338390&rev=338390&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
> (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp Tue
> Jul 31 07:48:32 2018
> @@ -1,4 +1,4 @@
> -//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
> --------------===//
> +//===- llvm/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
> -------------===//
>  //
>  //                     The LLVM Compiler Infrastructure
>  //
> @@ -7,7 +7,7 @@
>  //
>
>  //===----------------------------------------------------------------------===//
>
> -#include "DbgValueHistoryCalculator.h"
> +#include "DbgEntityHistoryCalculator.h"
>  #include "llvm/ADT/BitVector.h"
>  #include "llvm/ADT/STLExtras.h"
>  #include "llvm/ADT/SmallVector.h"
> @@ -78,11 +78,17 @@ unsigned DbgValueHistoryMap::getRegister
>    return isDescribedByReg(*Ranges.back().first);
>  }
>
> +void DbgLabelInstrMap::addInstr(InlinedLabel Label, const MachineInstr
> &MI) {
> +  assert(MI.isDebugLabel() && "not a DBG_LABEL");
> +  LabelInstr[Label] = &MI;
> +}
> +
>  namespace {
>
>  // Maps physreg numbers to the variables they describe.
>  using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
>  using RegDescribedVarsMap = std::map<unsigned,
> SmallVector<InlinedVariable, 1>>;
> +using InlinedLabel = DbgLabelInstrMap::InlinedLabel;
>
>  } // end anonymous namespace
>
> @@ -187,9 +193,10 @@ static void collectChangingRegs(const Ma
>    }
>  }
>
> -void llvm::calculateDbgValueHistory(const MachineFunction *MF,
> -                                    const TargetRegisterInfo *TRI,
> -                                    DbgValueHistoryMap &Result) {
> +void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
> +                                     const TargetRegisterInfo *TRI,
> +                                     DbgValueHistoryMap &DbgValues,
> +                                     DbgLabelInstrMap &DbgLabels) {
>    BitVector ChangingRegs(TRI->getNumRegs());
>    collectChangingRegs(MF, TRI, ChangingRegs);
>
> @@ -210,14 +217,14 @@ void llvm::calculateDbgValueHistory(cons
>              // If this is a virtual register, only clobber it since it
> doesn't
>              // have aliases.
>              if (TRI->isVirtualRegister(MO.getReg()))
> -              clobberRegisterUses(RegVars, MO.getReg(), Result, MI);
> +              clobberRegisterUses(RegVars, MO.getReg(), DbgValues, MI);
>              // If this is a register def operand, it may end a debug value
>              // range.
>              else {
>                for (MCRegAliasIterator AI(MO.getReg(), TRI, true);
> AI.isValid();
>                     ++AI)
>                  if (ChangingRegs.test(*AI))
> -                  clobberRegisterUses(RegVars, *AI, Result, MI);
> +                  clobberRegisterUses(RegVars, *AI, DbgValues, MI);
>              }
>            } else if (MO.isRegMask()) {
>              // If this is a register mask operand, clobber all debug
> values in
> @@ -226,7 +233,7 @@ void llvm::calculateDbgValueHistory(cons
>                // Don't consider SP to be clobbered by register masks.
>                if (unsigned(I) != SP && TRI->isPhysicalRegister(I) &&
>                    MO.clobbersPhysReg(I)) {
> -                clobberRegisterUses(RegVars, I, Result, MI);
> +                clobberRegisterUses(RegVars, I, DbgValues, MI);
>                }
>              }
>            }
> @@ -234,26 +241,34 @@ void llvm::calculateDbgValueHistory(cons
>          continue;
>        }
>
> -      // Skip DBG_LABEL instructions.
> -      if (MI.isDebugLabel())
> -        continue;
> -
> -      assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!");
> -      // Use the base variable (without any DW_OP_piece expressions)
> -      // as index into History. The full variables including the
> -      // piece expressions are attached to the MI.
> -      const DILocalVariable *RawVar = MI.getDebugVariable();
> -      assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
> -             "Expected inlined-at fields to agree");
> -      InlinedVariable Var(RawVar, MI.getDebugLoc()->getInlinedAt());
> -
> -      if (unsigned PrevReg = Result.getRegisterForVar(Var))
> -        dropRegDescribedVar(RegVars, PrevReg, Var);
> -
> -      Result.startInstrRange(Var, MI);
> -
> -      if (unsigned NewReg = isDescribedByReg(MI))
> -        addRegDescribedVar(RegVars, NewReg, Var);
> +      if (MI.isDebugValue()) {
> +        assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE
> instruction!");
> +        // Use the base variable (without any DW_OP_piece expressions)
> +        // as index into History. The full variables including the
> +        // piece expressions are attached to the MI.
> +        const DILocalVariable *RawVar = MI.getDebugVariable();
> +        assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
> +               "Expected inlined-at fields to agree");
> +        InlinedVariable Var(RawVar, MI.getDebugLoc()->getInlinedAt());
> +
> +        if (unsigned PrevReg = DbgValues.getRegisterForVar(Var))
> +          dropRegDescribedVar(RegVars, PrevReg, Var);
> +
> +        DbgValues.startInstrRange(Var, MI);
> +
> +        if (unsigned NewReg = isDescribedByReg(MI))
> +          addRegDescribedVar(RegVars, NewReg, Var);
> +      } else if (MI.isDebugLabel()) {
> +        assert(MI.getNumOperands() == 1 && "Invalid DBG_LABEL
> instruction!");
> +        const DILabel *RawLabel = MI.getDebugLabel();
> +        assert(RawLabel->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
> +            "Expected inlined-at fields to agree");
> +        // When collecting debug information for labels, there is no
> MCSymbol
> +        // generated for it. So, we keep MachineInstr in DbgLabels in
> order
> +        // to query MCSymbol afterward.
> +        InlinedLabel L(RawLabel, MI.getDebugLoc()->getInlinedAt());
> +        DbgLabels.addInstr(L, MI);
> +      }
>      }
>
>      // Make sure locations for register-described variables are valid only
> @@ -264,7 +279,7 @@ void llvm::calculateDbgValueHistory(cons
>          auto CurElem = I++; // CurElem can be erased below.
>          if (TRI->isVirtualRegister(CurElem->first) ||
>              ChangingRegs.test(CurElem->first))
> -          clobberRegisterUses(RegVars, CurElem, Result, MBB.back());
> +          clobberRegisterUses(RegVars, CurElem, DbgValues, MBB.back());
>        }
>      }
>    }
>
> Copied: llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.h
> (from r338388,
> llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h)
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.h?p2=llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.h&p1=llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h&r1=338388&r2=338390&rev=338390&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
> (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.h Tue Jul
> 31 07:48:32 2018
> @@ -1,4 +1,4 @@
> -//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h ------*- C++
> -*-===//
> +//===- llvm/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.h -----*- C++
> -*-===//
>  //
>  //                     The LLVM Compiler Infrastructure
>  //
> @@ -58,9 +58,30 @@ public:
>  #endif
>  };
>
> -void calculateDbgValueHistory(const MachineFunction *MF,
> -                              const TargetRegisterInfo *TRI,
> -                              DbgValueHistoryMap &Result);
> +/// For each inlined instance of a source-level label, keep the
> corresponding
> +/// DBG_LABEL instruction. The DBG_LABEL instruction could be used to
> generate
> +/// a temporary (assembler) label before it.
> +class DbgLabelInstrMap {
> +public:
> +  using InlinedLabel = std::pair<const DILabel *, const DILocation *>;
> +  using InstrMap = MapVector<InlinedLabel, const MachineInstr *>;
> +
> +private:
> +  InstrMap LabelInstr;
> +
> +public:
> +  void  addInstr(InlinedLabel Label, const MachineInstr &MI);
> +
> +  bool empty() const { return LabelInstr.empty(); }
> +  void clear() { LabelInstr.clear(); }
> +  InstrMap::const_iterator begin() const { return LabelInstr.begin(); }
> +  InstrMap::const_iterator end() const { return LabelInstr.end(); }
> +};
> +
> +void calculateDbgEntityHistory(const MachineFunction *MF,
> +                               const TargetRegisterInfo *TRI,
> +                               DbgValueHistoryMap &DbgValues,
> +                               DbgLabelInstrMap &DbgLabels);
>
>  } // end namespace llvm
>
>
> Removed: llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp?rev=338389&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
> (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
> (removed)
> @@ -1,301 +0,0 @@
> -//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
> --------------===//
> -//
> -//                     The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
>
> -//===----------------------------------------------------------------------===//
> -
> -#include "DbgValueHistoryCalculator.h"
> -#include "llvm/ADT/BitVector.h"
> -#include "llvm/ADT/STLExtras.h"
> -#include "llvm/ADT/SmallVector.h"
> -#include "llvm/CodeGen/MachineBasicBlock.h"
> -#include "llvm/CodeGen/MachineFunction.h"
> -#include "llvm/CodeGen/MachineInstr.h"
> -#include "llvm/CodeGen/MachineOperand.h"
> -#include "llvm/CodeGen/TargetLowering.h"
> -#include "llvm/CodeGen/TargetRegisterInfo.h"
> -#include "llvm/CodeGen/TargetSubtargetInfo.h"
> -#include "llvm/IR/DebugInfoMetadata.h"
> -#include "llvm/IR/DebugLoc.h"
> -#include "llvm/MC/MCRegisterInfo.h"
> -#include "llvm/Support/Debug.h"
> -#include "llvm/Support/raw_ostream.h"
> -#include <cassert>
> -#include <map>
> -#include <utility>
> -
> -using namespace llvm;
> -
> -#define DEBUG_TYPE "dwarfdebug"
> -
> -// If @MI is a DBG_VALUE with debug value described by a
> -// defined register, returns the number of this register.
> -// In the other case, returns 0.
> -static unsigned isDescribedByReg(const MachineInstr &MI) {
> -  assert(MI.isDebugValue());
> -  assert(MI.getNumOperands() == 4);
> -  // If location of variable is described using a register (directly or
> -  // indirectly), this register is always a first operand.
> -  return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0;
> -}
> -
> -void DbgValueHistoryMap::startInstrRange(InlinedVariable Var,
> -                                         const MachineInstr &MI) {
> -  // Instruction range should start with a DBG_VALUE instruction for the
> -  // variable.
> -  assert(MI.isDebugValue() && "not a DBG_VALUE");
> -  auto &Ranges = VarInstrRanges[Var];
> -  if (!Ranges.empty() && Ranges.back().second == nullptr &&
> -      Ranges.back().first->isIdenticalTo(MI)) {
> -    LLVM_DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n"
> -                      << "\t" << Ranges.back().first << "\t" << MI <<
> "\n");
> -    return;
> -  }
> -  Ranges.push_back(std::make_pair(&MI, nullptr));
> -}
> -
> -void DbgValueHistoryMap::endInstrRange(InlinedVariable Var,
> -                                       const MachineInstr &MI) {
> -  auto &Ranges = VarInstrRanges[Var];
> -  // Verify that the current instruction range is not yet closed.
> -  assert(!Ranges.empty() && Ranges.back().second == nullptr);
> -  // For now, instruction ranges are not allowed to cross basic block
> -  // boundaries.
> -  assert(Ranges.back().first->getParent() == MI.getParent());
> -  Ranges.back().second = &MI;
> -}
> -
> -unsigned DbgValueHistoryMap::getRegisterForVar(InlinedVariable Var) const
> {
> -  const auto &I = VarInstrRanges.find(Var);
> -  if (I == VarInstrRanges.end())
> -    return 0;
> -  const auto &Ranges = I->second;
> -  if (Ranges.empty() || Ranges.back().second != nullptr)
> -    return 0;
> -  return isDescribedByReg(*Ranges.back().first);
> -}
> -
> -namespace {
> -
> -// Maps physreg numbers to the variables they describe.
> -using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
> -using RegDescribedVarsMap = std::map<unsigned,
> SmallVector<InlinedVariable, 1>>;
> -
> -} // end anonymous namespace
> -
> -// Claim that @Var is not described by @RegNo anymore.
> -static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned
> RegNo,
> -                                InlinedVariable Var) {
> -  const auto &I = RegVars.find(RegNo);
> -  assert(RegNo != 0U && I != RegVars.end());
> -  auto &VarSet = I->second;
> -  const auto &VarPos = llvm::find(VarSet, Var);
> -  assert(VarPos != VarSet.end());
> -  VarSet.erase(VarPos);
> -  // Don't keep empty sets in a map to keep it as small as possible.
> -  if (VarSet.empty())
> -    RegVars.erase(I);
> -}
> -
> -// Claim that @Var is now described by @RegNo.
> -static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned
> RegNo,
> -                               InlinedVariable Var) {
> -  assert(RegNo != 0U);
> -  auto &VarSet = RegVars[RegNo];
> -  assert(!is_contained(VarSet, Var));
> -  VarSet.push_back(Var);
> -}
> -
> -// Terminate the location range for variables described by register at
> -// @I by inserting @ClobberingInstr to their history.
> -static void clobberRegisterUses(RegDescribedVarsMap &RegVars,
> -                                RegDescribedVarsMap::iterator I,
> -                                DbgValueHistoryMap &HistMap,
> -                                const MachineInstr &ClobberingInstr) {
> -  // Iterate over all variables described by this register and add this
> -  // instruction to their history, clobbering it.
> -  for (const auto &Var : I->second)
> -    HistMap.endInstrRange(Var, ClobberingInstr);
> -  RegVars.erase(I);
> -}
> -
> -// Terminate the location range for variables described by register
> -// @RegNo by inserting @ClobberingInstr to their history.
> -static void clobberRegisterUses(RegDescribedVarsMap &RegVars, unsigned
> RegNo,
> -                                DbgValueHistoryMap &HistMap,
> -                                const MachineInstr &ClobberingInstr) {
> -  const auto &I = RegVars.find(RegNo);
> -  if (I == RegVars.end())
> -    return;
> -  clobberRegisterUses(RegVars, I, HistMap, ClobberingInstr);
> -}
> -
> -// Returns the first instruction in @MBB which corresponds to
> -// the function epilogue, or nullptr if @MBB doesn't contain an epilogue.
> -static const MachineInstr *getFirstEpilogueInst(const MachineBasicBlock
> &MBB) {
> -  auto LastMI = MBB.getLastNonDebugInstr();
> -  if (LastMI == MBB.end() || !LastMI->isReturn())
> -    return nullptr;
> -  // Assume that epilogue starts with instruction having the same debug
> location
> -  // as the return instruction.
> -  DebugLoc LastLoc = LastMI->getDebugLoc();
> -  auto Res = LastMI;
> -  for (MachineBasicBlock::const_reverse_iterator I = LastMI.getReverse(),
> -                                                 E = MBB.rend();
> -       I != E; ++I) {
> -    if (I->getDebugLoc() != LastLoc)
> -      return &*Res;
> -    Res = &*I;
> -  }
> -  // If all instructions have the same debug location, assume whole MBB is
> -  // an epilogue.
> -  return &*MBB.begin();
> -}
> -
> -// Collect registers that are modified in the function body (their
> -// contents is changed outside of the prologue and epilogue).
> -static void collectChangingRegs(const MachineFunction *MF,
> -                                const TargetRegisterInfo *TRI,
> -                                BitVector &Regs) {
> -  for (const auto &MBB : *MF) {
> -    auto FirstEpilogueInst = getFirstEpilogueInst(MBB);
> -
> -    for (const auto &MI : MBB) {
> -      // Avoid looking at prologue or epilogue instructions.
> -      if (&MI == FirstEpilogueInst)
> -        break;
> -      if (MI.getFlag(MachineInstr::FrameSetup))
> -        continue;
> -
> -      // Look for register defs and register masks. Register masks are
> -      // typically on calls and they clobber everything not in the mask.
> -      for (const MachineOperand &MO : MI.operands()) {
> -        // Skip virtual registers since they are handled by the parent.
> -        if (MO.isReg() && MO.isDef() && MO.getReg() &&
> -            !TRI->isVirtualRegister(MO.getReg())) {
> -          for (MCRegAliasIterator AI(MO.getReg(), TRI, true);
> AI.isValid();
> -               ++AI)
> -            Regs.set(*AI);
> -        } else if (MO.isRegMask()) {
> -          Regs.setBitsNotInMask(MO.getRegMask());
> -        }
> -      }
> -    }
> -  }
> -}
> -
> -void llvm::calculateDbgValueHistory(const MachineFunction *MF,
> -                                    const TargetRegisterInfo *TRI,
> -                                    DbgValueHistoryMap &Result) {
> -  BitVector ChangingRegs(TRI->getNumRegs());
> -  collectChangingRegs(MF, TRI, ChangingRegs);
> -
> -  const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
> -  unsigned SP = TLI->getStackPointerRegisterToSaveRestore();
> -  RegDescribedVarsMap RegVars;
> -  for (const auto &MBB : *MF) {
> -    for (const auto &MI : MBB) {
> -      if (!MI.isDebugInstr()) {
> -        // Not a DBG_VALUE instruction. It may clobber registers which
> describe
> -        // some variables.
> -        for (const MachineOperand &MO : MI.operands()) {
> -          if (MO.isReg() && MO.isDef() && MO.getReg()) {
> -            // Ignore call instructions that claim to clobber SP. The
> AArch64
> -            // backend does this for aggregate function arguments.
> -            if (MI.isCall() && MO.getReg() == SP)
> -              continue;
> -            // If this is a virtual register, only clobber it since it
> doesn't
> -            // have aliases.
> -            if (TRI->isVirtualRegister(MO.getReg()))
> -              clobberRegisterUses(RegVars, MO.getReg(), Result, MI);
> -            // If this is a register def operand, it may end a debug value
> -            // range.
> -            else {
> -              for (MCRegAliasIterator AI(MO.getReg(), TRI, true);
> AI.isValid();
> -                   ++AI)
> -                if (ChangingRegs.test(*AI))
> -                  clobberRegisterUses(RegVars, *AI, Result, MI);
> -            }
> -          } else if (MO.isRegMask()) {
> -            // If this is a register mask operand, clobber all debug
> values in
> -            // non-CSRs.
> -            for (unsigned I : ChangingRegs.set_bits()) {
> -              // Don't consider SP to be clobbered by register masks.
> -              if (unsigned(I) != SP && TRI->isPhysicalRegister(I) &&
> -                  MO.clobbersPhysReg(I)) {
> -                clobberRegisterUses(RegVars, I, Result, MI);
> -              }
> -            }
> -          }
> -        }
> -        continue;
> -      }
> -
> -      // Skip DBG_LABEL instructions.
> -      if (MI.isDebugLabel())
> -        continue;
> -
> -      assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!");
> -      // Use the base variable (without any DW_OP_piece expressions)
> -      // as index into History. The full variables including the
> -      // piece expressions are attached to the MI.
> -      const DILocalVariable *RawVar = MI.getDebugVariable();
> -      assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
> -             "Expected inlined-at fields to agree");
> -      InlinedVariable Var(RawVar, MI.getDebugLoc()->getInlinedAt());
> -
> -      if (unsigned PrevReg = Result.getRegisterForVar(Var))
> -        dropRegDescribedVar(RegVars, PrevReg, Var);
> -
> -      Result.startInstrRange(Var, MI);
> -
> -      if (unsigned NewReg = isDescribedByReg(MI))
> -        addRegDescribedVar(RegVars, NewReg, Var);
> -    }
> -
> -    // Make sure locations for register-described variables are valid only
> -    // until the end of the basic block (unless it's the last basic
> block, in
> -    // which case let their liveness run off to the end of the function).
> -    if (!MBB.empty() && &MBB != &MF->back()) {
> -      for (auto I = RegVars.begin(), E = RegVars.end(); I != E;) {
> -        auto CurElem = I++; // CurElem can be erased below.
> -        if (TRI->isVirtualRegister(CurElem->first) ||
> -            ChangingRegs.test(CurElem->first))
> -          clobberRegisterUses(RegVars, CurElem, Result, MBB.back());
> -      }
> -    }
> -  }
> -}
> -
> -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
> -LLVM_DUMP_METHOD void DbgValueHistoryMap::dump() const {
> -  dbgs() << "DbgValueHistoryMap:\n";
> -  for (const auto &VarRangePair : *this) {
> -    const InlinedVariable &Var = VarRangePair.first;
> -    const InstrRanges &Ranges = VarRangePair.second;
> -
> -    const DILocalVariable *LocalVar = Var.first;
> -    const DILocation *Location = Var.second;
> -
> -    dbgs() << " - " << LocalVar->getName() << " at ";
> -
> -    if (Location)
> -      dbgs() << Location->getFilename() << ":" << Location->getLine() <<
> ":"
> -             << Location->getColumn();
> -    else
> -      dbgs() << "<unknown location>";
> -
> -    dbgs() << " --\n";
> -
> -    for (const InstrRange &Range : Ranges) {
> -      dbgs() << "   Begin: " << *Range.first;
> -      if (Range.second)
> -        dbgs() << "   End  : " << *Range.second;
> -      dbgs() << "\n";
> -    }
> -  }
> -}
> -#endif
>
> Removed: llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h?rev=338389&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
> (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h (removed)
> @@ -1,67 +0,0 @@
> -//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h ------*- C++
> -*-===//
> -//
> -//                     The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
>
> -//===----------------------------------------------------------------------===//
> -
> -#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DBGVALUEHISTORYCALCULATOR_H
> -#define LLVM_LIB_CODEGEN_ASMPRINTER_DBGVALUEHISTORYCALCULATOR_H
> -
> -#include "llvm/ADT/MapVector.h"
> -#include "llvm/ADT/SmallVector.h"
> -#include "llvm/IR/DebugInfoMetadata.h"
> -#include <utility>
> -
> -namespace llvm {
> -
> -class DILocalVariable;
> -class MachineFunction;
> -class MachineInstr;
> -class TargetRegisterInfo;
> -
> -// For each user variable, keep a list of instruction ranges where this
> variable
> -// is accessible. The variables are listed in order of appearance.
> -class DbgValueHistoryMap {
> -  // Each instruction range starts with a DBG_VALUE instruction,
> specifying the
> -  // location of a variable, which is assumed to be valid until the end
> of the
> -  // range. If end is not specified, location is valid until the start
> -  // instruction of the next instruction range, or until the end of the
> -  // function.
> -public:
> -  using InstrRange = std::pair<const MachineInstr *, const MachineInstr
> *>;
> -  using InstrRanges = SmallVector<InstrRange, 4>;
> -  using InlinedVariable =
> -      std::pair<const DILocalVariable *, const DILocation *>;
> -  using InstrRangesMap = MapVector<InlinedVariable, InstrRanges>;
> -
> -private:
> -  InstrRangesMap VarInstrRanges;
> -
> -public:
> -  void startInstrRange(InlinedVariable Var, const MachineInstr &MI);
> -  void endInstrRange(InlinedVariable Var, const MachineInstr &MI);
> -
> -  // Returns register currently describing @Var. If @Var is currently
> -  // unaccessible or is not described by a register, returns 0.
> -  unsigned getRegisterForVar(InlinedVariable Var) const;
> -
> -  bool empty() const { return VarInstrRanges.empty(); }
> -  void clear() { VarInstrRanges.clear(); }
> -  InstrRangesMap::const_iterator begin() const { return
> VarInstrRanges.begin(); }
> -  InstrRangesMap::const_iterator end() const { return
> VarInstrRanges.end(); }
> -
> -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
> -  LLVM_DUMP_METHOD void dump() const;
> -#endif
> -};
> -
> -void calculateDbgValueHistory(const MachineFunction *MF,
> -                              const TargetRegisterInfo *TRI,
> -                              DbgValueHistoryMap &Result);
> -
> -} // end namespace llvm
> -
> -#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DBGVALUEHISTORYCALCULATOR_H
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp?rev=338390&r1=338389&r2=338390&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp Tue Jul 31
> 07:48:32 2018
> @@ -190,8 +190,9 @@ void DebugHandlerBase::beginFunction(con
>
>    // Calculate history for local variables.
>    assert(DbgValues.empty() && "DbgValues map wasn't cleaned!");
> -  calculateDbgValueHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(),
> -                           DbgValues);
> +  assert(DbgLabels.empty() && "DbgLabels map wasn't cleaned!");
> +  calculateDbgEntityHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(),
> +                            DbgValues, DbgLabels);
>    LLVM_DEBUG(DbgValues.dump());
>
>    // Request labels for the full history.
> @@ -229,6 +230,12 @@ void DebugHandlerBase::beginFunction(con
>      }
>    }
>
> +  // Ensure there is a symbol before DBG_LABEL.
> +  for (const auto &I : DbgLabels) {
> +    const MachineInstr *MI = I.second;
> +    requestLabelBeforeInsn(MI);
> +  }
> +
>    PrevInstLoc = DebugLoc();
>    PrevLabel = Asm->getFunctionBegin();
>    beginFunctionImpl(MF);
> @@ -296,6 +303,7 @@ void DebugHandlerBase::endFunction(const
>    if (hasDebugInfo(MMI, MF))
>      endFunctionImpl(MF);
>    DbgValues.clear();
> +  DbgLabels.clear();
>    LabelsBeforeInsn.clear();
>    LabelsAfterInsn.clear();
>  }
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h?rev=338390&r1=338389&r2=338390&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h Tue Jul 31
> 07:48:32 2018
> @@ -16,7 +16,7 @@
>  #define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGHANDLERBASE_H
>
>  #include "AsmPrinterHandler.h"
> -#include "DbgValueHistoryCalculator.h"
> +#include "DbgEntityHistoryCalculator.h"
>  #include "llvm/ADT/Optional.h"
>  #include "llvm/CodeGen/LexicalScopes.h"
>  #include "llvm/CodeGen/MachineInstr.h"
> @@ -82,6 +82,9 @@ protected:
>    /// variable.  Variables are listed in order of appearance.
>    DbgValueHistoryMap DbgValues;
>
> +  /// Mapping of inlined labels and DBG_LABEL machine instruction.
> +  DbgLabelInstrMap DbgLabels;
> +
>    /// Maps instruction with label emitted before instruction.
>    /// FIXME: Make this private from DwarfDebug, we have the necessary
> accessors
>    /// for it.
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=338390&r1=338389&r2=338390&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Tue Jul 31
> 07:48:32 2018
> @@ -506,6 +506,18 @@ DIE *DwarfCompileUnit::constructVariable
>    return D;
>  }
>
> +DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL,
> +                                         const LexicalScope &Scope) {
> +  auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag());
> +  insertDIE(DL.getLabel(), LabelDie);
> +  DL.setDIE(*LabelDie);
> +
> +  if (Scope.isAbstractScope())
> +    applyLabelAttributes(DL, *LabelDie);
> +
> +  return LabelDie;
> +}
> +
>  DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
>                                                  bool Abstract) {
>    // Define variable debug information entry.
> @@ -699,6 +711,9 @@ DIE *DwarfCompileUnit::createScopeChildr
>    if (HasNonScopeChildren)
>      *HasNonScopeChildren = !Children.empty();
>
> +  for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope))
> +    Children.push_back(constructLabelDIE(*DL, *Scope));
> +
>    for (LexicalScope *LS : Scope->getChildren())
>      constructScopeDIE(LS, Children);
>
> @@ -824,40 +839,52 @@ void DwarfCompileUnit::finishSubprogramD
>    }
>  }
>
> -void DwarfCompileUnit::finishVariableDefinition(const DbgVariable &Var) {
> -  DbgVariable *AbsVar = getExistingAbstractVariable(
> -      InlinedVariable(Var.getVariable(), Var.getInlinedAt()));
> -  auto *VariableDie = Var.getDIE();
> -  if (AbsVar && AbsVar->getDIE()) {
> -    addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin,
> -                      *AbsVar->getDIE());
> -  } else
> -    applyVariableAttributes(Var, *VariableDie);
> -}
> -
> -DbgVariable
> *DwarfCompileUnit::getExistingAbstractVariable(InlinedVariable IV) {
> -  const DILocalVariable *Cleansed;
> -  return getExistingAbstractVariable(IV, Cleansed);
> -}
> -
> -// Find abstract variable, if any, associated with Var.
> -DbgVariable *DwarfCompileUnit::getExistingAbstractVariable(
> -    InlinedVariable IV, const DILocalVariable *&Cleansed) {
> -  // More then one inlined variable corresponds to one abstract variable.
> -  Cleansed = IV.first;
> -  auto &AbstractVariables = getAbstractVariables();
> -  auto I = AbstractVariables.find(Cleansed);
> -  if (I != AbstractVariables.end())
> +void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {
> +  DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity());
> +
> +  auto *Die = Entity->getDIE();
> +  /// Label may be used to generate DW_AT_low_pc, so put it outside
> +  /// if/else block.
> +  const DbgLabel *Label = nullptr;
> +  if (AbsEntity && AbsEntity->getDIE()) {
> +    addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE());
> +    Label = dyn_cast<const DbgLabel>(Entity);
> +  } else {
> +    if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity))
> +      applyVariableAttributes(*Var, *Die);
> +    else if ((Label = dyn_cast<const DbgLabel>(Entity)))
> +      applyLabelAttributes(*Label, *Die);
> +    else
> +      llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel.");
> +  }
> +
> +  if (Label) {
> +    const MCSymbol *Sym = Label->getSymbol();
> +    addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);
> +  }
> +}
> +
> +DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode
> *Node) {
> +  auto &AbstractEntities = getAbstractEntities();
> +  auto I = AbstractEntities.find(Node);
> +  if (I != AbstractEntities.end())
>      return I->second.get();
>    return nullptr;
>  }
>
> -void DwarfCompileUnit::createAbstractVariable(const DILocalVariable *Var,
> -                                        LexicalScope *Scope) {
> +void DwarfCompileUnit::createAbstractEntity(const DINode *Node,
> +                                            LexicalScope *Scope) {
>    assert(Scope && Scope->isAbstractScope());
> -  auto AbsDbgVariable = llvm::make_unique<DbgVariable>(Var, /* IA */
> nullptr);
> -  DU->addScopeVariable(Scope, AbsDbgVariable.get());
> -  getAbstractVariables()[Var] = std::move(AbsDbgVariable);
> +  auto &Entity = getAbstractEntities()[Node];
> +  if (isa<const DILocalVariable>(Node)) {
> +    Entity = llvm::make_unique<DbgVariable>(
> +                        cast<const DILocalVariable>(Node), nullptr /* IA
> */);;
> +    DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get()));
> +  } else if (isa<const DILabel>(Node)) {
> +    Entity = llvm::make_unique<DbgLabel>(
> +                        cast<const DILabel>(Node), nullptr /* IA */);
> +    DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get()));
> +  }
>  }
>
>  void DwarfCompileUnit::emitHeader(bool UseOffsets) {
> @@ -1012,6 +1039,15 @@ void DwarfCompileUnit::applyVariableAttr
>      addFlag(VariableDie, dwarf::DW_AT_artificial);
>  }
>
> +void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label,
> +                                            DIE &LabelDie) {
> +  StringRef Name = Label.getName();
> +  if (!Name.empty())
> +    addString(LabelDie, dwarf::DW_AT_name, Name);
> +  const auto *DILabel = Label.getLabel();
> +  addSourceLine(LabelDie, DILabel);
> +}
> +
>  /// Add a Dwarf expression attribute data and value.
>  void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
>                                 const MCExpr *Expr) {
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h?rev=338390&r1=338389&r2=338390&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h Tue Jul 31
> 07:48:32 2018
> @@ -14,7 +14,7 @@
>  #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
>  #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
>
> -#include "DbgValueHistoryCalculator.h"
> +#include "DbgEntityHistoryCalculator.h"
>  #include "DwarfDebug.h"
>  #include "DwarfUnit.h"
>  #include "llvm/ADT/ArrayRef.h"
> @@ -81,7 +81,7 @@ class DwarfCompileUnit final : public Dw
>    const MCSymbol *BaseAddress = nullptr;
>
>    DenseMap<const MDNode *, DIE *> AbstractSPDies;
> -  DenseMap<const MDNode *, std::unique_ptr<DbgVariable>>
> AbstractVariables;
> +  DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
>
>    /// DWO ID for correlating skeleton and split units.
>    uint64_t DWOId = 0;
> @@ -98,10 +98,10 @@ class DwarfCompileUnit final : public Dw
>      return DU->getAbstractSPDies();
>    }
>
> -  DenseMap<const MDNode *, std::unique_ptr<DbgVariable>>
> &getAbstractVariables() {
> +  DenseMap<const DINode *, std::unique_ptr<DbgEntity>>
> &getAbstractEntities() {
>      if (isDwoUnit() && !DD->shareAcrossDWOCUs())
> -      return AbstractVariables;
> -    return DU->getAbstractVariables();
> +      return AbstractEntities;
> +    return DU->getAbstractEntities();
>    }
>
>  public:
> @@ -194,6 +194,9 @@ public:
>    DIE *constructVariableDIE(DbgVariable &DV, const LexicalScope &Scope,
>                              DIE *&ObjectPointer);
>
> +  /// Construct a DIE for the given DbgLabel.
> +  DIE *constructLabelDIE(DbgLabel &DL, const LexicalScope &Scope);
> +
>    /// A helper function to create children of a Scope DIE.
>    DIE *createScopeChildrenDIE(LexicalScope *Scope,
>                                SmallVectorImpl<DIE *> &Children,
> @@ -210,14 +213,12 @@ public:
>    DIE *constructImportedEntityDIE(const DIImportedEntity *Module);
>
>    void finishSubprogramDefinition(const DISubprogram *SP);
> -  void finishVariableDefinition(const DbgVariable &Var);
> +  void finishEntityDefinition(const DbgEntity *Entity);
>
>    /// Find abstract variable associated with Var.
>    using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
> -  DbgVariable *getExistingAbstractVariable(InlinedVariable IV,
> -                                           const DILocalVariable
> *&Cleansed);
> -  DbgVariable *getExistingAbstractVariable(InlinedVariable IV);
> -  void createAbstractVariable(const DILocalVariable *Var, LexicalScope
> *Scope);
> +  DbgEntity *getExistingAbstractEntity(const DINode *Node);
> +  void createAbstractEntity(const DINode *Node, LexicalScope *Scope);
>
>    /// Set the skeleton unit associated with this unit.
>    void setSkeleton(DwarfCompileUnit &Skel) { Skeleton = &Skel; }
> @@ -288,6 +289,8 @@ public:
>    void applySubprogramAttributesToDefinition(const DISubprogram *SP,
>                                               DIE &SPDie);
>
> +  void applyLabelAttributes(const DbgLabel &Label, DIE &LabelDie);
> +
>    /// getRangeLists - Get the vector of range lists.
>    const SmallVectorImpl<RangeSpanList> &getRangeLists() const {
>      return (Skeleton ? Skeleton : this)->CURangeLists;
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=338390&r1=338389&r2=338390&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Jul 31 07:48:32
> 2018
> @@ -188,12 +188,12 @@ bool DebugLocDwarfExpression::isFrameReg
>  }
>
>  bool DbgVariable::isBlockByrefVariable() const {
> -  assert(Var && "Invalid complex DbgVariable!");
> -  return Var->getType().resolve()->isBlockByrefStruct();
> +  assert(getVariable() && "Invalid complex DbgVariable!");
> +  return getVariable()->getType().resolve()->isBlockByrefStruct();
>  }
>
>  const DIType *DbgVariable::getType() const {
> -  DIType *Ty = Var->getType().resolve();
> +  DIType *Ty = getVariable()->getType().resolve();
>    // FIXME: isBlockByrefVariable should be reformulated in terms of
> complex
>    // addresses instead.
>    if (Ty->isBlockByrefStruct()) {
> @@ -258,8 +258,8 @@ ArrayRef<DbgVariable::FrameIndexExpr> Db
>  void DbgVariable::addMMIEntry(const DbgVariable &V) {
>    assert(DebugLocListIndex == ~0U && !MInsn && "not an MMI entry");
>    assert(V.DebugLocListIndex == ~0U && !V.MInsn && "not an MMI entry");
> -  assert(V.Var == Var && "conflicting variable");
> -  assert(V.IA == IA && "conflicting inlined-at location");
> +  assert(V.getVariable() == getVariable() && "conflicting variable");
> +  assert(V.getInlinedAt() == getInlinedAt() && "conflicting inlined-at
> location");
>
>    assert(!FrameIndexExprs.empty() && "Expected an MMI entry");
>    assert(!V.FrameIndexExprs.empty() && "Expected an MMI entry");
> @@ -726,16 +726,16 @@ void DwarfDebug::beginModule() {
>    }
>  }
>
> -void DwarfDebug::finishVariableDefinitions() {
> -  for (const auto &Var : ConcreteVariables) {
> -    DIE *VariableDie = Var->getDIE();
> -    assert(VariableDie);
> +void DwarfDebug::finishEntityDefinitions() {
> +  for (const auto &Entity : ConcreteEntities) {
> +    DIE *Die = Entity->getDIE();
> +    assert(Die);
>      // FIXME: Consider the time-space tradeoff of just storing the unit
> pointer
> -    // in the ConcreteVariables list, rather than looking it up again
> here.
> +    // in the ConcreteEntities list, rather than looking it up again here.
>      // DIE::getUnit isn't simple - it walks parent pointers, etc.
> -    DwarfCompileUnit *Unit = CUDieMap.lookup(VariableDie->getUnitDie());
> +    DwarfCompileUnit *Unit = CUDieMap.lookup(Die->getUnitDie());
>      assert(Unit);
> -    Unit->finishVariableDefinition(*Var);
> +    Unit->finishEntityDefinition(Entity.get());
>    }
>  }
>
> @@ -753,7 +753,7 @@ void DwarfDebug::finalizeModuleInfo() {
>
>    finishSubprogramDefinitions();
>
> -  finishVariableDefinitions();
> +  finishEntityDefinitions();
>
>    // Include the DWO file name in the hash if there's more than one CU.
>    // This handles ThinLTO's situation where imported CUs may very easily
> be
> @@ -914,25 +914,24 @@ void DwarfDebug::endModule() {
>    // FIXME: AbstractVariables.clear();
>  }
>
> -void DwarfDebug::ensureAbstractVariableIsCreated(DwarfCompileUnit &CU,
> InlinedVariable IV,
> -                                                 const MDNode *ScopeNode)
> {
> -  const DILocalVariable *Cleansed = nullptr;
> -  if (CU.getExistingAbstractVariable(IV, Cleansed))
> +void DwarfDebug::ensureAbstractEntityIsCreated(DwarfCompileUnit &CU,
> +                                               const DINode *Node,
> +                                               const MDNode *ScopeNode) {
> +  if (CU.getExistingAbstractEntity(Node))
>      return;
>
> -  CU.createAbstractVariable(Cleansed, LScopes.getOrCreateAbstractScope(
> +  CU.createAbstractEntity(Node, LScopes.getOrCreateAbstractScope(
>                                         cast<DILocalScope>(ScopeNode)));
>  }
>
> -void DwarfDebug::ensureAbstractVariableIsCreatedIfScoped(DwarfCompileUnit
> &CU,
> -    InlinedVariable IV, const MDNode *ScopeNode) {
> -  const DILocalVariable *Cleansed = nullptr;
> -  if (CU.getExistingAbstractVariable(IV, Cleansed))
> +void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit
> &CU,
> +    const DINode *Node, const MDNode *ScopeNode) {
> +  if (CU.getExistingAbstractEntity(Node))
>      return;
>
>    if (LexicalScope *Scope =
>
>  LScopes.findAbstractScope(cast_or_null<DILocalScope>(ScopeNode)))
> -    CU.createAbstractVariable(Cleansed, Scope);
> +    CU.createAbstractEntity(Node, Scope);
>  }
>
>  // Collect variable information from side table maintained by MF.
> @@ -953,14 +952,14 @@ void DwarfDebug::collectVariableInfoFrom
>      if (!Scope)
>        continue;
>
> -    ensureAbstractVariableIsCreatedIfScoped(TheCU, Var,
> Scope->getScopeNode());
> +    ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
> Scope->getScopeNode());
>      auto RegVar = llvm::make_unique<DbgVariable>(Var.first, Var.second);
>      RegVar->initializeMMI(VI.Expr, VI.Slot);
>      if (DbgVariable *DbgVar = MFVars.lookup(Var))
>        DbgVar->addMMIEntry(*RegVar);
>      else if (InfoHolder.addScopeVariable(Scope, RegVar.get())) {
>        MFVars.insert({Var, RegVar.get()});
> -      ConcreteVariables.push_back(std::move(RegVar));
> +      ConcreteEntities.push_back(std::move(RegVar));
>      }
>    }
>  }
> @@ -1125,14 +1124,26 @@ DwarfDebug::buildLocationList(SmallVecto
>    }
>  }
>
> -DbgVariable *DwarfDebug::createConcreteVariable(DwarfCompileUnit &TheCU,
> -                                                LexicalScope &Scope,
> -                                                InlinedVariable IV) {
> -  ensureAbstractVariableIsCreatedIfScoped(TheCU, IV,
> Scope.getScopeNode());
> -  ConcreteVariables.push_back(
> -      llvm::make_unique<DbgVariable>(IV.first, IV.second));
> -  InfoHolder.addScopeVariable(&Scope, ConcreteVariables.back().get());
> -  return ConcreteVariables.back().get();
> +DbgEntity *DwarfDebug::createConcreteEntity(DwarfCompileUnit &TheCU,
> +                                            LexicalScope &Scope,
> +                                            const DINode *Node,
> +                                            const DILocation *Location,
> +                                            const MCSymbol *Sym) {
> +  ensureAbstractEntityIsCreatedIfScoped(TheCU, Node,
> Scope.getScopeNode());
> +  if (isa<const DILocalVariable>(Node)) {
> +    ConcreteEntities.push_back(
> +        llvm::make_unique<DbgVariable>(cast<const DILocalVariable>(Node),
> +                                       Location));
> +    InfoHolder.addScopeVariable(&Scope,
> +        cast<DbgVariable>(ConcreteEntities.back().get()));
> +  } else if (isa<const DILabel>(Node)) {
> +    ConcreteEntities.push_back(
> +        llvm::make_unique<DbgLabel>(cast<const DILabel>(Node),
> +                                    Location, Sym));
> +    InfoHolder.addScopeLabel(&Scope,
> +        cast<DbgLabel>(ConcreteEntities.back().get()));
> +  }
> +  return ConcreteEntities.back().get();
>  }
>
>  /// Determine whether a *singular* DBG_VALUE is valid for the entirety of
> its
> @@ -1194,9 +1205,9 @@ static bool validThroughout(LexicalScope
>  }
>
>  // Find variables for each lexical scope.
> -void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU,
> -                                     const DISubprogram *SP,
> -                                     DenseSet<InlinedVariable>
> &Processed) {
> +void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
> +                                   const DISubprogram *SP,
> +                                   DenseSet<InlinedVariable> &Processed) {
>    // Grab the variable info that was squirreled away in the MMI
> side-table.
>    collectVariableInfoFromMFTable(TheCU, Processed);
>
> @@ -1220,7 +1231,8 @@ void DwarfDebug::collectVariableInfo(Dwa
>        continue;
>
>      Processed.insert(IV);
> -    DbgVariable *RegVar = createConcreteVariable(TheCU, *Scope, IV);
> +    DbgVariable *RegVar = cast<DbgVariable>(createConcreteEntity(TheCU,
> +                                            *Scope, IV.first, IV.second));
>
>      const MachineInstr *MInsn = Ranges.front().first;
>      assert(MInsn->isDebugValue() && "History must begin with debug
> value");
> @@ -1253,13 +1265,44 @@ void DwarfDebug::collectVariableInfo(Dwa
>        Entry.finalize(*Asm, List, BT);
>    }
>
> -  // Collect info for variables that were optimized out.
> +  // For each InlinedLabel collected from DBG_LABEL instructions, convert
> to
> +  // DWARF-related DbgLabel.
> +  for (const auto &I : DbgLabels) {
> +    InlinedLabel IL = I.first;
> +    const MachineInstr *MI = I.second;
> +    if (MI == nullptr)
> +      continue;
> +
> +    LexicalScope *Scope = nullptr;
> +    // Get inlined DILocation if it is inlined label.
> +    if (const DILocation *IA = IL.second)
> +      Scope = LScopes.findInlinedScope(IL.first->getScope(), IA);
> +    else
> +      Scope = LScopes.findLexicalScope(IL.first->getScope());
> +    // If label scope is not found then skip this label.
> +    if (!Scope)
> +      continue;
> +
> +    /// At this point, the temporary label is created.
> +    /// Save the temporary label to DbgLabel entity to get the
> +    /// actually address when generating Dwarf DIE.
> +    MCSymbol *Sym = getLabelBeforeInsn(MI);
> +    createConcreteEntity(TheCU, *Scope, IL.first, IL.second, Sym);
> +  }
> +
> +  // Collect info for variables/labels that were optimized out.
>    for (const DINode *DN : SP->getRetainedNodes()) {
> +    LexicalScope *Scope = nullptr;
>      if (auto *DV = dyn_cast<DILocalVariable>(DN)) {
> -      if (Processed.insert(InlinedVariable(DV, nullptr)).second)
> -        if (LexicalScope *Scope =
> LScopes.findLexicalScope(DV->getScope()))
> -          createConcreteVariable(TheCU, *Scope, InlinedVariable(DV,
> nullptr));
> +      if (!Processed.insert(InlinedVariable(DV, nullptr)).second)
> +        continue;
> +      Scope = LScopes.findLexicalScope(DV->getScope());
> +    } else if (auto *DL = dyn_cast<DILabel>(DN)) {
> +      Scope = LScopes.findLexicalScope(DL->getScope());
>      }
> +
> +    if (Scope)
> +      createConcreteEntity(TheCU, *Scope, DN, nullptr);
>    }
>  }
>
> @@ -1417,7 +1460,7 @@ void DwarfDebug::endFunctionImpl(const M
>    DwarfCompileUnit &TheCU = *CUMap.lookup(SP->getUnit());
>
>    DenseSet<InlinedVariable> ProcessedVars;
> -  collectVariableInfo(TheCU, SP, ProcessedVars);
> +  collectEntityInfo(TheCU, SP, ProcessedVars);
>
>    // Add the range of this function to the list of ranges for the CU.
>    TheCU.addRange(RangeSpan(Asm->getFunctionBegin(),
> Asm->getFunctionEnd()));
> @@ -1445,10 +1488,11 @@ void DwarfDebug::endFunctionImpl(const M
>          // Collect info for variables that were optimized out.
>          if (!ProcessedVars.insert(InlinedVariable(DV, nullptr)).second)
>            continue;
> -        ensureAbstractVariableIsCreated(TheCU, InlinedVariable(DV,
> nullptr),
> -                                        DV->getScope());
> +        ensureAbstractEntityIsCreated(TheCU, DV, DV->getScope());
>          assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes
> -               && "ensureAbstractVariableIsCreated inserted abstract
> scopes");
> +               && "ensureAbstractEntityIsCreated inserted abstract
> scopes");
> +      } else if (auto *DL = dyn_cast<DILabel>(DN)) {
> +        ensureAbstractEntityIsCreated(TheCU, DL, DL->getScope());
>        }
>      }
>      constructAbstractSubprogramScopeDIE(TheCU, AScope);
> @@ -1466,6 +1510,7 @@ void DwarfDebug::endFunctionImpl(const M
>    // DbgVariables except those that are also in AbstractVariables (since
> they
>    // can be used cross-function)
>    InfoHolder.getScopeVariables().clear();
> +  InfoHolder.getScopeLabels().clear();
>    PrevLabel = nullptr;
>    CurFn = nullptr;
>  }
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=338390&r1=338389&r2=338390&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Tue Jul 31 07:48:32 2018
> @@ -15,7 +15,7 @@
>  #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H
>
>  #include "AddressPool.h"
> -#include "DbgValueHistoryCalculator.h"
> +#include "DbgEntityHistoryCalculator.h"
>  #include "DebugHandlerBase.h"
>  #include "DebugLocStream.h"
>  #include "DwarfFile.h"
> @@ -62,6 +62,46 @@ class MDNode;
>  class Module;
>
>
>  //===----------------------------------------------------------------------===//
> +/// This class is defined as the common parent of DbgVariable and DbgLabel
> +/// such that it could levarage polymorphism to extract common code for
> +/// DbgVariable and DbgLabel.
> +class DbgEntity {
> +  const DINode *Entity;
> +  const DILocation *InlinedAt;
> +  DIE *TheDIE = nullptr;
> +  unsigned SubclassID;
> +
> +public:
> +  enum DbgEntityKind {
> +    DbgVariableKind,
> +    DbgLabelKind
> +  };
> +
> +  DbgEntity(const DINode *N, const DILocation *IA, unsigned ID)
> +    : Entity(N), InlinedAt(IA), SubclassID(ID) {}
> +
> +  /// Accessors.
> +  /// @{
> +  const DINode *getEntity() const { return Entity; }
> +  const DILocation *getInlinedAt() const { return InlinedAt; }
> +  DIE *getDIE() const { return TheDIE; }
> +  unsigned getDbgEntityID() const { return SubclassID; }
> +  /// @}
> +
> +  void setDIE(DIE &D) { TheDIE = &D; }
> +
> +  static bool classof(const DbgEntity *N) {
> +    switch (N->getDbgEntityID()) {
> +    default:
> +      return false;
> +    case DbgVariableKind:
> +    case DbgLabelKind:
> +      return true;
> +    }
> +  }
> +};
> +
>
> +//===----------------------------------------------------------------------===//
>  /// This class is used to track local variable information.
>  ///
>  /// Variables can be created from allocas, in which case they're
> generated from
> @@ -73,10 +113,7 @@ class Module;
>  /// single instruction use \a MInsn and (optionally) a single entry of \a
> Expr.
>  ///
>  /// Variables that have been optimized out use none of these fields.
> -class DbgVariable {
> -  const DILocalVariable *Var;                /// Variable Descriptor.
> -  const DILocation *IA;                      /// Inlined at location.
> -  DIE *TheDIE = nullptr;                     /// Variable DIE.
> +class DbgVariable : public DbgEntity {
>    unsigned DebugLocListIndex = ~0u;          /// Offset in DebugLocs.
>    const MachineInstr *MInsn = nullptr;       /// DBG_VALUE instruction.
>
> @@ -93,7 +130,7 @@ public:
>    /// Creates a variable without any DW_AT_location.  Call \a
> initializeMMI()
>    /// for MMI entries, or \a initializeDbgValue() for DBG_VALUE
> instructions.
>    DbgVariable(const DILocalVariable *V, const DILocation *IA)
> -      : Var(V), IA(IA) {}
> +      : DbgEntity(V, IA, DbgVariableKind) {}
>
>    /// Initialize from the MMI table.
>    void initializeMMI(const DIExpression *E, int FI) {
> @@ -111,8 +148,9 @@ public:
>      assert(FrameIndexExprs.empty() && "Already initialized?");
>      assert(!MInsn && "Already initialized?");
>
> -    assert(Var == DbgValue->getDebugVariable() && "Wrong variable");
> -    assert(IA == DbgValue->getDebugLoc()->getInlinedAt() && "Wrong
> inlined-at");
> +    assert(getVariable() == DbgValue->getDebugVariable() && "Wrong
> variable");
> +    assert(getInlinedAt() == DbgValue->getDebugLoc()->getInlinedAt() &&
> +           "Wrong inlined-at");
>
>      MInsn = DbgValue;
>      if (auto *E = DbgValue->getDebugExpression())
> @@ -121,19 +159,18 @@ public:
>    }
>
>    // Accessors.
> -  const DILocalVariable *getVariable() const { return Var; }
> -  const DILocation *getInlinedAt() const { return IA; }
> +  const DILocalVariable *getVariable() const {
> +    return cast<DILocalVariable>(getEntity());
> +  }
>
>    const DIExpression *getSingleExpression() const {
>      assert(MInsn && FrameIndexExprs.size() <= 1);
>      return FrameIndexExprs.size() ? FrameIndexExprs[0].Expr : nullptr;
>    }
>
> -  void setDIE(DIE &D) { TheDIE = &D; }
> -  DIE *getDIE() const { return TheDIE; }
>    void setDebugLocListIndex(unsigned O) { DebugLocListIndex = O; }
>    unsigned getDebugLocListIndex() const { return DebugLocListIndex; }
> -  StringRef getName() const { return Var->getName(); }
> +  StringRef getName() const { return getVariable()->getName(); }
>    const MachineInstr *getMInsn() const { return MInsn; }
>    /// Get the FI entries, sorted by fragment offset.
>    ArrayRef<FrameIndexExpr> getFrameIndexExprs() const;
> @@ -143,7 +180,7 @@ public:
>    // Translate tag to proper Dwarf tag.
>    dwarf::Tag getTag() const {
>      // FIXME: Why don't we just infer this tag and store it all along?
> -    if (Var->isParameter())
> +    if (getVariable()->isParameter())
>        return dwarf::DW_TAG_formal_parameter;
>
>      return dwarf::DW_TAG_variable;
> @@ -151,7 +188,7 @@ public:
>
>    /// Return true if DbgVariable is artificial.
>    bool isArtificial() const {
> -    if (Var->isArtificial())
> +    if (getVariable()->isArtificial())
>        return true;
>      if (getType()->isArtificial())
>        return true;
> @@ -159,7 +196,7 @@ public:
>    }
>
>    bool isObjectPointer() const {
> -    if (Var->isObjectPointer())
> +    if (getVariable()->isObjectPointer())
>        return true;
>      if (getType()->isObjectPointer())
>        return true;
> @@ -178,6 +215,45 @@ public:
>    bool isBlockByrefVariable() const;
>    const DIType *getType() const;
>
> +  static bool classof(const DbgEntity *N) {
> +    return N->getDbgEntityID() == DbgVariableKind;
> +  }
> +
> +private:
> +  template <typename T> T *resolve(TypedDINodeRef<T> Ref) const {
> +    return Ref.resolve();
> +  }
> +};
> +
>
> +//===----------------------------------------------------------------------===//
> +/// This class is used to track label information.
> +///
> +/// Labels are collected from \c DBG_LABEL instructions.
> +class DbgLabel : public DbgEntity {
> +  const MCSymbol *Sym;                  /// Symbol before DBG_LABEL
> instruction.
> +
> +public:
> +  /// We need MCSymbol information to generate DW_AT_low_pc.
> +  DbgLabel(const DILabel *L, const DILocation *IA, const MCSymbol *Sym =
> nullptr)
> +      : DbgEntity(L, IA, DbgLabelKind), Sym(Sym) {}
> +
> +  /// Accessors.
> +  /// @{
> +  const DILabel *getLabel() const { return cast<DILabel>(getEntity()); }
> +  const MCSymbol *getSymbol() const { return Sym; }
> +
> +  StringRef getName() const { return getLabel()->getName(); }
> +  /// @}
> +
> +  /// Translate tag to proper Dwarf tag.
> +  dwarf::Tag getTag() const {
> +    return dwarf::DW_TAG_label;
> +  }
> +
> +  static bool classof(const DbgEntity *N) {
> +    return N->getDbgEntityID() == DbgLabelKind;
> +  }
> +
>  private:
>    template <typename T> T *resolve(TypedDINodeRef<T> Ref) const {
>      return Ref.resolve();
> @@ -217,8 +293,8 @@ class DwarfDebug : public DebugHandlerBa
>    /// Size of each symbol emitted (for those symbols that have a specific
> size).
>    DenseMap<const MCSymbol *, uint64_t> SymSize;
>
> -  /// Collection of abstract variables.
> -  SmallVector<std::unique_ptr<DbgVariable>, 64> ConcreteVariables;
> +  /// Collection of abstract variables/labels.
> +  SmallVector<std::unique_ptr<DbgEntity>, 64> ConcreteEntities;
>
>    /// Collection of DebugLocEntry. Stored in a linked list so that
> DIELocLists
>    /// can refer to them in spite of insertions into this list.
> @@ -333,14 +409,20 @@ class DwarfDebug : public DebugHandlerBa
>    }
>
>    using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
> +  using InlinedLabel = DbgLabelInstrMap::InlinedLabel;
>
> -  void ensureAbstractVariableIsCreated(DwarfCompileUnit &CU,
> InlinedVariable IV,
> -                                       const MDNode *Scope);
> -  void ensureAbstractVariableIsCreatedIfScoped(DwarfCompileUnit &CU,
> InlinedVariable IV,
> -                                               const MDNode *Scope);
> -
> -  DbgVariable *createConcreteVariable(DwarfCompileUnit &TheCU,
> -                                      LexicalScope &Scope,
> InlinedVariable IV);
> +  void ensureAbstractEntityIsCreated(DwarfCompileUnit &CU,
> +                                     const DINode *Node,
> +                                     const MDNode *Scope);
> +  void ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
> +                                             const DINode *Node,
> +                                             const MDNode *Scope);
> +
> +  DbgEntity *createConcreteEntity(DwarfCompileUnit &TheCU,
> +                                  LexicalScope &Scope,
> +                                  const DINode *Node,
> +                                  const DILocation *Location,
> +                                  const MCSymbol *Sym = nullptr);
>
>    /// Construct a DIE for this abstract scope.
>    void constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU,
> LexicalScope *Scope);
> @@ -349,7 +431,7 @@ class DwarfDebug : public DebugHandlerBa
>    void addAccelNameImpl(AccelTable<DataT> &AppleAccel, StringRef Name,
>                          const DIE &Die);
>
> -  void finishVariableDefinitions();
> +  void finishEntityDefinitions();
>
>    void finishSubprogramDefinitions();
>
> @@ -466,8 +548,8 @@ class DwarfDebug : public DebugHandlerBa
>                          unsigned Flags);
>
>    /// Populate LexicalScope entries with variables' info.
> -  void collectVariableInfo(DwarfCompileUnit &TheCU, const DISubprogram
> *SP,
> -                           DenseSet<InlinedVariable> &ProcessedVars);
> +  void collectEntityInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP,
> +                         DenseSet<InlinedVariable> &ProcessedVars);
>
>    /// Build the location list for all DBG_VALUEs in the
>    /// function that describe the same variable.
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.cpp?rev=338390&r1=338389&r2=338390&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.cpp Tue Jul 31 07:48:32
> 2018
> @@ -98,3 +98,8 @@ bool DwarfFile::addScopeVariable(Lexical
>    }
>    return true;
>  }
> +
> +void DwarfFile::addScopeLabel(LexicalScope *LS, DbgLabel *Label) {
> +  SmallVectorImpl<DbgLabel *> &Labels = ScopeLabels[LS];
> +  Labels.push_back(Label);
> +}
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h?rev=338390&r1=338389&r2=338390&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h Tue Jul 31 07:48:32 2018
> @@ -24,7 +24,9 @@
>  namespace llvm {
>
>  class AsmPrinter;
> +class DbgEntity;
>  class DbgVariable;
> +class DbgLabel;
>  class DwarfCompileUnit;
>  class DwarfUnit;
>  class LexicalScope;
> @@ -62,9 +64,13 @@ class DwarfFile {
>    /// Collection of DbgVariables of each lexical scope.
>    DenseMap<LexicalScope *, ScopeVars> ScopeVariables;
>
> +  /// Collection of DbgLabels of each lexical scope.
> +  using LabelList = SmallVector<DbgLabel *, 4>;
> +  DenseMap<LexicalScope *, LabelList> ScopeLabels;
> +
>    // Collection of abstract subprogram DIEs.
>    DenseMap<const MDNode *, DIE *> AbstractSPDies;
> -  DenseMap<const MDNode *, std::unique_ptr<DbgVariable>>
> AbstractVariables;
> +  DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
>
>    /// Maps MDNodes for type system with the corresponding DIEs. These
> DIEs can
>    /// be shared across CUs, that is why we keep the map here instead
> @@ -122,16 +128,22 @@ public:
>    /// \returns false if the variable was merged with a previous one.
>    bool addScopeVariable(LexicalScope *LS, DbgVariable *Var);
>
> +  void addScopeLabel(LexicalScope *LS, DbgLabel *Label);
> +
>    DenseMap<LexicalScope *, ScopeVars> &getScopeVariables() {
>      return ScopeVariables;
>    }
>
> +  DenseMap<LexicalScope *, LabelList> &getScopeLabels() {
> +    return ScopeLabels;
> +  }
> +
>    DenseMap<const MDNode *, DIE *> &getAbstractSPDies() {
>      return AbstractSPDies;
>    }
>
> -  DenseMap<const MDNode *, std::unique_ptr<DbgVariable>>
> &getAbstractVariables() {
> -    return AbstractVariables;
> +  DenseMap<const DINode *, std::unique_ptr<DbgEntity>>
> &getAbstractEntities() {
> +    return AbstractEntities;
>    }
>
>    void insertDIE(const MDNode *TypeMD, DIE *Die) {
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp?rev=338390&r1=338389&r2=338390&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp Tue Jul 31 07:48:32
> 2018
> @@ -401,6 +401,12 @@ void DwarfUnit::addSourceLine(DIE &Die,
>    addSourceLine(Die, SP->getLine(), SP->getFile());
>  }
>
> +void DwarfUnit::addSourceLine(DIE &Die, const DILabel *L) {
> +  assert(L);
> +
> +  addSourceLine(Die, L->getLine(), L->getFile());
> +}
> +
>  void DwarfUnit::addSourceLine(DIE &Die, const DIType *Ty) {
>    assert(Ty);
>
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h
> URL:
> <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h?rev=338390&r1=338389&r2=338390&view=diff>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180731/16792cbc/attachment-0001.html>


More information about the llvm-commits mailing list