LLVM  14.0.0git
Speculation.h
Go to the documentation of this file.
1 //===-- Speculation.h - Speculative Compilation --*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Contains the definition to support speculative compilation when laziness is
10 // enabled.
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_EXECUTIONENGINE_ORC_SPECULATION_H
14 #define LLVM_EXECUTIONENGINE_ORC_SPECULATION_H
15 
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/Optional.h"
21 #include "llvm/Support/Debug.h"
22 #include <mutex>
23 #include <type_traits>
24 #include <utility>
25 
26 namespace llvm {
27 namespace orc {
28 
29 class Speculator;
30 
31 // Track the Impls (JITDylib,Symbols) of Symbols while lazy call through
32 // trampolines are created. Operations are guarded by locks tp ensure that Imap
33 // stays in consistent state after read/write
34 
36  friend class Speculator;
37 
38 public:
39  using AliaseeDetails = std::pair<SymbolStringPtr, JITDylib *>;
42  void trackImpls(SymbolAliasMap ImplMaps, JITDylib *SrcJD);
43 
44 private:
45  // FIX ME: find a right way to distinguish the pre-compile Symbols, and update
46  // the callsite
47  Optional<AliaseeDetails> getImplFor(const SymbolStringPtr &StubSymbol) {
48  std::lock_guard<std::mutex> Lockit(ConcurrentAccess);
49  auto Position = Maps.find(StubSymbol);
50  if (Position != Maps.end())
51  return Position->getSecond();
52  else
53  return None;
54  }
55 
56  std::mutex ConcurrentAccess;
57  ImapTy Maps;
58 };
59 
60 // Defines Speculator Concept,
61 class Speculator {
62 public:
66 
67 private:
68  void registerSymbolsWithAddr(TargetFAddr ImplAddr,
69  SymbolNameSet likelySymbols) {
70  std::lock_guard<std::mutex> Lockit(ConcurrentAccess);
71  GlobalSpecMap.insert({ImplAddr, std::move(likelySymbols)});
72  }
73 
74  void launchCompile(JITTargetAddress FAddr) {
75  SymbolNameSet CandidateSet;
76  // Copy CandidateSet is necessary, to avoid unsynchronized access to
77  // the datastructure.
78  {
79  std::lock_guard<std::mutex> Lockit(ConcurrentAccess);
80  auto It = GlobalSpecMap.find(FAddr);
81  if (It == GlobalSpecMap.end())
82  return;
83  CandidateSet = It->getSecond();
84  }
85 
86  SymbolDependenceMap SpeculativeLookUpImpls;
87 
88  for (auto &Callee : CandidateSet) {
89  auto ImplSymbol = AliaseeImplTable.getImplFor(Callee);
90  // try to distinguish already compiled & library symbols
91  if (!ImplSymbol.hasValue())
92  continue;
93  const auto &ImplSymbolName = ImplSymbol.getPointer()->first;
94  JITDylib *ImplJD = ImplSymbol.getPointer()->second;
95  auto &SymbolsInJD = SpeculativeLookUpImpls[ImplJD];
96  SymbolsInJD.insert(ImplSymbolName);
97  }
98 
99  DEBUG_WITH_TYPE("orc", {
100  for (auto &I : SpeculativeLookUpImpls) {
101  llvm::dbgs() << "\n In " << I.first->getName() << " JITDylib ";
102  for (auto &N : I.second)
103  llvm::dbgs() << "\n Likely Symbol : " << N;
104  }
105  });
106 
107  // for a given symbol, there may be no symbol qualified for speculatively
108  // compile try to fix this before jumping to this code if possible.
109  for (auto &LookupPair : SpeculativeLookUpImpls)
110  ES.lookup(
112  makeJITDylibSearchOrder(LookupPair.first,
114  SymbolLookupSet(LookupPair.second), SymbolState::Ready,
115  [this](Expected<SymbolMap> Result) {
116  if (auto Err = Result.takeError())
117  ES.reportError(std::move(Err));
118  },
120  }
121 
122 public:
124  : AliaseeImplTable(Impl), ES(ref), GlobalSpecMap(0) {}
125  Speculator(const Speculator &) = delete;
126  Speculator(Speculator &&) = delete;
127  Speculator &operator=(const Speculator &) = delete;
128  Speculator &operator=(Speculator &&) = delete;
129 
130  /// Define symbols for this Speculator object (__orc_speculator) and the
131  /// speculation runtime entry point symbol (__orc_speculate_for) in the
132  /// given JITDylib.
134 
135  // Speculatively compile likely functions for the given Stub Address.
136  // destination of __orc_speculate_for jump
137  void speculateFor(TargetFAddr StubAddr) { launchCompile(StubAddr); }
138 
139  // FIXME : Register with Stub Address, after JITLink Fix.
141  for (auto &SymPair : Candidates) {
142  auto Target = SymPair.first;
143  auto Likely = SymPair.second;
144 
145  auto OnReadyFixUp = [Likely, Target,
146  this](Expected<SymbolMap> ReadySymbol) {
147  if (ReadySymbol) {
148  auto RAddr = (*ReadySymbol)[Target].getAddress();
149  registerSymbolsWithAddr(RAddr, std::move(Likely));
150  } else
151  this->getES().reportError(ReadySymbol.takeError());
152  };
153  // Include non-exported symbols also.
154  ES.lookup(
159  }
160  }
161 
162  ExecutionSession &getES() { return ES; }
163 
164 private:
165  static void speculateForEntryPoint(Speculator *Ptr, uint64_t StubId);
166  std::mutex ConcurrentAccess;
167  ImplSymbolMap &AliaseeImplTable;
168  ExecutionSession &ES;
169  StubAddrLikelies GlobalSpecMap;
170 };
171 
172 class IRSpeculationLayer : public IRLayer {
173 public:
177 
179  Speculator &Spec, MangleAndInterner &Mangle,
181  : IRLayer(ES, BaseLayer.getManglingOptions()), NextLayer(BaseLayer),
182  S(Spec), Mangle(Mangle), QueryAnalysis(Interpreter) {}
183 
184  void emit(std::unique_ptr<MaterializationResponsibility> R,
185  ThreadSafeModule TSM) override;
186 
187 private:
189  internToJITSymbols(DenseMap<StringRef, DenseSet<StringRef>> IRNames) {
190  assert(!IRNames.empty() && "No IRNames received to Intern?");
191  TargetAndLikelies InternedNames;
192  for (auto &NamePair : IRNames) {
193  DenseSet<SymbolStringPtr> TargetJITNames;
194  for (auto &TargetNames : NamePair.second)
195  TargetJITNames.insert(Mangle(TargetNames));
196  InternedNames[Mangle(NamePair.first)] = std::move(TargetJITNames);
197  }
198  return InternedNames;
199  }
200 
201  IRCompileLayer &NextLayer;
202  Speculator &S;
203  MangleAndInterner &Mangle;
204  ResultEval QueryAnalysis;
205 };
206 
207 } // namespace orc
208 } // namespace llvm
209 
210 #endif // LLVM_EXECUTIONENGINE_ORC_SPECULATION_H
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::orc::JITDylib
Represents a JIT'd dynamic library.
Definition: Core.h:938
Optional.h
llvm::orc::ImplSymbolMap
Definition: Speculation.h:35
llvm::orc::ExecutionSession::reportError
void reportError(Error Err)
Report a error for this execution session.
Definition: Core.h:1462
llvm::orc::Speculator::speculateFor
void speculateFor(TargetFAddr StubAddr)
Definition: Speculation.h:137
llvm::orc::ImplSymbolMap::AliaseeDetails
std::pair< SymbolStringPtr, JITDylib * > AliaseeDetails
Definition: Speculation.h:39
llvm::Function
Definition: Function.h:62
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:137
llvm::orc::SymbolLookupSet
A set of symbols to look up, each associated with a SymbolLookupFlags value.
Definition: Core.h:175
llvm::orc::LookupKind::Static
@ Static
llvm::orc::SymbolStringPtr
Pointer to a pooled string representing a symbol name.
Definition: SymbolStringPool.h:50
DenseMap.h
llvm::AMDGPU::Exp::Target
Target
Definition: SIDefines.h:743
llvm::Optional
Definition: APInt.h:33
llvm::orc::IRCompileLayer
Definition: IRCompileLayer.h:31
llvm::orc::IRLayer::getManglingOptions
const IRSymbolMapper::ManglingOptions *& getManglingOptions() const
Get the mangling options for this layer.
Definition: Layer.h:79
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::detail::DenseSetImpl::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
llvm::orc::IRSpeculationLayer::ResultEval
std::function< IRlikiesStrRef(Function &)> ResultEval
Definition: Speculation.h:175
DebugUtils.h
llvm::orc::Speculator::operator=
Speculator & operator=(const Speculator &)=delete
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
DEBUG_WITH_TYPE
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Definition: Debug.h:64
llvm::orc::Speculator::Speculator
Speculator(ImplSymbolMap &Impl, ExecutionSession &ref)
Definition: Speculation.h:123
llvm::orc::IRSpeculationLayer
Definition: Speculation.h:172
llvm::orc::NoDependenciesToRegister
RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
Definition: Core.cpp:34
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::orc::Speculator::addSpeculationRuntime
Error addSpeculationRuntime(JITDylib &JD, MangleAndInterner &Mangle)
Define symbols for this Speculator object (__orc_speculator) and the speculation runtime entry point ...
Definition: Speculation.cpp:42
llvm::orc::Speculator
Definition: Speculation.h:61
DebugLocVerifyLevel::None
@ None
llvm::orc::SymbolLookupFlags::WeaklyReferencedSymbol
@ WeaklyReferencedSymbol
llvm::DenseSet< SymbolStringPtr >
IRCompileLayer.h
uint64_t
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::DenseMap< Alias, AliaseeDetails >
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::DenseMapBase::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::orc::IRSpeculationLayer::IRlikiesStrRef
Optional< DenseMap< StringRef, DenseSet< StringRef > >> IRlikiesStrRef
Definition: Speculation.h:174
llvm::orc::Speculator::registerSymbols
void registerSymbols(FunctionCandidatesMap Candidates, JITDylib *JD)
Definition: Speculation.h:140
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::orc::SymbolState::Ready
@ Ready
Emitted to memory, but waiting on transitive dependencies.
llvm::DenseMapBase::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:207
llvm::orc::IRSpeculationLayer::TargetAndLikelies
DenseMap< SymbolStringPtr, SymbolNameSet > TargetAndLikelies
Definition: Speculation.h:176
llvm::orc::SymbolDependenceMap
DenseMap< JITDylib *, SymbolNameSet > SymbolDependenceMap
A map from JITDylibs to sets of symbols.
Definition: Core.h:119
llvm::orc::MangleAndInterner
Mangles symbol names then uniques them in the context of an ExecutionSession.
Definition: Mangling.h:26
llvm::orc::ImplSymbolMap::trackImpls
void trackImpls(SymbolAliasMap ImplMaps, JITDylib *SrcJD)
Definition: Speculation.cpp:25
llvm::DenseMapBase::end
iterator end()
Definition: DenseMap.h:83
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1346
llvm::orc::Speculator::getES
ExecutionSession & getES()
Definition: Speculation.h:162
llvm::orc::Speculator::StubAddrLikelies
DenseMap< TargetFAddr, SymbolNameSet > StubAddrLikelies
Definition: Speculation.h:65
llvm::orc::IRSpeculationLayer::IRSpeculationLayer
IRSpeculationLayer(ExecutionSession &ES, IRCompileLayer &BaseLayer, Speculator &Spec, MangleAndInterner &Mangle, ResultEval Interpreter)
Definition: Speculation.h:178
llvm::JITTargetAddress
uint64_t JITTargetAddress
Represents an address in the target process's address space.
Definition: JITSymbol.h:42
Core.h
llvm::Interpreter
Definition: Interpreter.h:74
N
#define N
llvm::orc::ExecutionSession::lookup
void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder, SymbolLookupSet Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete, RegisterDependenciesFunction RegisterDependencies)
Search the given JITDylibs for the given symbols.
Definition: Core.cpp:2035
llvm::orc::ImplSymbolMap::ImapTy
DenseMap< Alias, AliaseeDetails > ImapTy
Definition: Speculation.h:41
llvm::orc::ThreadSafeModule
An LLVM Module together with a shared ThreadSafeContext.
Definition: ThreadSafeModule.h:77
llvm::orc::IRSpeculationLayer::emit
void emit(std::unique_ptr< MaterializationResponsibility > R, ThreadSafeModule TSM) override
Emit should materialize the given IR.
Definition: Speculation.cpp:58
llvm::orc::JITDylibLookupFlags::MatchAllSymbols
@ MatchAllSymbols
llvm::orc::IRLayer
Interface for layers that accept LLVM IR.
Definition: Layer.h:68
Debug.h
llvm::orc::makeJITDylibSearchOrder
JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...
Definition: Core.h:158