LLVM  16.0.0git
MCJIT.h
Go to the documentation of this file.
1 //===-- MCJIT.h - Class definition for the MCJIT ----------------*- 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 #ifndef LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H
10 #define LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H
11 
12 #include "llvm/ADT/SmallPtrSet.h"
13 #include "llvm/ADT/SmallVector.h"
17 
18 namespace llvm {
19 class MCJIT;
20 class Module;
21 class ObjectCache;
22 
23 // This is a helper class that the MCJIT execution engine uses for linking
24 // functions across modules that it owns. It aggregates the memory manager
25 // that is passed in to the MCJIT constructor and defers most functionality
26 // to that object.
28 public:
30  std::shared_ptr<LegacyJITSymbolResolver> Resolver)
31  : ParentEngine(Parent), ClientResolver(std::move(Resolver)) {}
32 
33  JITSymbol findSymbol(const std::string &Name) override;
34 
35  // MCJIT doesn't support logical dylibs.
36  JITSymbol findSymbolInLogicalDylib(const std::string &Name) override {
37  return nullptr;
38  }
39 
40 private:
41  MCJIT &ParentEngine;
42  std::shared_ptr<LegacyJITSymbolResolver> ClientResolver;
43  void anchor() override;
44 };
45 
46 // About Module states: added->loaded->finalized.
47 //
48 // The purpose of the "added" state is having modules in standby. (added=known
49 // but not compiled). The idea is that you can add a module to provide function
50 // definitions but if nothing in that module is referenced by a module in which
51 // a function is executed (note the wording here because it's not exactly the
52 // ideal case) then the module never gets compiled. This is sort of lazy
53 // compilation.
54 //
55 // The purpose of the "loaded" state (loaded=compiled and required sections
56 // copied into local memory but not yet ready for execution) is to have an
57 // intermediate state wherein clients can remap the addresses of sections, using
58 // MCJIT::mapSectionAddress, (in preparation for later copying to a new location
59 // or an external process) before relocations and page permissions are applied.
60 //
61 // It might not be obvious at first glance, but the "remote-mcjit" case in the
62 // lli tool does this. In that case, the intermediate action is taken by the
63 // RemoteMemoryManager in response to the notifyObjectLoaded function being
64 // called.
65 
66 class MCJIT : public ExecutionEngine {
67  MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> tm,
68  std::shared_ptr<MCJITMemoryManager> MemMgr,
69  std::shared_ptr<LegacyJITSymbolResolver> Resolver);
70 
72 
73  class OwningModuleContainer {
74  public:
75  OwningModuleContainer() = default;
76  ~OwningModuleContainer() {
77  freeModulePtrSet(AddedModules);
78  freeModulePtrSet(LoadedModules);
79  freeModulePtrSet(FinalizedModules);
80  }
81 
82  ModulePtrSet::iterator begin_added() { return AddedModules.begin(); }
83  ModulePtrSet::iterator end_added() { return AddedModules.end(); }
85  return make_range(begin_added(), end_added());
86  }
87 
88  ModulePtrSet::iterator begin_loaded() { return LoadedModules.begin(); }
89  ModulePtrSet::iterator end_loaded() { return LoadedModules.end(); }
90 
91  ModulePtrSet::iterator begin_finalized() { return FinalizedModules.begin(); }
92  ModulePtrSet::iterator end_finalized() { return FinalizedModules.end(); }
93 
94  void addModule(std::unique_ptr<Module> M) {
95  AddedModules.insert(M.release());
96  }
97 
98  bool removeModule(Module *M) {
99  return AddedModules.erase(M) || LoadedModules.erase(M) ||
100  FinalizedModules.erase(M);
101  }
102 
103  bool hasModuleBeenAddedButNotLoaded(Module *M) {
104  return AddedModules.contains(M);
105  }
106 
107  bool hasModuleBeenLoaded(Module *M) {
108  // If the module is in either the "loaded" or "finalized" sections it
109  // has been loaded.
110  return LoadedModules.contains(M) || FinalizedModules.contains(M);
111  }
112 
113  bool hasModuleBeenFinalized(Module *M) {
114  return FinalizedModules.contains(M);
115  }
116 
117  bool ownsModule(Module* M) {
118  return AddedModules.contains(M) || LoadedModules.contains(M) ||
119  FinalizedModules.contains(M);
120  }
121 
122  void markModuleAsLoaded(Module *M) {
123  // This checks against logic errors in the MCJIT implementation.
124  // This function should never be called with either a Module that MCJIT
125  // does not own or a Module that has already been loaded and/or finalized.
126  assert(AddedModules.count(M) &&
127  "markModuleAsLoaded: Module not found in AddedModules");
128 
129  // Remove the module from the "Added" set.
130  AddedModules.erase(M);
131 
132  // Add the Module to the "Loaded" set.
133  LoadedModules.insert(M);
134  }
135 
136  void markModuleAsFinalized(Module *M) {
137  // This checks against logic errors in the MCJIT implementation.
138  // This function should never be called with either a Module that MCJIT
139  // does not own, a Module that has not been loaded or a Module that has
140  // already been finalized.
141  assert(LoadedModules.count(M) &&
142  "markModuleAsFinalized: Module not found in LoadedModules");
143 
144  // Remove the module from the "Loaded" section of the list.
145  LoadedModules.erase(M);
146 
147  // Add the Module to the "Finalized" section of the list by inserting it
148  // before the 'end' iterator.
149  FinalizedModules.insert(M);
150  }
151 
152  void markAllLoadedModulesAsFinalized() {
153  for (Module *M : LoadedModules)
154  FinalizedModules.insert(M);
155  LoadedModules.clear();
156  }
157 
158  private:
159  ModulePtrSet AddedModules;
160  ModulePtrSet LoadedModules;
161  ModulePtrSet FinalizedModules;
162 
163  void freeModulePtrSet(ModulePtrSet& MPS) {
164  // Go through the module set and delete everything.
165  for (Module *M : MPS)
166  delete M;
167  MPS.clear();
168  }
169  };
170 
171  std::unique_ptr<TargetMachine> TM;
172  MCContext *Ctx;
173  std::shared_ptr<MCJITMemoryManager> MemMgr;
175  RuntimeDyld Dyld;
176  std::vector<JITEventListener*> EventListeners;
177 
178  OwningModuleContainer OwnedModules;
179 
182 
184 
185  // An optional ObjectCache to be notified of compiled objects and used to
186  // perform lookup of pre-compiled code to avoid re-compilation.
187  ObjectCache *ObjCache;
188 
189  Function *FindFunctionNamedInModulePtrSet(StringRef FnName,
192 
193  GlobalVariable *FindGlobalVariableNamedInModulePtrSet(StringRef Name,
194  bool AllowInternal,
197 
198  void runStaticConstructorsDestructorsInModulePtrSet(bool isDtors,
201 
202 public:
203  ~MCJIT() override;
204 
205  /// @name ExecutionEngine interface implementation
206  /// @{
207  void addModule(std::unique_ptr<Module> M) override;
208  void addObjectFile(std::unique_ptr<object::ObjectFile> O) override;
211  bool removeModule(Module *M) override;
212 
213  /// FindFunctionNamed - Search all of the active modules to find the function that
214  /// defines FnName. This is very slow operation and shouldn't be used for
215  /// general code.
216  Function *FindFunctionNamed(StringRef FnName) override;
217 
218  /// FindGlobalVariableNamed - Search all of the active modules to find the
219  /// global variable that defines Name. This is very slow operation and
220  /// shouldn't be used for general code.
222  bool AllowInternal = false) override;
223 
224  /// Sets the object manager that MCJIT should use to avoid compilation.
225  void setObjectCache(ObjectCache *manager) override;
226 
227  void setProcessAllSections(bool ProcessAllSections) override {
228  Dyld.setProcessAllSections(ProcessAllSections);
229  }
230 
231  void generateCodeForModule(Module *M) override;
232 
233  /// finalizeObject - ensure the module is fully processed and is usable.
234  ///
235  /// It is the user-level function for completing the process of making the
236  /// object usable for execution. It should be called after sections within an
237  /// object have been relocated using mapSectionAddress. When this method is
238  /// called the MCJIT execution engine will reapply relocations for a loaded
239  /// object.
240  /// Is it OK to finalize a set of modules, add modules and finalize again.
241  // FIXME: Do we really need both of these?
242  void finalizeObject() override;
243  virtual void finalizeModule(Module *);
244  void finalizeLoadedModules();
245 
246  /// runStaticConstructorsDestructors - This method is used to execute all of
247  /// the static constructors or destructors for a program.
248  ///
249  /// \param isDtors - Run the destructors instead of constructors.
250  void runStaticConstructorsDestructors(bool isDtors) override;
251 
252  void *getPointerToFunction(Function *F) override;
253 
255  ArrayRef<GenericValue> ArgValues) override;
256 
257  /// getPointerToNamedFunction - This method returns the address of the
258  /// specified function by using the dlsym function call. As such it is only
259  /// useful for resolving library symbols, not code generated symbols.
260  ///
261  /// If AbortOnFailure is false and no function with the given name is
262  /// found, this function silently returns a null pointer. Otherwise,
263  /// it prints a message to stderr and aborts.
264  ///
266  bool AbortOnFailure = true) override;
267 
268  /// mapSectionAddress - map a section to its target address space value.
269  /// Map the address of a JIT section as returned from the memory manager
270  /// to the address in the target process as the running code will see it.
271  /// This is the address which will be used for relocation resolution.
272  void mapSectionAddress(const void *LocalAddress,
273  uint64_t TargetAddress) override {
274  Dyld.mapSectionAddress(LocalAddress, TargetAddress);
275  }
276  void RegisterJITEventListener(JITEventListener *L) override;
278 
279  // If successful, these function will implicitly finalize all loaded objects.
280  // To get a function address within MCJIT without causing a finalize, use
281  // getSymbolAddress.
282  uint64_t getGlobalValueAddress(const std::string &Name) override;
283  uint64_t getFunctionAddress(const std::string &Name) override;
284 
285  TargetMachine *getTargetMachine() override { return TM.get(); }
286 
287  /// @}
288  /// @name (Private) Registration Interfaces
289  /// @{
290 
291  static void Register() {
293  }
294 
295  static ExecutionEngine *
296  createJIT(std::unique_ptr<Module> M, std::string *ErrorStr,
297  std::shared_ptr<MCJITMemoryManager> MemMgr,
298  std::shared_ptr<LegacyJITSymbolResolver> Resolver,
299  std::unique_ptr<TargetMachine> TM);
300 
301  // @}
302 
303  // Takes a mangled name and returns the corresponding JITSymbol (if a
304  // definition of that mangled name has been added to the JIT).
305  JITSymbol findSymbol(const std::string &Name, bool CheckFunctionsOnly);
306 
307  // DEPRECATED - Please use findSymbol instead.
308  //
309  // This is not directly exposed via the ExecutionEngine API, but it is
310  // used by the LinkingMemoryManager.
311  //
312  // getSymbolAddress takes an unmangled name and returns the corresponding
313  // JITSymbol if a definition of the name has been added to the JIT.
314  uint64_t getSymbolAddress(const std::string &Name,
315  bool CheckFunctionsOnly);
316 
317 protected:
318  /// emitObject -- Generate a JITed object in memory from the specified module
319  /// Currently, MCJIT only supports a single module and the module passed to
320  /// this function call is expected to be the contained module. The module
321  /// is passed as a parameter here to prepare for multiple module support in
322  /// the future.
323  std::unique_ptr<MemoryBuffer> emitObject(Module *M);
324 
325  void notifyObjectLoaded(const object::ObjectFile &Obj,
327  void notifyFreeingObject(const object::ObjectFile &Obj);
328 
329  JITSymbol findExistingSymbol(const std::string &Name);
330  Module *findModuleForSymbol(const std::string &Name, bool CheckFunctionsOnly);
331 };
332 
333 } // end llvm namespace
334 
335 #endif // LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H
llvm::MCJIT::getFunctionAddress
uint64_t getFunctionAddress(const std::string &Name) override
getFunctionAddress - Return the address of the specified function.
Definition: MCJIT.cpp:404
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:53
llvm::MCJIT::finalizeLoadedModules
void finalizeLoadedModules()
Definition: MCJIT.cpp:238
llvm::MCJIT::mapSectionAddress
void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress) override
mapSectionAddress - map a section to its target address space value.
Definition: MCJIT.h:272
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:76
llvm::Function
Definition: Function.h:60
ExecutionEngine.h
llvm::MCJIT::FindFunctionNamed
Function * FindFunctionNamed(StringRef FnName) override
FindFunctionNamed - Search all of the active modules to find the function that defines FnName.
Definition: MCJIT.cpp:489
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1181
llvm::GlobalVariable
Definition: GlobalVariable.h:39
llvm::LinkingSymbolResolver
Definition: MCJIT.h:27
llvm::MCJIT::setObjectCache
void setObjectCache(ObjectCache *manager) override
Sets the object manager that MCJIT should use to avoid compilation.
Definition: MCJIT.cpp:141
llvm::MCJIT::getPointerToNamedFunction
void * getPointerToNamedFunction(StringRef Name, bool AbortOnFailure=true) override
getPointerToNamedFunction - This method returns the address of the specified function by using the dl...
Definition: MCJIT.cpp:616
llvm::MCJIT::getSymbolAddress
uint64_t getSymbolAddress(const std::string &Name, bool CheckFunctionsOnly)
Definition: MCJIT.cpp:322
llvm::ObjectCache
This is the base ObjectCache type which can be provided to an ExecutionEngine for the purpose of avoi...
Definition: ObjectCache.h:23
llvm::SmallPtrSet< Module *, 4 >
llvm::MCJIT::generateCodeForModule
void generateCodeForModule(Module *M) override
generateCodeForModule - Run code generation for the specified module and load it into memory.
Definition: MCJIT.cpp:189
RuntimeDyld.h
llvm::MCJIT::getPointerToFunction
void * getPointerToFunction(Function *F) override
getPointerToFunction - The different EE's represent function bodies in different ways.
Definition: MCJIT.cpp:413
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::ExecutionEngine::MCJITCtor
static ExecutionEngine *(* MCJITCtor)(std::unique_ptr< Module > M, std::string *ErrorStr, std::shared_ptr< MCJITMemoryManager > MM, std::shared_ptr< LegacyJITSymbolResolver > SR, std::unique_ptr< TargetMachine > TM)
Definition: ExecutionEngine.h:138
llvm::RuntimeDyld::setProcessAllSections
void setProcessAllSections(bool ProcessAllSections)
By default, only sections that are "required for execution" are passed to the RTDyldMemoryManager,...
Definition: RuntimeDyld.h:263
llvm::Resolver
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Definition: Record.h:2133
llvm::GenericValue
Definition: GenericValue.h:23
llvm::MCJIT::runFunction
GenericValue runFunction(Function *F, ArrayRef< GenericValue > ArgValues) override
runFunction - Execute the specified function with the specified arguments, and return the result.
Definition: MCJIT.cpp:513
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MCJIT::finalizeObject
void finalizeObject() override
finalizeObject - ensure the module is fully processed and is usable.
Definition: MCJIT.cpp:258
llvm::MCJIT::~MCJIT
~MCJIT() override
Definition: MCJIT.cpp:93
llvm::MCJIT::runStaticConstructorsDestructors
void runStaticConstructorsDestructors(bool isDtors) override
runStaticConstructorsDestructors - This method is used to execute all of the static constructors or d...
Definition: MCJIT.cpp:455
llvm::MCJIT::addModule
void addModule(std::unique_ptr< Module > M) override
Add a Module to the list of modules that we can JIT from.
Definition: MCJIT.cpp:105
llvm::MCJIT::findModuleForSymbol
Module * findModuleForSymbol(const std::string &Name, bool CheckFunctionsOnly)
Definition: MCJIT.cpp:295
llvm::LegacyJITSymbolResolver
Legacy symbol resolution interface.
Definition: JITSymbol.h:401
SmallPtrSet.h
llvm::MCJIT::notifyFreeingObject
void notifyFreeingObject(const object::ObjectFile &Obj)
Definition: MCJIT.cpp:666
llvm::MCJIT::removeModule
bool removeModule(Module *M) override
removeModule - Removes a Module from the list of modules, but does not free the module's memory.
Definition: MCJIT.cpp:114
llvm::LinkingSymbolResolver::findSymbol
JITSymbol findSymbol(const std::string &Name) override
This method returns the address of the specified function or variable.
Definition: MCJIT.cpp:675
llvm::MCJIT::Register
static void Register()
Definition: MCJIT.h:291
llvm::MCJIT::getGlobalValueAddress
uint64_t getGlobalValueAddress(const std::string &Name) override
getGlobalValueAddress - Return the address of the specified global value.
Definition: MCJIT.cpp:396
llvm::MCJIT::finalizeModule
virtual void finalizeModule(Module *)
Definition: MCJIT.cpp:273
llvm::SmallPtrSetImpl< Module * >::iterator
SmallPtrSetIterator< Module * > iterator
Definition: SmallPtrSet.h:354
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:264
llvm::MCJIT::emitObject
std::unique_ptr< MemoryBuffer > emitObject(Module *M)
emitObject – Generate a JITed object in memory from the specified module Currently,...
Definition: MCJIT.cpp:146
uint64_t
I
#define I(x, y, z)
Definition: MD5.cpp:58
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1666
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::MCJIT::notifyObjectLoaded
void notifyObjectLoaded(const object::ObjectFile &Obj, const RuntimeDyld::LoadedObjectInfo &L)
Definition: MCJIT.cpp:656
llvm::JITEventListener
JITEventListener - Abstract interface for use by the JIT to notify clients about significant events d...
Definition: JITEventListener.h:40
llvm::MCJIT::findExistingSymbol
JITSymbol findExistingSymbol(const std::string &Name)
Definition: MCJIT.cpp:286
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition: ObjectFile.h:228
Module
Machine Check Debug Module
Definition: MachineCheckDebugify.cpp:122
llvm::MCJIT::getTargetMachine
TargetMachine * getTargetMachine() override
Return the target machine (if available).
Definition: MCJIT.h:285
RTDyldMemoryManager.h
llvm::LinkingSymbolResolver::findSymbolInLogicalDylib
JITSymbol findSymbolInLogicalDylib(const std::string &Name) override
This method returns the address of the specified symbol if it exists within the logical dynamic libra...
Definition: MCJIT.h:36
llvm::MCJIT::createJIT
static ExecutionEngine * createJIT(std::unique_ptr< Module > M, std::string *ErrorStr, std::shared_ptr< MCJITMemoryManager > MemMgr, std::shared_ptr< LegacyJITSymbolResolver > Resolver, std::unique_ptr< TargetMachine > TM)
Definition: MCJIT.cpp:45
llvm::ExecutionEngine
Abstract interface for implementation execution of LLVM modules, designed to support both interpreter...
Definition: ExecutionEngine.h:99
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
std
Definition: BitVector.h:851
llvm::object::OwningBinary
Definition: RuntimeDyld.h:36
llvm::RuntimeDyld::LoadedObjectInfo
Information about the loaded object.
Definition: RuntimeDyld.h:69
llvm::MCJIT::FindGlobalVariableNamed
GlobalVariable * FindGlobalVariableNamed(StringRef Name, bool AllowInternal=false) override
FindGlobalVariableNamed - Search all of the active modules to find the global variable that defines N...
Definition: MCJIT.cpp:501
llvm::LinkingSymbolResolver::LinkingSymbolResolver
LinkingSymbolResolver(MCJIT &Parent, std::shared_ptr< LegacyJITSymbolResolver > Resolver)
Definition: MCJIT.h:29
llvm::MCJIT::UnregisterJITEventListener
void UnregisterJITEventListener(JITEventListener *L) override
Definition: MCJIT.cpp:645
SmallVector.h
llvm::iterator_range
A range adaptor for a pair of iterators.
Definition: iterator_range.h:30
llvm::MCJIT::findSymbol
JITSymbol findSymbol(const std::string &Name, bool CheckFunctionsOnly)
Definition: MCJIT.cpp:339
llvm::MCJIT
Definition: MCJIT.h:66
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::RuntimeDyld
Definition: RuntimeDyld.h:58
llvm::JITSymbol
Represents a symbol in the JIT.
Definition: JITSymbol.h:265
llvm::MCJIT::addObjectFile
void addObjectFile(std::unique_ptr< object::ObjectFile > O) override
addObjectFile - Add an ObjectFile to the execution engine.
Definition: MCJIT.cpp:119
llvm::RuntimeDyld::mapSectionAddress
void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress)
Map a section to its target address space value.
Definition: RuntimeDyld.cpp:1407
llvm::MCJIT::RegisterJITEventListener
void RegisterJITEventListener(JITEventListener *L) override
Registers a listener to be called back on various events within the JIT.
Definition: MCJIT.cpp:638
llvm::MCJIT::addArchive
void addArchive(object::OwningBinary< object::Archive > O) override
addArchive - Add an Archive to the execution engine.
Definition: MCJIT.cpp:137
llvm::MCJIT::setProcessAllSections
void setProcessAllSections(bool ProcessAllSections) override
setProcessAllSections (MCJIT Only): By default, only sections that are "required for execution" are p...
Definition: MCJIT.h:227