<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>Hi Eric,</p>
    <p>    Thank you for taking care of this. Yes there is a dependency
      cycle in my patch:
      CodeGen->AsmPrinter->DebugInfoDWARF->CodeGen. I would fix
      it, Thanks! Do you know whether there is some machinery to detect
      such cases ? Usual "check-all" build did not report any problem. <br>
    </p>
    <p>Thank you, Alexey.<br>
    </p>
    <div class="moz-cite-prefix">20.12.2019 0:31, Eric Christopher
      пишет:<br>
    </div>
    <blockquote type="cite"
cite="mid:CALehDX7Bmnym+GHh=R_xLU1RYCwEFpsReG_KkuaA6XvXVtSw0w@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr">Hi Alexey,
        <div><br>
        </div>
        <div>I've temporarily reverted this here:</div>
        <div><br>
        </div>
        <div>echristo@athyra ~/r/llvm-project> git push<br>
          To github.com:llvm/llvm-project.git<br>
             918d3939722..3075cd5c9fc  master -> master<br>
        </div>
        <div><br>
        </div>
        <div>as this caused a layering violation/dependency cycle in the
          build graph. If you need any help looking into this let me or
          Tobias know :)</div>
        <div><br>
        </div>
        <div>Thanks and sorry for the inconvenience!</div>
        <div><br>
        </div>
        <div>-eric</div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Thu, Dec 19, 2019 at 4:42
          AM Alexey Lapshin via llvm-commits <<a
            href="mailto:llvm-commits@lists.llvm.org"
            moz-do-not-send="true">llvm-commits@lists.llvm.org</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px
          0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
          Author: Alexey Lapshin<br>
          Date: 2019-12-19T15:41:48+03:00<br>
          New Revision: abc7f6800df8a1f40e1e2c9ccce826abb0208284<br>
          <br>
          URL: <a
href="https://github.com/llvm/llvm-project/commit/abc7f6800df8a1f40e1e2c9ccce826abb0208284"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://github.com/llvm/llvm-project/commit/abc7f6800df8a1f40e1e2c9ccce826abb0208284</a><br>
          DIFF: <a
href="https://github.com/llvm/llvm-project/commit/abc7f6800df8a1f40e1e2c9ccce826abb0208284.diff"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://github.com/llvm/llvm-project/commit/abc7f6800df8a1f40e1e2c9ccce826abb0208284.diff</a><br>
          <br>
          LOG: [Dsymutil][Debuginfo][NFC] Refactor dsymutil to separate
          DWARF optimizing part 2.<br>
          <br>
          That patch is extracted from the D70709. It moves CompileUnit,
          DeclContext<br>
          into llvm/DebugInfo/DWARF. It also adds new file
          DWARFOptimizer with<br>
          AddressesMap class. AddressesMap generalizes functionality<br>
          from RelocationManager.<br>
          <br>
          Differential Revision: <a
            href="https://reviews.llvm.org/D71271" rel="noreferrer"
            target="_blank" moz-do-not-send="true">https://reviews.llvm.org/D71271</a><br>
          <br>
          Added: <br>
              llvm/include/llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h<br>
              llvm/include/llvm/DebugInfo/DWARF/DWARFOptDeclContext.h<br>
              llvm/include/llvm/DebugInfo/DWARF/DWARFOptimizer.h<br>
              llvm/lib/DebugInfo/DWARF/DWARFOptCompileUnit.cpp<br>
              llvm/lib/DebugInfo/DWARF/DWARFOptDeclContext.cpp<br>
              llvm/lib/DebugInfo/DWARF/DWARFOptimizer.cpp<br>
          <br>
          Modified: <br>
              llvm/lib/DebugInfo/DWARF/CMakeLists.txt<br>
              llvm/lib/DebugInfo/DWARF/LLVMBuild.txt<br>
              llvm/tools/dsymutil/CMakeLists.txt<br>
              llvm/tools/dsymutil/DwarfLinker.cpp<br>
              llvm/tools/dsymutil/DwarfLinker.h<br>
              llvm/tools/dsymutil/DwarfStreamer.cpp<br>
              llvm/tools/dsymutil/DwarfStreamer.h<br>
          <br>
          Removed: <br>
              llvm/tools/dsymutil/CompileUnit.cpp<br>
              llvm/tools/dsymutil/CompileUnit.h<br>
              llvm/tools/dsymutil/DeclContext.cpp<br>
              llvm/tools/dsymutil/DeclContext.h<br>
          <br>
          <br>
