int main() { LLVMContextRef context = LLVMGetGlobalContext(); LLVMModuleRef module = LLVMModuleCreateWithName("test-101"); LLVMBuilderRef builder = LLVMCreateBuilder(); // LLVMInt32Type() // LLVMFunctionType(rtnType, paramType, parmCnt, isVarArg) // LLVMAddFunction(module, name, functionType) LLVMTypeRef main = LLVMFunctionType(LLVMInt32Type(), NULL, 0, 0); LLVMValueRef mainFn = LLVMAddFunction(module, "main", main); LLVMBasicBlockRef mainBlk = LLVMAppendBasicBlock(mainFn, "entry"); LLVMPositionBuilderAtEnd(builder, mainBlk); LLVMValueRef str = LLVMBuildGlobalStringPtr(builder, "Hello World!", "str"); LLVMTypeRef args[1]; args[0] = LLVMPointerType(LLVMInt8Type(), 0); LLVMTypeRef puts = LLVMFunctionType(LLVMInt32Type(), args, 1, 0); LLVMValueRef putsFn = LLVMAddFunction(module, "puts", puts); LLVMBuildCall(builder, putsFn, &str, 1, ""); LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 0, 0)); LLVMDumpModule(module); return 0; }
static void make_rdtscp(compile_t* c) { if(target_is_x86(c->opt->triple)) { // i64 @llvm.x86.rdtscp(i8*) LLVMTypeRef f_type = LLVMFunctionType(c->i64, &c->void_ptr, 1, false); LLVMValueRef rdtscp = LLVMAddFunction(c->module, "llvm.x86.rdtscp", f_type); // i64 @internal.x86.rdtscp(i32*) LLVMTypeRef i32_ptr = LLVMPointerType(c->i32, 0); f_type = LLVMFunctionType(c->i64, &i32_ptr, 1, false); LLVMValueRef fun = codegen_addfun(c, "internal.x86.rdtscp", f_type); LLVMSetFunctionCallConv(fun, LLVMCCallConv); codegen_startfun(c, fun, NULL, NULL); // Cast i32* to i8* and call the intrinsic. LLVMValueRef arg = LLVMGetParam(fun, 0); arg = LLVMBuildBitCast(c->builder, arg, c->void_ptr, ""); LLVMValueRef result = LLVMBuildCall(c->builder, rdtscp, &arg, 1, ""); LLVMBuildRet(c->builder, result); codegen_finishfun(c); } else { (void)c; } }
struct vm_state * vm_state_create(const char *module_name) { struct vm_state *vm; LLVMTypeRef function_type; LLVMValueRef function_value; LLVMBasicBlockRef entry_block; vm = calloc(1, sizeof(struct vm_state)); if (vm == NULL) { fprintf(stderr, "Memory allocation request failed.\n"); exit(EXIT_FAILURE); } vm->module = LLVMModuleCreateWithName(module_name); vm->builder = LLVMCreateBuilder(); function_type = LLVMFunctionType(LLVMVoidType(), NULL, 0, 0); function_value = LLVMAddFunction(vm->module, "main", function_type); entry_block = LLVMAppendBasicBlock(function_value, "entry"); LLVMPositionBuilderAtEnd(vm->builder, entry_block); vm->symtab = symbol_table_create(); return vm; }
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); }
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 }; }
static void handle_line(char **tokens, int ntokens) { char *name = tokens[0]; LLVMValueRef param; LLVMValueRef res; LLVMModuleRef M = LLVMModuleCreateWithName(name); LLVMTypeRef I64ty = LLVMInt64Type(); LLVMTypeRef I64Ptrty = LLVMPointerType(I64ty, 0); LLVMTypeRef Fty = LLVMFunctionType(I64ty, &I64Ptrty, 1, 0); LLVMValueRef F = LLVMAddFunction(M, name, Fty); LLVMBuilderRef builder = LLVMCreateBuilder(); LLVMPositionBuilderAtEnd(builder, LLVMAppendBasicBlock(F, "entry")); LLVMGetParams(F, ¶m); LLVMSetValueName(param, "in"); res = build_from_tokens(tokens + 1, ntokens - 1, builder, param); if (res) { char *irstr = LLVMPrintModuleToString(M); puts(irstr); LLVMDisposeMessage(irstr); } LLVMDisposeBuilder(builder); LLVMDisposeModule(M); }
struct type *type_new_function( struct type *ret, size_t n_params, struct type *params[/* n_params */], bool is_variadic ) { assert(ret); struct type *r = malloc(sizeof *r); r->val = TYPE_FUNCTION; r->next = ret; r->u.func.n_params = n_params; r->u.func.params = malloc(n_params * sizeof (struct type)); r->u.func.is_variadic = is_variadic; LLVMTypeRef llvm_param_types[n_params]; for (unsigned i = 0; i < n_params; ++i) { r->u.func.params[i] = params[i]; llvm_param_types[i] = params[i]->llvm_type; } r->llvm_type = LLVMFunctionType( ret->llvm_type, llvm_param_types, ARRAY_LENGTH(llvm_param_types), is_variadic ); return r; }
static void createPushHeapFunction() { // Saving last BasicBlock; LLVMBasicBlockRef OldBB = LLVMGetInsertBlock(Builder); LLVMTypeRef ParamType = LLVMPointerType(RAType, 0); LLVMTypeRef FunctionType = LLVMFunctionType(LLVMVoidType(), &ParamType, 1, 0); LLVMValueRef Function = LLVMAddFunction(Module, "push.heap", FunctionType); LLVMBasicBlockRef Entry = LLVMAppendBasicBlock(Function, "entry"); LLVMPositionBuilderAtEnd(Builder, Entry); // Function Body LLVMValueRef HeapMalloc = LLVMBuildMalloc(Builder, HeapType, "heap.malloc"); LLVMValueRef ExPtrIdx[] = { getSConstInt(0), getSConstInt(0) }; LLVMValueRef LastPtrIdx[] = { getSConstInt(0), getSConstInt(1) }; LLVMValueRef ExPtr = LLVMBuildInBoundsGEP(Builder, HeapMalloc, ExPtrIdx, 2, "heap.exec"); LLVMValueRef LastPtr = LLVMBuildInBoundsGEP(Builder, HeapMalloc, LastPtrIdx, 2, "heap.last"); LLVMBuildStore(Builder, LLVMGetParam(Function, 0), ExPtr); LLVMBuildStore(Builder, LLVMBuildLoad(Builder, HeapHead, "ld.heap.head"), LastPtr); LLVMBuildStore(Builder, HeapMalloc, HeapHead); LLVMBuildRetVoid(Builder); // Restoring last BasicBlock LLVMPositionBuilderAtEnd(Builder, OldBB); }
static LLVMValueRef get_prototype(compile_t* c, gentype_t* g, const char *name, ast_t* typeargs, ast_t* fun) { // Behaviours and actor constructors also have sender functions. bool sender = false; switch(ast_id(fun)) { case TK_NEW: sender = g->underlying == TK_ACTOR; break; case TK_BE: sender = true; break; default: {} } // Get a fully qualified name: starts with the type name, followed by the // type arguments, followed by the function name, followed by the function // level type arguments. const char* funname = genname_fun(g->type_name, name, typeargs); // If the function already exists, just return it. LLVMValueRef func = LLVMGetNamedFunction(c->module, funname); if(func != NULL) return func; LLVMTypeRef ftype = get_signature(c, g, fun); if(ftype == NULL) return NULL; // If the function exists now, just return it. func = LLVMGetNamedFunction(c->module, funname); if(func != NULL) return func; if(sender) { // Generate the sender prototype. const char* be_name = genname_be(funname); func = codegen_addfun(c, be_name, ftype); // Change the return type to void for the handler. size_t count = LLVMCountParamTypes(ftype); size_t buf_size = count *sizeof(LLVMTypeRef); LLVMTypeRef* tparams = (LLVMTypeRef*)pool_alloc_size(buf_size); LLVMGetParamTypes(ftype, tparams); ftype = LLVMFunctionType(c->void_type, tparams, (int)count, false); pool_free_size(buf_size, tparams); } // Generate the function prototype. return codegen_addfun(c, funname, ftype); }
static void donotoptimise_apply(compile_t* c, reach_type_t* t, reach_method_t* m) { const char* strtab_name = m->name; m->intrinsic = true; ast_t* typearg = ast_child(m->typeargs); reach_type_t* t_elem = reach_type(c->reach, typearg); LLVMTypeRef params[2]; params[0] = t->use_type; params[1] = t_elem->use_type; start_function(c, m, m->result->use_type, params, 2); LLVMValueRef obj = LLVMGetParam(m->func, 1); LLVMTypeRef void_fn = LLVMFunctionType(c->void_type, &t_elem->use_type, 1, false); LLVMValueRef asmstr = LLVMConstInlineAsm(void_fn, "", "imr,~{memory}", true, false); LLVMBuildCall(c->builder, asmstr, &obj, 1, ""); LLVMBuildRet(c->builder, m->result->instance); codegen_finishfun(c); BOX_FUNCTION(); }
static LLVMValueRef CreateFibFunction(LLVMModuleRef M, LLVMContextRef Context) { LLVMBuilderRef B = LLVMCreateBuilderInContext(Context); // Create the fib function and insert it into module M. This function is said // to return an int and take an int parameter. LLVMTypeRef ParamTypes[] = {LLVMInt32TypeInContext(Context)}; LLVMTypeRef ReturnType = LLVMInt32TypeInContext(Context); LLVMTypeRef FunctionTy = LLVMFunctionType(ReturnType, ParamTypes, 1, 0); LLVMValueRef FibF = LLVMAddFunction(M, "fib", FunctionTy); // Add a basic block to the function. LLVMBasicBlockRef BB = LLVMAppendBasicBlockInContext(Context, FibF, "EntryBlock"); // Get pointers to the constants. LLVMValueRef One = LLVMConstInt(LLVMInt32TypeInContext(Context), 1, 0); LLVMValueRef Two = LLVMConstInt(LLVMInt32TypeInContext(Context), 2, 0); // Get pointer to the integer argument of the add1 function... LLVMValueRef ArgX = LLVMGetFirstParam(FibF); // Get the arg. LLVMSetValueName(ArgX, "AnArg"); // Give it a nice symbolic name for fun. // Create the true_block. LLVMBasicBlockRef RetBB = LLVMAppendBasicBlockInContext(Context, FibF, "return"); // Create an exit block. LLVMBasicBlockRef RecurseBB = LLVMAppendBasicBlockInContext(Context, FibF, "recurse"); // Create the "if (arg <= 2) goto exitbb" LLVMPositionBuilderAtEnd(B, BB); LLVMValueRef CondInst = LLVMBuildICmp(B, LLVMIntSLE, ArgX, Two, "cond"); LLVMBuildCondBr(B, CondInst, RetBB, RecurseBB); // Create: ret int 1 LLVMPositionBuilderAtEnd(B, RetBB); LLVMBuildRet(B, One); // create fib(x-1) LLVMPositionBuilderAtEnd(B, RecurseBB); LLVMValueRef Sub = LLVMBuildSub(B, ArgX, One, "arg"); LLVMValueRef CallFibX1 = LLVMBuildCall(B, FibF, &Sub, 1, "fibx1"); LLVMSetTailCall(CallFibX1, 1); // create fib(x-2) LLVMPositionBuilderAtEnd(B, RecurseBB); Sub = LLVMBuildSub(B, ArgX, Two, "arg"); LLVMValueRef CallFibX2 = LLVMBuildCall(B, FibF, &Sub, 1, "fibx2"); LLVMSetTailCall(CallFibX2, 1); // fib(x-1)+fib(x-2) LLVMPositionBuilderAtEnd(B, RecurseBB); LLVMValueRef Sum = LLVMBuildAdd(B, CallFibX1, CallFibX2, "addresult"); // Create the return instruction and add it to the basic block LLVMPositionBuilderAtEnd(B, RecurseBB); LLVMBuildRet(B, Sum); return FibF; }
static void start_function(compile_t* c, reach_method_t* m, LLVMTypeRef result, LLVMTypeRef* params, unsigned count) { m->func_type = LLVMFunctionType(result, params, count, false); m->func = codegen_addfun(c, m->full_name, m->func_type); codegen_startfun(c, m->func, NULL, NULL); }
static LLVMValueRef add_printf_test(struct gallivm_state *gallivm) { LLVMModuleRef module = gallivm->module; LLVMTypeRef args[1] = { LLVMIntTypeInContext(gallivm->context, 32) }; LLVMValueRef func = LLVMAddFunction(module, "test_printf", LLVMFunctionType(LLVMVoidTypeInContext(gallivm->context), args, 1, 0)); LLVMBuilderRef builder = gallivm->builder; LLVMBasicBlockRef block = LLVMAppendBasicBlockInContext(gallivm->context, func, "entry"); LLVMSetFunctionCallConv(func, LLVMCCallConv); LLVMPositionBuilderAtEnd(builder, block); lp_build_printf(gallivm, "hello, world\n"); lp_build_printf(gallivm, "print 5 6: %d %d\n", LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), 5, 0), LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), 6, 0)); /* Also test lp_build_assert(). This should not fail. */ lp_build_assert(gallivm, LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), 1, 0), "assert(1)"); LLVMBuildRetVoid(builder); gallivm_verify_function(gallivm, func); return func; }
static LLVMValueRef add_test(LLVMModuleRef module, const char *name, lp_func_t lp_func) { LLVMTypeRef v4sf = LLVMVectorType(LLVMFloatType(), 4); LLVMTypeRef args[1] = { v4sf }; LLVMValueRef func = LLVMAddFunction(module, name, LLVMFunctionType(v4sf, args, 1, 0)); LLVMValueRef arg1 = LLVMGetParam(func, 0); LLVMBuilderRef builder = LLVMCreateBuilder(); LLVMBasicBlockRef block = LLVMAppendBasicBlock(func, "entry"); LLVMValueRef ret; struct lp_build_context bld; bld.builder = builder; bld.type.floating = 1; bld.type.width = 32; bld.type.length = 4; LLVMSetFunctionCallConv(func, LLVMCCallConv); LLVMPositionBuilderAtEnd(builder, block); ret = lp_func(&bld, arg1); LLVMBuildRet(builder, ret); LLVMDisposeBuilder(builder); return func; }
/** * Generates LLVM IR to call debug_printf. */ static LLVMValueRef lp_build_print_args(struct gallivm_state* gallivm, int argcount, LLVMValueRef* args) { LLVMBuilderRef builder = gallivm->builder; LLVMContextRef context = gallivm->context; LLVMValueRef func_printf; LLVMTypeRef printf_type; int i; assert(args); assert(argcount > 0); assert(LLVMTypeOf(args[0]) == LLVMPointerType(LLVMInt8TypeInContext(context), 0)); /* Cast any float arguments to doubles as printf expects */ for (i = 1; i < argcount; i++) { LLVMTypeRef type = LLVMTypeOf(args[i]); if (LLVMGetTypeKind(type) == LLVMFloatTypeKind) args[i] = LLVMBuildFPExt(builder, args[i], LLVMDoubleTypeInContext(context), ""); } printf_type = LLVMFunctionType(LLVMInt32TypeInContext(context), NULL, 0, 1); func_printf = lp_build_const_int_pointer(gallivm, func_to_pointer((func_pointer)debug_printf)); func_printf = LLVMBuildBitCast(builder, func_printf, LLVMPointerType(printf_type, 0), "debug_printf"); return LLVMBuildCall(builder, func_printf, args, argcount, ""); }
static bool genfun_allocator(compile_t* c, gentype_t* g) { // No allocator for primitive types or pointers. if((g->primitive != NULL) || is_pointer(g->ast)) return true; const char* funname = genname_fun(g->type_name, "Alloc", NULL); LLVMTypeRef ftype = LLVMFunctionType(g->use_type, NULL, 0, false); LLVMValueRef fun = codegen_addfun(c, funname, ftype); codegen_startfun(c, fun, false); LLVMValueRef result; switch(g->underlying) { case TK_PRIMITIVE: case TK_CLASS: // Allocate the object or return the global instance. result = gencall_alloc(c, g); break; case TK_ACTOR: // Allocate the actor. result = gencall_create(c, g); break; default: assert(0); return false; } LLVMBuildRet(c->builder, result); codegen_finishfun(c); return true; }
static LLVMValueRef add_blend_test(struct gallivm_state *gallivm, const struct pipe_blend_state *blend, struct lp_type type) { LLVMModuleRef module = gallivm->module; LLVMContextRef context = gallivm->context; LLVMTypeRef vec_type; LLVMTypeRef args[5]; LLVMValueRef func; LLVMValueRef src_ptr; LLVMValueRef src1_ptr; LLVMValueRef dst_ptr; LLVMValueRef const_ptr; LLVMValueRef res_ptr; LLVMBasicBlockRef block; LLVMBuilderRef builder; const enum pipe_format format = PIPE_FORMAT_R8G8B8A8_UNORM; const unsigned rt = 0; const unsigned char swizzle[4] = { 0, 1, 2, 3 }; LLVMValueRef src; LLVMValueRef src1; LLVMValueRef dst; LLVMValueRef con; LLVMValueRef res; vec_type = lp_build_vec_type(gallivm, type); args[4] = args[3] = args[2] = args[1] = args[0] = LLVMPointerType(vec_type, 0); func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidTypeInContext(context), args, 5, 0)); LLVMSetFunctionCallConv(func, LLVMCCallConv); src_ptr = LLVMGetParam(func, 0); src1_ptr = LLVMGetParam(func, 1); dst_ptr = LLVMGetParam(func, 2); const_ptr = LLVMGetParam(func, 3); res_ptr = LLVMGetParam(func, 4); block = LLVMAppendBasicBlockInContext(context, func, "entry"); builder = gallivm->builder; LLVMPositionBuilderAtEnd(builder, block); src = LLVMBuildLoad(builder, src_ptr, "src"); src1 = LLVMBuildLoad(builder, src1_ptr, "src1"); dst = LLVMBuildLoad(builder, dst_ptr, "dst"); con = LLVMBuildLoad(builder, const_ptr, "const"); res = lp_build_blend_aos(gallivm, blend, format, type, rt, src, NULL, src1, NULL, dst, NULL, con, NULL, swizzle, 4); lp_build_name(res, "res"); LLVMBuildStore(builder, res, res_ptr); LLVMBuildRetVoid(builder);; gallivm_verify_function(gallivm, func); return func; }
static LLVMValueRef declare_ffi_vararg(compile_t* c, const char* f_name, reach_type_t* t) { LLVMTypeRef r_type = ffi_return_type(c, t, false); LLVMTypeRef f_type = LLVMFunctionType(r_type, NULL, 0, true); LLVMValueRef func = LLVMAddFunction(c->module, f_name, f_type); return func; }
int main (void) { LLVMModuleRef module = LLVMModuleCreateWithName("kal"); LLVMBuilderRef builder = LLVMCreateBuilder(); // LLVMInitializeNativeTarget(); LLVMTypeRef funcType = LLVMFunctionType(LLVMVoidType(), NULL, 0, 0); LLVMValueRef func = LLVMAddFunction(module, "main", funcType); LLVMSetLinkage(func, LLVMExternalLinkage); LLVMBasicBlockRef block = LLVMAppendBasicBlock(func, "entry"); LLVMPositionBuilderAtEnd(builder, block); LLVMValueRef cond = LLVMBuildICmp(builder, LLVMIntNE, LLVMConstInt(LLVMInt32Type(), 2, 0), LLVMConstInt(LLVMInt32Type(), 1, 0), "ifcond"); LLVMValueRef owning_block = LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder)); //TODO: WRONG?? //LLVMValueRef owning_block = LLVMBasicBlockAsValue(LLVMGetPreviousBasicBlock(LLVMGetInsertBlock(builder))); // 2. Generate new blocks for cases. LLVMBasicBlockRef then_ref = LLVMAppendBasicBlock(owning_block, "then"); LLVMBasicBlockRef else_ref = LLVMAppendBasicBlock(owning_block, "else"); LLVMBasicBlockRef merge_ref = LLVMAppendBasicBlock(owning_block, "ifmerge"); // 3. Branch conditionally on then or else. LLVMBuildCondBr(builder, cond, then_ref, else_ref); // 4. Build then branch prologue. LLVMPositionBuilderAtEnd(builder, then_ref); LLVMValueRef hi1 = LLVMBuildXor(builder, LLVMGetUndef(LLVMInt32Type()), LLVMGetUndef(LLVMInt32Type()), "subtmp"); // 5. Connect then branch to merge block. LLVMBuildBr(builder, merge_ref); then_ref = LLVMGetInsertBlock(builder); // 6. Build else branch prologue. LLVMPositionBuilderAtEnd(builder, else_ref); LLVMValueRef hi2 = LLVMBuildXor(builder, LLVMGetUndef(LLVMInt32Type()), LLVMGetUndef(LLVMInt32Type()), "subtmp2"); // 7. Connect else branch to merge block. LLVMBuildBr(builder, merge_ref); else_ref = LLVMGetInsertBlock(builder); // 8. Position ourselves after the merge block. LLVMPositionBuilderAtEnd(builder, merge_ref); // 9. Build the phi node. // LLVMValueRef phi = LLVMBuildPhi(builder, LLVMDoubleType(), "phi"); // 10. Add incoming edges. // LLVMAddIncoming(phi, &hi1, &then_ref, 1); // LLVMAddIncoming(phi, &hi2, &else_ref, 1); LLVMDumpModule(module); LLVMDisposeBuilder(builder); LLVMDisposeModule(module); return 0; }
static LLVMTypeRef function_type(SCM scm_return_type, SCM scm_argument_types) { int n_arguments = scm_ilength(scm_argument_types); LLVMTypeRef *parameters = scm_gc_malloc_pointerless(n_arguments * sizeof(LLVMTypeRef), "make-llvm-function"); for (int i=0; i<n_arguments; i++) { parameters[i] = llvm_type(scm_to_int(scm_car(scm_argument_types))); scm_argument_types = scm_cdr(scm_argument_types); }; return LLVMFunctionType(llvm_type(scm_to_int(scm_return_type)), parameters, n_arguments, 0); }
LLVMValueRef build_utcb_get(struct llvm_ctx *ctx) { LLVMTypeRef fntype = LLVMFunctionType(ctx->wordt, NULL, 0, 0); LLVMValueRef func = LLVMConstInlineAsm(fntype, "movl %gs:0,$0\n", "=r,~{dirflag},~{fpsr},~{flags}", 0, 0); LLVMValueRef call = LLVMBuildCall(ctx->builder, func, NULL, 0, "utcbget"); LLVMSetTailCall(call, 1); return LLVMBuildIntToPtr(ctx->builder, call, LLVMPointerType(ctx->wordt, 0), "utcb.wordp"); }
static LLVMValueRef gen_digestof_box(compile_t* c, reach_type_t* type, LLVMValueRef value, int boxed_subtype) { pony_assert(LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMPointerTypeKind); LLVMBasicBlockRef box_block = NULL; LLVMBasicBlockRef nonbox_block = NULL; LLVMBasicBlockRef post_block = NULL; LLVMValueRef desc = gendesc_fetch(c, value); if((boxed_subtype & SUBTYPE_KIND_UNBOXED) != 0) { box_block = codegen_block(c, "digestof_box"); nonbox_block = codegen_block(c, "digestof_nonbox"); post_block = codegen_block(c, "digestof_post"); // Check if it's a boxed value. LLVMValueRef type_id = gendesc_typeid(c, desc); LLVMValueRef boxed_mask = LLVMConstInt(c->i32, 1, false); LLVMValueRef is_boxed = LLVMBuildAnd(c->builder, type_id, boxed_mask, ""); LLVMValueRef zero = LLVMConstInt(c->i32, 0, false); is_boxed = LLVMBuildICmp(c->builder, LLVMIntEQ, is_boxed, zero, ""); LLVMBuildCondBr(c->builder, is_boxed, box_block, nonbox_block); LLVMPositionBuilderAtEnd(c->builder, box_block); } // Call the type-specific __digestof function, which will unbox the value. reach_method_t* digest_fn = reach_method(type, TK_BOX, stringtab("__digestof"), NULL); pony_assert(digest_fn != NULL); LLVMValueRef func = gendesc_vtable(c, desc, digest_fn->vtable_index); LLVMTypeRef fn_type = LLVMFunctionType(c->intptr, &c->object_ptr, 1, false); func = LLVMBuildBitCast(c->builder, func, LLVMPointerType(fn_type, 0), ""); LLVMValueRef box_digest = codegen_call(c, func, &value, 1, true); if((boxed_subtype & SUBTYPE_KIND_UNBOXED) != 0) { LLVMBuildBr(c->builder, post_block); // Just cast the address. LLVMPositionBuilderAtEnd(c->builder, nonbox_block); LLVMValueRef nonbox_digest = LLVMBuildPtrToInt(c->builder, value, c->intptr, ""); LLVMBuildBr(c->builder, post_block); LLVMPositionBuilderAtEnd(c->builder, post_block); LLVMValueRef phi = LLVMBuildPhi(c->builder, c->intptr, ""); LLVMAddIncoming(phi, &box_digest, &box_block, 1); LLVMAddIncoming(phi, &nonbox_digest, &nonbox_block, 1); return phi; } else { return box_digest; } }
static LLVMValueRef translateFunCallExpr(SymbolTable *TyTable, SymbolTable *ValTable, ASTNode *Node) { PtrVector *V = &(Node->Child); ASTNode *ExprNode = (ASTNode*) ptrVectorGet(V, 0), *ParamsNode = (ASTNode*) ptrVectorGet(V, 1); LLVMTypeRef ReturnType = toTransitionType(getLLVMTypeFromType(TyTable, Node->Value)), *ParamsType = NULL, FunctionType; LLVMValueRef *ParamsValue = NULL; unsigned Count = 0; if (ParamsNode) { ParamsValue = (LLVMValueRef*) malloc(sizeof(LLVMValueRef) * ParamsNode->Child.Size); for (Count = 0; Count < ParamsNode->Child.Size; ++Count) { LLVMValueRef ExprVal = translateExpr(TyTable, ValTable, ptrVectorGet(&(ParamsNode->Child), Count)); LLVMTypeRef ExprType = LLVMGetElementType(LLVMTypeOf(ExprVal)); switch (LLVMGetTypeKind(ExprType)) { case LLVMIntegerTypeKind: case LLVMFloatTypeKind: case LLVMPointerTypeKind: ExprVal = LLVMBuildLoad(Builder, ExprVal, "load.4.call"); break; default: break; } ParamsValue[Count] = ExprVal; if (!ParamsType) ParamsType = (LLVMTypeRef*) malloc(sizeof(LLVMTypeRef) * ParamsNode->Child.Size); ParamsType[Count] = LLVMTypeOf(ExprVal); } } FunctionType = LLVMFunctionType(ReturnType, ParamsType, Count, 0); FunctionType = LLVMPointerType(FunctionType, 0); LLVMValueRef Closure = translateExpr(TyTable, ValTable, ExprNode); LLVMValueRef CallValue = callClosure(FunctionType, Closure, ParamsValue, Count); switch (getLLVMValueTypeKind(CallValue)) { case LLVMIntegerTypeKind: case LLVMFloatTypeKind: case LLVMPointerTypeKind: { if (getLLVMValueTypeKind(CallValue) == LLVMPointerTypeKind && getLLVMElementTypeKind(CallValue) == LLVMStructTypeKind) break; LLVMValueRef PtrMem = LLVMBuildAlloca(Builder, LLVMTypeOf(CallValue), ""); LLVMBuildStore(Builder, CallValue, PtrMem); return PtrMem; } } return CallValue; }
static LLVMValueRef declare_ffi_vararg(compile_t* c, const char* f_name, gentype_t* g, bool err) { LLVMTypeRef f_type = LLVMFunctionType(g->use_type, NULL, 0, true); LLVMValueRef func = LLVMAddFunction(c->module, f_name, f_type); if(!err) LLVMAddFunctionAttr(func, LLVMNoUnwindAttribute); return func; }
LLVMTypeRef ett_closure_type(EagleComplexType *type) { if(!ET_IS_CLOSURE(type)) return NULL; EagleFunctionType *ft = (EagleFunctionType *)type; LLVMTypeRef *tys = malloc(sizeof(LLVMTypeRef) * (ft->pct + 1)); int i; for(i = 1; i < ft->pct + 1; i++) tys[i] = ett_llvm_type(ft->params[i - 1]); tys[0] = LLVMPointerType(LLVMInt8TypeInContext(utl_get_current_context()), 0); LLVMTypeRef out = LLVMFunctionType(ett_llvm_type(ft->retType), tys, ft->pct + 1, 0); free(tys); return out; }
static LLVMValueRef add_conv_test(struct gallivm_state *gallivm, struct lp_type src_type, unsigned num_srcs, struct lp_type dst_type, unsigned num_dsts) { LLVMModuleRef module = gallivm->module; LLVMContextRef context = gallivm->context; LLVMBuilderRef builder = gallivm->builder; LLVMTypeRef args[2]; LLVMValueRef func; LLVMValueRef src_ptr; LLVMValueRef dst_ptr; LLVMBasicBlockRef block; LLVMValueRef src[LP_MAX_VECTOR_LENGTH]; LLVMValueRef dst[LP_MAX_VECTOR_LENGTH]; unsigned i; args[0] = LLVMPointerType(lp_build_vec_type(gallivm, src_type), 0); args[1] = LLVMPointerType(lp_build_vec_type(gallivm, dst_type), 0); func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidTypeInContext(context), args, 2, 0)); LLVMSetFunctionCallConv(func, LLVMCCallConv); src_ptr = LLVMGetParam(func, 0); dst_ptr = LLVMGetParam(func, 1); block = LLVMAppendBasicBlockInContext(context, func, "entry"); LLVMPositionBuilderAtEnd(builder, block); for(i = 0; i < num_srcs; ++i) { LLVMValueRef index = LLVMConstInt(LLVMInt32TypeInContext(context), i, 0); LLVMValueRef ptr = LLVMBuildGEP(builder, src_ptr, &index, 1, ""); src[i] = LLVMBuildLoad(builder, ptr, ""); } lp_build_conv(gallivm, src_type, dst_type, src, num_srcs, dst, num_dsts); for(i = 0; i < num_dsts; ++i) { LLVMValueRef index = LLVMConstInt(LLVMInt32TypeInContext(context), i, 0); LLVMValueRef ptr = LLVMBuildGEP(builder, dst_ptr, &index, 1, ""); LLVMBuildStore(builder, dst[i], ptr); } LLVMBuildRetVoid(builder);; gallivm_verify_function(gallivm, func); return func; }
static LLVMValueRef make_unbox_function(compile_t* c, gentype_t* g, const char* name) { LLVMValueRef fun = LLVMGetNamedFunction(c->module, name); if(fun == NULL) return LLVMConstNull(c->void_ptr); // Create a new unboxing function that forwards to the real function. LLVMTypeRef f_type = LLVMGetElementType(LLVMTypeOf(fun)); int count = LLVMCountParamTypes(f_type); // If it takes no arguments, it's a special number constructor. Don't put it // in the vtable. if(count == 0) return LLVMConstNull(c->void_ptr); size_t buf_size = count *sizeof(LLVMTypeRef); LLVMTypeRef* params = (LLVMTypeRef*)pool_alloc_size(buf_size); LLVMGetParamTypes(f_type, params); LLVMTypeRef ret_type = LLVMGetReturnType(f_type); // It's the same type, but it takes the boxed type instead of the primitive // type as the receiver. params[0] = g->structure_ptr; const char* unbox_name = genname_unbox(name); LLVMTypeRef unbox_type = LLVMFunctionType(ret_type, params, count, false); LLVMValueRef unbox_fun = codegen_addfun(c, unbox_name, unbox_type); codegen_startfun(c, unbox_fun, false); // Extract the primitive type from element 1 and call the real function. LLVMValueRef this_ptr = LLVMGetParam(unbox_fun, 0); LLVMValueRef primitive_ptr = LLVMBuildStructGEP(c->builder, this_ptr, 1, ""); LLVMValueRef primitive = LLVMBuildLoad(c->builder, primitive_ptr, ""); LLVMValueRef* args = (LLVMValueRef*)pool_alloc_size(buf_size); args[0] = primitive; for(int i = 1; i < count; i++) args[i] = LLVMGetParam(unbox_fun, i); LLVMValueRef result = codegen_call(c, fun, args, count); LLVMBuildRet(c->builder, result); codegen_finishfun(c); pool_free_size(buf_size, params); pool_free_size(buf_size, args); return LLVMConstBitCast(unbox_fun, c->void_ptr); }
static LLVMTypeRef get_signature(compile_t* c, gentype_t* g, ast_t* fun) { // Get a type for the result. ast_t* rtype = ast_childidx(fun, 4); gentype_t rtype_g; if(!gentype(c, rtype, &rtype_g)) { ast_error(rtype, "couldn't generate result type"); return NULL; } // Count the parameters, including the receiver. ast_t* params = ast_childidx(fun, 3); size_t count = ast_childcount(params) + 1; size_t buf_size = count *sizeof(LLVMTypeRef); LLVMTypeRef* tparams = (LLVMTypeRef*)pool_alloc_size(buf_size); count = 0; // Get a type for the receiver. tparams[count++] = g->use_type; // Get a type for each parameter. ast_t* param = ast_child(params); while(param != NULL) { ast_t* ptype = ast_childidx(param, 1); gentype_t ptype_g; if(!gentype(c, ptype, &ptype_g)) { ast_error(ptype, "couldn't generate parameter type"); pool_free_size(buf_size, tparams); return NULL; } tparams[count++] = ptype_g.use_type; param = ast_sibling(param); } LLVMTypeRef result = rtype_g.use_type; // Generate the function type. LLVMTypeRef r = LLVMFunctionType(result, tparams, (int)count, false); pool_free_size(buf_size, tparams); return r; }
static void donotoptimise_observe(compile_t* c, reach_type_t* t) { FIND_METHOD("observe"); start_function(c, m, m->result->use_type, &t->use_type, 1); LLVMTypeRef void_fn = LLVMFunctionType(c->void_type, NULL, 0, false); LLVMValueRef asmstr = LLVMConstInlineAsm(void_fn, "", "~{memory}", true, false); LLVMBuildCall(c->builder, asmstr, NULL, 0, ""); LLVMBuildRet(c->builder, m->result->instance); codegen_finishfun(c); BOX_FUNCTION(); }
LLVMValueRef build_l4_ipc_call( struct llvm_ctx *ctx, LLVMValueRef arg_to, LLVMValueRef arg_timeouts, LLVMValueRef arg_fromspec, LLVMValueRef arg_mr0, LLVMValueRef *from_p, LLVMValueRef *mr1_p, LLVMValueRef *mr2_p) { LLVMTypeRef params[5]; for(int i=0; i<5; i++) params[i] = ctx->wordt; LLVMTypeRef ipc_result_type = LLVMStructTypeInContext(ctx->ctx, params, 4, 0); LLVMTypeRef ipc_type = LLVMFunctionType(ipc_result_type, params, 5, 0); LLVMValueRef fn = LLVMConstInlineAsm(ipc_type, /* NOTE: this compensates against LLVM 3.3's inability to save %ebp * over an asm statement. clearly a bug, but w/e. * * it's been around since at least LLVM 3.2. */ " pushl %ebp\n" "\tcall __L4_Ipc\n" "\tmovl %ebp, %ecx\n" "\tpopl %ebp\n", "={ax},={si},={bx},={cx},{ax},{cx},{dx},{si},{di},~{dirflag},~{fpsr},~{flags}", 1, 0); LLVMValueRef args[5] = { arg_to, arg_timeouts, arg_fromspec, arg_mr0, LLVMBuildPtrToInt(ctx->builder, ctx->utcb, ctx->wordt, "l4ipc.utcb"), }; LLVMValueRef result = LLVMBuildCall(ctx->builder, fn, args, 5, "l4ipc"); LLVMSetTailCall(result, 1); if(from_p != NULL) { *from_p = LLVMBuildExtractValue(ctx->builder, result, 0, "from"); } if(mr1_p != NULL) { *mr1_p = LLVMBuildExtractValue(ctx->builder, result, 2, "mr1"); } if(mr2_p != NULL) { *mr2_p = LLVMBuildExtractValue(ctx->builder, result, 3, "mr2"); } return LLVMBuildExtractValue(ctx->builder, result, 1, "mr0"); }