[llvm] b384736 - Revert "[JITLink][NFC] Add TableManager to replace PerGraph...Builder pass"

via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 6 06:34:34 PDT 2021


Author: luxufan
Date: 2021-10-06T21:34:18+08:00
New Revision: b384736b205ecc96a906683076aa9f4b337e03b0

URL: https://github.com/llvm/llvm-project/commit/b384736b205ecc96a906683076aa9f4b337e03b0
DIFF: https://github.com/llvm/llvm-project/commit/b384736b205ecc96a906683076aa9f4b337e03b0.diff

LOG: Revert "[JITLink][NFC] Add TableManager to replace PerGraph...Builder pass"

This reverts commit 50a278c2aef21bf9b78865ad7c7554e506434b9c.

Added: 
    llvm/lib/ExecutionEngine/JITLink/PerGraphTLSInfoEntryBuilder.h

Modified: 
    llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
    llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp

Removed: 
    llvm/lib/ExecutionEngine/JITLink/TableManager.h


################################################################################
diff  --git a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
index 7fdbc2d67bf47..3bd9d6c979834 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
@@ -1688,30 +1688,6 @@ Error markAllSymbolsLive(LinkGraph &G);
 Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B,
                                 const Edge &E);
 
-static void visitEdge(LinkGraph &G, Block *B, Edge &E) {}
-
-template <typename FixerT, typename... FixerTs>
-static void visitEdge(LinkGraph &G, Block *B, Edge &E, FixerT &&Fixer,
-                      FixerTs &&...Fixers) {
-  if (!Fixer.visitEdge(G, B, E))
-    visitEdge(G, B, E, std::forward<FixerTs>(Fixers)...);
-}
-
-/// Visits edges exist in graph by Fixers.
-///
-/// Note: that if a fixer fixes the edge successfully,
-/// the rest of the fixers will not visit this edge.
-template <typename... FixerTs>
-void visitExistingEdges(LinkGraph &G, FixerTs &&...Fixers) {
-  // We're going to be adding new blocks, but we don't want to iterate over
-  // the new ones, so build a worklist.
-  std::vector<Block *> Worklist(G.blocks().begin(), G.blocks().end());
-
-  for (auto *B : Worklist)
-    for (auto &E : B->edges())
-      visitEdge(G, B, E, std::forward<FixerTs>(Fixers)...);
-}
-
 /// Create a LinkGraph from the given object buffer.
 ///
 /// Note: The graph does not take ownership of the underlying buffer, nor copy

diff  --git a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
index 11efd20cad2c2..0a50f40ff9eb4 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
@@ -21,7 +21,7 @@
 #include "ELFLinkGraphBuilder.h"
 #include "JITLinkGeneric.h"
 #include "PerGraphGOTAndPLTStubsBuilder.h"
-#include "TableManager.h"
+#include "PerGraphTLSInfoEntryBuilder.h"
 
 #define DEBUG_TYPE "jitlink"
 
@@ -35,109 +35,148 @@ constexpr StringRef ELFGOTSectionName = "$__GOT";
 constexpr StringRef ELFGOTSymbolName = "_GLOBAL_OFFSET_TABLE_";
 constexpr StringRef ELFTLSInfoSectionName = "$__TLSINFO";
 
