summaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm18/include/llvm/ExecutionEngine/JITLink/TableManager.h
blob: 8eeaa3462f94ce6473a290402235913c8e6ec753 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#pragma once

#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

//===---------------------- 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"

namespace llvm {
namespace jitlink {

/// A CRTP base for tables that are built on demand, e.g. Global Offset Tables
/// and Procedure Linkage Tables.
/// The getEntyrForTarget function returns the table entry corresponding to the
/// given target, calling down to the implementation class to build an entry if
/// one does not already exist.
template <typename TableManagerImplT> class TableManager {
public:
  /// 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);
      DEBUG_WITH_TYPE("jitlink", {
        dbgs() << "    Created " << impl().getSectionName() << " 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");
    DEBUG_WITH_TYPE("jitlink", {
      dbgs() << "    Using " << impl().getSectionName() << " entry "
             << *EntryI->second << "\n";
    });
    return *EntryI->second;
  }

  /// Register a pre-existing entry.
  ///
  /// Objects may include pre-existing table entries (e.g. for GOTs).
  /// This method can be used to register those entries so that they will not
  /// be duplicated by createEntry  the first time that getEntryForTarget is
  /// called.
  bool registerPreExistingEntry(Symbol &Target, Symbol &Entry) {
    assert(Target.hasName() && "Edge cannot point to anonymous target");
    auto Res = Entries.insert({
        Target.getName(),
        &Entry,
    });
    return Res.second;
  }

private:
  TableManagerImplT &impl() { return static_cast<TableManagerImplT &>(*this); }
  DenseMap<StringRef, Symbol *> Entries;
};

} // namespace jitlink
} // namespace llvm

#endif

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif