/** * Allocate gallivm LLVM objects. * \return TRUE for success, FALSE for failure */ static boolean init_gallivm_state(struct gallivm_state *gallivm) { assert(!gallivm->context); assert(!gallivm->module); assert(!gallivm->provider); lp_build_init(); gallivm->context = LLVMContextCreate(); if (!gallivm->context) goto fail; gallivm->module = LLVMModuleCreateWithNameInContext("gallivm", gallivm->context); if (!gallivm->module) goto fail; gallivm->provider = LLVMCreateModuleProviderForExistingModule(gallivm->module); if (!gallivm->provider) goto fail; if (!GlobalEngine) { /* We can only create one LLVMExecutionEngine (w/ LLVM 2.6 anyway) */ enum LLVM_CodeGenOpt_Level optlevel; char *error = NULL; if (gallivm_debug & GALLIVM_DEBUG_NO_OPT) { optlevel = None; } else { optlevel = Default; } if (LLVMCreateJITCompiler(&GlobalEngine, gallivm->provider, (unsigned) optlevel, &error)) { _debug_printf("%s\n", error); LLVMDisposeMessage(error); goto fail; } #if defined(DEBUG) || defined(PROFILE) lp_register_oprofile_jit_event_listener(GlobalEngine); #endif } gallivm->engine = GlobalEngine; LLVMAddModuleProvider(gallivm->engine, gallivm->provider);//new gallivm->target = LLVMGetExecutionEngineTargetData(gallivm->engine); if (!gallivm->target) goto fail; if (!create_pass_manager(gallivm)) goto fail; gallivm->builder = LLVMCreateBuilderInContext(gallivm->context); if (!gallivm->builder) goto fail; return TRUE; fail: free_gallivm_state(gallivm); return FALSE; }
/** * Allocate gallivm LLVM objects. * \return TRUE for success, FALSE for failure */ static boolean init_gallivm_state(struct gallivm_state *gallivm) { assert(!gallivm->context); assert(!gallivm->module); assert(!gallivm->provider); lp_build_init(); if (!gallivm_context) { gallivm_context = LLVMContextCreate(); } gallivm->context = gallivm_context; if (!gallivm->context) goto fail; gallivm->module = LLVMModuleCreateWithNameInContext("gallivm", gallivm->context); if (!gallivm->module) goto fail; gallivm->provider = LLVMCreateModuleProviderForExistingModule(gallivm->module); if (!gallivm->provider) goto fail; gallivm->builder = LLVMCreateBuilderInContext(gallivm->context); if (!gallivm->builder) goto fail; /* FIXME: MC-JIT only allows compiling one module at a time, and it must be * complete when MC-JIT is created. So defer the MC-JIT engine creation for * now. */ #if !USE_MCJIT if (!init_gallivm_engine(gallivm)) { goto fail; } #else /* * MC-JIT engine compiles the module immediately on creation, so we can't * obtain the target data from it. Instead we create a target data layout * from a string. * * The produced layout strings are not precisely the same, but should make * no difference for the kind of optimization passes we run. * * For reference this is the layout string on x64: * * e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64 * * See also: * - http://llvm.org/docs/LangRef.html#datalayout */ { const unsigned pointer_size = 8 * sizeof(void *); char layout[512]; util_snprintf(layout, sizeof layout, "%c-p:%u:%u:%u-i64:64:64-a0:0:%u-s0:%u:%u", #ifdef PIPE_ARCH_LITTLE_ENDIAN 'e', // little endian #else 'E', // big endian #endif pointer_size, pointer_size, pointer_size, // pointer size, abi alignment, preferred alignment pointer_size, // aggregate preferred alignment pointer_size, pointer_size); // stack objects abi alignment, preferred alignment gallivm->target = LLVMCreateTargetData(layout); if (!gallivm->target) { return FALSE; } } #endif if (!create_pass_manager(gallivm)) goto fail; return TRUE; fail: free_gallivm_state(gallivm); return FALSE; }