LLVM  8.0.1
ExecutionEngineBindings.cpp
Go to the documentation of this file.
1 //===-- ExecutionEngineBindings.cpp - C bindings for EEs ------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the C bindings for the ExecutionEngine library.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm-c/ExecutionEngine.h"
19 #include "llvm/IR/DerivedTypes.h"
20 #include "llvm/IR/Module.h"
24 #include <cstring>
25 
26 using namespace llvm;
27 
28 #define DEBUG_TYPE "jit"
29 
30 // Wrapping the C bindings types.
32 
33 
35  return
36  reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P));
37 }
38 
39 /*===-- Operations on generic values --------------------------------------===*/
40 
42  unsigned long long N,
43  LLVMBool IsSigned) {
44  GenericValue *GenVal = new GenericValue();
45  GenVal->IntVal = APInt(unwrap<IntegerType>(Ty)->getBitWidth(), N, IsSigned);
46  return wrap(GenVal);
47 }
48 
50  GenericValue *GenVal = new GenericValue();
51  GenVal->PointerVal = P;
52  return wrap(GenVal);
53 }
54 
56  GenericValue *GenVal = new GenericValue();
57  switch (unwrap(TyRef)->getTypeID()) {
58  case Type::FloatTyID:
59  GenVal->FloatVal = N;
60  break;
61  case Type::DoubleTyID:
62  GenVal->DoubleVal = N;
63  break;
64  default:
65  llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
66  }
67  return wrap(GenVal);
68 }
69 
71  return unwrap(GenValRef)->IntVal.getBitWidth();
72 }
73 
74 unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenValRef,
75  LLVMBool IsSigned) {
76  GenericValue *GenVal = unwrap(GenValRef);
77  if (IsSigned)
78  return GenVal->IntVal.getSExtValue();
79  else
80  return GenVal->IntVal.getZExtValue();
81 }
82 
84  return unwrap(GenVal)->PointerVal;
85 }
86 
88  switch (unwrap(TyRef)->getTypeID()) {
89  case Type::FloatTyID:
90  return unwrap(GenVal)->FloatVal;
91  case Type::DoubleTyID:
92  return unwrap(GenVal)->DoubleVal;
93  default:
94  llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
95  }
96 }
97 
99  delete unwrap(GenVal);
100 }
101 
102 /*===-- Operations on execution engines -----------------------------------===*/
103 
105  LLVMModuleRef M,
106  char **OutError) {
107  std::string Error;
108  EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
110  .setErrorStr(&Error);
111  if (ExecutionEngine *EE = builder.create()){
112  *OutEE = wrap(EE);
113  return 0;
114  }
115  *OutError = strdup(Error.c_str());
116  return 1;
117 }
118 
120  LLVMModuleRef M,
121  char **OutError) {
122  std::string Error;
123  EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
125  .setErrorStr(&Error);
126  if (ExecutionEngine *Interp = builder.create()) {
127  *OutInterp = wrap(Interp);
128  return 0;
129  }
130  *OutError = strdup(Error.c_str());
131  return 1;
132 }
133 
135  LLVMModuleRef M,
136  unsigned OptLevel,
137  char **OutError) {
138  std::string Error;
139  EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
141  .setErrorStr(&Error)
142  .setOptLevel((CodeGenOpt::Level)OptLevel);
143  if (ExecutionEngine *JIT = builder.create()) {
144  *OutJIT = wrap(JIT);
145  return 0;
146  }
147  *OutError = strdup(Error.c_str());
148  return 1;
149 }
150 
152  size_t SizeOfPassedOptions) {
153  LLVMMCJITCompilerOptions options;
154  memset(&options, 0, sizeof(options)); // Most fields are zero by default.
156 
157  memcpy(PassedOptions, &options,
158  std::min(sizeof(options), SizeOfPassedOptions));
159 }
160 
163  LLVMMCJITCompilerOptions *PassedOptions, size_t SizeOfPassedOptions,
164  char **OutError) {
165  LLVMMCJITCompilerOptions options;
166  // If the user passed a larger sized options struct, then they were compiled
167  // against a newer LLVM. Tell them that something is wrong.
168  if (SizeOfPassedOptions > sizeof(options)) {
169  *OutError = strdup(
170  "Refusing to use options struct that is larger than my own; assuming "
171  "LLVM library mismatch.");
172  return 1;
173  }
174 
175  // Defend against the user having an old version of the API by ensuring that
176  // any fields they didn't see are cleared. We must defend against fields being
177  // set to the bitwise equivalent of zero, and assume that this means "do the
178  // default" as if that option hadn't been available.
179  LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
180  memcpy(&options, PassedOptions, SizeOfPassedOptions);
181 
182  TargetOptions targetOptions;
183  targetOptions.EnableFastISel = options.EnableFastISel;
184  std::unique_ptr<Module> Mod(unwrap(M));
185 
186  if (Mod)
187  // Set function attribute "no-frame-pointer-elim" based on
188  // NoFramePointerElim.
189  for (auto &F : *Mod) {
190  auto Attrs = F.getAttributes();
191  StringRef Value(options.NoFramePointerElim ? "true" : "false");
192  Attrs = Attrs.addAttribute(F.getContext(), AttributeList::FunctionIndex,
193  "no-frame-pointer-elim", Value);
194  F.setAttributes(Attrs);
195  }
196 
197  std::string Error;
198  EngineBuilder builder(std::move(Mod));
200  .setErrorStr(&Error)
202  .setTargetOptions(targetOptions);
203  bool JIT;
204  if (Optional<CodeModel::Model> CM = unwrap(options.CodeModel, JIT))
205  builder.setCodeModel(*CM);
206  if (options.MCJMM)
207  builder.setMCJITMemoryManager(
208  std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM)));
209  if (ExecutionEngine *JIT = builder.create()) {
210  *OutJIT = wrap(JIT);
211  return 0;
212  }
213  *OutError = strdup(Error.c_str());
214  return 1;
215 }
216 
218  delete unwrap(EE);
219 }
220 
222  unwrap(EE)->finalizeObject();
223  unwrap(EE)->runStaticConstructorsDestructors(false);
224 }
225 
227  unwrap(EE)->finalizeObject();
228  unwrap(EE)->runStaticConstructorsDestructors(true);
229 }
230 
232  unsigned ArgC, const char * const *ArgV,
233  const char * const *EnvP) {
234  unwrap(EE)->finalizeObject();
235 
236  std::vector<std::string> ArgVec(ArgV, ArgV + ArgC);
237  return unwrap(EE)->runFunctionAsMain(unwrap<Function>(F), ArgVec, EnvP);
238 }
239 
241  unsigned NumArgs,
243  unwrap(EE)->finalizeObject();
244 
245  std::vector<GenericValue> ArgVec;
246  ArgVec.reserve(NumArgs);
247  for (unsigned I = 0; I != NumArgs; ++I)
248  ArgVec.push_back(*unwrap(Args[I]));
249 
250  GenericValue *Result = new GenericValue();
251  *Result = unwrap(EE)->runFunction(unwrap<Function>(F), ArgVec);
252  return wrap(Result);
253 }
254 
256 }
257 
259  unwrap(EE)->addModule(std::unique_ptr<Module>(unwrap(M)));
260 }
261 
263  LLVMModuleRef *OutMod, char **OutError) {
264  Module *Mod = unwrap(M);
265  unwrap(EE)->removeModule(Mod);
266  *OutMod = wrap(Mod);
267  return 0;
268 }
269 
271  LLVMValueRef *OutFn) {
272  if (Function *F = unwrap(EE)->FindFunctionNamed(Name)) {
273  *OutFn = wrap(F);
274  return 0;
275  }
276  return 1;
277 }
278 
280  LLVMValueRef Fn) {
281  return nullptr;
282 }
283 
285  return wrap(&unwrap(EE)->getDataLayout());
286 }
287 
290  return wrap(unwrap(EE)->getTargetMachine());
291 }
292 
294  void* Addr) {
295  unwrap(EE)->addGlobalMapping(unwrap<GlobalValue>(Global), Addr);
296 }
297 
299  unwrap(EE)->finalizeObject();
300 
301  return unwrap(EE)->getPointerToGlobal(unwrap<GlobalValue>(Global));
302 }
303 
305  return unwrap(EE)->getGlobalValueAddress(Name);
306 }
307 
309  return unwrap(EE)->getFunctionAddress(Name);
310 }
311 
312 /*===-- Operations on memory managers -------------------------------------===*/
313 
314 namespace {
315 
316 struct SimpleBindingMMFunctions {
321 };
322 
323 class SimpleBindingMemoryManager : public RTDyldMemoryManager {
324 public:
325  SimpleBindingMemoryManager(const SimpleBindingMMFunctions& Functions,
326  void *Opaque);
327  ~SimpleBindingMemoryManager() override;
328 
329  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
330  unsigned SectionID,
331  StringRef SectionName) override;
332 
333  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
334  unsigned SectionID, StringRef SectionName,
335  bool isReadOnly) override;
336 
337  bool finalizeMemory(std::string *ErrMsg) override;
338 
339 private:
340  SimpleBindingMMFunctions Functions;
341  void *Opaque;
342 };
343 
344 SimpleBindingMemoryManager::SimpleBindingMemoryManager(
345  const SimpleBindingMMFunctions& Functions,
346  void *Opaque)
347  : Functions(Functions), Opaque(Opaque) {
348  assert(Functions.AllocateCodeSection &&
349  "No AllocateCodeSection function provided!");
350  assert(Functions.AllocateDataSection &&
351  "No AllocateDataSection function provided!");
352  assert(Functions.FinalizeMemory &&
353  "No FinalizeMemory function provided!");
354  assert(Functions.Destroy &&
355  "No Destroy function provided!");
356 }
357 
358 SimpleBindingMemoryManager::~SimpleBindingMemoryManager() {
359  Functions.Destroy(Opaque);
360 }
361 
362 uint8_t *SimpleBindingMemoryManager::allocateCodeSection(
363  uintptr_t Size, unsigned Alignment, unsigned SectionID,
365  return Functions.AllocateCodeSection(Opaque, Size, Alignment, SectionID,
366  SectionName.str().c_str());
367 }
368 
369 uint8_t *SimpleBindingMemoryManager::allocateDataSection(
370  uintptr_t Size, unsigned Alignment, unsigned SectionID,
371  StringRef SectionName, bool isReadOnly) {
372  return Functions.AllocateDataSection(Opaque, Size, Alignment, SectionID,
373  SectionName.str().c_str(),
374  isReadOnly);
375 }
376 
377 bool SimpleBindingMemoryManager::finalizeMemory(std::string *ErrMsg) {
378  char *errMsgCString = nullptr;
379  bool result = Functions.FinalizeMemory(Opaque, &errMsgCString);
380  assert((result || !errMsgCString) &&
381  "Did not expect an error message if FinalizeMemory succeeded");
382  if (errMsgCString) {
383  if (ErrMsg)
384  *ErrMsg = errMsgCString;
385  free(errMsgCString);
386  }
387  return result;
388 }
389 
390 } // anonymous namespace
391 
393  void *Opaque,
398 
399  if (!AllocateCodeSection || !AllocateDataSection || !FinalizeMemory ||
400  !Destroy)
401  return nullptr;
402 
403  SimpleBindingMMFunctions functions;
404  functions.AllocateCodeSection = AllocateCodeSection;
405  functions.AllocateDataSection = AllocateDataSection;
406  functions.FinalizeMemory = FinalizeMemory;
407  functions.Destroy = Destroy;
408  return wrap(new SimpleBindingMemoryManager(functions, Opaque));
409 }
410 
412  delete unwrap(MM);
413 }
414 
415 /*===-- JIT Event Listener functions -------------------------------------===*/
416 
417 
418 #if !LLVM_USE_INTEL_JITEVENTS
420 {
421  return nullptr;
422 }
423 #endif
424 
425 #if !LLVM_USE_OPROFILE
427 {
428  return nullptr;
429 }
430 #endif
431 
432 #if !LLVM_USE_PERF
434 {
435  return nullptr;
436 }
437 #endif
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
PointerTy PointerVal
Definition: GenericValue.h:32
uint8_t *(* LLVMMemoryManagerAllocateCodeSectionCallback)(void *Opaque, uintptr_t Size, unsigned Alignment, unsigned SectionID, const char *SectionName)
LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef TyRef, double N)
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1563
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:228
void LLVMInitializeMCJITCompilerOptions(LLVMMCJITCompilerOptions *PassedOptions, size_t SizeOfPassedOptions)
This class represents lattice values for constants.
Definition: AllocatorList.h:24
struct LLVMOpaqueModule * LLVMModuleRef
The top-level container for all other LLVM Intermediate Representation (IR) objects.
Definition: Types.h:62
LLVMMCJITMemoryManagerRef MCJMM
struct LLVMOpaqueExecutionEngine * LLVMExecutionEngineRef
unsigned EnableFastISel
EnableFastISel - This flag enables fast-path instruction selection which trades away generated code q...
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
2: 32-bit floating point type
Definition: Type.h:59
void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE)
void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal)
void * LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE, LLVMValueRef Fn)
F(f)
LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M, unsigned OptLevel, char **OutError)
double LLVMGenericValueToFloat(LLVMTypeRef TyRef, LLVMGenericValueRef GenVal)
void * LLVMGenericValueToPointer(LLVMGenericValueRef GenVal)
amdgpu Simplify well known AMD library false Value Value const Twine & Name
struct LLVMOpaqueMCJITMemoryManager * LLVMMCJITMemoryManagerRef
#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref)
struct LLVMOpaqueTargetData * LLVMTargetDataRef
Definition: DataLayout.h:39
struct LLVMOpaqueTargetMachine * LLVMTargetMachineRef
Definition: TargetMachine.h:28
Attribute unwrap(LLVMAttributeRef Attr)
Definition: Attributes.h:195
LLVMJITEventListenerRef LLVMCreateOProfileJITEventListener(void)
LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P)
void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global, void *Addr)
always Inliner for always_inline functions
struct LLVMOpaqueType * LLVMTypeRef
Each value in the LLVM IR has a type, an LLVMTypeRef.
Definition: Types.h:69
int64_t getSExtValue() const
Get sign extended value.
Definition: APInt.h:1575
uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE, const char *Name)
EngineBuilder & setCodeModel(CodeModel::Model M)
setCodeModel - Set the CodeModel that the ExecutionEngine target data is using.
LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager(void *Opaque, LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection, LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection, LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory, LLVMMemoryManagerDestroyCallback Destroy)
Create a simple custom MCJIT memory manager.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
LLVMJITEventListenerRef LLVMCreateIntelJITEventListener(void)
int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F, unsigned ArgC, const char *const *ArgV, const char *const *EnvP)
EngineBuilder & setEngineKind(EngineKind::Kind w)
setEngineKind - Controls whether the user wants the interpreter, the JIT, or whichever engine works...
#define P(N)
LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE, LLVMModuleRef M, char **OutError)
EngineBuilder & setErrorStr(std::string *e)
setErrorStr - Set the error string to write to on error.
LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty, unsigned long long N, LLVMBool IsSigned)
static const Kind Either
LLVMJITEventListenerRef LLVMCreatePerfJITEventListener(void)
LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE)
LLVMBool(* LLVMMemoryManagerFinalizeMemoryCallback)(void *Opaque, char **ErrMsg)
void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM)
void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE)
int LLVMBool
Definition: Types.h:29
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract interface for implementation execution of LLVM modules, designed to support both interpreter...
void * LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global)
EngineBuilder & setTargetOptions(const TargetOptions &Opts)
setTargetOptions - Set the target options that the ExecutionEngine target is using.
Module.h This file contains the declarations for the Module class.
uint8_t *(* LLVMMemoryManagerAllocateDataSectionCallback)(void *Opaque, uintptr_t Size, unsigned Alignment, unsigned SectionID, const char *SectionName, LLVMBool IsReadOnly)
The access may modify the value stored in memory.
LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp, LLVMModuleRef M, char **OutError)
Class for arbitrary precision integers.
Definition: APInt.h:70
static char getTypeID(Type *Ty)
ExecutionEngine * create()
void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE)
LLVMAttributeRef wrap(Attribute Attr)
Definition: Attributes.h:190
void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M)
uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE, const char *Name)
unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenValRef, LLVMBool IsSigned)
LLVMTargetMachineRef LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE)
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
uint32_t Size
Definition: Profile.cpp:47
LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F, unsigned NumArgs, LLVMGenericValueRef *Args)
Builder class for ExecutionEngines.
EngineBuilder & setMCJITMemoryManager(std::unique_ptr< RTDyldMemoryManager > mcjmm)
setMCJITMemoryManager - Sets the MCJIT memory manager to use.
unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef)
void(* LLVMMemoryManagerDestroyCallback)(void *Opaque)
3: 64-bit floating point type
Definition: Type.h:60
LLVMBool LLVMCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M, LLVMMCJITCompilerOptions *PassedOptions, size_t SizeOfPassedOptions, char **OutError)
Create an MCJIT execution engine for a module, with the given options.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
struct LLVMOpaqueJITEventListener * LLVMJITEventListenerRef
Definition: Types.h:164
aarch64 promote const
LLVM Value Representation.
Definition: Value.h:73
void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F)
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:59
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
struct LLVMOpaqueGenericValue * LLVMGenericValueRef
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
EngineBuilder & setOptLevel(CodeGenOpt::Level l)
setOptLevel - Set the optimization level for the JIT.
struct LLVMOpaqueValue * LLVMValueRef
Represents an individual value in LLVM IR.
Definition: Types.h:76
LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name, LLVMValueRef *OutFn)
LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M, LLVMModuleRef *OutMod, char **OutError)