################################################################################<br>
          diff  --git a/llvm/tools/dsymutil/CompileUnit.h
          b/llvm/include/llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h<br>
          similarity index 97%<br>
          rename from llvm/tools/dsymutil/CompileUnit.h<br>
          rename to
          llvm/include/llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h<br>
          index e0f5d3bc65b2..010862966846 100644<br>
          --- a/llvm/tools/dsymutil/CompileUnit.h<br>
          +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h<br>
          @@ -1,4 +1,4 @@<br>
          -//===- tools/dsymutil/CompileUnit.h - Dwarf debug info linker
          ---*- C++ -*-===//<br>
          +//===- DWARFOptCompileUnit.h
          ------------------------------------*- C++ -*-===//<br>
           //<br>
           // Part of the LLVM Project, under the Apache License v2.0
          with LLVM Exceptions.<br>
           // See <a href="https://llvm.org/LICENSE.txt"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://llvm.org/LICENSE.txt</a>
          for license information.<br>
          @@ -6,15 +6,15 @@<br>
           //<br>
 //===----------------------------------------------------------------------===//<br>
          <br>
          -#ifndef LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H<br>
          -#define LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H<br>
          +#ifndef LLVM_DEBUGINFO_DWARF_OPT_COMPILEUNIT_H<br>
          +#define LLVM_DEBUGINFO_DWARF_OPT_COMPILEUNIT_H<br>
          <br>
           #include "llvm/ADT/IntervalMap.h"<br>
           #include "llvm/CodeGen/DIE.h"<br>
           #include "llvm/DebugInfo/DWARF/DWARFUnit.h"<br>
          +#include "llvm/Support/DataExtractor.h"<br>
          <br>
           namespace llvm {<br>
          -namespace dsymutil {<br>
          <br>
           class DeclContext;<br>
          <br>
          @@ -46,7 +46,7 @@ struct PatchLocation {<br>
           };<br>
          <br>
           /// Stores all information relating to a compile unit, be it
          in its original<br>
          -/// instance in the object file to its brand new cloned and
          linked DIE tree.<br>
          +/// instance in the object file to its brand new cloned and
          generated DIE tree.<br>
           class CompileUnit {<br>
           public:<br>
             /// Information gathered about a DIE in the object file.<br>
          @@ -325,7 +325,6 @@ class CompileUnit {<br>
             std::string ClangModuleName;<br>
           };<br>
          <br>
          -} // end namespace dsymutil<br>
           } // end namespace llvm<br>
          <br>
          -#endif // LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H<br>
          +#endif // LLVM_DEBUGINFO_DWARF_OPT_COMPILEUNIT_H<br>
          <br>
          diff  --git a/llvm/tools/dsymutil/DeclContext.h
          b/llvm/include/llvm/DebugInfo/DWARF/DWARFOptDeclContext.h<br>
          similarity index 95%<br>
          rename from llvm/tools/dsymutil/DeclContext.h<br>
          rename to
          llvm/include/llvm/DebugInfo/DWARF/DWARFOptDeclContext.h<br>
          index 36ef50944083..6045ed72b259 100644<br>
          --- a/llvm/tools/dsymutil/DeclContext.h<br>
          +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFOptDeclContext.h<br>
          @@ -1,4 +1,4 @@<br>
          -//===- tools/dsymutil/DeclContext.h - Dwarf debug info linker
          ---*- C++ -*-===//<br>
          +//===- llvm/DebugInfo/DWARF/DWARFOptDeclContext.h
          ---------------*- C++ -*-===//<br>
           //<br>
           // Part of the LLVM Project, under the Apache License v2.0
          with LLVM Exceptions.<br>
           // See <a href="https://llvm.org/LICENSE.txt"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://llvm.org/LICENSE.txt</a>
          for license information.<br>
          @@ -6,20 +6,19 @@<br>
           //<br>
 //===----------------------------------------------------------------------===//<br>
          <br>
          -#ifndef LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H<br>
          -#define LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H<br>
          +#ifndef LLVM_DEBUGINFO_DWARF_OPT_DECLCONTEXT_H<br>
          +#define LLVM_DEBUGINFO_DWARF_OPT_DECLCONTEXT_H<br>
          <br>
          -#include "CompileUnit.h"<br>
           #include "llvm/ADT/DenseMap.h"<br>
           #include "llvm/ADT/DenseMapInfo.h"<br>
           #include "llvm/ADT/DenseSet.h"<br>
           #include "llvm/ADT/StringRef.h"<br>
           #include "llvm/CodeGen/NonRelocatableStringpool.h"<br>
           #include "llvm/DebugInfo/DWARF/DWARFDie.h"<br>
          +#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"<br>
           #include "llvm/Support/Path.h"<br>
          <br>
           namespace llvm {<br>
          -namespace dsymutil {<br>
          <br>
           struct DeclMapInfo;<br>
          <br>
          @@ -165,7 +164,6 @@ struct DeclMapInfo : private
          DenseMapInfo<DeclContext *> {<br>
             }<br>
           };<br>
          <br>
          -} // end namespace dsymutil<br>
           } // end namespace llvm<br>
          <br>
          -#endif // LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H<br>
          +#endif // LLVM_DEBUGINFO_DWARF_OPT_DECLCONTEXT_H<br>
          <br>
          diff  --git
          a/llvm/include/llvm/DebugInfo/DWARF/DWARFOptimizer.h
          b/llvm/include/llvm/DebugInfo/DWARF/DWARFOptimizer.h<br>
          new file mode 100644<br>
          index 000000000000..5700c97a92fe<br>
          --- /dev/null<br>
          +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFOptimizer.h<br>
          @@ -0,0 +1,86 @@<br>
          +//===- llvm/DebugInfo/DWARF/DWARFOptimizer.h
          --------------------*- C++ -*-===//<br>
          +//<br>
          +// Part of the LLVM Project, under the Apache License v2.0
          with LLVM Exceptions.<br>
          +// See <a href="https://llvm.org/LICENSE.txt"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://llvm.org/LICENSE.txt</a>
          for license information.<br>
          +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
          +//<br>
