LLVM  10.0.0svn
ExecutionEngineBindings.cpp
Go to the documentation of this file.
1 //===-- ExecutionEngineBindings.cpp - C bindings for EEs ------------------===//
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 // This file defines the C bindings for the ExecutionEngine library.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm-c/ExecutionEngine.h"
18 #include "llvm/IR/DerivedTypes.h"
19 #include "llvm/IR/Module.h"
23 #include <cstring>
24 
25 using namespace llvm;
26 
27 #define DEBUG_TYPE "jit"
28 
29 // Wrapping the C bindings types.
31 
32 
34  return
35  reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P));
36 }
37 
38 /*===-- Operations on generic values --------------------------------------===*/
39 
41  unsigned long long N,
42  LLVMBool IsSigned) {
43  GenericValue *GenVal = new GenericValue();
44  GenVal->IntVal = APInt(unwrap<IntegerType>(Ty)->getBitWidth(), N, IsSigned);
45  return wrap(GenVal);
46 }
47 
49  GenericValue *GenVal = new GenericValue();
50  GenVal->PointerVal = P;
51  return wrap(GenVal);
52 }
53 
55  GenericValue *GenVal = new GenericValue();
56  switch (unwrap(TyRef)->getTypeID()) {
57  case Type::FloatTyID:
58  GenVal->FloatVal = N;
59  break;
60  case Type::DoubleTyID:
61  GenVal->DoubleVal = N;
62  break;
63  default:
64  llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
65  }
66  return wrap(GenVal);
67 }
68 
70  return unwrap(GenValRef)->IntVal.getBitWidth();
71 }
72 
73 unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenValRef,
74  LLVMBool IsSigned) {
75  GenericValue *GenVal = unwrap(GenValRef);
76  if (IsSigned)
77  return GenVal->IntVal.getSExtValue();
78  else
79  return GenVal->IntVal.getZExtValue();
80 }
81 
83  return unwrap(GenVal)->PointerVal;
84 }
85 
87  switch (unwrap(TyRef)->getTypeID()) {
88  case Type::FloatTyID:
89  return unwrap(GenVal)->FloatVal;
90  case Type::DoubleTyID:
91  return unwrap(GenVal)->DoubleVal;
92  default:
93  llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
94  }
95 }
96 
98  delete unwrap(GenVal);
99 }
100 
101 /*===-- Operations on execution engines -----------------------------------===*/
102 
104  LLVMModuleRef M,
105  char **OutError) {
106  std::string Error;
107  EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
109  .setErrorStr(&Error);
110  if (ExecutionEngine *EE = builder.create()){
111  *OutEE = wrap(EE);
112  return 0;
113  }
114  *OutError = strdup(Error.c_str());
115  return 1;
116 }
117 
119  LLVMModuleRef M,
120  char **OutError) {
121  std::string Error;
122  EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
124  .setErrorStr(&Error);
125  if (ExecutionEngine *Interp = builder.create()) {
126  *OutInterp = wrap(Interp);
127  return 0;
128  }
129  *OutError = strdup(Error.c_str());
130  return 1;
131 }
132 
134  LLVMModuleRef M,
135  unsigned OptLevel,
136  char **OutError) {
137  std::string Error;
138  EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
140  .setErrorStr(&Error)
141  .setOptLevel((CodeGenOpt::Level)OptLevel);
142  if (ExecutionEngine *JIT = builder.create()) {
143  *OutJIT = wrap(JIT);
144  return 0;
145  }
146  *OutError = strdup(Error.c_str());
147  return 1;
148 }
149 
151  size_t SizeOfPassedOptions) {
152  LLVMMCJITCompilerOptions options;
153  memset(&options, 0, sizeof(options)); // Most fields are zero by default.
155 
156  memcpy(PassedOptions, &options,
157  std::min(sizeof(options), SizeOfPassedOptions));
158 }
159 
162  LLVMMCJITCompilerOptions *PassedOptions, size_t SizeOfPassedOptions,
163  char **OutError) {
164  LLVMMCJITCompilerOptions options;
165  // If the user passed a larger sized options struct, then they were compiled
166  // against a newer LLVM. Tell them that something is wrong.
167  if (SizeOfPassedOptions > sizeof(options)) {
168  *OutError = strdup(
169  "Refusing to use options struct that is larger than my own; assuming "
170  "LLVM library mismatch.");
171  return 1;
172  }
173 
174  // Defend against the user having an old version of the API by ensuring that
175  // any fields they didn't see are cleared. We must defend against fields being
176  // set to the bitwise equivalent of zero, and assume that this means "do the
177  // default" as if that option hadn't been available.
178  LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
179  memcpy(&options, PassedOptions, SizeOfPassedOptions);
180 
181  TargetOptions targetOptions;
182  targetOptions.EnableFastISel = options.EnableFastISel;
183  std::unique_ptr<Module> Mod(unwrap(M));
184 
185  if (Mod)
186  // Set function attribute "no-frame-pointer-elim" based on
187  // NoFramePointerElim.
188  for (auto &F : *Mod) {
189  auto Attrs = F.getAttributes();
190  StringRef Value(options.NoFramePointerElim ? "true" : "false");
191  Attrs = Attrs.addAttribute(F.getContext(), AttributeList::FunctionIndex,
192  "no-frame-pointer-elim", Value);
193  F.setAttributes(Attrs);
194  }
195 
196  std::string Error;
197  EngineBuilder builder(std::move(Mod));
199  .setErrorStr(&Error)
201  .setTargetOptions(targetOptions);
202  bool JIT;
203  if (Optional<CodeModel::Model> CM = unwrap(options.CodeModel, JIT))
204  builder.setCodeModel(*CM);
205  if (options.MCJMM)
206  builder.setMCJITMemoryManager(
207  std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM)));
208  if (ExecutionEngine *JIT = builder.create()) {
209  *OutJIT = wrap(JIT);
210  return 0;
211  }
212  *OutError = strdup(Error.c_str());
213  return 1;
214 }
215 
217  delete unwrap(EE);
218 }
219 
221  unwrap(EE)->finalizeObject();
222  unwrap(EE)->runStaticConstructorsDestructors(false);
223 }
224 
226  unwrap(EE)->finalizeObject();
227  unwrap(EE)->runStaticConstructorsDestructors(true);
228 }
229 
231  unsigned ArgC, const char * const *ArgV,
232  const char * const *EnvP) {
233  unwrap(EE)->finalizeObject();
234 
235  std::vector<std::string> ArgVec(ArgV, ArgV + ArgC);
236  return unwrap(EE)->runFunctionAsMain(unwrap<Function>(F), ArgVec, EnvP);
237 }
238 
240  unsigned NumArgs,
242  unwrap(EE)->finalizeObject();
243 
244  std::vector<GenericValue> ArgVec;
245  ArgVec.reserve(NumArgs);
246  for (unsigned I = 0; I != NumArgs; ++I)
247  ArgVec.push_back(*unwrap(Args[I]));
248 
249  GenericValue *Result = new GenericValue();
250  *Result = unwrap(EE)->runFunction(unwrap<Function>(F), ArgVec);
251  return wrap(Result);
252 }
253 
255 }
256 
258  unwrap(EE)->addModule(std::unique_ptr<Module>(unwrap(M)));
259 }
260 
262  LLVMModuleRef *OutMod, char **OutError) {
263  Module *Mod = unwrap(M);
264  unwrap(EE)->removeModule(Mod);
265  *OutMod = wrap(Mod);
266  return 0;
267 }
268 
270  LLVMValueRef *OutFn) {
271  if (Function *F = unwrap(EE)->FindFunctionNamed(Name)) {
272  *OutFn = wrap(F);
273  return 0;
274  }
275  return 1;
276 }
277 
279  LLVMValueRef Fn) {
280  return nullptr;
281 }
282 
284  return wrap(&unwrap(EE)->getDataLayout());
285 }
286 
289  return wrap(unwrap(EE)->getTargetMachine());
290 }
291 
293  void* Addr) {
294  unwrap(EE)->addGlobalMapping(unwrap<GlobalValue>(Global), Addr);
295 }
296 
298  unwrap(EE)->finalizeObject();
299 
300  return unwrap(EE)->getPointerToGlobal(unwrap<GlobalValue>(Global));
301 }
302 
304  return unwrap(EE)->getGlobalValueAddress(Name);
305 }
306 
308  return unwrap(EE)->getFunctionAddress(Name);
309 }
310 
311 /*===-- Operations on memory managers -------------------------------------===*/
312 
313 namespace {
314 
315 struct SimpleBindingMMFunctions {
320 };
321 
322 class SimpleBindingMemoryManager : public RTDyldMemoryManager {
323 public:
324  SimpleBindingMemoryManager(const SimpleBindingMMFunctions& Functions,
325  void *Opaque);
326  ~SimpleBindingMemoryManager() override;
327 
328  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
329  unsigned SectionID,
330  StringRef SectionName) override;
331 
332  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
333  unsigned SectionID, StringRef SectionName,
334  bool isReadOnly) override;
335 
336  bool finalizeMemory(std::string *ErrMsg) override;
337 
338 private:
339  SimpleBindingMMFunctions Functions;
340  void *Opaque;
341 };
342 
343 SimpleBindingMemoryManager::SimpleBindingMemoryManager(
344  const SimpleBindingMMFunctions& Functions,
345  void *Opaque)
346  : Functions(Functions), Opaque(Opaque) {
347  assert(Functions.AllocateCodeSection &&
348  "No AllocateCodeSection function provided!");
349  assert(Functions.AllocateDataSection &&
350  "No AllocateDataSection function provided!");
351  assert(Functions.FinalizeMemory &&
352  "No FinalizeMemory function provided!");
353  assert(Functions.Destroy &&
354  "No Destroy function provided!");
355 }
356 
357 SimpleBindingMemoryManager::~SimpleBindingMemoryManager() {
358  Functions.Destroy(Opaque);
359 }
360 
361 uint8_t *SimpleBindingMemoryManager::allocateCodeSection(
362  uintptr_t Size, unsigned Alignment, unsigned SectionID,
364  return Functions.AllocateCodeSection(Opaque, Size, Alignment, SectionID,
365  SectionName.str().c_str());
366 }
367 
368 uint8_t *SimpleBindingMemoryManager::allocateDataSection(
369  uintptr_t Size, unsigned Alignment, unsigned SectionID,
370  StringRef SectionName, bool isReadOnly) {
371  return Functions.AllocateDataSection(Opaque, Size, Alignment, SectionID,
372  SectionName.str().c_str(),
373  isReadOnly);
374 }
375 
376 bool SimpleBindingMemoryManager::finalizeMemory(std::string *ErrMsg) {
377  char *errMsgCString = nullptr;
378  bool result = Functions.FinalizeMemory(Opaque, &errMsgCString);
379  assert((result || !errMsgCString) &&
380  "Did not expect an error message if FinalizeMemory succeeded");
381  if (errMsgCString) {
382  if (ErrMsg)
383  *ErrMsg = errMsgCString;
384  free(errMsgCString);
385  }
386  return result;
387 }
388 
389 } // anonymous namespace
390 
392  void *Opaque,
397 
398  if (!AllocateCodeSection || !AllocateDataSection || !FinalizeMemory ||
399  !Destroy)
400  return nullptr;
401 
402  SimpleBindingMMFunctions functions;
403  functions.AllocateCodeSection = AllocateCodeSection;
404  functions.AllocateDataSection = AllocateDataSection;
405  functions.FinalizeMemory = FinalizeMemory;
406  functions.Destroy = Destroy;
407  return wrap(new SimpleBindingMemoryManager(functions, Opaque));
408 }
409 
411  delete unwrap(MM);
412 }
413 
414 /*===-- JIT Event Listener functions -------------------------------------===*/
415 
416 
417 #if !LLVM_USE_INTEL_JITEVENTS
419 {
420  return nullptr;
421 }
422 #endif
423 
424 #if !LLVM_USE_OPROFILE
426 {
427  return nullptr;
428 }
429 #endif
430 
431 #if !LLVM_USE_PERF
433 {
434  return nullptr;
435 }
436 #endif
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
PointerTy PointerVal
Definition: GenericValue.h:31
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:1571
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:232
void LLVMInitializeMCJITCompilerOptions(LLVMMCJITCompilerOptions *PassedOptions, size_t SizeOfPassedOptions)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
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:58
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
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)
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:204
LLVMJITEventListenerRef LLVMCreateOProfileJITEventListener(void)
LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P)
void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global, void *Addr)
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:1583
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)
amdgpu propagate attributes Late propagate attributes from kernels to functions
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:69
static char getTypeID(Type *Ty)
ExecutionEngine * create()
void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE)
LLVMAttributeRef wrap(Attribute Attr)
Definition: Attributes.h:199
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:46
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:59
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
void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F)
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:65
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
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)