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