-class GOTTableManager_ELF_x86_64
-    : public TableManager<GOTTableManager_ELF_x86_64> {
+class PerGraphTLSInfoBuilder_ELF_x86_64
+    : public PerGraphTLSInfoEntryBuilder<PerGraphTLSInfoBuilder_ELF_x86_64> {
+public:
+  static const uint8_t TLSInfoEntryContent[16];
+  using PerGraphTLSInfoEntryBuilder<
+      PerGraphTLSInfoBuilder_ELF_x86_64>::PerGraphTLSInfoEntryBuilder;
+
+  bool isTLSEdgeToFix(Edge &E) {
+    return E.getKind() == x86_64::RequestTLSDescInGOTAndTransformToDelta32;
+  }
+
+  Symbol &createTLSInfoEntry(Symbol &Target) {
+    // the TLS Info entry's key value will be written by the fixTLVSectionByName
+    // pass, so create mutable content.
+    auto &TLSInfoEntry = G.createMutableContentBlock(
+        getTLSInfoSection(), G.allocateContent(getTLSInfoEntryContent()), 0, 8,
+        0);
+    TLSInfoEntry.addEdge(x86_64::Pointer64, 8, Target, 0);
+    return G.addAnonymousSymbol(TLSInfoEntry, 0, 16, false, false);
+  }
+
+  void fixTLSEdge(Edge &E, Symbol &Target) {
+    if (E.getKind() == x86_64::RequestTLSDescInGOTAndTransformToDelta32) {
+      E.setTarget(Target);
+      E.setKind(x86_64::Delta32);
+    }
+  }
+
+  Section &getTLSInfoSection() const {
+    if (!TLSInfoSection)
+      TLSInfoSection =
+          &G.createSection(ELFTLSInfoSectionName, sys::Memory::MF_READ);
+    return *TLSInfoSection;
+  }
+
+private:
+  ArrayRef<char> getTLSInfoEntryContent() {
+    return {reinterpret_cast<const char *>(TLSInfoEntryContent),
+            sizeof(TLSInfoEntryContent)};
+  }
+
+  mutable Section *TLSInfoSection = nullptr;
+};
+
+const uint8_t PerGraphTLSInfoBuilder_ELF_x86_64::TLSInfoEntryContent[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*pthread key */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /*data address*/
+};
+
+class PerGraphGOTAndPLTStubsBuilder_ELF_x86_64
+    : public PerGraphGOTAndPLTStubsBuilder<
+          PerGraphGOTAndPLTStubsBuilder_ELF_x86_64> {
 public:
   static const uint8_t NullGOTEntryContent[8];
+  static const uint8_t StubContent[6];
 
-  // Nice name for table
-  StringRef getTableName() { return "GOT"; }
+  using PerGraphGOTAndPLTStubsBuilder<
+      PerGraphGOTAndPLTStubsBuilder_ELF_x86_64>::PerGraphGOTAndPLTStubsBuilder;
 
-  bool fixEdgeKind(LinkGraph &G, Block *B, Edge &E) {
-    Edge::Kind KindToSet = E.getKind();
-    switch (E.getKind()) {
-    case x86_64::Delta64FromGOT: {
-      // we need to make sure that the GOT section exists, but don't otherwise
-      // need to fix up this edge
-      getGOTSection(G);
+  bool isGOTEdgeToFix(Edge &E) const {
+    if (E.getKind() == x86_64::Delta64FromGOT) {
+      // We need to make sure that the GOT section exists, but don't otherwise
+      // need to fix up this edge.
+      getGOTSection();
       return false;
     }
+    return E.getKind() == x86_64::RequestGOTAndTransformToDelta32 ||
+           E.getKind() == x86_64::RequestGOTAndTransformToDelta64 ||
+           E.getKind() ==
+               x86_64::RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable ||
+           E.getKind() == x86_64::RequestGOTAndTransformToDelta64FromGOT ||
+           E.getKind() ==
+               x86_64::RequestGOTAndTransformToPCRel32GOTLoadRelaxable;
+  }
+
+  Symbol &createGOTEntry(Symbol &Target) {
+    auto &GOTEntryBlock = G.createContentBlock(
+        getGOTSection(), getGOTEntryBlockContent(), 0, 8, 0);
+    GOTEntryBlock.addEdge(x86_64::Pointer64, 0, Target, 0);
+    return G.addAnonymousSymbol(GOTEntryBlock, 0, 8, false, false);
+  }
+
+  void fixGOTEdge(Edge &E, Symbol &GOTEntry) {
+    // If this is a PCRel32GOT/PCRel64GOT then change it to an ordinary
+    // PCRel32/PCRel64. If it is a PCRel32GOTLoad then leave it as-is for now:
+    // We will use the kind to check for GOT optimization opportunities in the
+    // optimizeMachO_x86_64_GOTAndStubs pass below.
+    // If it's a GOT64 leave it as is.
+    switch (E.getKind()) {
     case x86_64::RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable:
-      KindToSet = x86_64::PCRel32GOTLoadREXRelaxable;
+      E.setKind(x86_64::PCRel32GOTLoadREXRelaxable);
       break;
     case x86_64::RequestGOTAndTransformToPCRel32GOTLoadRelaxable:
-      KindToSet = x86_64::PCRel32GOTLoadRelaxable;
+      E.setKind(x86_64::PCRel32GOTLoadRelaxable);
       break;
     case x86_64::RequestGOTAndTransformToDelta64:
-      KindToSet = x86_64::Delta64;
+      E.setKind(x86_64::Delta64);
       break;
     case x86_64::RequestGOTAndTransformToDelta64FromGOT:
-      KindToSet = x86_64::Delta64FromGOT;
+      E.setKind(x86_64::Delta64FromGOT);
       break;
     case x86_64::RequestGOTAndTransformToDelta32:
-      KindToSet = x86_64::Delta32;
+      E.setKind(x86_64::Delta32);
       break;
     default:
-      return false;
+      llvm_unreachable("Unexpected GOT edge kind");
     }
-    LLVM_DEBUG({
-      dbgs() << "  Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
-             << formatv("{0:x}", B->getFixupAddress(E)) << " ("
-             << formatv("{0:x}", B->getAddress()) << " + "
-             << formatv("{0:x}", E.getOffset()) << ")\n";
-    });
-    E.setKind(KindToSet);
-    return true;
-  }
-
-  Symbol &createEntry(LinkGraph &G, Symbol &Target) {
-    auto &GOTEntryBlock = G.createContentBlock(
-        getGOTSection(G), getGOTEntryBlockContent(), 0, 8, 0);
-    GOTEntryBlock.addEdge(x86_64::Pointer64, 0, Target, 0);
-    return G.addAnonymousSymbol(GOTEntryBlock, 0, 8, false, false);
-  }
 
-private:
-  Section &getGOTSection(LinkGraph &G) {
-    if (!GOTSection)
-      GOTSection = &G.createSection(ELFGOTSectionName, sys::Memory::MF_READ);
-    return *GOTSection;
+    E.setTarget(GOTEntry);
+    // Leave the edge addend as-is.
   }
-  ArrayRef<char> getGOTEntryBlockContent() const {
-    return {reinterpret_cast<const char *>(NullGOTEntryContent),
-            sizeof(NullGOTEntryContent)};
-  }
-  Section *GOTSection = nullptr;
-};
-const uint8_t GOTTableManager_ELF_x86_64::NullGOTEntryContent[8] = {
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-class PLTTableManager_ELF_x86_64
-    : public TableManager<PLTTableManager_ELF_x86_64> {
-public:
-  PLTTableManager_ELF_x86_64(GOTTableManager_ELF_x86_64 &GOTTable)
-      : GOTTable(GOTTable) {}
-
-  StringRef getTableName() { return "PLT"; }
 
-  static const uint8_t StubContent[6];
-  bool fixEdgeKind(LinkGraph &G, Block *B, Edge &E) {
-    if (E.getKind() == x86_64::BranchPCRel32 && !E.getTarget().isDefined()) {
-      LLVM_DEBUG({
-        dbgs() << "  Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
-               << formatv("{0:x}", B->getFixupAddress(E)) << " ("
-               << formatv("{0:x}", B->getAddress()) << " + "
-               << formatv("{0:x}", E.getOffset()) << ")\n";
-      });
-      // Set the edge kind to Branch32ToPtrJumpStubBypassable to enable it to
-      // be optimized when the target is in-range.
-      E.setKind(x86_64::BranchPCRel32ToPtrJumpStubBypassable);
-      return true;
-    }
-    return false;
+  bool isExternalBranchEdge(Edge &E) {
+    return E.getKind() == x86_64::BranchPCRel32 && !E.getTarget().isDefined();
   }
 
-  Symbol &createEntry(LinkGraph &G, Symbol &Target) {
-    auto &StubContentBlock = G.createContentBlock(
-        getStubsSection(G), getStubBlockContent(), 0, 1, 0);
+  Symbol &createPLTStub(Symbol &Target) {
+    auto &StubContentBlock =
+        G.createContentBlock(getStubsSection(), getStubBlockContent(), 0, 1, 0);
     // Re-use GOT entries for stub targets.
-    auto &GOTEntrySymbol = GOTTable.getEntryForTarget(G, Target);
+    auto &GOTEntrySymbol = getGOTEntry(Target);
     StubContentBlock.addEdge(x86_64::Delta32, 2, GOTEntrySymbol, -4);
     return G.addAnonymousSymbol(StubContentBlock, 0, 6, true, false);
   }
 
+  void fixPLTEdge(Edge &E, Symbol &Stub) {
+    assert(E.getKind() == x86_64::BranchPCRel32 && "Not a Branch32 edge?");
+
+    // Set the edge kind to Branch32ToPtrJumpStubBypassable to enable it to be
+    // optimized when the target is in-range.
+    E.setKind(x86_64::BranchPCRel32ToPtrJumpStubBypassable);
+    E.setTarget(Stub);
+  }
+
 private:
-  Section &getStubsSection(LinkGraph &G) {
+  Section &getGOTSection() const {
+    if (!GOTSection)
+      GOTSection = &G.createSection(ELFGOTSectionName, sys::Memory::MF_READ);
+    return *GOTSection;
+  }
+
+  Section &getStubsSection() const {
     if (!StubsSection) {
       auto StubsProt = static_cast<sys::Memory::ProtectionFlags>(
           sys::Memory::MF_READ | sys::Memory::MF_EXEC);
@@ -146,79 +185,26 @@ class PLTTableManager_ELF_x86_64
     return *StubsSection;
   }
 
-  ArrayRef<char> getStubBlockContent() {
-    return {reinterpret_cast<const char *>(StubContent), sizeof(StubContent)};
-  }
-
-  Section *StubsSection = nullptr;
-  GOTTableManager_ELF_x86_64 &GOTTable;
-};
-const uint8_t PLTTableManager_ELF_x86_64::StubContent[6] = {0xFF, 0x25, 0x00,
-                                                            0x00, 0x00, 0x00};
-
-class TLSInfoTableManager_ELF_x86_64
-    : public TableManager<TLSInfoTableManager_ELF_x86_64> {
-public:
-  static const uint8_t TLSInfoEntryContent[16];
-
-  StringRef getTableName() { return "TLSInfo"; }
-
-  bool fixEdgeKind(LinkGraph &G, Block *B, Edge &E) {
-    if (E.getKind() == x86_64::RequestTLSDescInGOTAndTransformToDelta32) {
-      LLVM_DEBUG({
-        dbgs() << "  Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
-               << formatv("{0:x}", B->getFixupAddress(E)) << " ("
-               << formatv("{0:x}", B->getAddress()) << " + "
-               << formatv("{0:x}", E.getOffset()) << ")\n";
-      });
-      E.setKind(x86_64::Delta32);
-      return true;
-    }
-    return false;
-  }
-
-  Symbol &createEntry(LinkGraph &G, Symbol &Target) {
-    // the TLS Info entry's key value will be written by the fixTLVSectionByName
-    // pass, so create mutable content.
-    auto &TLSInfoEntry = G.createMutableContentBlock(
-        getTLSInfoSection(G), G.allocateContent(getTLSInfoEntryContent()), 0, 8,
-        0);
-    TLSInfoEntry.addEdge(x86_64::Pointer64, 8, Target, 0);
-    return G.addAnonymousSymbol(TLSInfoEntry, 0, 16, false, false);
-  }
-
-private:
-  Section &getTLSInfoSection(LinkGraph &G) {
-    if (!TLSInfoTable)
-      TLSInfoTable =
-          &G.createSection(ELFTLSInfoSectionName, sys::Memory::MF_READ);
-    return *TLSInfoTable;
+  ArrayRef<char> getGOTEntryBlockContent() {
+    return {reinterpret_cast<const char *>(NullGOTEntryContent),
+            sizeof(NullGOTEntryContent)};
   }
 
-  ArrayRef<char> getTLSInfoEntryContent() const {
-    return {reinterpret_cast<const char *>(TLSInfoEntryContent),
-            sizeof(TLSInfoEntryContent)};
+  ArrayRef<char> getStubBlockContent() {
+    return {reinterpret_cast<const char *>(StubContent), sizeof(StubContent)};
   }
 
-  Section *TLSInfoTable = nullptr;
-};
-
-const uint8_t TLSInfoTableManager_ELF_x86_64::TLSInfoEntryContent[16] = {
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*pthread key */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /*data address*/
+  mutable Section *GOTSection = nullptr;
+  mutable Section *StubsSection = nullptr;
 };
 
-Error buildTables_ELF_x86_64(LinkGraph &G) {
-  LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n");
-
-  GOTTableManager_ELF_x86_64 GOT;
-  PLTTableManager_ELF_x86_64 PLT(GOT);
-  TLSInfoTableManager_ELF_x86_64 TLSInfo;
-  visitExistingEdges(G, GOT, PLT, TLSInfo);
-  return Error::success();
-}
 } // namespace
 
+const uint8_t PerGraphGOTAndPLTStubsBuilder_ELF_x86_64::NullGOTEntryContent[8] =
+    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+const uint8_t PerGraphGOTAndPLTStubsBuilder_ELF_x86_64::StubContent[6] = {
+    0xFF, 0x25, 0x00, 0x00, 0x00, 0x00};
+
 static const char *getELFX86_64RelocName(uint32_t Type) {
   switch (Type) {
 #define ELF_RELOC(Name, Number)                                                \
@@ -511,8 +497,11 @@ void link_ELF_x86_64(std::unique_ptr<LinkGraph> G,
     else
       Config.PrePrunePasses.push_back(markAllSymbolsLive);
 
-    // Add an in-place GOT/Stubs/TLSInfoEntry build pass.
-    Config.PostPrunePasses.push_back(buildTables_ELF_x86_64);
+    // Add an in-place GOT/Stubs pass.
+
+    Config.PostPrunePasses.push_back(PerGraphTLSInfoBuilder_ELF_x86_64::asPass);
+    Config.PostPrunePasses.push_back(
+        PerGraphGOTAndPLTStubsBuilder_ELF_x86_64::asPass);
 
     // Resolve any external section start / end symbols.
     Config.PostAllocationPasses.push_back(

diff  --git a/llvm/lib/ExecutionEngine/JITLink/PerGraphTLSInfoEntryBuilder.h b/llvm/lib/ExecutionEngine/JITLink/PerGraphTLSInfoEntryBuilder.h
new file mode 100644
index 0000000000000..3eea8eb8d0da1
--- /dev/null
+++ b/llvm/lib/ExecutionEngine/JITLink/PerGraphTLSInfoEntryBuilder.h
@@ -0,0 +1,78 @@
+//===---------------- PerGraphTLSInfoEntryBuilder.h -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Construct Thread local storage info entry for each graph.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_JITLINK_PERGRAPHTLSINFOENTRYBUILDER_H
+#define LLVM_EXECUTIONENGINE_JITLINK_PERGRAPHTLSINFOENTRYBUILDER_H
+
+#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "jitlink"
+namespace llvm {
+namespace jitlink {
+
+template <typename BuilderImplT> class PerGraphTLSInfoEntryBuilder {
+public:
+  PerGraphTLSInfoEntryBuilder(LinkGraph &G) : G(G) {}
+  static Error asPass(LinkGraph &G) { return BuilderImplT(G).run(); }
+
+  Error run() {
+    LLVM_DEBUG(dbgs() << "Running Per-Graph TLS Info entry builder:\n ");
+
+    std::vector<Block *> Worklist(G.blocks().begin(), G.blocks().end());
+
+    for (auto *B : Worklist)
+      for (auto &E : B->edges()) {
+        if (impl().isTLSEdgeToFix(E)) {
+          LLVM_DEBUG({
+            dbgs() << "  Fixing " << G.getEdgeKindName(E.getKind())
+                   << " edge at " << formatv("{0:x}", B->getFixupAddress(E))
+                   << " (" << formatv("{0:x}", B->getAddress()) << " + "
+                   << formatv("{0:x}", E.getOffset()) << ")\n";
+          });
+          impl().fixTLSEdge(E, getTLSInfoEntry(E.getTarget()));
+        }
+      }
+    return Error::success();
+  }
+
+protected:
+  LinkGraph &G;
+
+  Symbol &getTLSInfoEntry(Symbol &Target) {
+    assert(Target.hasName() && "TLS edge cannot point to anonymous target");
+    auto TLSInfoEntryI = TLSInfoEntries.find(Target.getName());
+    if (TLSInfoEntryI == TLSInfoEntries.end()) {
+      auto &TLSInfoEntry = impl().createTLSInfoEntry(Target);
+      LLVM_DEBUG({
+        dbgs() << "    Created TLS Info entry for " << Target.getName() << ": "
+               << TLSInfoEntry << "\n";
+      });
+      TLSInfoEntryI =
+          TLSInfoEntries.insert(std::make_pair(Target.getName(), &TLSInfoEntry))
+              .first;
+    }
+    assert(TLSInfoEntryI != TLSInfoEntries.end() &&
+           "Could not get TLSInfo symbol");
+    LLVM_DEBUG({
+      dbgs() << "    Using TLS Info entry" << *TLSInfoEntryI->second << "\n";
+    });
+    return *TLSInfoEntryI->second;
+  }
+
+private:
+  DenseMap<StringRef, Symbol *> TLSInfoEntries;
+  BuilderImplT &impl() { return static_cast<BuilderImplT &>(*this); }
+};
+} // namespace jitlink
+} // namespace llvm
+#endif

diff  --git a/llvm/lib/ExecutionEngine/JITLink/TableManager.h b/llvm/lib/ExecutionEngine/JITLink/TableManager.h
deleted file mode 100644
index e03948b49b219..0000000000000
--- a/llvm/lib/ExecutionEngine/JITLink/TableManager.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//===---------------------- TableManager.h ----------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Fix edge for edge that needs an entry to reference the target symbol
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_JITLINK_TABLEMANAGER_H
-#define LLVM_EXECUTIONENGINE_JITLINK_TABLEMANAGER_H
-
-#include "llvm/ExecutionEngine/JITLink/JITLink.h"
-#include "llvm/Support/Debug.h"
-
-#define DEBUG_TYPE "jitlink"
-
-namespace llvm {
-namespace jitlink {
-
-/// Table like section manager
-template <typename TableManagerImplT> class TableManager {
-public:
-  /// Visit edge, return true if the edge was dealt with, otherwise return
-  /// false(let other managers to visit).
-  bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
-    if (impl().fixEdgeKind(G, B, E)) {
-      fixTarget(G, E);
-      return true;
-    }
-    return false;
-  }
-
-  /// Return the constructed entry
-  ///
-  /// Use parameter G to construct the entry for target symbol
-  Symbol &getEntryForTarget(LinkGraph &G, Symbol &Target) {
-    assert(Target.hasName() && "Edge cannot point to anonymous target");
-
-    auto EntryI = Entries.find(Target.getName());
-
-    // Build the entry if it doesn't exist.
-    if (EntryI == Entries.end()) {
-      auto &Entry = impl().createEntry(G, Target);
-      LLVM_DEBUG({
-        dbgs() << "    Created" << impl().getTableName() << "entry for "
-               << Target.getName() << ": " << Entry << "\n";
-      });
-      EntryI = Entries.insert(std::make_pair(Target.getName(), &Entry)).first;
-    }
-
-    assert(EntryI != Entries.end() && "Could not get entry symbol");
-    LLVM_DEBUG({
-      dbgs() << "    Using " << impl().getTableName() << " entry "
-             << *EntryI->second << "\n";
-    });
-    return *EntryI->second;
-  }
-
-private:
-  void fixTarget(LinkGraph &G, Edge &E) {
-    E.setTarget(getEntryForTarget(G, E.getTarget()));
-  }
-
-  TableManagerImplT &impl() { return static_cast<TableManagerImplT &>(*this); }
-  DenseMap<StringRef, Symbol *> Entries;
-};
-
-} // namespace jitlink
-} // namespace llvm
-
-#endif


        


More information about the llvm-commits mailing list