ExecutionEngineBindings.cpp revision 251662
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#define DEBUG_TYPE "jit"
15#include "llvm-c/ExecutionEngine.h"
16#include "llvm/ExecutionEngine/ExecutionEngine.h"
17#include "llvm/ExecutionEngine/GenericValue.h"
18#include "llvm/IR/DerivedTypes.h"
19#include "llvm/IR/Module.h"
20#include "llvm/Support/ErrorHandling.h"
21#include <cstring>
22
23using namespace llvm;
24
25// Wrapping the C bindings types.
26DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef)
27
28inline DataLayout *unwrap(LLVMTargetDataRef P) {
29  return reinterpret_cast<DataLayout*>(P);
30}
31
32inline LLVMTargetDataRef wrap(const DataLayout *P) {
33  return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P));
34}
35
36inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {
37  return reinterpret_cast<TargetLibraryInfo*>(P);
38}
39
40inline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfo *P) {
41  TargetLibraryInfo *X = const_cast<TargetLibraryInfo*>(P);
42  return reinterpret_cast<LLVMTargetLibraryInfoRef>(X);
43}
44
45/*===-- Operations on generic values --------------------------------------===*/
46
47LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty,
48                                                unsigned long long N,
49                                                LLVMBool IsSigned) {
50  GenericValue *GenVal = new GenericValue();
51  GenVal->IntVal = APInt(unwrap<IntegerType>(Ty)->getBitWidth(), N, IsSigned);
52  return wrap(GenVal);
53}
54
55LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P) {
56  GenericValue *GenVal = new GenericValue();
57  GenVal->PointerVal = P;
58  return wrap(GenVal);
59}
60
61LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef TyRef, double N) {
62  GenericValue *GenVal = new GenericValue();
63  switch (unwrap(TyRef)->getTypeID()) {
64  case Type::FloatTyID:
65    GenVal->FloatVal = N;
66    break;
67  case Type::DoubleTyID:
68    GenVal->DoubleVal = N;
69    break;
70  default:
71    llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
72  }
73  return wrap(GenVal);
74}
75
76unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef) {
77  return unwrap(GenValRef)->IntVal.getBitWidth();
78}
79
80unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenValRef,
81                                         LLVMBool IsSigned) {
82  GenericValue *GenVal = unwrap(GenValRef);
83  if (IsSigned)
84    return GenVal->IntVal.getSExtValue();
85  else
86    return GenVal->IntVal.getZExtValue();
87}
88
89void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal) {
90  return unwrap(GenVal)->PointerVal;
91}
92
93double LLVMGenericValueToFloat(LLVMTypeRef TyRef, LLVMGenericValueRef GenVal) {
94  switch (unwrap(TyRef)->getTypeID()) {
95  case Type::FloatTyID:
96    return unwrap(GenVal)->FloatVal;
97  case Type::DoubleTyID:
98    return unwrap(GenVal)->DoubleVal;
99  default:
100    llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
101  }
102}
103
104void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal) {
105  delete unwrap(GenVal);
106}
107
108/*===-- Operations on execution engines -----------------------------------===*/
109
110LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE,
111                                            LLVMModuleRef M,
112                                            char **OutError) {
113  std::string Error;
114  EngineBuilder builder(unwrap(M));
115  builder.setEngineKind(EngineKind::Either)
116         .setErrorStr(&Error);
117  if (ExecutionEngine *EE = builder.create()){
118    *OutEE = wrap(EE);
119    return 0;
120  }
121  *OutError = strdup(Error.c_str());
122  return 1;
123}
124
125LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp,
126                                        LLVMModuleRef M,
127                                        char **OutError) {
128  std::string Error;
129  EngineBuilder builder(unwrap(M));
130  builder.setEngineKind(EngineKind::Interpreter)
131         .setErrorStr(&Error);
132  if (ExecutionEngine *Interp = builder.create()) {
133    *OutInterp = wrap(Interp);
134    return 0;
135  }
136  *OutError = strdup(Error.c_str());
137  return 1;
138}
139
140LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
141                                        LLVMModuleRef M,
142                                        unsigned OptLevel,
143                                        char **OutError) {
144  std::string Error;
145  EngineBuilder builder(unwrap(M));
146  builder.setEngineKind(EngineKind::JIT)
147         .setErrorStr(&Error)
148         .setOptLevel((CodeGenOpt::Level)OptLevel);
149  if (ExecutionEngine *JIT = builder.create()) {
150    *OutJIT = wrap(JIT);
151    return 0;
152  }
153  *OutError = strdup(Error.c_str());
154  return 1;
155}
156
157void LLVMInitializeMCJITCompilerOptions(LLVMMCJITCompilerOptions *PassedOptions,
158                                        size_t SizeOfPassedOptions) {
159  LLVMMCJITCompilerOptions options;
160  options.OptLevel = 0;
161  options.CodeModel = LLVMCodeModelJITDefault;
162  options.NoFramePointerElim = false;
163  options.EnableFastISel = false;
164
165  memcpy(PassedOptions, &options,
166         std::min(sizeof(options), SizeOfPassedOptions));
167}
168
169LLVMBool LLVMCreateMCJITCompilerForModule(
170    LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M,
171    LLVMMCJITCompilerOptions *PassedOptions, size_t SizeOfPassedOptions,
172    char **OutError) {
173  LLVMMCJITCompilerOptions options;
174  // If the user passed a larger sized options struct, then they were compiled
175  // against a newer LLVM. Tell them that something is wrong.
176  if (SizeOfPassedOptions > sizeof(options)) {
177    *OutError = strdup(
178      "Refusing to use options struct that is larger than my own; assuming "
179      "LLVM library mismatch.");
180    return 1;
181  }
182
183  // Defend against the user having an old version of the API by ensuring that
184  // any fields they didn't see are cleared. We must defend against fields being
185  // set to the bitwise equivalent of zero, and assume that this means "do the
186  // default" as if that option hadn't been available.
187  LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
188  memcpy(&options, PassedOptions, SizeOfPassedOptions);
189
190  TargetOptions targetOptions;
191  targetOptions.NoFramePointerElim = options.NoFramePointerElim;
192  targetOptions.EnableFastISel = options.EnableFastISel;
193
194  std::string Error;
195  EngineBuilder builder(unwrap(M));
196  builder.setEngineKind(EngineKind::JIT)
197         .setErrorStr(&Error)
198         .setUseMCJIT(true)
199         .setOptLevel((CodeGenOpt::Level)options.OptLevel)
200         .setCodeModel(unwrap(options.CodeModel))
201         .setTargetOptions(targetOptions);
202  if (ExecutionEngine *JIT = builder.create()) {
203    *OutJIT = wrap(JIT);
204    return 0;
205  }
206  *OutError = strdup(Error.c_str());
207  return 1;
208}
209
210LLVMBool LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE,
211                                   LLVMModuleProviderRef MP,
212                                   char **OutError) {
213  /* The module provider is now actually a module. */
214  return LLVMCreateExecutionEngineForModule(OutEE,
215                                            reinterpret_cast<LLVMModuleRef>(MP),
216                                            OutError);
217}
218
219LLVMBool LLVMCreateInterpreter(LLVMExecutionEngineRef *OutInterp,
220                               LLVMModuleProviderRef MP,
221                               char **OutError) {
222  /* The module provider is now actually a module. */
223  return LLVMCreateInterpreterForModule(OutInterp,
224                                        reinterpret_cast<LLVMModuleRef>(MP),
225                                        OutError);
226}
227
228LLVMBool LLVMCreateJITCompiler(LLVMExecutionEngineRef *OutJIT,
229                               LLVMModuleProviderRef MP,
230                               unsigned OptLevel,
231                               char **OutError) {
232  /* The module provider is now actually a module. */
233  return LLVMCreateJITCompilerForModule(OutJIT,
234                                        reinterpret_cast<LLVMModuleRef>(MP),
235                                        OptLevel, OutError);
236}
237
238
239void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE) {
240  delete unwrap(EE);
241}
242
243void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE) {
244  unwrap(EE)->runStaticConstructorsDestructors(false);
245}
246
247void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE) {
248  unwrap(EE)->runStaticConstructorsDestructors(true);
249}
250
251int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F,
252                          unsigned ArgC, const char * const *ArgV,
253                          const char * const *EnvP) {
254  unwrap(EE)->finalizeObject();
255
256  std::vector<std::string> ArgVec;
257  for (unsigned I = 0; I != ArgC; ++I)
258    ArgVec.push_back(ArgV[I]);
259
260  return unwrap(EE)->runFunctionAsMain(unwrap<Function>(F), ArgVec, EnvP);
261}
262
263LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F,
264                                    unsigned NumArgs,
265                                    LLVMGenericValueRef *Args) {
266  unwrap(EE)->finalizeObject();
267
268  std::vector<GenericValue> ArgVec;
269  ArgVec.reserve(NumArgs);
270  for (unsigned I = 0; I != NumArgs; ++I)
271    ArgVec.push_back(*unwrap(Args[I]));
272
273  GenericValue *Result = new GenericValue();
274  *Result = unwrap(EE)->runFunction(unwrap<Function>(F), ArgVec);
275  return wrap(Result);
276}
277
278void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) {
279  unwrap(EE)->freeMachineCodeForFunction(unwrap<Function>(F));
280}
281
282void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M){
283  unwrap(EE)->addModule(unwrap(M));
284}
285
286void LLVMAddModuleProvider(LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP){
287  /* The module provider is now actually a module. */
288  LLVMAddModule(EE, reinterpret_cast<LLVMModuleRef>(MP));
289}
290
291LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M,
292                          LLVMModuleRef *OutMod, char **OutError) {
293  Module *Mod = unwrap(M);
294  unwrap(EE)->removeModule(Mod);
295  *OutMod = wrap(Mod);
296  return 0;
297}
298
299LLVMBool LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE,
300                                  LLVMModuleProviderRef MP,
301                                  LLVMModuleRef *OutMod, char **OutError) {
302  /* The module provider is now actually a module. */
303  return LLVMRemoveModule(EE, reinterpret_cast<LLVMModuleRef>(MP), OutMod,
304                          OutError);
305}
306
307LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
308                          LLVMValueRef *OutFn) {
309  if (Function *F = unwrap(EE)->FindFunctionNamed(Name)) {
310    *OutFn = wrap(F);
311    return 0;
312  }
313  return 1;
314}
315
316void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE,
317                                     LLVMValueRef Fn) {
318  return unwrap(EE)->recompileAndRelinkFunction(unwrap<Function>(Fn));
319}
320
321LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE) {
322  return wrap(unwrap(EE)->getDataLayout());
323}
324
325void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
326                          void* Addr) {
327  unwrap(EE)->addGlobalMapping(unwrap<GlobalValue>(Global), Addr);
328}
329
330void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global) {
331  unwrap(EE)->finalizeObject();
332
333  return unwrap(EE)->getPointerToGlobal(unwrap<GlobalValue>(Global));
334}
335