/* unit -> bool */ CAMLprim value llvm_ee_initialize(value Unit) { LLVMLinkInMCJIT(); return Val_bool(!LLVMInitializeNativeTarget() && !LLVMInitializeNativeAsmParser() && !LLVMInitializeNativeAsmPrinter()); }
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); }
bool codegen_llvm_init() { LLVMLinkInMCJIT(); LLVMInitializeNativeTarget(); LLVMInitializeAllTargets(); LLVMInitializeAllTargetMCs(); LLVMInitializeAllTargetInfos(); LLVMInitializeAllAsmPrinters(); LLVMInitializeAllAsmParsers(); LLVMEnablePrettyStackTrace(); LLVMInstallFatalErrorHandler(fatal_error); LLVMPassRegistryRef passreg = LLVMGetGlobalPassRegistry(); LLVMInitializeCore(passreg); LLVMInitializeTransformUtils(passreg); LLVMInitializeScalarOpts(passreg); LLVMInitializeObjCARCOpts(passreg); LLVMInitializeVectorization(passreg); LLVMInitializeInstCombine(passreg); LLVMInitializeIPO(passreg); LLVMInitializeInstrumentation(passreg); LLVMInitializeAnalysis(passreg); LLVMInitializeIPA(passreg); LLVMInitializeCodeGen(passreg); LLVMInitializeTarget(passreg); return true; }
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 }; }
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); }
Manager(int argc,char* argv[]): debug(0){ if(argc == 2){ input_file = argv[1]; } else if(argc > 2){ option(argc, argv); } else{ std::cerr << "cook: no input files"<< std::endl; } LLVMInitializeNativeTarget(); llvm::sys::PrintStackTraceOnErrorSignal(); }
bool codegen_init(pass_opt_t* opt) { LLVMInitializeNativeTarget(); LLVMInitializeAllTargets(); LLVMInitializeAllTargetMCs(); LLVMInitializeAllTargetInfos(); LLVMInitializeAllAsmPrinters(); LLVMInitializeAllAsmParsers(); LLVMEnablePrettyStackTrace(); LLVMInstallFatalErrorHandler(fatal_error); LLVMPassRegistryRef passreg = LLVMGetGlobalPassRegistry(); LLVMInitializeCore(passreg); LLVMInitializeTransformUtils(passreg); LLVMInitializeScalarOpts(passreg); LLVMInitializeObjCARCOpts(passreg); LLVMInitializeVectorization(passreg); LLVMInitializeInstCombine(passreg); LLVMInitializeIPO(passreg); LLVMInitializeInstrumentation(passreg); LLVMInitializeAnalysis(passreg); LLVMInitializeIPA(passreg); LLVMInitializeCodeGen(passreg); LLVMInitializeTarget(passreg); // Default triple, cpu and features. if(opt->triple != NULL) { opt->triple = LLVMCreateMessage(opt->triple); } else { #ifdef PLATFORM_IS_MACOSX // This is to prevent XCode 7+ from claiming OSX 14.5 is required. opt->triple = LLVMCreateMessage("x86_64-apple-macosx"); #else opt->triple = LLVMGetDefaultTargetTriple(); #endif } if(opt->cpu != NULL) opt->cpu = LLVMCreateMessage(opt->cpu); else opt->cpu = LLVMGetHostCPUName(); if(opt->features != NULL) opt->features = LLVMCreateMessage(opt->features); else opt->features = LLVMCreateMessage(""); return true; }
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); }
bool codegen_init(pass_opt_t* opt) { LLVMInitializeNativeTarget(); LLVMInitializeAllTargets(); LLVMInitializeAllTargetMCs(); LLVMInitializeAllAsmPrinters(); LLVMInitializeAllAsmParsers(); LLVMEnablePrettyStackTrace(); LLVMInstallFatalErrorHandler(fatal_error); LLVMPassRegistryRef passreg = LLVMGetGlobalPassRegistry(); LLVMInitializeCore(passreg); LLVMInitializeTransformUtils(passreg); LLVMInitializeScalarOpts(passreg); LLVMInitializeObjCARCOpts(passreg); LLVMInitializeVectorization(passreg); LLVMInitializeInstCombine(passreg); LLVMInitializeIPO(passreg); LLVMInitializeInstrumentation(passreg); LLVMInitializeAnalysis(passreg); LLVMInitializeIPA(passreg); LLVMInitializeCodeGen(passreg); LLVMInitializeTarget(passreg); // Default triple, cpu and features. if(opt->triple != NULL) opt->triple = LLVMCreateMessage(opt->triple); else opt->triple = LLVMGetDefaultTargetTriple(); if(opt->cpu != NULL) opt->cpu = LLVMCreateMessage(opt->cpu); else opt->cpu = LLVMGetHostCPUName(); if(opt->features != NULL) opt->features = LLVMCreateMessage(opt->features); else opt->features = LLVMCreateMessage(""); return true; }
int main(int argc, char **argv) { int n = argc > 1 ? atol(argv[1]) : 24; LLVMInitializeNativeTarget(); LLVMLinkInInterpreter(); LLVMContextRef Context = LLVMContextCreate(); // Create some module to put our function into it. LLVMModuleRef M = LLVMModuleCreateWithNameInContext("test", Context); // We are about to create the "fib" function: LLVMValueRef FibF = CreateFibFunction(M, Context); // Now we going to create JIT LLVMExecutionEngineRef EE; char * outError; if (LLVMCreateInterpreterForModule(&EE, M, &outError) != 0) { printf("%s\n", outError); return 1; } printf("verifying...\n"); if (LLVMVerifyModule(M, LLVMReturnStatusAction, &outError) != 0) { printf("%s\n", outError); return 1; } printf("OK\n"); printf("We just constructed this LLVM module:\n\n---------\n"); printf("%s\n", LLVMPrintModuleToString(M)); LLVMGenericValueRef Args = LLVMCreateGenericValueOfInt(LLVMInt32TypeInContext(Context), n, 0); LLVMGenericValueRef Result = LLVMRunFunction(EE, FibF, 1, &Args); printf("Result: %llu\n", LLVMGenericValueToInt(Result, 0)); return 0; }
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; }
extern "C" JSC::LLVMAPI* initializeAndGetJSCLLVMAPI(void (*callback)(const char*, ...)) { g_llvmTrapCallback = callback; LLVMInstallFatalErrorHandler(llvmCrash); if (!LLVMStartMultithreaded()) callback("Could not start LLVM multithreading"); LLVMLinkInMCJIT(); LLVMInitializeNativeTarget(); LLVMInitializeX86AsmPrinter(); LLVMInitializeX86Disassembler(); JSC::LLVMAPI* result = new JSC::LLVMAPI; #define LLVM_API_FUNCTION_ASSIGNMENT(returnType, name, signature) \ result->name = LLVM##name; FOR_EACH_LLVM_API_FUNCTION(LLVM_API_FUNCTION_ASSIGNMENT); #undef LLVM_API_FUNCTION_ASSIGNMENT return result; }
LLVMBool LLVMInitializeNativeTarget_() { return LLVMInitializeNativeTarget(); }
/* TODO: funcao booleana teste(booleano x, booleano y, booleano z) retorna (x & y) | (x & z) | (~z & ~y) teste(falso, falso, verdadeiro) funcao real exemplo (real a, real b) retorna (a*b) - 2.0 * (a mod b) exemplo(10.0, 5.0) static Type* getDoubleTy(context) */ int main(){ llvm::LLVMContext &Context = llvm::getGlobalContext(); llvm::Module *OurModule; llvm::IRBuilder<> Builder(Context); OurModule = new llvm::Module("Our first intermediary code", Context); // main llvm::Type* intType = llvm::Type::getInt64Ty(Context); llvm::FunctionType* typeOfMain = llvm::FunctionType::get(intType,false); llvm::Function* ourMain = llvm::Function::Create(typeOfMain,llvm::Function::ExternalLinkage, "main", OurModule); llvm::BasicBlock *mainBB = llvm::BasicBlock::Create(Context, "entry", ourMain); Builder.SetInsertPoint(mainBB); // constants auto Zero_I = llvm::ConstantInt::get(Context, llvm::APInt(1, 0)); auto One_I = llvm::ConstantInt::get(Context, llvm::APInt(1, 1)); auto Two_D = llvm::ConstantFP::get(Context, llvm::APFloat(2.0)); auto Five_D = llvm::ConstantFP::get(Context, llvm::APFloat(5.0)); auto Ten_D = llvm::ConstantFP::get(Context, llvm::APFloat(10.0)); // teste auto boolType = llvm::Type::getInt1Ty(Context); std::vector<llvm::Type*> TesteParameters(3, boolType); llvm::FunctionType* typeOfTeste = llvm::FunctionType::get(boolType, TesteParameters, false); llvm::Function* ourTeste = llvm::Function::Create(typeOfTeste,llvm::Function::ExternalLinkage, "teste", OurModule); llvm::Function::arg_iterator params = ourTeste->arg_begin(); params->setName("x"); ++params; params->setName("y"); ++params; params->setName("z"); llvm::BasicBlock *testeBB = llvm::BasicBlock::Create(Context, "tst", ourTeste); Builder.SetInsertPoint(testeBB); auto x = ourTeste->arg_begin(); auto y = ++(ourTeste->arg_begin()); auto z = ++(++(ourTeste->arg_begin())); auto xANDy = Builder.CreateAnd(x,y,"xANDy"); auto xANDz = Builder.CreateAnd(x,z,"xANDz"); auto notZ = Builder.CreateNot(z, "notZ"); auto notY = Builder.CreateNot(y, "notY"); auto zANDy = Builder.CreateAnd(notZ, notY,"nzANDny"); auto tmp = Builder.CreateOr(xANDy, xANDz, "ortmp"); tmp = Builder.CreateOr(tmp, zANDy, "ortmp"); Builder.CreateRet(tmp); llvm::verifyFunction(*ourTeste); // main Builder.SetInsertPoint(mainBB); std::vector<llvm::Value*> arguments; arguments.push_back(Zero_I); arguments.push_back(Zero_I); arguments.push_back(One_I); auto tstReturn = Builder.CreateCall(ourTeste, arguments, "calltst"); auto intRet = Builder.CreateIntCast(tstReturn, intType, false); Builder.CreateRet(intRet); llvm::verifyFunction(*ourMain); OurModule->dump(); llvm::ExecutionEngine* OurExecutionEngine; std::string Error; LLVMInitializeNativeTarget(); //target = generates code for my processor OurExecutionEngine = llvm::EngineBuilder(OurModule).setErrorStr(&Error).create(); if (!OurExecutionEngine) { fprintf(stderr, "Could not create OurExecutionEngine: %s\n", Error.c_str()); exit(1); } // JIT our main. It returns a function pointer. void *mainPointer = OurExecutionEngine->getPointerToFunction(ourMain); // Translate the pointer and run our main to get its results int (*result)() = (int (*)())(intptr_t)mainPointer; std::cout << "Result of our main = " << result() << std::endl; return 0; }
int main(int c, char **v) { LLVMContextRef *contexts; LLVMModuleRef *modules; char *error; const char *mode = "opt"; const char **filenames; unsigned numFiles; unsigned i; bool moreOptions; static int verboseFlag = 0; static int timingFlag = 0; static int disassembleFlag = 0; bool manyContexts = true; double beforeAll; if (c == 1) usage(); moreOptions = true; while (moreOptions) { static struct option longOptions[] = { {"verbose", no_argument, &verboseFlag, 1}, {"timing", no_argument, &timingFlag, 1}, {"disassemble", no_argument, &disassembleFlag, 1}, {"mode", required_argument, 0, 0}, {"contexts", required_argument, 0, 0}, {"help", no_argument, 0, 0} }; int optionIndex; int optionValue; optionValue = getopt_long(c, v, "", longOptions, &optionIndex); switch (optionValue) { case -1: moreOptions = false; break; case 0: { const char* thisOption = longOptions[optionIndex].name; if (!strcmp(thisOption, "help")) usage(); if (!strcmp(thisOption, "contexts")) { if (!strcasecmp(optarg, "one")) manyContexts = false; else if (!strcasecmp(optarg, "many")) manyContexts = true; else { fprintf(stderr, "Invalid argument for --contexts.\n"); exit(1); } break; } if (!strcmp(thisOption, "mode")) { mode = strdup(optarg); break; } break; } case '?': exit(0); break; default: printf("optionValue = %d\n", optionValue); abort(); break; } } LLVMLinkInMCJIT(); LLVMInitializeNativeTarget(); LLVMInitializeX86AsmPrinter(); LLVMInitializeX86Disassembler(); filenames = (const char **)(v + optind); numFiles = c - optind; contexts = malloc(sizeof(LLVMContextRef) * numFiles); modules = malloc(sizeof(LLVMModuleRef) * numFiles); if (manyContexts) { for (i = 0; i < numFiles; ++i) contexts[i] = LLVMContextCreate(); } else { LLVMContextRef context = LLVMContextCreate(); for (i = 0; i < numFiles; ++i) contexts[i] = context; } for (i = 0; i < numFiles; ++i) { LLVMMemoryBufferRef buffer; const char* filename = filenames[i]; if (LLVMCreateMemoryBufferWithContentsOfFile(filename, &buffer, &error)) { fprintf(stderr, "Error reading file %s: %s\n", filename, error); exit(1); } if (LLVMParseBitcodeInContext(contexts[i], buffer, modules + i, &error)) { fprintf(stderr, "Error parsing file %s: %s\n", filename, error); exit(1); } LLVMDisposeMemoryBuffer(buffer); if (verboseFlag) { printf("Module #%u (%s) after parsing:\n", i, filename); LLVMDumpModule(modules[i]); } } if (verboseFlag) printf("Generating code for modules...\n"); if (timingFlag) beforeAll = currentTime(); for (i = 0; i < numFiles; ++i) { LLVMModuleRef module; LLVMExecutionEngineRef engine; struct LLVMMCJITCompilerOptions options; LLVMValueRef value; LLVMPassManagerRef functionPasses = 0; LLVMPassManagerRef modulePasses = 0; double before; if (timingFlag) before = currentTime(); module = modules[i]; LLVMInitializeMCJITCompilerOptions(&options, sizeof(options)); options.OptLevel = 2; options.EnableFastISel = 0; options.MCJMM = LLVMCreateSimpleMCJITMemoryManager( 0, mmAllocateCodeSection, mmAllocateDataSection, mmApplyPermissions, mmDestroy); if (LLVMCreateMCJITCompilerForModule(&engine, module, &options, sizeof(options), &error)) { fprintf(stderr, "Error building MCJIT: %s\n", error); exit(1); } if (!strcasecmp(mode, "simple")) { modulePasses = LLVMCreatePassManager(); LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), modulePasses); LLVMAddConstantPropagationPass(modulePasses); LLVMAddInstructionCombiningPass(modulePasses); LLVMAddPromoteMemoryToRegisterPass(modulePasses); LLVMAddBasicAliasAnalysisPass(modulePasses); LLVMAddTypeBasedAliasAnalysisPass(modulePasses); LLVMAddGVNPass(modulePasses); LLVMAddCFGSimplificationPass(modulePasses); LLVMRunPassManager(modulePasses, module); } else if (!strcasecmp(mode, "opt")) { LLVMPassManagerBuilderRef passBuilder; passBuilder = LLVMPassManagerBuilderCreate(); LLVMPassManagerBuilderSetOptLevel(passBuilder, 2); LLVMPassManagerBuilderSetSizeLevel(passBuilder, 0); functionPasses = LLVMCreateFunctionPassManagerForModule(module); modulePasses = LLVMCreatePassManager(); LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), modulePasses); LLVMPassManagerBuilderPopulateFunctionPassManager(passBuilder, functionPasses); LLVMPassManagerBuilderPopulateModulePassManager(passBuilder, modulePasses); LLVMPassManagerBuilderDispose(passBuilder); LLVMInitializeFunctionPassManager(functionPasses); for (value = LLVMGetFirstFunction(module); value; value = LLVMGetNextFunction(value)) LLVMRunFunctionPassManager(functionPasses, value); LLVMFinalizeFunctionPassManager(functionPasses); LLVMRunPassManager(modulePasses, module); } else { fprintf(stderr, "Bad optimization mode: %s.\n", mode); fprintf(stderr, "Valid modes are: \"simple\" or \"opt\".\n"); exit(1); } if (verboseFlag) { printf("Module #%d (%s) after optimization:\n", i, filenames[i]); LLVMDumpModule(module); } for (value = LLVMGetFirstFunction(module); value; value = LLVMGetNextFunction(value)) { if (LLVMIsDeclaration(value)) continue; LLVMGetPointerToGlobal(engine, value); } if (functionPasses) LLVMDisposePassManager(functionPasses); if (modulePasses) LLVMDisposePassManager(modulePasses); LLVMDisposeExecutionEngine(engine); if (timingFlag) { double after = currentTime(); printf("Module #%d (%s) took %lf ms.\n", i, filenames[i], (after - before) * 1000); } } if (timingFlag) { double after = currentTime(); printf("Compilation took a total of %lf ms.\n", (after - beforeAll) * 1000); } if (disassembleFlag) { LLVMDisasmContextRef disassembler; struct MemorySection *section; disassembler = LLVMCreateDisasm("x86_64-apple-darwin", 0, 0, 0, symbolLookupCallback); if (!disassembler) { fprintf(stderr, "Error building disassembler.\n"); exit(1); } for (section = sectionHead; section; section = section->next) { printf("Disassembly for section %p:\n", section); char pcString[20]; char instructionString[1000]; uint8_t *pc; uint8_t *end; pc = section->start; end = pc + section->size; while (pc < end) { snprintf( pcString, sizeof(pcString), "0x%lx", (unsigned long)(uintptr_t)pc); size_t instructionSize = LLVMDisasmInstruction( disassembler, pc, end - pc, (uintptr_t)pc, instructionString, sizeof(instructionString)); if (!instructionSize) snprintf(instructionString, sizeof(instructionString), ".byte 0x%02x", *pc++); else pc += instructionSize; printf(" %16s: %s\n", pcString, instructionString); } } } return 0; }
void init_core(void) { LLVMLinkInMCJIT(); LLVMInitializeNativeTarget(); LLVMInitializeNativeAsmPrinter(); LLVMInitializeNativeAsmParser(); llvm_module_tag = scm_make_smob_type("llvm_module", sizeof(struct llvm_module_t)); scm_set_smob_free(llvm_module_tag, free_llvm_module); llvm_function_tag = scm_make_smob_type("llvm_function", sizeof(struct llvm_function_t)); scm_set_smob_free(llvm_function_tag, free_llvm_function); llvm_value_tag = scm_make_smob_type("llvm_value", sizeof(struct llvm_value_t)); llvm_basic_block_tag = scm_make_smob_type("llvm_basic_block", sizeof(struct llvm_basic_block_t)); scm_c_define("llvm-bool" , scm_from_int(SCM_FOREIGN_TYPE_LAST + 1)); scm_c_define("llvm-void" , scm_from_int(SCM_FOREIGN_TYPE_VOID )); scm_c_define("llvm-float" , scm_from_int(SCM_FOREIGN_TYPE_FLOAT )); scm_c_define("llvm-double", scm_from_int(SCM_FOREIGN_TYPE_DOUBLE )); scm_c_define("llvm-uint8" , scm_from_int(SCM_FOREIGN_TYPE_UINT8 )); scm_c_define("llvm-int8" , scm_from_int(SCM_FOREIGN_TYPE_INT8 )); scm_c_define("llvm-uint16", scm_from_int(SCM_FOREIGN_TYPE_UINT16 )); scm_c_define("llvm-int16" , scm_from_int(SCM_FOREIGN_TYPE_INT16 )); scm_c_define("llvm-uint32", scm_from_int(SCM_FOREIGN_TYPE_UINT32 )); scm_c_define("llvm-int32" , scm_from_int(SCM_FOREIGN_TYPE_INT32 )); scm_c_define("llvm-uint64", scm_from_int(SCM_FOREIGN_TYPE_UINT64 )); scm_c_define("llvm-int64" , scm_from_int(SCM_FOREIGN_TYPE_INT64 )); scm_c_define("llvm-int-slt" , scm_from_int(LLVMIntSLT)); scm_c_define("llvm-int-ult" , scm_from_int(LLVMIntULT)); scm_c_define("llvm-int-sle" , scm_from_int(LLVMIntSLE)); scm_c_define("llvm-int-ule" , scm_from_int(LLVMIntULE)); scm_c_define("llvm-int-ugt" , scm_from_int(LLVMIntUGT)); scm_c_define("llvm-int-sgt" , scm_from_int(LLVMIntSGT)); scm_c_define("llvm-int-uge" , scm_from_int(LLVMIntUGE)); scm_c_define("llvm-int-sge" , scm_from_int(LLVMIntSGE)); scm_c_define("llvm-int-eq" , scm_from_int(LLVMIntEQ )); scm_c_define("llvm-int-ne" , scm_from_int(LLVMIntNE )); scm_c_define("llvm-real-lt" , scm_from_int(LLVMRealOLT)); scm_c_define("llvm-real-le" , scm_from_int(LLVMRealOLE)); scm_c_define("llvm-real-gt" , scm_from_int(LLVMRealOGT)); scm_c_define("llvm-real-ge" , scm_from_int(LLVMRealOGE)); scm_c_define("llvm-real-eq" , scm_from_int(LLVMRealOEQ)); scm_c_define("llvm-real-ne" , scm_from_int(LLVMRealONE)); scm_c_define_gsubr("make-llvm-module-base" , 0, 0, 0, SCM_FUNC(make_llvm_module_base )); scm_c_define_gsubr("llvm-module-destroy" , 1, 0, 0, SCM_FUNC(llvm_module_destroy )); scm_c_define_gsubr("llvm-dump-module" , 1, 0, 0, SCM_FUNC(llvm_dump_module )); scm_c_define_gsubr("make-llvm-function" , 4, 0, 0, SCM_FUNC(make_llvm_function )); scm_c_define_gsubr("llvm-function-destroy" , 1, 0, 0, SCM_FUNC(llvm_function_destroy )); scm_c_define_gsubr("llvm-function-return" , 2, 0, 0, SCM_FUNC(llvm_function_return )); scm_c_define_gsubr("llvm-function-return-void" , 1, 0, 0, SCM_FUNC(llvm_function_return_void )); scm_c_define_gsubr("llvm-compile-module" , 1, 0, 0, SCM_FUNC(llvm_compile_module )); scm_c_define_gsubr("llvm-get-function-address" , 2, 0, 0, SCM_FUNC(llvm_get_function_address )); scm_c_define_gsubr("llvm-verify-module" , 1, 0, 0, SCM_FUNC(llvm_verify_module )); scm_c_define_gsubr("make-llvm-basic-block" , 2, 0, 0, SCM_FUNC(make_llvm_basic_block )); scm_c_define_gsubr("llvm-position-builder-at-end", 2, 0, 0, SCM_FUNC(llvm_position_builder_at_end)); scm_c_define_gsubr("llvm-build-branch" , 2, 0, 0, SCM_FUNC(llvm_build_branch )); scm_c_define_gsubr("llvm-build-cond-branch" , 4, 0, 0, SCM_FUNC(llvm_build_cond_branch )); scm_c_define_gsubr("llvm-build-select" , 4, 0, 0, SCM_FUNC(llvm_build_select )); scm_c_define_gsubr("make-llvm-constant" , 2, 0, 0, SCM_FUNC(make_llvm_constant )); scm_c_define_gsubr("llvm-get-type" , 1, 0, 0, SCM_FUNC(llvm_get_type )); scm_c_define_gsubr("llvm-build-load" , 3, 0, 0, SCM_FUNC(llvm_build_load )); scm_c_define_gsubr("llvm-build-store" , 4, 0, 0, SCM_FUNC(llvm_build_store )); scm_c_define_gsubr("llvm-get-param" , 2, 0, 0, SCM_FUNC(llvm_get_param )); scm_c_define_gsubr("llvm-build-neg" , 2, 0, 0, SCM_FUNC(llvm_build_neg )); scm_c_define_gsubr("llvm-build-fneg" , 2, 0, 0, SCM_FUNC(llvm_build_fneg )); scm_c_define_gsubr("llvm-build-not" , 2, 0, 0, SCM_FUNC(llvm_build_not )); scm_c_define_gsubr("llvm-build-add" , 3, 0, 0, SCM_FUNC(llvm_build_add )); scm_c_define_gsubr("llvm-build-fadd" , 3, 0, 0, SCM_FUNC(llvm_build_fadd )); scm_c_define_gsubr("llvm-build-sub" , 3, 0, 0, SCM_FUNC(llvm_build_sub )); scm_c_define_gsubr("llvm-build-fsub" , 3, 0, 0, SCM_FUNC(llvm_build_fsub )); scm_c_define_gsubr("llvm-build-mul" , 3, 0, 0, SCM_FUNC(llvm_build_mul )); scm_c_define_gsubr("llvm-build-fmul" , 3, 0, 0, SCM_FUNC(llvm_build_fmul )); scm_c_define_gsubr("llvm-build-udiv" , 3, 0, 0, SCM_FUNC(llvm_build_udiv )); scm_c_define_gsubr("llvm-build-sdiv" , 3, 0, 0, SCM_FUNC(llvm_build_sdiv )); scm_c_define_gsubr("llvm-build-fdiv" , 3, 0, 0, SCM_FUNC(llvm_build_fdiv )); scm_c_define_gsubr("llvm-build-shl" , 3, 0, 0, SCM_FUNC(llvm_build_shl )); scm_c_define_gsubr("llvm-build-lshr" , 3, 0, 0, SCM_FUNC(llvm_build_lshr )); scm_c_define_gsubr("llvm-build-ashr" , 3, 0, 0, SCM_FUNC(llvm_build_ashr )); scm_c_define_gsubr("llvm-build-urem" , 3, 0, 0, SCM_FUNC(llvm_build_urem )); scm_c_define_gsubr("llvm-build-srem" , 3, 0, 0, SCM_FUNC(llvm_build_srem )); scm_c_define_gsubr("llvm-build-frem" , 3, 0, 0, SCM_FUNC(llvm_build_frem )); scm_c_define_gsubr("llvm-build-and" , 3, 0, 0, SCM_FUNC(llvm_build_and )); scm_c_define_gsubr("llvm-build-or" , 3, 0, 0, SCM_FUNC(llvm_build_or )); scm_c_define_gsubr("llvm-build-xor" , 3, 0, 0, SCM_FUNC(llvm_build_xor )); scm_c_define_gsubr("llvm-build-trunc" , 3, 0, 0, SCM_FUNC(llvm_build_trunc )); scm_c_define_gsubr("llvm-build-sext" , 3, 0, 0, SCM_FUNC(llvm_build_sext )); scm_c_define_gsubr("llvm-build-zext" , 3, 0, 0, SCM_FUNC(llvm_build_zext )); scm_c_define_gsubr("llvm-build-fp-cast" , 3, 0, 0, SCM_FUNC(llvm_build_fp_cast )); scm_c_define_gsubr("llvm-build-fp-to-si" , 3, 0, 0, SCM_FUNC(llvm_build_fp_to_si )); scm_c_define_gsubr("llvm-build-fp-to-ui" , 3, 0, 0, SCM_FUNC(llvm_build_fp_to_ui )); scm_c_define_gsubr("llvm-build-si-to-fp" , 3, 0, 0, SCM_FUNC(llvm_build_si_to_fp )); scm_c_define_gsubr("llvm-build-ui-to-fp" , 3, 0, 0, SCM_FUNC(llvm_build_ui_to_fp )); scm_c_define_gsubr("llvm-build-call" , 6, 0, 0, SCM_FUNC(llvm_build_call )); scm_c_define_gsubr("llvm-build-integer-cmp" , 4, 0, 0, SCM_FUNC(llvm_build_integer_cmp )); scm_c_define_gsubr("llvm-build-float-cmp" , 4, 0, 0, SCM_FUNC(llvm_build_float_cmp )); scm_c_define_gsubr("llvm-build-alloca" , 2, 0, 0, SCM_FUNC(llvm_build_alloca )); scm_c_define_gsubr("llvm-build-phi" , 2, 0, 0, SCM_FUNC(llvm_build_phi )); scm_c_define_gsubr("llvm-add-incoming" , 3, 0, 0, SCM_FUNC(llvm_add_incoming )); }
/* unit -> bool */ CAMLprim value llvm_initialize_native_target(value Unit) { return Val_bool(LLVMInitializeNativeTarget()); }
/** * Compile many queries, then arrange them into a chain and squirt reads * through it. */ int main(int argc, char *const *argv) { const char *input_filename = nullptr; bool binary = false; ChainPattern chain = known_chains["parallel"]; bool help = false; bool ignore_index = false; int c; while ((c = getopt(argc, argv, "bc:f:hI")) != -1) { switch (c) { case 'b': binary = true; break; case 'c': if (known_chains.find(optarg) == known_chains.end()) { std::cerr << "Unknown chaining method: " << optarg << std::endl; return 1; } else { chain = known_chains[optarg]; } break; case 'h': help = true; break; case 'I': ignore_index = true; break; case 'f': input_filename = optarg; break; case '?': fprintf(stderr, "Option -%c is not valid.\n", optopt); return 1; default: abort(); } } if (help) { std::cout << argv[0] << " [-b] [-c] [-I] [-v] -f input.bam " " query1 output1.bam ..." << std::endl; std::cout << "Filter a BAM/SAM file based on the provided query. For " "details, see the man page." << std::endl; std::cout << "\t-b\tThe input file is binary (BAM) not text (SAM)." << std::endl; std::cout << "\t-c\tChain the queries, rather than use them independently." << std::endl; std::cout << "\t-I\tDo not use the index, even if it exists." << std::endl; std::cout << "\t-v\tPrint some information along the way." << std::endl; return 0; } if (optind >= argc) { std::cout << "Need a query and a BAM file." << std::endl; return 1; } if ((argc - optind) % 2 != 0) { std::cout << "Queries and BAM files must be paired." << std::endl; return 1; } if (input_filename == nullptr) { std::cout << "An input file is required." << std::endl; return 1; } // Create a new LLVM module and JIT LLVMInitializeNativeTarget(); llvm::InitializeNativeTargetAsmParser(); llvm::InitializeNativeTargetAsmPrinter(); std::unique_ptr<llvm::Module> module( new llvm::Module("bamql", llvm::getGlobalContext())); auto generator = std::make_shared<bamql::Generator>(module.get(), nullptr); auto engine = bamql::createEngine(std::move(module)); if (!engine) { return 1; } // Prepare a chain of wranglers. std::shared_ptr<OutputWrangler> output; for (auto it = argc - 2; it >= optind; it -= 2) { // Prepare the output file. std::shared_ptr<htsFile> output_file; if (strcmp("-", argv[it + 1]) != 0) { output_file = std::shared_ptr<htsFile>(hts_open(argv[it + 1], "wb"), hts_close); if (!output_file) { perror(optarg); return 1; } } // Parse the input query. std::string query(argv[it]); auto ast = bamql::AstNode::parseWithLogging(query, bamql::getDefaultPredicates()); if (!ast) { return 1; } // Add the link to the chain. std::stringstream function_name; function_name << "filter" << it; output = std::make_shared<OutputWrangler>(engine, generator, query, ast, function_name.str(), chain, std::string(argv[it + 1]), output_file, output); } engine->finalizeObject(); output->prepareExecution(); // Run the chain. if (output->processFile(input_filename, binary, ignore_index)) { output->write_summary(); return 0; } else { return 1; } }
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 }
int main() { llvm::LLVMContext &Context = llvm::getGlobalContext(); llvm::Module *OurModule; llvm::IRBuilder<> Builder(Context); OurModule = new llvm::Module("Our first intermediary code", Context); /***** Main: a function that gets no parameters and returns an integer *****/ /* http://llvm.org/docs/doxygen/html/classllvm_1_1FunctionType.html * static FunctionType * get (Type *Result, bool isVarArg) * FunctionType::get - Create a FunctionType taking no parameters. */ llvm::Type* intType = llvm::Type::getInt64Ty(Context); llvm::FunctionType* typeOfMain = llvm::FunctionType::get(intType,false); /* http://llvm.org/docs/doxygen/html/classllvm_1_1Function.html * static Function * Create (FunctionType *Ty, LinkageTypes Linkage, const Twine &N="", Module *M=nullptr) */ llvm::Function* ourMain = llvm::Function::Create(typeOfMain,llvm::Function::ExternalLinkage, "main", OurModule); /* http://llvm.org/docs/doxygen/html/classllvm_1_1BasicBlock.html * static BasicBlock * Create (LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr) * Creates a new BasicBlock. */ llvm::BasicBlock *mainBB = llvm::BasicBlock::Create(Context, "entry", ourMain); /* http://llvm.org/docs/doxygen/html/classllvm_1_1IRBuilderBase.html * void SetInsertPoint (BasicBlock *TheBB) * This specifies that created instructions should be appended to the end of the specified block. */ Builder.SetInsertPoint(mainBB); /*** Constants are all unified ***/ /* http://llvm.org/docs/doxygen/html/classllvm_1_1ConstantInt.html * static ConstantInt * get (LLVMContext &Context, const APInt &V) * Return a ConstantInt with the specified value and an implied Type. * APInt = Arbitrary Precision Integer */ llvm::ConstantInt* Ten = llvm::ConstantInt::get(Context, llvm::APInt(64,10)); auto One = llvm::ConstantInt::get(Context, llvm::APInt(64, 1)); auto Zero = llvm::ConstantInt::get(Context, llvm::APInt(64, 0)); /* static ConstantInt * get (IntegerType *Ty, uint64_t V, bool isSigned=false) * Return a ConstantInt with the specified integer value for the specified type. */ llvm::Constant* NegativeOne = llvm::ConstantInt::get( intType, -1, true); /*** A and B are variables in memory, so we can read and write from them ***/ /* http://llvm.org/docs/doxygen/html/classllvm_1_1IRBuilder.html * AllocaInst * CreateAlloca (Type *Ty, Value *ArraySize=nullptr, const Twine &Name="") */ llvm::AllocaInst* A = Builder.CreateAlloca(intType, NULL, "A"); llvm::AllocaInst* B = Builder.CreateAlloca(intType, NULL, "B"); /*** lets compute * 0. A = 0; * 1. x = A; * 2. y = 0; * 3. x = y + 10 - (-1) + x; * 4. x = x + 1 + 10 + 10 + 10 * 5. A = x; * 6. return x; ***/ Builder.CreateStore(Zero, A); //0 llvm::Value* x = Builder.CreateLoad(A, "x"); //1 auto y = Builder.CreateAdd(Zero, Zero, "y"); //2 (one way to set to zero ;) auto tmp = Builder.CreateAdd(y, Ten, "tmp"); //3.1 tmp = Builder.CreateSub(tmp, NegativeOne, "tmp"); //3.2 x = Builder.CreateAdd(tmp, x, "x"); //3.3 x = Builder.CreateAdd(x, One, "x"); //4 x = Builder.CreateAdd(x, Ten, "x"); //4 x = Builder.CreateAdd(x, Ten, "x"); //4 x = Builder.CreateAdd(x, Ten, "x"); //4 Builder.CreateStore(x, A); //5 Builder.CreateRet(x); //6 llvm::verifyFunction(*ourMain); //Checks if everything is okay with our function /*** Lets print the intermediary representation generated ***/ OurModule->dump(); //ourMain->dump(); /*** Now lets compute it with a just in time (JIT) compiler ***/ llvm::ExecutionEngine* OurExecutionEngine; std::string Error; LLVMInitializeNativeTarget(); //target = generates code for my processor OurExecutionEngine = llvm::EngineBuilder(OurModule).setErrorStr(&Error).create(); if (!OurExecutionEngine) { fprintf(stderr, "Could not create OurExecutionEngine: %s\n", Error.c_str()); exit(1); } // JIT our main. It returns a function pointer. void *mainPointer = OurExecutionEngine->getPointerToFunction(ourMain); // Translate the pointer and run our main to get its results int (*result)() = (int (*)())(intptr_t)mainPointer; std::cout << "Result of our main = " << result() << std::endl; return 0; }
int main() { llvm::LLVMContext &context = llvm::getGlobalContext(); llvm::Module* module; llvm::IRBuilder<> builder(context); module = new llvm::Module("intermediary code", context); /* function Main */ llvm::Type* int64Type = llvm::Type::getInt64Ty(context); llvm::FunctionType* typeOfMain = llvm::FunctionType::get(int64Type, false); llvm::Function* mainFunction = llvm::Function::Create(typeOfMain, llvm::Function::ExternalLinkage, "main", module); llvm::BasicBlock* mainBB = llvm::BasicBlock::Create(context, "mainBB", mainFunction); builder.SetInsertPoint(mainBB); /* function Teste */ llvm::Type* boolType = llvm::Type::getInt1Ty(context); std::vector<llvm::Type*> testeParams(3, boolType); llvm::FunctionType* typeOfTeste = llvm::FunctionType::get(boolType, testeParams, false); llvm::Function* testeFunction = llvm::Function::Create(typeOfTeste, llvm::Function::ExternalLinkage, "teste", module); llvm::Function::arg_iterator params = testeFunction->arg_begin(); params->setName("x"); params++; params->setName("y"); params++; params->setName("z"); llvm::BasicBlock* testeBB = llvm::BasicBlock::Create(context, "testeBB", testeFunction); builder.SetInsertPoint(testeBB); llvm::Function::arg_iterator declParams = testeFunction->arg_begin(); auto x = declParams; auto y = ++declParams; auto z = ++declParams; auto xy = builder.CreateAnd(x, y, "andxy"); auto xz = builder.CreateAnd(x, z, "andxz"); auto nz = builder.CreateNot(z, "nz"); auto ny = builder.CreateNot(y, "ny"); auto nzny = builder.CreateAnd(nz, ny, "nzny"); auto res = builder.CreateOr(xy, xz, "res"); res = builder.CreateOr(res, nzny, "res"); builder.CreateRet(res); llvm::verifyFunction(*testeFunction); /* function Exemplo */ llvm::Type* realType = llvm::Type::getDoubleTy(context); std::vector<llvm::Type*> exemploParams(2, realType); llvm::FunctionType* typeOfExemplo = llvm::FunctionType::get(realType, exemploParams, false); llvm::Function* exemploFunction = llvm::Function::Create(typeOfExemplo, llvm::Function::ExternalLinkage, "exemplo", module); params = exemploFunction->arg_begin(); params->setName("a"); params++; params->setName("b"); llvm::BasicBlock* exemploBB = llvm::BasicBlock::Create(context, "exemploBB", exemploFunction); builder.SetInsertPoint(exemploBB); auto a = exemploFunction->arg_begin(); auto b = ++(exemploFunction->arg_begin()); auto multab = builder.CreateFMul(a, b, "multab"); auto const20 = llvm::ConstantFP::get(context, llvm::APFloat(2.0)); auto modab = builder.CreateFRem(a, b, "modab");//??? auto ret = builder.CreateFMul(const20, modab, "ret"); ret = builder.CreateFSub(multab, ret, "ret"); builder.CreateRet(ret); llvm::verifyFunction(*exemploFunction); /* Chamando as funções */ builder.SetInsertPoint(mainBB); std::vector<llvm::Value*> args; args.push_back(llvm::ConstantInt::get(context, llvm::APInt(1, 0))); args.push_back(llvm::ConstantInt::get(context, llvm::APInt(1, 0))); args.push_back(llvm::ConstantInt::get(context, llvm::APInt(1, 1))); auto testeRet = builder.CreateCall(testeFunction, args, "callteste"); std::vector<llvm::Value*> args2; args2.push_back(llvm::ConstantFP::get(context, llvm::APFloat(10.0))); args2.push_back(llvm::ConstantFP::get(context, llvm::APFloat(5.0))); auto exemploRet = builder.CreateCall(exemploFunction, args2, "callexemplo"); builder.CreateRet(testeRet); module->dump(); llvm::ExecutionEngine* execEngine; std::string err; LLVMInitializeNativeTarget(); execEngine = llvm::EngineBuilder(module).setErrorStr(&err).create(); if(!execEngine) { fprintf(stderr, "Could not create execEngine: %s\n", err.c_str()); exit(1); } void* mainPtr = execEngine->getPointerToFunction(mainFunction); int(*result)() = (int (*)())(intptr_t)mainPtr; std::cout << "Result of main: " << result() << std::endl; }
bool JITRotation::initializeWithFile(const char* filename) { // note: string literals in rotation scripts are actually compiled as their FNV1A hash instead const char header[] = "class Actor;\n" "uint64 AuraCount(const Actor* actor, uint64 identifier, const Actor* source);\n" "double GlobalCooldownRemaining(const Actor* actor);\n" "double CooldownRemaining(const Actor* actor, uint64 identifier);\n" "double AuraTimeRemaining(const Actor* actor, uint64 identifier, const Actor* source);\n" "Actor* Pet(Actor* owner);\n" "uint64 TP(const Actor* actor);\n" "uint64 MP(const Actor* actor);\n" "uint64 MaximumMP(const Actor* actor);\n" "double GlobalCooldown(const Actor* actor);\n" "double Time(const Actor* actor);\n" "void RemoveAura(Actor* actor, uint64 identifier, const Actor* source);\n" "uint8 IsReady(const Actor* actor, uint64 identifier);\n" "void Command(Actor* actor, uint64 identifier);\n" "void StopAutoAttack(Actor* actor);\n" "__end __hidden const uint64 NextAction(Actor* self, const Actor* target) {\n" ; const char footer[] = "\n}"; FILE* f = fopen(filename, "r"); if (!f) { printf("Unable to open file %s\n", filename); return false; } fseek(f, 0, SEEK_END); auto fsize = ftell(f); rewind(f); auto sourceLength = sizeof(header) + fsize + sizeof(footer); auto source = (char*)malloc(sourceLength); if (!source) { printf("Unable to allocate memory for rotation source\n"); fclose(f); return false; } memcpy(source, header, sizeof(header)); if (fread(source + sizeof(header), fsize, 1, f) != 1) { printf("Unable to read file %s\n", filename); fclose(f); return false; } memcpy(source + sizeof(header) + fsize, footer, sizeof(footer)); fclose(f); // PREPROCESS Preprocessor pp; if (!pp.process_file(filename, source, sourceLength)) { printf("Couldn't preprocess file.\n"); free(source); return false; } free(source); // PARSE Parser p; ASTSequence* ast = p.generate_ast(pp.tokens()); if (p.errors().size() > 0) { delete ast; for (const ParseError& e : p.errors()) { printf("Error: %s\n", e.message.c_str()); e.token->print_pointer(); } return false; } if (!ast) { printf("Couldn't generate AST.\n"); return false; } // GENERATE CODE LLVMCodeGenerator cg; if (!cg.build_ir(ast)) { printf("Couldn't build IR.\n"); delete ast; return false; } delete ast; // COMPILE LLVMInitializeNativeTarget(); auto module = cg.release_module(); std::string error; auto engine = llvm::EngineBuilder(module).setErrorStr(&error).setEngineKind(llvm::EngineKind::JIT).create(); if (!engine) { printf("Couldn't build execution engine: %s\n", error.c_str()); return false; } engine->addGlobalMapping(module->getFunction("^AuraCount"), (void*)&JITRotation::ActorAuraCount); engine->addGlobalMapping(module->getFunction("^GlobalCooldownRemaining"), (void*)&JITRotation::ActorGlobalCooldownRemaining); engine->addGlobalMapping(module->getFunction("^CooldownRemaining"), (void*)&JITRotation::ActorCooldownRemaining); engine->addGlobalMapping(module->getFunction("^AuraTimeRemaining"), (void*)&JITRotation::ActorAuraTimeRemaining); engine->addGlobalMapping(module->getFunction("^Pet"), (void*)&JITRotation::ActorPet); engine->addGlobalMapping(module->getFunction("^TP"), (void*)&JITRotation::ActorTP); engine->addGlobalMapping(module->getFunction("^MP"), (void*)&JITRotation::ActorMP); engine->addGlobalMapping(module->getFunction("^MaximumMP"), (void*)&JITRotation::ActorMaximumMP); engine->addGlobalMapping(module->getFunction("^GlobalCooldown"), (void*)&JITRotation::ActorGlobalCooldown); engine->addGlobalMapping(module->getFunction("^Time"), (void*)&JITRotation::ActorTime); engine->addGlobalMapping(module->getFunction("^RemoveAura"), (void*)&JITRotation::ActorRemoveAura); engine->addGlobalMapping(module->getFunction("^IsReady"), (void*)&JITRotation::ActionIsReady); engine->addGlobalMapping(module->getFunction("^Command"), (void*)&JITRotation::ActorCommand); engine->addGlobalMapping(module->getFunction("^StopAutoAttack"), (void*)&JITRotation::ActorStopAutoAttack); _jitNextAction = decltype(_jitNextAction)((std::intptr_t)engine->getPointerToFunction(module->getFunction("^NextAction"))); return _jitNextAction; }