LLVMCompiledProgram LLVM_compile(ASTNode *node) { char *error = NULL; // Used to retrieve messages from functions LLVMLinkInJIT(); LLVMInitializeNativeTarget(); LLVMModuleRef mod = LLVMModuleCreateWithName("calc_module"); LLVMTypeRef program_args[] = { }; LLVMValueRef program = LLVMAddFunction(mod, "program", LLVMFunctionType(LLVMInt32Type(), program_args, 0, 0)); LLVMSetFunctionCallConv(program, LLVMCCallConv); LLVMBuilderRef builder = LLVMCreateBuilder(); LLVMBasicBlockRef entry = LLVMAppendBasicBlock(program, "entry"); LLVMPositionBuilderAtEnd(builder, entry); LLVMValueRef res = LLVM_visit(node, builder); LLVMBuildRet(builder, res); LLVMVerifyModule(mod, LLVMAbortProcessAction, &error); LLVMDisposeMessage(error); // Handler == LLVMAbortProcessAction -> No need to check errors LLVMDisposeBuilder(builder); return (LLVMCompiledProgram) { .module = mod, .function = program }; }
int main(int argc, char const *argv[]) { LLVMModuleRef mod = LLVMModuleCreateWithName("sum"); LLVMTypeRef param_types[] = { LLVMInt32Type(), LLVMInt32Type() }; LLVMTypeRef ret_type = LLVMFunctionType(LLVMInt32Type(), /* ret type */ param_types, /* arg types */ 2, /* arg count */ 0 /* is variadic */); LLVMValueRef sum = LLVMAddFunction(mod, "sum", ret_type); LLVMBasicBlockRef entry = LLVMAppendBasicBlock(sum, "entry"); LLVMBuilderRef builder = LLVMCreateBuilder(); LLVMPositionBuilderAtEnd(builder, entry); LLVMValueRef tmp = LLVMBuildAdd(builder, LLVMGetParam(sum, 0), LLVMGetParam(sum, 1), "tmp"); LLVMBuildRet(builder, tmp); char *error = NULL; LLVMVerifyModule(mod, LLVMAbortProcessAction, &error); LLVMDisposeMessage(error); LLVMExecutionEngineRef engine; error = NULL; LLVMLinkInJIT(); LLVMInitializeNativeTarget(); if (LLVMCreateExecutionEngineForModule(&engine, mod, &error) != 0) { fprintf(stderr, "failed to create execution engine\n"); abort(); } if (error) { fprintf(stderr, "error: %s\n", error); LLVMDisposeMessage(error); exit(EXIT_FAILURE); } if (argc < 3) { fprintf(stderr, "usage: %s x y\n", argv[0]); exit(EXIT_FAILURE); } long long x = strtoll(argv[1], NULL, 10); long long y = strtoll(argv[2], NULL, 10); LLVMGenericValueRef args[] = { LLVMCreateGenericValueOfInt(LLVMInt32Type(), x, 0), LLVMCreateGenericValueOfInt(LLVMInt32Type(), y, 0), }; LLVMGenericValueRef res = LLVMRunFunction(engine, sum, 2, args); printf("%d\n", (int)LLVMGenericValueToInt(res, 0)); // write bitcode to file if (LLVMWriteBitcodeToFile(mod, "sum.bc") != 0) { fprintf(stderr, "error writing bitcode to file\n"); } LLVMDisposeBuilder(builder); LLVMDisposeExecutionEngine(engine); }
void llvm_new_compiler(lua_State *L) { global_State *g = G(L); if(g_need_init) { LLVMLinkInJIT(); LLVMInitializeNativeTarget(); g_need_init = 0; } g->llvm_compiler = new LLVMCompiler(g_useJIT); }
void lp_build_init(void) { if (gallivm_initialized) return; #ifdef DEBUG gallivm_debug = debug_get_option_gallivm_debug(); #endif lp_set_target_options(); #if USE_MCJIT LLVMLinkInMCJIT(); #else LLVMLinkInJIT(); #endif util_cpu_detect(); /* AMD Bulldozer AVX's throughput is the same as SSE2; and because using * 8-wide vector needs more floating ops than 4-wide (due to padding), it is * actually more efficient to use 4-wide vectors on this processor. * * See also: * - http://www.anandtech.com/show/4955/the-bulldozer-review-amd-fx8150-tested/2 */ if (HAVE_AVX && util_cpu_caps.has_avx && util_cpu_caps.has_intel) { lp_native_vector_width = 256; } else { /* Leave it at 128, even when no SIMD extensions are available. * Really needs to be a multiple of 128 so can fit 4 floats. */ lp_native_vector_width = 128; } lp_native_vector_width = debug_get_num_option("LP_NATIVE_VECTOR_WIDTH", lp_native_vector_width); gallivm_initialized = TRUE; #if 0 /* For simulating less capable machines */ util_cpu_caps.has_sse3 = 0; util_cpu_caps.has_ssse3 = 0; util_cpu_caps.has_sse4_1 = 0; #endif }
static void jit_init_llvm(const char *path) { char *error; LLVMMemoryBufferRef buf; if (LLVMCreateMemoryBufferWithContentsOfFile(path, &buf, &error)) fatal("error reading bitcode from %s: %s", path, error); if (LLVMParseBitcode(buf, &module, &error)) fatal("error parsing bitcode: %s", error); LLVMDisposeMemoryBuffer(buf); LLVMInitializeNativeTarget(); LLVMLinkInJIT(); if (LLVMCreateExecutionEngineForModule(&exec_engine, module, &error)) fatal("error creating execution engine: %s", error); }
void lp_build_init(void) { if (gallivm_initialized) return; #ifdef DEBUG gallivm_debug = debug_get_option_gallivm_debug(); #endif lp_set_target_options(); #if USE_MCJIT LLVMLinkInMCJIT(); #else LLVMLinkInJIT(); #endif util_cpu_detect(); if (HAVE_AVX && util_cpu_caps.has_avx) { lp_native_vector_width = 256; } else { /* Leave it at 128, even when no SIMD extensions are available. * Really needs to be a multiple of 128 so can fit 4 floats. */ lp_native_vector_width = 128; } lp_native_vector_width = debug_get_num_option("LP_NATIVE_VECTOR_WIDTH", lp_native_vector_width); gallivm_initialized = TRUE; #if 0 /* For simulating less capable machines */ util_cpu_caps.has_sse3 = 0; util_cpu_caps.has_ssse3 = 0; util_cpu_caps.has_sse4_1 = 0; #endif }
void JITImpl::init() { if (initialized) return; LLVMLinkInJIT(); LLVMInitializeNativeTarget(); LLVMMemoryBufferRef memBuffer = LLVMExtraCreateMemoryBufferWithPtr(instructionBitcode, instructionBitcodeSize); char *outMessage; if (LLVMParseBitcode(memBuffer, &module, &outMessage)) { std::cerr << "Error loading bitcode: " << outMessage << '\n'; std::abort(); } // TODO experiment with opt level. if (LLVMCreateJITCompilerForModule(&executionEngine, module, 1, &outMessage)) { std::cerr << "Error creating JIT compiler: " << outMessage << '\n'; std::abort(); } builder = LLVMCreateBuilder(); LLVMValueRef callee = LLVMGetNamedFunction(module, "jitInstructionTemplate"); assert(callee && "jitInstructionTemplate() not found in module"); jitFunctionType = LLVMGetElementType(LLVMTypeOf(callee)); functions.init(module); FPM = LLVMCreateFunctionPassManagerForModule(module); LLVMAddTargetData(LLVMGetExecutionEngineTargetData(executionEngine), FPM); LLVMAddBasicAliasAnalysisPass(FPM); LLVMAddJumpThreadingPass(FPM); LLVMAddGVNPass(FPM); LLVMAddJumpThreadingPass(FPM); LLVMAddCFGSimplificationPass(FPM); LLVMAddDeadStoreEliminationPass(FPM); LLVMAddInstructionCombiningPass(FPM); LLVMInitializeFunctionPassManager(FPM); if (DEBUG_JIT) { LLVMExtraRegisterJitDisassembler(executionEngine, LLVMGetTarget(module)); } initialized = true; }
int main(int argc, char **argv) { unsigned verbose = 0; FILE *fp = NULL; unsigned long n = 1000; unsigned i; boolean success; for(i = 1; i < argc; ++i) { if(strcmp(argv[i], "-v") == 0) ++verbose; else if(strcmp(argv[i], "-o") == 0) fp = fopen(argv[++i], "wt"); else n = atoi(argv[i]); } LLVMLinkInJIT(); LLVMInitializeNativeTarget(); util_cpu_detect(); if(fp) { /* Warm up the caches */ test_some(0, NULL, 100); write_tsv_header(fp); } if(n) success = test_some(verbose, fp, n); else success = test_all(verbose, fp); if(fp) fclose(fp); return success ? 0 : 1; }
/* Force the LLVM interpreter and JIT to be linked in. */ void llvm_initialize(void) { LLVMLinkInInterpreter(); LLVMLinkInJIT(); }
SWIGEXPORT void JNICALL Java_org_jllvm_bindings_ExecutionEngineJNI_LLVMLinkInJIT(JNIEnv *jenv, jclass jcls) { (void)jenv; (void)jcls; LLVMLinkInJIT(); }
void lp_build_init(void) { #ifdef DEBUG gallivm_debug = debug_get_option_gallivm_debug(); #endif lp_set_target_options(); LLVMInitializeNativeTarget(); LLVMLinkInJIT(); if (!lp_build_module) lp_build_module = LLVMModuleCreateWithName("gallivm"); if (!lp_build_provider) lp_build_provider = LLVMCreateModuleProviderForExistingModule(lp_build_module); if (!lp_build_engine) { enum LLVM_CodeGenOpt_Level optlevel; char *error = NULL; if (gallivm_debug & GALLIVM_DEBUG_NO_OPT) { optlevel = None; } else { optlevel = Default; } if (LLVMCreateJITCompiler(&lp_build_engine, lp_build_provider, (unsigned)optlevel, &error)) { _debug_printf("%s\n", error); LLVMDisposeMessage(error); assert(0); } #if defined(DEBUG) || defined(PROFILE) lp_register_oprofile_jit_event_listener(lp_build_engine); #endif } if (!lp_build_target) lp_build_target = LLVMGetExecutionEngineTargetData(lp_build_engine); if (!lp_build_pass) { lp_build_pass = LLVMCreateFunctionPassManager(lp_build_provider); LLVMAddTargetData(lp_build_target, lp_build_pass); if ((gallivm_debug & GALLIVM_DEBUG_NO_OPT) == 0) { /* These are the passes currently listed in llvm-c/Transforms/Scalar.h, * but there are more on SVN. */ /* TODO: Add more passes */ LLVMAddCFGSimplificationPass(lp_build_pass); LLVMAddPromoteMemoryToRegisterPass(lp_build_pass); LLVMAddConstantPropagationPass(lp_build_pass); if(util_cpu_caps.has_sse4_1) { /* FIXME: There is a bug in this pass, whereby the combination of fptosi * and sitofp (necessary for trunc/floor/ceil/round implementation) * somehow becomes invalid code. */ LLVMAddInstructionCombiningPass(lp_build_pass); } LLVMAddGVNPass(lp_build_pass); } else { /* We need at least this pass to prevent the backends to fail in * unexpected ways. */ LLVMAddPromoteMemoryToRegisterPass(lp_build_pass); } } util_cpu_detect(); #if 0 /* For simulating less capable machines */ util_cpu_caps.has_sse3 = 0; util_cpu_caps.has_ssse3 = 0; util_cpu_caps.has_sse4_1 = 0; #endif }