<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">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">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">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">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">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">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">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">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">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">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">llvm-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>