+//===----------------------------------------------------------------------===//<br>
          +<br>
          +#ifndef LLVM_DEBUGINFO_DWARFOPTIMIZER_H<br>
          +#define LLVM_DEBUGINFO_DWARFOPTIMIZER_H<br>
          +<br>
          +#include "llvm/CodeGen/NonRelocatableStringpool.h"<br>
          +#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"<br>
          +#include "llvm/DebugInfo/DWARF/DWARFContext.h"<br>
          +#include "llvm/DebugInfo/DWARF/DWARFOptDeclContext.h"<br>
          +#include <map><br>
          +<br>
          +namespace llvm {<br>
          +<br>
          +enum class DwarfOptimizerClient { Dsymutil, LLD, General };<br>
          +<br>
          +/// Partial address range. Besides an offset, only the<br>
          +/// HighPC is stored. The structure is stored in a map where
          the LowPC is the<br>
          +/// key.<br>
          +struct ObjFileAddressRange {<br>
          +  /// Function HighPC.<br>
          +  uint64_t HighPC;<br>
          +  /// Offset to apply to the linked address.<br>
          +  /// should be 0 for not-linked object file.<br>
          +  int64_t Offset;<br>
          +<br>
          +  ObjFileAddressRange(uint64_t EndPC, int64_t Offset)<br>
          +      : HighPC(EndPC), Offset(Offset) {}<br>
          +<br>
          +  ObjFileAddressRange() : HighPC(0), Offset(0) {}<br>
          +};<br>
          +<br>
          +/// Map LowPC to ObjFileAddressRange.<br>
          +using RangesTy = std::map<uint64_t,
          ObjFileAddressRange>;<br>
          +<br>
          +/// AddressesMap represents information about valid addresses
          used<br>
          +/// by debug information. Valid addresses are those which
          points to<br>
          +/// live code sections. i.e. relocations for these addresses
          point<br>
          +/// into sections which would be/are placed into resulting
          binary.<br>
          +class AddressesMap {<br>
          +public:<br>
          +  virtual ~AddressesMap();<br>
          +<br>
          +  /// Returns true if represented addresses are from linked
          file.<br>
          +  /// Returns false if represented addresses are from
          not-linked<br>
          +  /// object file.<br>
          +  virtual bool areRelocationsResolved() const = 0;<br>
          +<br>
          +  /// Checks that there are valid relocations against a
          .debug_info<br>
          +  /// section. Reset current relocation pointer if
          neccessary.<br>
          +  virtual bool hasValidRelocs(bool resetRelocsPtr = true) =
          0;<br>
          +<br>
          +  /// Checks that there is a relocation against .debug_info<br>
          +  /// table between \p StartOffset and \p NextOffset.<br>
          +  ///<br>
          +  /// This function must be called with offsets in strictly
          ascending<br>
          +  /// order because it never looks back at relocations it
          already 'went past'.<br>
          +  /// \returns true and sets Info.InDebugMap if it is the
          case.<br>
          +  virtual bool hasValidRelocationAt(uint64_t StartOffset,
          uint64_t EndOffset,<br>
          +                                    CompileUnit::DIEInfo
          &Info) = 0;<br>
          +<br>
          +  /// Apply the valid relocations to the buffer \p Data,
          taking into<br>
          +  /// account that Data is at \p BaseOffset in the debug_info
          section.<br>
          +  ///<br>
          +  /// This function must be called with monotonic \p
          BaseOffset values.<br>
          +  ///<br>
          +  /// \returns true whether any reloc has been applied.<br>
          +  virtual bool applyValidRelocs(MutableArrayRef<char>
          Data, uint64_t BaseOffset,<br>
          +                                bool IsLittleEndian) = 0;<br>
          +<br>
          +  /// Returns all valid functions address ranges(i.e., those
          ranges<br>
          +  /// which points to sections with code).<br>
          +  virtual RangesTy &getValidAddressRanges() = 0;<br>
          +<br>
          +  /// Erases all data.<br>
          +  virtual void clear() = 0;<br>
          +};<br>
          +<br>
          +} // end namespace llvm<br>
          +<br>
          +#endif // LLVM_DEBUGINFO_DWARFOPTIMIZER_H<br>
          <br>
          diff  --git a/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
          b/llvm/lib/DebugInfo/DWARF/CMakeLists.txt<br>
          index 3fe9904f221b..d51fe2653631 100644<br>
          --- a/llvm/lib/DebugInfo/DWARF/CMakeLists.txt<br>
          +++ b/llvm/lib/DebugInfo/DWARF/CMakeLists.txt<br>
          @@ -27,6 +27,9 @@
          add_llvm_component_library(LLVMDebugInfoDWARF<br>
             DWARFUnitIndex.cpp<br>
             DWARFUnit.cpp<br>
             DWARFVerifier.cpp<br>
          +  DWARFOptCompileUnit.cpp<br>
          +  DWARFOptDeclContext.cpp<br>
          +  DWARFOptimizer.cpp<br>
          <br>
             ADDITIONAL_HEADER_DIRS<br>
             ${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/DWARF<br>
          <br>
          diff  --git a/llvm/tools/dsymutil/CompileUnit.cpp
          b/llvm/lib/DebugInfo/DWARF/DWARFOptCompileUnit.cpp<br>
          similarity index 96%<br>
          rename from llvm/tools/dsymutil/CompileUnit.cpp<br>
          rename to llvm/lib/DebugInfo/DWARF/DWARFOptCompileUnit.cpp<br>
          index 036c61a6b926..6ca5f1289283 100644<br>
          --- a/llvm/tools/dsymutil/CompileUnit.cpp<br>
          +++ b/llvm/lib/DebugInfo/DWARF/DWARFOptCompileUnit.cpp<br>
          @@ -1,4 +1,4 @@<br>
          -//===- tools/dsymutil/CompileUnit.h - Dwarf compile unit
          ------------------===//<br>
          +//===- llvm/DebugInfo/DWARF/DWARFOptCompileUnit.cpp
          -----------------------===//<br>
           //<br>
           // Part of the LLVM Project, under the Apache License v2.0
          with LLVM Exceptions.<br>
           // See <a href="https://llvm.org/LICENSE.txt"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://llvm.org/LICENSE.txt</a>
          for license information.<br>
          @@ -6,11 +6,10 @@<br>
           //<br>
 //===----------------------------------------------------------------------===//<br>
          <br>
          -#include "CompileUnit.h"<br>
          -#include "DeclContext.h"<br>
          +#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"<br>
          +#include "llvm/DebugInfo/DWARF/DWARFOptDeclContext.h"<br>
          <br>
           namespace llvm {<br>
          -namespace dsymutil {<br>
          <br>
           /// Check if the DIE at \p Idx is in the scope of a function.<br>
           static bool inFunctionScope(CompileUnit &U, unsigned Idx)
          {<br>
          @@ -142,5 +141,4 @@ void CompileUnit::addTypeAccelerator(const
          DIE *Die,<br>
             Pubtypes.emplace_back(Name, Die, QualifiedNameHash,
          ObjcClassImplementation);<br>
           }<br>
          <br>
          -} // namespace dsymutil<br>
           } // namespace llvm<br>
          <br>
          diff  --git a/llvm/tools/dsymutil/DeclContext.cpp
          b/llvm/lib/DebugInfo/DWARF/DWARFOptDeclContext.cpp<br>
          similarity index 98%<br>
          rename from llvm/tools/dsymutil/DeclContext.cpp<br>
          rename to llvm/lib/DebugInfo/DWARF/DWARFOptDeclContext.cpp<br>
          index 1c33b672c26b..95cf58444e1a 100644<br>
          --- a/llvm/tools/dsymutil/DeclContext.cpp<br>
          +++ b/llvm/lib/DebugInfo/DWARF/DWARFOptDeclContext.cpp<br>
          @@ -1,4 +1,4 @@<br>
          -//===- tools/dsymutil/DeclContext.cpp - Declaration context
          ---------------===//<br>
          +//===- llvm/DebugInfo/DWARF/DWARFOptDeclContext.cpp
          -----------------------===//<br>
           //<br>
           // Part of the LLVM Project, under the Apache License v2.0
          with LLVM Exceptions.<br>
           // See <a href="https://llvm.org/LICENSE.txt"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://llvm.org/LICENSE.txt</a>
          for license information.<br>
          @@ -6,13 +6,12 @@<br>
           //<br>
 //===----------------------------------------------------------------------===//<br>
          <br>
          -#include "DeclContext.h"<br>
          +#include "llvm/DebugInfo/DWARF/DWARFOptDeclContext.h"<br>
           #include "llvm/DebugInfo/DWARF/DWARFContext.h"<br>
           #include "llvm/DebugInfo/DWARF/DWARFDie.h"<br>
           #include "llvm/DebugInfo/DWARF/DWARFUnit.h"<br>
          <br>
           namespace llvm {<br>
          -namespace dsymutil {<br>
          <br>
           /// Set the last DIE/CU a context was seen in and, possibly
          invalidate the<br>
           /// context if it is ambiguous.<br>
          @@ -206,5 +205,5 @@ PointerIntPair<DeclContext *, 1>
          DeclContextTree::getChildDeclContext(<br>
          <br>
             return PointerIntPair<DeclContext *,
          1>(*ContextIter);<br>
           }<br>
          -} // namespace dsymutil<br>
          +<br>
           } // namespace llvm<br>
          <br>
          diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFOptimizer.cpp
          b/llvm/lib/DebugInfo/DWARF/DWARFOptimizer.cpp<br>
          new file mode 100644<br>
          index 000000000000..535d2a047076<br>
          --- /dev/null<br>
          +++ b/llvm/lib/DebugInfo/DWARF/DWARFOptimizer.cpp<br>
          @@ -0,0 +1,15 @@<br>
          +//=== llvm/DebugInfo/DWARF/DWARFOptimizer.cpp
          -----------------------------===//<br>
          +//<br>
          +// Part of the LLVM Project, under the Apache License v2.0
          with LLVM Exceptions.<br>
          +// See <a href="https://llvm.org/LICENSE.txt"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://llvm.org/LICENSE.txt</a>
          for license information.<br>
          +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
          +//<br>
+//===----------------------------------------------------------------------===//<br>
          +<br>
          +#include "llvm/DebugInfo/DWARF/DWARFOptimizer.h"<br>
          +<br>
          +namespace llvm {<br>
          +<br>
          +AddressesMap::~AddressesMap() {}<br>
          +<br>
          +} // namespace llvm<br>
          <br>
          diff  --git a/llvm/lib/DebugInfo/DWARF/LLVMBuild.txt
          b/llvm/lib/DebugInfo/DWARF/LLVMBuild.txt<br>
          index 182be10f0b4c..e72360deaf88 100644<br>
          --- a/llvm/lib/DebugInfo/DWARF/LLVMBuild.txt<br>
          +++ b/llvm/lib/DebugInfo/DWARF/LLVMBuild.txt<br>
          @@ -18,4 +18,4 @@<br>
           type = Library<br>
           name = DebugInfoDWARF<br>
           parent = DebugInfo<br>
          -required_libraries = BinaryFormat Object MC Support<br>
          +required_libraries = BinaryFormat Object MC Support CodeGen<br>
          <br>
          diff  --git a/llvm/tools/dsymutil/CMakeLists.txt
          b/llvm/tools/dsymutil/CMakeLists.txt<br>
          index b8466baa6346..e21215b2417d 100644<br>
          --- a/llvm/tools/dsymutil/CMakeLists.txt<br>
          +++ b/llvm/tools/dsymutil/CMakeLists.txt<br>
          @@ -22,9 +22,7 @@ add_llvm_tool(dsymutil<br>
             dsymutil.cpp<br>
             BinaryHolder.cpp<br>
             CFBundle.cpp<br>
          -  CompileUnit.cpp<br>
             DebugMap.cpp<br>
          -  DeclContext.cpp<br>
             DwarfLinker.cpp<br>
             DwarfStreamer.cpp<br>
             MachODebugMapParser.cpp<br>
          <br>
          diff  --git a/llvm/tools/dsymutil/DwarfLinker.cpp
          b/llvm/tools/dsymutil/DwarfLinker.cpp<br>
          index 64acab698434..521d3635dab2 100644<br>
          --- a/llvm/tools/dsymutil/DwarfLinker.cpp<br>
          +++ b/llvm/tools/dsymutil/DwarfLinker.cpp<br>
          @@ -9,7 +9,6 @@<br>
           #include "DwarfLinker.h"<br>
           #include "BinaryHolder.h"<br>
           #include "DebugMap.h"<br>
          -#include "DeclContext.h"<br>
           #include "DwarfStreamer.h"<br>
           #include "MachOUtils.h"<br>
           #include "dsymutil.h"<br>
          @@ -45,6 +44,7 @@<br>
           #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"<br>
           #include "llvm/DebugInfo/DWARF/DWARFDie.h"<br>
           #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"<br>
          +#include "llvm/DebugInfo/DWARF/DWARFOptDeclContext.h"<br>
           #include "llvm/DebugInfo/DWARF/DWARFSection.h"<br>
           #include "llvm/DebugInfo/DWARF/DWARFUnit.h"<br>
           #include "llvm/MC/MCAsmBackend.h"<br>
          @@ -374,30 +374,6 @@ static bool
          dieNeedsChildrenToBeMeaningful(uint32_t Tag) {<br>
           }<br>
          <br>
           void DwarfLinker::startDebugObject(LinkContext &Context)
          {<br>
          -  // Iterate over the debug map entries and put all the ones
          that are<br>
          -  // functions (because they have a size) into the Ranges
          map. This map is<br>
          -  // very similar to the FunctionRanges that are stored in
          each unit, with 2<br>
          -  // notable <br>
          diff erences:<br>
          -  //<br>
          -  //  1. Obviously this one is global, while the other ones
          are per-unit.<br>
          -  //<br>
          -  //  2. This one contains not only the functions described
          in the DIE<br>
          -  //     tree, but also the ones that are only in the debug
          map.<br>
          -  //<br>
          -  // The latter information is required to reproduce
          dsymutil's logic while<br>
          -  // linking line tables. The cases where this information
          matters look like<br>
          -  // bugs that need to be investigated, but for now we need
          to reproduce<br>
          -  // dsymutil's behavior.<br>
          -  // FIXME: Once we understood exactly if that information is
          needed,<br>
          -  // maybe totally remove this (or try to use it to do a real<br>
          -  // -gline-tables-only on Darwin.<br>
          -  for (const auto &Entry : Context.DMO.symbols()) {<br>
          -    const auto &Mapping = Entry.getValue();<br>
          -    if (Mapping.Size && Mapping.ObjectAddress)<br>
          -      Context.Ranges[*Mapping.ObjectAddress] =
          DebugMapObjectRange(<br>
          -          *Mapping.ObjectAddress + Mapping.Size,<br>
          -          int64_t(Mapping.BinaryAddress) -
          *Mapping.ObjectAddress);<br>
          -  }<br>
           }<br>
          <br>
           void DwarfLinker::endDebugObject(LinkContext &Context) {<br>
          @@ -560,7 +536,7 @@ bool
          DwarfLinker::RelocationManager::findValidRelocsInDebugInfo(<br>
           /// This function must be called with offsets in strictly
          ascending<br>
           /// order because it never looks back at relocations it
          already 'went past'.<br>
           /// \returns true and sets Info.InDebugMap if it is the case.<br>
          -bool DwarfLinker::RelocationManager::hasValidRelocation(<br>
          +bool DwarfLinker::RelocationManager::hasValidRelocationAt(<br>
               uint64_t StartOffset, uint64_t EndOffset,
          CompileUnit::DIEInfo &Info) {<br>
             assert(NextValidReloc == 0 ||<br>
                    StartOffset > ValidRelocs[NextValidReloc -
          1].Offset);<br>
          @@ -651,7 +627,8 @@ unsigned
          DwarfLinker::shouldKeepVariableDIE(RelocationManager
          &RelocMgr,<br>
             // always check if the variable has a valid relocation, so
          that the<br>
             // DIEInfo is filled. However, we don't want a static
          variable in a<br>
             // function to force us to keep the enclosing function.<br>
          -  if (!RelocMgr.hasValidRelocation(LocationOffset,
          LocationEndOffset, MyInfo) ||<br>
          +  if (!RelocMgr.hasValidRelocationAt(LocationOffset,
          LocationEndOffset,<br>
          +                                     MyInfo) ||<br>
                 (Flags & TF_InFunctionScope))<br>
               return Flags;<br>
          <br>
          @@ -689,7 +666,7 @@ unsigned
          DwarfLinker::shouldKeepSubprogramDIE(<br>
             auto LowPc =
          dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc));<br>
             assert(LowPc.hasValue() && "low_pc attribute is not
          an address.");<br>
             if (!LowPc ||<br>
          -      !RelocMgr.hasValidRelocation(LowPcOffset,
          LowPcEndOffset, MyInfo))<br>
          +      !RelocMgr.hasValidRelocationAt(LowPcOffset,
          LowPcEndOffset, MyInfo))<br>
               return Flags;<br>
          <br>
             if (Options.Verbose) {<br>
          @@ -724,7 +701,7 @@ unsigned
          DwarfLinker::shouldKeepSubprogramDIE(<br>
             }<br>
          <br>
             // Replace the debug map range with a more accurate one.<br>
          -  Ranges[*LowPc] = DebugMapObjectRange(*HighPc,
          MyInfo.AddrAdjust);<br>
          +  Ranges[*LowPc] = ObjFileAddressRange(*HighPc,
          MyInfo.AddrAdjust);<br>
             Unit.addFunctionRange(*LowPc, *HighPc, MyInfo.AddrAdjust);<br>
             return Flags;<br>
           }<br>
          @@ -1651,7 +1628,8 @@ DIE *DwarfLinker::DIECloner::cloneDIE(<br>
             Data =<br>
                 DWARFDataExtractor(DIECopy, Data.isLittleEndian(),
          Data.getAddressSize());<br>
             // Modify the copy with relocated addresses.<br>
          -  if (RelocMgr.applyValidRelocs(DIECopy, Offset,
          Data.isLittleEndian())) {<br>
          +  if (RelocMgr.areRelocationsResolved() &&<br>
          +      RelocMgr.applyValidRelocs(DIECopy, Offset,
          Data.isLittleEndian())) {<br>
               // If we applied relocations, we store the value of
          high_pc that was<br>
               // potentially stored in the input DIE. If high_pc is an
          address<br>
               // (Dwarf version == 2), then it might have been
          relocated to a<br>
          @@ -2393,7 +2371,7 @@ Error DwarfLinker::loadClangModule(<br>
          <br>
             // Setup access to the debug info.<br>
             auto DwarfContext = DWARFContext::create(*ErrOrObj);<br>
          -  RelocationManager RelocMgr(*this);<br>
          +  RelocationManager RelocMgr(*this, *ErrOrObj, DMO);<br>
          <br>
             for (const auto &CU : DwarfContext->compile_units())
          {<br>
               updateDwarfVersion(CU->getVersion());<br>
          @@ -2774,8 +2752,7 @@ bool DwarfLinker::link(const DebugMap
          &Map) {<br>
               // Look for relocations that correspond to debug map
          entries.<br>
          <br>
               if (LLVM_LIKELY(!Options.Update) &&<br>
          -        !LinkContext.RelocMgr.findValidRelocsInDebugInfo(<br>
          -            *LinkContext.ObjectFile, LinkContext.DMO)) {<br>
          +        !LinkContext.RelocMgr->hasValidRelocs()) {<br>
                 if (Options.Verbose)<br>
                   outs() << "No valid relocations found.
          Skipping.\n";<br>
          <br>
          @@ -2892,7 +2869,7 @@ bool DwarfLinker::link(const DebugMap
          &Map) {<br>
               
           Streamer->copyInvariantDebugSection(*LinkContext.ObjectFile);<br>
               } else {<br>
                 for (auto &CurrentUnit : LinkContext.CompileUnits)<br>
          -        lookForDIEsToKeep(LinkContext.RelocMgr,
          LinkContext.Ranges,<br>
          +        lookForDIEsToKeep(*LinkContext.RelocMgr,
          LinkContext.Ranges,<br>
                                     LinkContext.CompileUnits,<br>
                                   
           CurrentUnit->getOrigUnit().getUnitDIE(),<br>
                                     LinkContext.DMO, *CurrentUnit, 0);<br>
          @@ -2901,10 +2878,9 @@ bool DwarfLinker::link(const DebugMap
          &Map) {<br>
               // The calls to applyValidRelocs inside cloneDIE will
          walk the reloc<br>
               // array again (in the same way
          findValidRelocsInDebugInfo() did). We<br>
               // need to reset the NextValidReloc index to the
          beginning.<br>
          -    LinkContext.RelocMgr.resetValidRelocs();<br>
          -    if (LinkContext.RelocMgr.hasValidRelocs() ||
          LLVM_UNLIKELY(Options.Update))<br>
          -      DIECloner(*this, LinkContext.RelocMgr, DIEAlloc,
          LinkContext.CompileUnits,<br>
          -                Options)<br>
          +    if (LinkContext.RelocMgr->hasValidRelocs() ||
          LLVM_UNLIKELY(Options.Update))<br>
          +      DIECloner(*this, *LinkContext.RelocMgr, DIEAlloc,<br>
          +                LinkContext.CompileUnits, Options)<br>
                     .cloneAllCompileUnits(*LinkContext.DwarfContext,
          LinkContext.DMO,<br>
                                           LinkContext.Ranges,
          OffsetsStringPool,<br>
                                         
           LinkContext.DwarfContext->isLittleEndian());<br>
          <br>
          diff  --git a/llvm/tools/dsymutil/DwarfLinker.h
          b/llvm/tools/dsymutil/DwarfLinker.h<br>
          index b8d8e9d02e32..748377f802b3 100644<br>
          --- a/llvm/tools/dsymutil/DwarfLinker.h<br>
          +++ b/llvm/tools/dsymutil/DwarfLinker.h<br>
          @@ -10,33 +10,17 @@<br>
           #define LLVM_TOOLS_DSYMUTIL_DWARFLINKER_H<br>
          <br>
           #include "BinaryHolder.h"<br>
          -#include "CompileUnit.h"<br>
           #include "DebugMap.h"<br>
          -#include "DeclContext.h"<br>
           #include "DwarfStreamer.h"<br>
           #include "LinkUtils.h"<br>
           #include "llvm/DebugInfo/DWARF/DWARFContext.h"<br>
          +#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"<br>
          +#include "llvm/DebugInfo/DWARF/DWARFOptDeclContext.h"<br>
          +#include "llvm/DebugInfo/DWARF/DWARFOptimizer.h"<br>
          <br>
           namespace llvm {<br>
           namespace dsymutil {<br>
          <br>
          -/// Partial address range for debug map objects. Besides an
          offset, only the<br>
          -/// HighPC is stored. The structure is stored in a map where
          the LowPC is the<br>
          -/// key.<br>
          -struct DebugMapObjectRange {<br>
          -  /// Function HighPC.<br>
          -  uint64_t HighPC;<br>
          -  /// Offset to apply to the linked address.<br>
          -  int64_t Offset;<br>
          -<br>
          -  DebugMapObjectRange(uint64_t EndPC, int64_t Offset)<br>
          -      : HighPC(EndPC), Offset(Offset) {}<br>
          -<br>
          -  DebugMapObjectRange() : HighPC(0), Offset(0) {}<br>
          -};<br>
          -<br>
          -/// Map LowPC to DebugMapObjectRange.<br>
          -using RangesTy = std::map<uint64_t,
          DebugMapObjectRange>;<br>
           using UnitListTy =
          std::vector<std::unique_ptr<CompileUnit>>;<br>
          <br>
           /// The core of the Dwarf linking logic.<br>
          @@ -89,7 +73,7 @@ class DwarfLinker {<br>
                                         OffsetsStringPool
          &StringPool);<br>
          <br>
             /// Keeps track of relocations.<br>
          -  class RelocationManager {<br>
          +  class RelocationManager : public AddressesMap {<br>
               struct ValidReloc {<br>
                 uint64_t Offset;<br>
                 uint32_t Size;<br>
          @@ -117,13 +101,50 @@ class DwarfLinker {<br>
               /// cheap lookup during the root DIE selection and during
          DIE cloning.<br>
               unsigned NextValidReloc = 0;<br>
          <br>
          +    RangesTy AddressRanges;<br>
          +<br>
             public:<br>
          -    RelocationManager(DwarfLinker &Linker) :
          Linker(Linker) {}<br>
          +    RelocationManager(DwarfLinker &Linker, const
          object::ObjectFile &Obj,<br>
          +                      const DebugMapObject &DMO)<br>
          +        : Linker(Linker) {<br>
          +      findValidRelocsInDebugInfo(Obj, DMO);<br>
          +<br>
          +      // Iterate over the debug map entries and put all the
          ones that are<br>
          +      // functions (because they have a size) into the Ranges
          map. This map is<br>
          +      // very similar to the FunctionRanges that are stored
          in each unit, with 2<br>
          +      // notable <br>
          diff erences:<br>
          +      //<br>
          +      //  1. Obviously this one is global, while the other
          ones are per-unit.<br>
          +      //<br>
          +      //  2. This one contains not only the functions
          described in the DIE<br>
          +      //     tree, but also the ones that are only in the
          debug map.<br>
          +      //<br>
          +      // The latter information is required to reproduce
          dsymutil's logic while<br>
          +      // linking line tables. The cases where this
          information matters look like<br>
          +      // bugs that need to be investigated, but for now we
          need to reproduce<br>
          +      // dsymutil's behavior.<br>
          +      // FIXME: Once we understood exactly if that
          information is needed,<br>
          +      // maybe totally remove this (or try to use it to do a
          real<br>
          +      // -gline-tables-only on Darwin.<br>
          +      for (const auto &Entry : DMO.symbols()) {<br>
          +        const auto &Mapping = Entry.getValue();<br>
          +        if (Mapping.Size && Mapping.ObjectAddress)<br>
          +          AddressRanges[*Mapping.ObjectAddress] =
          ObjFileAddressRange(<br>
          +              *Mapping.ObjectAddress + Mapping.Size,<br>
          +              int64_t(Mapping.BinaryAddress) -
          *Mapping.ObjectAddress);<br>
          +      }<br>
          +    }<br>
          +    virtual ~RelocationManager () override {<br>
          +        clear();<br>
          +    }<br>
          <br>
          -    bool hasValidRelocs() const { return
          !ValidRelocs.empty(); }<br>
          +    virtual bool areRelocationsResolved() const override {
          return true; }<br>
          <br>
          -    /// Reset the NextValidReloc counter.<br>
          -    void resetValidRelocs() { NextValidReloc = 0; }<br>
          +    bool hasValidRelocs(bool resetRelocsPtr = true) override
          {<br>
          +      if (resetRelocsPtr)<br>
          +        NextValidReloc = 0;<br>
          +      return !ValidRelocs.empty();<br>
          +    }<br>
          <br>
               /// \defgroup FindValidRelocations Translate debug map
          into a list<br>
               /// of relevant relocations<br>
          @@ -141,32 +162,43 @@ class DwarfLinker {<br>
                                         const DebugMapObject &DMO);<br>
               /// @}<br>
          <br>
          -    bool hasValidRelocation(uint64_t StartOffset, uint64_t
          EndOffset,<br>
          -                            CompileUnit::DIEInfo &Info);<br>
          +    bool hasValidRelocationAt(uint64_t StartOffset, uint64_t
          EndOffset,<br>
          +                              CompileUnit::DIEInfo &Info)
          override;<br>
          <br>
               bool applyValidRelocs(MutableArrayRef<char> Data,
          uint64_t BaseOffset,<br>
          -                          bool IsLittleEndian);<br>
          +                          bool IsLittleEndian) override;<br>
          +<br>
          +    RangesTy &getValidAddressRanges() override { return
          AddressRanges; }<br>
          +<br>
          +    void clear() override {<br>
          +      AddressRanges.clear();<br>
          +      ValidRelocs.clear();<br>
          +      NextValidReloc = 0;<br>
          +    }<br>
             };<br>
          <br>
             /// Keeps track of data associated with one object during
          linking.<br>
             struct LinkContext {<br>
          +    DwarfLinker &Linker;<br>
               DebugMapObject &DMO;<br>
          -    const object::ObjectFile *ObjectFile;<br>
          -    RelocationManager RelocMgr;<br>
          +    const object::ObjectFile *ObjectFile = nullptr;<br>
          +    std::unique_ptr<RelocationManager> RelocMgr;<br>
               std::unique_ptr<DWARFContext> DwarfContext;<br>
               RangesTy Ranges;<br>
               UnitListTy CompileUnits;<br>
          <br>
               LinkContext(const DebugMap &Map, DwarfLinker
          &Linker, DebugMapObject &DMO)<br>
          -        : DMO(DMO), RelocMgr(Linker) {<br>
          +        : Linker(Linker), DMO(DMO) {<br>
                 // Swift ASTs are not object files.<br>
                 if (DMO.getType() == MachO::N_AST) {<br>
                   ObjectFile = nullptr;<br>
                   return;<br>
                 }<br>
          -      auto ErrOrObj = Linker.loadObject(DMO, Map);<br>
          -      ObjectFile = ErrOrObj ? &*ErrOrObj : nullptr;<br>
          -      DwarfContext = ObjectFile ?
          DWARFContext::create(*ObjectFile) : nullptr;<br>
          +      if (auto ErrOrObj = Linker.loadObject(DMO, Map)) {<br>
          +        ObjectFile = &*ErrOrObj;<br>
          +        DwarfContext = DWARFContext::create(*ObjectFile);<br>
          +        RelocMgr.reset(new RelocationManager(Linker,
          *ObjectFile, DMO));<br>
          +      }<br>
               }<br>
          <br>
               /// Clear part of the context that's no longer needed
          when we're done with<br>
          @@ -175,6 +207,7 @@ class DwarfLinker {<br>
                 DwarfContext.reset(nullptr);<br>
                 CompileUnits.clear();<br>
                 Ranges.clear();<br>
          +      RelocMgr->clear();<br>
               }<br>
             };<br>
          <br>
          <br>
          diff  --git a/llvm/tools/dsymutil/DwarfStreamer.cpp
          b/llvm/tools/dsymutil/DwarfStreamer.cpp<br>
          index 8747aee458fd..33dc9fc850b5 100644<br>
          --- a/llvm/tools/dsymutil/DwarfStreamer.cpp<br>
          +++ b/llvm/tools/dsymutil/DwarfStreamer.cpp<br>
          @@ -7,11 +7,11 @@<br>
 //===----------------------------------------------------------------------===//<br>
          <br>
           #include "DwarfStreamer.h"<br>
          -#include "CompileUnit.h"<br>
           #include "LinkUtils.h"<br>
           #include "MachOUtils.h"<br>
           #include "llvm/ADT/Triple.h"<br>
           #include "llvm/DebugInfo/DWARF/DWARFContext.h"<br>
          +#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"<br>
           #include "llvm/MC/MCTargetOptions.h"<br>
           #include "llvm/MC/MCTargetOptionsCommandFlags.inc"<br>
           #include "llvm/Support/LEB128.h"<br>
          <br>
          diff  --git a/llvm/tools/dsymutil/DwarfStreamer.h
          b/llvm/tools/dsymutil/DwarfStreamer.h<br>
          index baf215ac1315..85e3d48b7581 100644<br>
          --- a/llvm/tools/dsymutil/DwarfStreamer.h<br>
          +++ b/llvm/tools/dsymutil/DwarfStreamer.h<br>
          @@ -9,7 +9,6 @@<br>
           #ifndef LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H<br>
           #define LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H<br>
          <br>
          -#include "CompileUnit.h"<br>
           #include "DebugMap.h"<br>
           #include "LinkUtils.h"<br>
           #include "llvm/CodeGen/AccelTable.h"<br>
          @@ -17,6 +16,7 @@<br>
           #include "llvm/CodeGen/NonRelocatableStringpool.h"<br>
           #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"<br>
           #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"<br>
          +#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"<br>
           #include "llvm/MC/MCAsmBackend.h"<br>
           #include "llvm/MC/MCAsmInfo.h"<br>
           #include "llvm/MC/MCCodeEmitter.h"<br>
          <br>
          <br>
          <br>
          _______________________________________________<br>
          llvm-commits mailing list<br>
          <a href="mailto:llvm-commits@lists.llvm.org" target="_blank"
            moz-do-not-send="true">llvm-commits@lists.llvm.org</a><br>
          <a
            href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
        </blockquote>
      </div>
    </blockquote>
  </body>
</html>