Skip to content

Commit

Permalink
Convert checked_trunc_[su]int intrinsics to Julia code
Browse files Browse the repository at this point in the history
  • Loading branch information
timholy committed Jul 8, 2017
1 parent 914c446 commit d5ec1c6
Show file tree
Hide file tree
Showing 10 changed files with 19 additions and 54 deletions.
5 changes: 0 additions & 5 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -449,9 +449,6 @@ add_tfunc(uitofp, 2, 2, bitcast_tfunc, 1)
add_tfunc(sitofp, 2, 2, bitcast_tfunc, 1)
add_tfunc(fptrunc, 2, 2, bitcast_tfunc, 1)
add_tfunc(fpext, 2, 2, bitcast_tfunc, 1)
## checked conversion ##
add_tfunc(checked_trunc_sint, 2, 2, bitcast_tfunc, 3)
add_tfunc(checked_trunc_uint, 2, 2, bitcast_tfunc, 3)
## arithmetic ##
add_tfunc(neg_int, 1, 1, math_tfunc, 1)
add_tfunc(add_int, 2, 2, math_tfunc, 1)
Expand Down Expand Up @@ -3745,8 +3742,6 @@ function is_pure_intrinsic(f::IntrinsicFunction)
return !(f === Intrinsics.pointerref || # this one is volatile
f === Intrinsics.pointerset || # this one is never effect-free
f === Intrinsics.llvmcall || # this one is never effect-free
f === Intrinsics.checked_trunc_sint ||
f === Intrinsics.checked_trunc_uint ||
f === Intrinsics.checked_sdiv_int ||
f === Intrinsics.checked_udiv_int ||
f === Intrinsics.checked_srem_int ||
Expand Down
16 changes: 16 additions & 0 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,22 @@ end

## integer conversions ##

function checked_trunc_sint{To,From}(::Type{To}, x::From)
@_inline_meta
y = trunc_int(To, x)
back = sext_int(From, y)
x == back || throw(InexactError())
y
end

function checked_trunc_uint{To,From}(::Type{To}, x::From)
@_inline_meta
y = trunc_int(To, x)
back = zext_int(From, y)
x == back || throw(InexactError())
y
end

for to in BitInteger_types, from in (BitInteger_types..., Bool)
if !(to === from)
if to.size < from.size
Expand Down
1 change: 0 additions & 1 deletion src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6231,7 +6231,6 @@ static void init_julia_llvm_env(Module *m)
global_jlvalue_to_llvm("jl_diverror_exception", &jl_diverror_exception, m);
global_jlvalue_to_llvm("jl_undefref_exception", &jl_undefref_exception, m);
global_jlvalue_to_llvm("jl_overflow_exception", &jl_overflow_exception, m);
global_jlvalue_to_llvm("jl_inexact_exception", &jl_inexact_exception, m);

jlRTLD_DEFAULT_var =
new GlobalVariable(*m, T_pint8,
Expand Down
1 change: 0 additions & 1 deletion src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,6 @@ void jl_get_builtin_hooks(void)
jl_stackovf_exception = jl_new_struct_uninit((jl_datatype_t*)core("StackOverflowError"));
jl_diverror_exception = jl_new_struct_uninit((jl_datatype_t*)core("DivideError"));
jl_overflow_exception = jl_new_struct_uninit((jl_datatype_t*)core("OverflowError"));
jl_inexact_exception = jl_new_struct_uninit((jl_datatype_t*)core("InexactError"));
jl_undefref_exception = jl_new_struct_uninit((jl_datatype_t*)core("UndefRefError"));
jl_undefvarerror_type = (jl_datatype_t*)core("UndefVarError");
jl_interrupt_exception = jl_new_struct_uninit((jl_datatype_t*)core("InterruptException"));
Expand Down
22 changes: 0 additions & 22 deletions src/intrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,24 +498,6 @@ static Value *generic_trunc(jl_codectx_t &ctx, Type *to, Value *x)
return ctx.builder.CreateTrunc(x, to);
}

static Value *generic_trunc_uchecked(jl_codectx_t &ctx, Type *to, Value *x)
{
Value *ans = ctx.builder.CreateTrunc(x, to);
Value *back = ctx.builder.CreateZExt(ans, x->getType());
raise_exception_unless(ctx, ctx.builder.CreateICmpEQ(back, x),
literal_pointer_val(ctx, jl_inexact_exception));
return ans;
}

static Value *generic_trunc_schecked(jl_codectx_t &ctx, Type *to, Value *x)
{
Value *ans = ctx.builder.CreateTrunc(x, to);
Value *back = ctx.builder.CreateSExt(ans, x->getType());
raise_exception_unless(ctx, ctx.builder.CreateICmpEQ(back, x),
literal_pointer_val(ctx, jl_inexact_exception));
return ans;
}

static Value *generic_sext(jl_codectx_t &ctx, Type *to, Value *x)
{
return ctx.builder.CreateSExt(x, to);
Expand Down Expand Up @@ -777,10 +759,6 @@ static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **ar
return generic_bitcast(ctx, argv);
case trunc_int:
return generic_cast(ctx, f, generic_trunc, argv, true, true);
case checked_trunc_uint:
return generic_cast(ctx, f, generic_trunc_uchecked, argv, true, true);
case checked_trunc_sint:
return generic_cast(ctx, f, generic_trunc_schecked, argv, true, true);
case sext_int:
return generic_cast(ctx, f, generic_sext, argv, true, true);
case zext_int:
Expand Down
3 changes: 0 additions & 3 deletions src/intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,6 @@
ADD_I(sitofp, 2) \
ADD_I(fptrunc, 2) \
ADD_I(fpext, 2) \
/* checked conversion */ \
ADD_I(checked_trunc_sint, 2) \
ADD_I(checked_trunc_uint, 2) \
/* checked arithmetic */ \
ADD_I(checked_sadd_int, 2) \
ADD_I(checked_uadd_int, 2) \
Expand Down
1 change: 0 additions & 1 deletion src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ jl_value_t *jl_segv_exception;
JL_DLLEXPORT jl_value_t *jl_diverror_exception;
JL_DLLEXPORT jl_value_t *jl_domain_exception;
JL_DLLEXPORT jl_value_t *jl_overflow_exception;
JL_DLLEXPORT jl_value_t *jl_inexact_exception;
JL_DLLEXPORT jl_value_t *jl_undefref_exception;
jl_value_t *jl_interrupt_exception;
jl_datatype_t *jl_boundserror_type;
Expand Down
1 change: 0 additions & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,6 @@ extern JL_DLLEXPORT jl_value_t *jl_memory_exception;
extern JL_DLLEXPORT jl_value_t *jl_readonlymemory_exception;
extern JL_DLLEXPORT jl_value_t *jl_diverror_exception;
extern JL_DLLEXPORT jl_value_t *jl_overflow_exception;
extern JL_DLLEXPORT jl_value_t *jl_inexact_exception;
extern JL_DLLEXPORT jl_value_t *jl_undefref_exception;
extern JL_DLLEXPORT jl_value_t *jl_interrupt_exception;
extern JL_DLLEXPORT jl_datatype_t *jl_boundserror_type;
Expand Down
3 changes: 0 additions & 3 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -807,9 +807,6 @@ JL_DLLEXPORT jl_value_t *jl_fptosi(jl_value_t *ty, jl_value_t *a);
JL_DLLEXPORT jl_value_t *jl_fptrunc(jl_value_t *ty, jl_value_t *a);
JL_DLLEXPORT jl_value_t *jl_fpext(jl_value_t *ty, jl_value_t *a);

JL_DLLEXPORT jl_value_t *jl_checked_trunc_sint(jl_value_t *ty, jl_value_t *a);
JL_DLLEXPORT jl_value_t *jl_checked_trunc_uint(jl_value_t *ty, jl_value_t *a);

JL_DLLEXPORT jl_value_t *jl_checked_sadd_int(jl_value_t *a, jl_value_t *b);
JL_DLLEXPORT jl_value_t *jl_checked_uadd_int(jl_value_t *a, jl_value_t *b);
JL_DLLEXPORT jl_value_t *jl_checked_ssub_int(jl_value_t *a, jl_value_t *b);
Expand Down
20 changes: 3 additions & 17 deletions src/runtime_intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,15 +378,13 @@ static inline jl_value_t *jl_intrinsiclambda_u1(jl_value_t *ty, void *pa, unsign

typedef void (*intrinsic_cvt_t)(unsigned, void*, unsigned, void*);
typedef unsigned (*intrinsic_cvt_check_t)(unsigned, unsigned, void*);
#define cvt_iintrinsic_checked(LLVMOP, check_op, name) \
#define cvt_iintrinsic(LLVMOP, name) \
JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *ty, jl_value_t *a) \
{ \
return jl_intrinsic_cvt(ty, a, #name, LLVMOP, check_op); \
return jl_intrinsic_cvt(ty, a, #name, LLVMOP); \
}
#define cvt_iintrinsic(LLVMOP, name) \
cvt_iintrinsic_checked(LLVMOP, NULL, name) \

static inline jl_value_t *jl_intrinsic_cvt(jl_value_t *ty, jl_value_t *a, const char *name, intrinsic_cvt_t op, intrinsic_cvt_check_t check_op)
static inline jl_value_t *jl_intrinsic_cvt(jl_value_t *ty, jl_value_t *a, const char *name, intrinsic_cvt_t op)
{
jl_ptls_t ptls = jl_get_ptls_states();
jl_value_t *aty = jl_typeof(a);
Expand All @@ -397,8 +395,6 @@ static inline jl_value_t *jl_intrinsic_cvt(jl_value_t *ty, jl_value_t *a, const
void *pa = jl_data_ptr(a);
unsigned isize = jl_datatype_size(aty);
unsigned osize = jl_datatype_size(ty);
if (check_op && check_op(isize, osize, pa))
jl_throw(jl_inexact_exception);
jl_value_t *newv = jl_gc_alloc(ptls, jl_datatype_size(ty), ty);
op(aty == (jl_value_t*)jl_bool_type ? 1 : isize * host_char_bit, pa,
osize * host_char_bit, jl_data_ptr(newv));
Expand Down Expand Up @@ -856,16 +852,6 @@ static inline int all_eq(char *p, char n, char v)
return 0;
return 1;
}
static unsigned check_trunc_sint(unsigned isize, unsigned osize, void *pa)
{
return !all_eq((char*)pa + osize, isize - osize, signbitbyte(pa, isize)); // TODO: assumes little-endian
}
cvt_iintrinsic_checked(LLVMTrunc, check_trunc_sint, checked_trunc_sint)
static unsigned check_trunc_uint(unsigned isize, unsigned osize, void *pa)
{
return !all_eq((char*)pa + osize, isize - osize, 0); // TODO: assumes little-endian
}
cvt_iintrinsic_checked(LLVMTrunc, check_trunc_uint, checked_trunc_uint)

// checked arithmetic
#define check_sadd_int(a,b) \
Expand Down

0 comments on commit d5ec1c6

Please sign in to comment.