Skip to content

Commit

Permalink
some cleanup of runtime-intrinsics entry points
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Oct 3, 2016
1 parent a09ee6c commit a8962f3
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 64 deletions.
11 changes: 0 additions & 11 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
74 changes: 27 additions & 47 deletions src/intrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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,
Expand Down
20 changes: 14 additions & 6 deletions src/intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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");
}
Expand Down
1 change: 1 addition & 0 deletions src/runtime_intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

0 comments on commit a8962f3

Please sign in to comment.