LLVM  14.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() {
76  }
77  ~OwningModuleContainer() {
78  freeModulePtrSet(AddedModules);
79  freeModulePtrSet(LoadedModules);
80  freeModulePtrSet(FinalizedModules);
81  }
82 
83  ModulePtrSet::iterator begin_added() { return AddedModules.begin(); }
84  ModulePtrSet::iterator end_added() { return AddedModules.end(); }
86  return make_range(begin_added(), end_added());
87  }
88 
89  ModulePtrSet::iterator begin_loaded() { return LoadedModules.begin(); }
90  ModulePtrSet::iterator end_loaded() { return LoadedModules.end(); }
91 
92  ModulePtrSet::iterator begin_finalized() { return FinalizedModules.begin(); }
93  ModulePtrSet::iterator end_finalized() { return FinalizedModules.end(); }
94 
95  void addModule(std::unique_ptr<Module> M) {
96  AddedModules.insert(M.release());
97  }
98 
99  bool removeModule(Module *M) {
100  return AddedModules.erase(M) || LoadedModules.erase(M) ||
101  FinalizedModules.erase(M);
102  }
103 
104  bool hasModuleBeenAddedButNotLoaded(Module *M) {
105  return AddedModules.contains(M);
106  }
107 
108  bool hasModuleBeenLoaded(Module *M) {
109  // If the module is in either the "loaded" or "finalized" sections it
110  // has been loaded.
111  return LoadedModules.contains(M) || FinalizedModules.contains(M);
112  }
113 
114  bool hasModuleBeenFinalized(Module *M) {
115  return FinalizedModules.contains(M);
116  }
117 
118  bool ownsModule(Module* M) {
119  return AddedModules.contains(M) || LoadedModules.contains(M) ||
120  FinalizedModules.contains(M);
121  }
122 
123  void markModuleAsLoaded(Module *M) {
124  // This checks against logic errors in the MCJIT implementation.
125  // This function should never be called with either a Module that MCJIT
126  // does not own or a Module that has already been loaded and/or finalized.
127  assert(AddedModules.count(M) &&
128  "markModuleAsLoaded: Module not found in AddedModules");
129 
130  // Remove the module from the "Added" set.
131  AddedModules.erase(M);
132 
133  // Add the Module to the "Loaded" set.
134  LoadedModules.insert(M);
135  }
136 
137  void markModuleAsFinalized(Module *M) {
138  // This checks against logic errors in the MCJIT implementation.
139  // This function should never be called with either a Module that MCJIT
140  // does not own, a Module that has not been loaded or a Module that has
141  // already been finalized.
142  assert(LoadedModules.count(M) &&
143  "markModuleAsFinalized: Module not found in LoadedModules");
144 
145  // Remove the module from the "Loaded" section of the list.
146  LoadedModules.erase(M);
147 
148  // Add the Module to the "Finalized" section of the list by inserting it
149  // before the 'end' iterator.
150  FinalizedModules.insert(M);
151  }
152 
153  void markAllLoadedModulesAsFinalized() {
154  for (ModulePtrSet::iterator I = LoadedModules.begin(),
155  E = LoadedModules.end();
156  I != E; ++I) {
157  Module *M = *I;
158  FinalizedModules.insert(M);
159  }
160  LoadedModules.clear();
161  }
162 
163  private:
164  ModulePtrSet AddedModules;
165  ModulePtrSet LoadedModules;
166  ModulePtrSet FinalizedModules;
167 
168  void freeModulePtrSet(ModulePtrSet& MPS) {
169  // Go through the module set and delete everything.
170  for (ModulePtrSet::iterator I = MPS.begin(), E = MPS.end(); I != E; ++I) {
171  Module *M = *I;
172  delete M;
173  }
174  MPS.clear();
175  }
176  };
177 
178  std::unique_ptr<TargetMachine> TM;
179  MCContext *Ctx;
180  std::shared_ptr<MCJITMemoryManager> MemMgr;
182  RuntimeDyld Dyld;
183  std::vector<JITEventListener*> EventListeners;
184 
185  OwningModuleContainer OwnedModules;
186 
189 
191 
192  // An optional ObjectCache to be notified of compiled objects and used to
193  // perform lookup of pre-compiled code to avoid re-compilation.
194  ObjectCache *ObjCache;
195 
196  Function *FindFunctionNamedInModulePtrSet(StringRef FnName,
199 
200  GlobalVariable *FindGlobalVariableNamedInModulePtrSet(StringRef Name,
201  bool AllowInternal,
204 
205  void runStaticConstructorsDestructorsInModulePtrSet(bool isDtors,
208 
209 public:
210  ~MCJIT() override;
211 
212  /// @name ExecutionEngine interface implementation
213  /// @{
214  void addModule(std::unique_ptr<Module> M) override;
215  void addObjectFile(std::unique_ptr<object::ObjectFile> O) override;
218  bool removeModule(Module *M) override;
219 
220  /// FindFunctionNamed - Search all of the active modules to find the function that
221  /// defines FnName. This is very slow operation and shouldn't be used for
222  /// general code.
223  Function *FindFunctionNamed(StringRef FnName) override;
224 
225  /// FindGlobalVariableNamed - Search all of the active modules to find the
226  /// global variable that defines Name. This is very slow operation and
227  /// shouldn't be used for general code.
229  bool AllowInternal = false) override;
230 
231  /// Sets the object manager that MCJIT should use to avoid compilation.
232  void setObjectCache(ObjectCache *manager) override;
233 
234  void setProcessAllSections(bool ProcessAllSections) override {
235  Dyld.setProcessAllSections(ProcessAllSections);
236  }
237 
238  void generateCodeForModule(Module *M) override;
239 
240  /// finalizeObject - ensure the module is fully processed and is usable.
241  ///
242  /// It is the user-level function for completing the process of making the
243  /// object usable for execution. It should be called after sections within an
244  /// object have been relocated using mapSectionAddress. When this method is
245  /// called the MCJIT execution engine will reapply relocations for a loaded
246  /// object.
247  /// Is it OK to finalize a set of modules, add modules and finalize again.
248  // FIXME: Do we really need both of these?
249  void finalizeObject() override;
250  virtual void finalizeModule(Module *);
251  void finalizeLoadedModules();
252 
253  /// runStaticConstructorsDestructors - This method is used to execute all of
254  /// the static constructors or destructors for a program.
255  ///
256  /// \param isDtors - Run the destructors instead of constructors.
257  void runStaticConstructorsDestructors(bool isDtors) override;
258 
259  void *getPointerToFunction(Function *F) override;
260 
262  ArrayRef<GenericValue> ArgValues) override;
263 
264  /// getPointerToNamedFunction - This method returns the address of the
265  /// specified function by using the dlsym function call. As such it is only
266  /// useful for resolving library symbols, not code generated symbols.
267  ///
268  /// If AbortOnFailure is false and no function with the given name is
269  /// found, this function silently returns a null pointer. Otherwise,
270  /// it prints a message to stderr and aborts.
271  ///
273  bool AbortOnFailure = true) override;
274 
275  /// mapSectionAddress - map a section to its target address space value.
276  /// Map the address of a JIT section as returned from the memory manager
277  /// to the address in the target process as the running code will see it.
278  /// This is the address which will be used for relocation resolution.
279  void mapSectionAddress(const void *LocalAddress,
280  uint64_t TargetAddress) override {
281  Dyld.mapSectionAddress(LocalAddress, TargetAddress);
282  }
283  void RegisterJITEventListener(JITEventListener *L) override;
285 
286  // If successful, these function will implicitly finalize all loaded objects.
287  // To get a function address within MCJIT without causing a finalize, use
288  // getSymbolAddress.
289  uint64_t getGlobalValueAddress(const std::string &Name) override;
290  uint64_t getFunctionAddress(const std::string &Name) override;
291 
292  TargetMachine *getTargetMachine() override { return TM.get(); }
293 
294  /// @}
295  /// @name (Private) Registration Interfaces
296  /// @{
297 
298  static void Register() {
300  }
301 
302  static ExecutionEngine *
303  createJIT(std::unique_ptr<Module> M, std::string *ErrorStr,
304  std::shared_ptr<MCJITMemoryManager> MemMgr,
305  std::shared_ptr<LegacyJITSymbolResolver> Resolver,
306  std::unique_ptr<TargetMachine> TM);
307 
308  // @}
309 
310  // Takes a mangled name and returns the corresponding JITSymbol (if a
311  // definition of that mangled name has been added to the JIT).
312  JITSymbol findSymbol(const std::string &Name, bool CheckFunctionsOnly);
313 
314  // DEPRECATED - Please use findSymbol instead.
315  //
316  // This is not directly exposed via the ExecutionEngine API, but it is
317  // used by the LinkingMemoryManager.
318  //
319  // getSymbolAddress takes an unmangled name and returns the corresponding
320  // JITSymbol if a definition of the name has been added to the JIT.
321  uint64_t getSymbolAddress(const std::string &Name,
322  bool CheckFunctionsOnly);
323 
324 protected:
325  /// emitObject -- Generate a JITed object in memory from the specified module
326  /// Currently, MCJIT only supports a single module and the module passed to
327  /// this function call is expected to be the contained module. The module
328  /// is passed as a parameter here to prepare for multiple module support in
329  /// the future.
330  std::unique_ptr<MemoryBuffer> emitObject(Module *M);
331 
332  void notifyObjectLoaded(const object::ObjectFile &Obj,
334  void notifyFreeingObject(const object::ObjectFile &Obj);
335 
336  JITSymbol findExistingSymbol(const std::string &Name);
337  Module *findModuleForSymbol(const std::string &Name, bool CheckFunctionsOnly);
338 };
339 
340 } // end llvm namespace
341 
342 #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
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
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:279
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:72
llvm::Function
Definition: Function.h:61
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:1168
llvm::GlobalVariable
Definition: GlobalVariable.h:40
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:140
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:188
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:56
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:2000
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:92
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:104
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:667
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:113
llvm::LinkingSymbolResolver::findSymbol
JITSymbol findSymbol(const std::string &Name) override
This method returns the address of the specified function or variable.
Definition: MCJIT.cpp:676
llvm::MCJIT::Register
static void Register()
Definition: MCJIT.h:298
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:353
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:197
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:145
uint64_t
llvm::SmallPtrSetImpl::end
iterator end() const
Definition: SmallPtrSet.h:407
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::SmallPtrSetImpl::begin
iterator begin() const
Definition: SmallPtrSet.h:402
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:79
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:1609
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
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:41
llvm::MCJIT::findExistingSymbol
JITSymbol findExistingSymbol(const std::string &Name)
Definition: MCJIT.cpp:286
llvm::SmallPtrSetImplBase::clear
void clear()
Definition: SmallPtrSet.h:94
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:58
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:292
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:44
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:52
std
Definition: BitVector.h:838
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:118
llvm::RuntimeDyld::mapSectionAddress
void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress)
Map a section to its target address space value.
Definition: RuntimeDyld.cpp:1405
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:136
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:234