From a8962f36e0c0ed046fdbfd0a30bc03ec662dcc89 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Fri, 30 Sep 2016 14:26:57 -0400 Subject: [PATCH] some cleanup of runtime-intrinsics entry points --- src/codegen.cpp | 11 ------ src/intrinsics.cpp | 74 +++++++++++++++------------------------- src/intrinsics.h | 20 +++++++---- src/runtime_intrinsics.c | 1 + 4 files changed, 42 insertions(+), 64 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 830eb56bd3625..f5c2cc5564e5f 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -341,8 +341,6 @@ static Function *jlboundserrorv_func; static Function *jlcheckassign_func; static Function *jldeclareconst_func; static Function *jlgetbindingorerror_func; -static Function *jlpref_func; -static Function *jlpset_func; static Function *jltopeval_func; static Function *jlcopyast_func; static Function *jltuple_func; @@ -5509,15 +5507,6 @@ static void init_julia_llvm_env(Module *m) "jl_get_binding_or_error", m); add_named_global(jlgetbindingorerror_func, &jl_get_binding_or_error); - jlpref_func = Function::Create(FunctionType::get(T_pjlvalue, three_pvalue_llvmt, false), - Function::ExternalLinkage, - "jl_pointerref", m); - - jlpset_func = Function::Create(FunctionType::get(T_pjlvalue, four_pvalue_llvmt, false), - Function::ExternalLinkage, - "jl_pointerset", m); - - builtin_func_map[jl_f_is] = jlcall_func_to_llvm("jl_f_is", &jl_f_is, m); builtin_func_map[jl_f_typeof] = jlcall_func_to_llvm("jl_f_typeof", &jl_f_typeof, m); builtin_func_map[jl_f_sizeof] = jlcall_func_to_llvm("jl_f_sizeof", &jl_f_sizeof, m); diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index df1d741aa9528..33eb2282b489e 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -659,9 +659,9 @@ static jl_cgval_t emit_runtime_pointerref(jl_value_t *e, jl_value_t *i, jl_value Value *iarg = boxed(emit_expr(i, ctx), ctx); Value *alignarg = boxed(emit_expr(align, ctx), ctx); #if JL_LLVM_VERSION >= 30700 - Value *ret = builder.CreateCall(prepare_call(jlpref_func), { boxed(parg, ctx), iarg, alignarg }); + Value *ret = builder.CreateCall(prepare_call(runtime_func[pointerref]), { boxed(parg, ctx), iarg, alignarg }); #else - Value *ret = builder.CreateCall3(prepare_call(jlpref_func), boxed(parg, ctx), iarg, alignarg); + Value *ret = builder.CreateCall3(prepare_call(runtime_func[pointerref]), boxed(parg, ctx), iarg, alignarg); #endif jl_value_t *ety; if (jl_is_cpointer_type(parg.typ)) { @@ -726,9 +726,9 @@ static jl_cgval_t emit_runtime_pointerset(jl_value_t *e, jl_value_t *x, jl_value Value *iarg = boxed(emit_expr(i, ctx), ctx); Value *alignarg = boxed(emit_expr(align, ctx), ctx); #if JL_LLVM_VERSION >= 30700 - builder.CreateCall(prepare_call(jlpset_func), { boxed(parg, ctx), xarg, iarg, alignarg }); + builder.CreateCall(prepare_call(runtime_func[pointerset]), { boxed(parg, ctx), xarg, iarg, alignarg }); #else - builder.CreateCall4(prepare_call(jlpset_func), boxed(parg, ctx), xarg, iarg, alignarg); + builder.CreateCall4(prepare_call(runtime_func[pointerset]), boxed(parg, ctx), xarg, iarg, alignarg); #endif return parg; } @@ -856,57 +856,37 @@ static jl_cgval_t emit_intrinsic(intrinsic f, jl_value_t **args, size_t nargs, jl_errorf("intrinsic #%d %s: wrong number of arguments", f, JL_I::jl_intrinsic_name((int)f)); } + if (f == llvmcall) + return emit_llvmcall(args, nargs, ctx); + if (f == unbox) + return generic_unbox(args[1], args[2], ctx); // TODO: replace with generic_box + +#if 0 // this section enables runtime-intrinsics (e.g. for testing), and disables their llvm counterparts + jl_cgval_t *argv = (jl_cgval_t*)alloca(sizeof(jl_cgval_t) * nargs); + for (size_t i = 0; i < nargs; ++i) { + argv[i] = emit_expr(args[i + 1], ctx); + } + Value *func = prepare_call(runtime_func[f]); + Value **argvalues = (Value**)alloca(sizeof(Value*) * nargs); + for (size_t i = 0; i < nargs; ++i) { + argvalues[i] = boxed(argv[i], ctx); + } + Value *r = builder.CreateCall(func, makeArrayRef(argvalues, nargs)); + return mark_julia_type(r, true, (jl_value_t*)jl_any_type, ctx); +#else switch (f) { - case cglobal_auto: - case cglobal: return emit_cglobal(args, nargs, ctx); - case llvmcall: return emit_llvmcall(args, nargs, ctx); case arraylen: return mark_julia_type(emit_arraylen(emit_expr(args[1], ctx), args[1], ctx), false, jl_long_type, ctx); -#if 0 // this section enables runtime-intrinsics (e.g. for testing), and disables their llvm counterparts - default: - Value *r; - Value *func = prepare_call(runtime_func[f]); - if (nargs == 1) { - Value *x = boxed(emit_expr(args[1], ctx), ctx); -#if JL_LLVM_VERSION >= 30700 - r = builder.CreateCall(func, {x}); -#else - r = builder.CreateCall(func, x); -#endif - } - else if (nargs == 2) { - Value *x = boxed(emit_expr(args[1], ctx), ctx); - Value *y = boxed(emit_expr(args[2], ctx), ctx); -#if JL_LLVM_VERSION >= 30700 - r = builder.CreateCall(func, {x, y}); -#else - r = builder.CreateCall2(func, x, y); -#endif - } - else if (nargs == 3) { - Value *x = boxed(emit_expr(args[1], ctx), ctx); - Value *y = boxed(emit_expr(args[2], ctx), ctx); - Value *z = boxed(emit_expr(args[3], ctx), ctx); -#if JL_LLVM_VERSION >= 30700 - r = builder.CreateCall(func, {x, y, z}); -#else - r = builder.CreateCall3(func, x, y, z); -#endif - } - else { - assert(0); - } - return mark_julia_type(r, true, (jl_value_t*)jl_any_type, ctx); -#else + case cglobal_auto: + case cglobal: + return emit_cglobal(args, nargs, ctx); case pointerref: return emit_pointerref(args[1], args[2], args[3], ctx); case pointerset: return emit_pointerset(args[1], args[2], args[3], args[4], ctx); case box: return generic_box(args[1], args[2], ctx); - case unbox: - return generic_unbox(args[1], args[2], ctx); // TODO: replace with generic_box case trunc_int: return generic_trunc(args[1], args[2], ctx, false, false); case checked_trunc_sint: @@ -1073,9 +1053,9 @@ static jl_cgval_t emit_intrinsic(intrinsic f, jl_value_t **args, size_t nargs, r = builder.CreateZExt(r, T_int8); return mark_julia_type(r, false, newtyp ? newtyp : xinfo.typ, ctx); } -#endif } - assert(0); +#endif + abort(); // unreachable } static Value *emit_untyped_intrinsic(intrinsic f, Value *x, Value *y, Value *z, size_t nargs, diff --git a/src/intrinsics.h b/src/intrinsics.h index 2ed6efd615d79..0669a4bcf4f8e 100644 --- a/src/intrinsics.h +++ b/src/intrinsics.h @@ -139,9 +139,6 @@ JL_DLLEXPORT const char *jl_intrinsic_name(int f) static void (*runtime_fp[num_intrinsics])(void); static unsigned intrinsic_nargs[num_intrinsics]; -typedef jl_value_t *(*intrinsic_call_1_arg)(jl_value_t*); -typedef jl_value_t *(*intrinsic_call_2_arg)(jl_value_t*, jl_value_t*); -typedef jl_value_t *(*intrinsic_call_3_arg)(jl_value_t*, jl_value_t*, jl_value_t*); #define jl_is_intrinsic(v) jl_typeis(v,jl_intrinsic_type) #ifdef __cplusplus @@ -162,13 +159,24 @@ JL_CALLABLE(jl_f_intrinsic_call) if (!fargs) jl_error("this intrinsic must be compiled to be called"); JL_NARGS(intrinsic_call, fargs, fargs); + + union { + void (*fptr)(void); + jl_value_t *(*call1)(jl_value_t*); + jl_value_t *(*call2)(jl_value_t*, jl_value_t*); + jl_value_t *(*call3)(jl_value_t*, jl_value_t*, jl_value_t*); + jl_value_t *(*call4)(jl_value_t*, jl_value_t*, jl_value_t*, jl_value_t*); + } fptr; + fptr.fptr = runtime_fp[f]; switch (fargs) { case 1: - return ((intrinsic_call_1_arg)runtime_fp[f])(args[0]); + return fptr.call1(args[0]); case 2: - return ((intrinsic_call_2_arg)runtime_fp[f])(args[0], args[1]); + return fptr.call2(args[0], args[1]); case 3: - return ((intrinsic_call_3_arg)runtime_fp[f])(args[0], args[1], args[2]); + return fptr.call3(args[0], args[1], args[2]); + case 4: + return fptr.call4(args[0], args[1], args[2], args[3]); default: assert(0 && "unexpected number of arguments to an intrinsic function"); } diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index 5d9d492f45a33..4580e8e9f6742 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -966,5 +966,6 @@ JL_DLLEXPORT jl_value_t *jl_select_value(jl_value_t *isfalse, jl_value_t *a, jl_ JL_DLLEXPORT jl_value_t *jl_arraylen(jl_value_t *a) { + JL_TYPECHK(arraylen, array, a); return jl_box_long(jl_array_len((jl_array_t*)a)); }