X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FExecutionEngine%2FExecutionEngineBindings.cpp;h=88e73bf253e496d2d46d316b714237212751569a;hb=7a88b655ccad0f128ea1a5e8ca433a8827a24ff3;hp=44fa92205b282410d13e310b6fd455a50fd6b984;hpb=d2755af8bda2e0fd80efb46556485c4cdbe8704a;p=oota-llvm.git diff --git a/lib/ExecutionEngine/ExecutionEngineBindings.cpp b/lib/ExecutionEngine/ExecutionEngineBindings.cpp index 44fa92205b2..88e73bf253e 100644 --- a/lib/ExecutionEngine/ExecutionEngineBindings.cpp +++ b/lib/ExecutionEngine/ExecutionEngineBindings.cpp @@ -15,13 +15,16 @@ #include "llvm-c/ExecutionEngine.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/GenericValue.h" +#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Module.h" #include "llvm/Support/ErrorHandling.h" #include using namespace llvm; // Wrapping the C bindings types. -DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef ) +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef) inline DataLayout *unwrap(LLVMTargetDataRef P) { return reinterpret_cast(P); @@ -152,18 +155,27 @@ LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, return 1; } -LLVMBool LLVMCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, - LLVMModuleRef M, - LLVMMCJITCompilerOptions *PassedOptions, - size_t SizeOfPassedOptions, - char **OutError) { +void LLVMInitializeMCJITCompilerOptions(LLVMMCJITCompilerOptions *PassedOptions, + size_t SizeOfPassedOptions) { + LLVMMCJITCompilerOptions options; + memset(&options, 0, sizeof(options)); // Most fields are zero by default. + options.CodeModel = LLVMCodeModelJITDefault; + + memcpy(PassedOptions, &options, + std::min(sizeof(options), SizeOfPassedOptions)); +} + +LLVMBool LLVMCreateMCJITCompilerForModule( + LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M, + LLVMMCJITCompilerOptions *PassedOptions, size_t SizeOfPassedOptions, + char **OutError) { LLVMMCJITCompilerOptions options; // If the user passed a larger sized options struct, then they were compiled // against a newer LLVM. Tell them that something is wrong. if (SizeOfPassedOptions > sizeof(options)) { *OutError = strdup( - "Refusing to use options struct that is larger than my own; assuming LLVM " - "library mismatch."); + "Refusing to use options struct that is larger than my own; assuming " + "LLVM library mismatch."); return 1; } @@ -171,11 +183,12 @@ LLVMBool LLVMCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, // any fields they didn't see are cleared. We must defend against fields being // set to the bitwise equivalent of zero, and assume that this means "do the // default" as if that option hadn't been available. - memset(&options, 0, sizeof(options)); + LLVMInitializeMCJITCompilerOptions(&options, sizeof(options)); memcpy(&options, PassedOptions, SizeOfPassedOptions); TargetOptions targetOptions; targetOptions.NoFramePointerElim = options.NoFramePointerElim; + targetOptions.EnableFastISel = options.EnableFastISel; std::string Error; EngineBuilder builder(unwrap(M)); @@ -183,7 +196,10 @@ LLVMBool LLVMCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, .setErrorStr(&Error) .setUseMCJIT(true) .setOptLevel((CodeGenOpt::Level)options.OptLevel) + .setCodeModel(unwrap(options.CodeModel)) .setTargetOptions(targetOptions); + if (options.MCJMM) + builder.setMCJITMemoryManager(unwrap(options.MCJMM)); if (ExecutionEngine *JIT = builder.create()) { *OutJIT = wrap(JIT); return 0; @@ -298,7 +314,8 @@ LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name, return 1; } -void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE, LLVMValueRef Fn) { +void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE, + LLVMValueRef Fn) { return unwrap(EE)->recompileAndRelinkFunction(unwrap(Fn)); } @@ -316,3 +333,110 @@ void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global) { return unwrap(EE)->getPointerToGlobal(unwrap(Global)); } + +/*===-- Operations on memory managers -------------------------------------===*/ + +namespace { + +struct SimpleBindingMMFunctions { + uint8_t *(*AllocateCodeSection)(void *Opaque, + uintptr_t Size, unsigned Alignment, + unsigned SectionID); + uint8_t *(*AllocateDataSection)(void *Opaque, + uintptr_t Size, unsigned Alignment, + unsigned SectionID, LLVMBool IsReadOnly); + LLVMBool (*FinalizeMemory)(void *Opaque, char **ErrMsg); + void (*Destroy)(void *Opaque); +}; + +class SimpleBindingMemoryManager : public RTDyldMemoryManager { +public: + SimpleBindingMemoryManager(const SimpleBindingMMFunctions& Functions, + void *Opaque); + virtual ~SimpleBindingMemoryManager(); + + virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID); + + virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, + bool isReadOnly); + + virtual bool finalizeMemory(std::string *ErrMsg); + +private: + SimpleBindingMMFunctions Functions; + void *Opaque; +}; + +SimpleBindingMemoryManager::SimpleBindingMemoryManager( + const SimpleBindingMMFunctions& Functions, + void *Opaque) + : Functions(Functions), Opaque(Opaque) { + assert(Functions.AllocateCodeSection && + "No AllocateCodeSection function provided!"); + assert(Functions.AllocateDataSection && + "No AllocateDataSection function provided!"); + assert(Functions.FinalizeMemory && + "No FinalizeMemory function provided!"); + assert(Functions.Destroy && + "No Destroy function provided!"); +} + +SimpleBindingMemoryManager::~SimpleBindingMemoryManager() { + Functions.Destroy(Opaque); +} + +uint8_t *SimpleBindingMemoryManager::allocateCodeSection( + uintptr_t Size, unsigned Alignment, unsigned SectionID) { + return Functions.AllocateCodeSection(Opaque, Size, Alignment, SectionID); +} + +uint8_t *SimpleBindingMemoryManager::allocateDataSection( + uintptr_t Size, unsigned Alignment, unsigned SectionID, bool isReadOnly) { + return Functions.AllocateDataSection(Opaque, Size, Alignment, SectionID, + isReadOnly); +} + +bool SimpleBindingMemoryManager::finalizeMemory(std::string *ErrMsg) { + char *errMsgCString = 0; + bool result = Functions.FinalizeMemory(Opaque, &errMsgCString); + assert((result || !errMsgCString) && + "Did not expect an error message if FinalizeMemory succeeded"); + if (errMsgCString) { + if (ErrMsg) + *ErrMsg = errMsgCString; + free(errMsgCString); + } + return result; +} + +} // anonymous namespace + +LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager( + void *Opaque, + uint8_t *(*AllocateCodeSection)(void *Opaque, + uintptr_t Size, unsigned Alignment, + unsigned SectionID), + uint8_t *(*AllocateDataSection)(void *Opaque, + uintptr_t Size, unsigned Alignment, + unsigned SectionID, LLVMBool IsReadOnly), + LLVMBool (*FinalizeMemory)(void *Opaque, char **ErrMsg), + void (*Destroy)(void *Opaque)) { + + if (!AllocateCodeSection || !AllocateDataSection || !FinalizeMemory || + !Destroy) + return NULL; + + SimpleBindingMMFunctions functions; + functions.AllocateCodeSection = AllocateCodeSection; + functions.AllocateDataSection = AllocateDataSection; + functions.FinalizeMemory = FinalizeMemory; + functions.Destroy = Destroy; + return wrap(new SimpleBindingMemoryManager(functions, Opaque)); +} + +void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM) { + delete unwrap(MM); +} +