Skip to content

Commit 8839e28

Browse files
committed
Optimize codegen for non-concrete pointer arithmetic.
1 parent 2de8148 commit 8839e28

File tree

2 files changed

+36
-27
lines changed

2 files changed

+36
-27
lines changed

base/compiler/tfuncs.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ function pointer_eltype(@nospecialize(ptr))
660660
return Any
661661
end
662662

663-
@nospecs function ptrarith_tfunc(𝕃::AbstractLattice, ptr, offset)
663+
@nospecs function pointerarith_tfunc(𝕃::AbstractLattice, ptr, offset)
664664
return ptr
665665
end
666666
@nospecs function pointerref_tfunc(𝕃::AbstractLattice, a, i, align)
@@ -706,8 +706,8 @@ end
706706
end
707707
return ccall(:jl_apply_cmpswap_type, Any, (Any,), T) where T
708708
end
709-
add_tfunc(add_ptr, 2, 2, ptrarith_tfunc, 1)
710-
add_tfunc(sub_ptr, 2, 2, ptrarith_tfunc, 1)
709+
add_tfunc(add_ptr, 2, 2, pointerarith_tfunc, 1)
710+
add_tfunc(sub_ptr, 2, 2, pointerarith_tfunc, 1)
711711
add_tfunc(pointerref, 3, 3, pointerref_tfunc, 4)
712712
add_tfunc(pointerset, 4, 4, pointerset_tfunc, 5)
713713
add_tfunc(atomic_fence, 1, 1, atomic_fence_tfunc, 4)

src/intrinsics.cpp

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ STATISTIC(EmittedRuntimeCalls, "Number of runtime intrinsic calls emitted");
1717
STATISTIC(EmittedIntrinsics, "Number of intrinsic calls emitted");
1818
STATISTIC(Emitted_pointerref, "Number of pointerref calls emitted");
1919
STATISTIC(Emitted_pointerset, "Number of pointerset calls emitted");
20-
STATISTIC(Emitted_add_ptr, "Number of add_ptr calls emitted");
21-
STATISTIC(Emitted_sub_ptr, "Number of sub_ptr calls emitted");
20+
STATISTIC(Emitted_pointerarith, "Number of pointer arithmetic calls emitted");
2221
STATISTIC(Emitted_atomic_fence, "Number of atomic_fence calls emitted");
2322
STATISTIC(Emitted_atomic_pointerref, "Number of atomic_pointerref calls emitted");
2423
STATISTIC(Emitted_atomic_pointerop, "Number of atomic_pointerop calls emitted");
@@ -860,6 +859,34 @@ static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, ArrayRef<jl_cgval_t> argv)
860859
return e;
861860
}
862861

862+
// ptr + offset
863+
// ptr - offset
864+
static jl_cgval_t emit_pointerarith(jl_codectx_t &ctx, intrinsic f,
865+
ArrayRef<jl_cgval_t> argv)
866+
{
867+
jl_value_t *ptrtyp = argv[0].typ;
868+
jl_value_t *offtyp = argv[1].typ;
869+
if (!jl_is_cpointer_type(ptrtyp) || offtyp != (jl_value_t *)jl_ulong_type)
870+
return emit_runtime_call(ctx, f, argv, argv.size());
871+
assert(f == add_ptr || f == sub_ptr);
872+
873+
Value *ptr = emit_unbox(ctx, ctx.types().T_ptr, argv[0], ptrtyp);
874+
Value *off = emit_unbox(ctx, ctx.types().T_size, argv[1], offtyp);
875+
if (f == sub_ptr)
876+
off = ctx.builder.CreateNeg(off);
877+
Value *ans = ctx.builder.CreateGEP(getInt8Ty(ctx.builder.getContext()), ptr, off);
878+
879+
if (jl_is_concrete_type(ptrtyp)) {
880+
return mark_julia_type(ctx, ans, false, ptrtyp);
881+
}
882+
else {
883+
Value *box = emit_allocobj(ctx, (jl_datatype_t *)ptrtyp, true);
884+
setName(ctx.emission_context, box, "ptr_box");
885+
init_bits_value(ctx, box, ans, ctx.tbaa().tbaa_immut);
886+
return mark_julia_type(ctx, box, true, (jl_datatype_t *)ptrtyp);
887+
}
888+
}
889+
863890
static jl_cgval_t emit_atomicfence(jl_codectx_t &ctx, ArrayRef<jl_cgval_t> argv)
864891
{
865892
const jl_cgval_t &ord = argv[0];
@@ -1278,29 +1305,11 @@ static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **ar
12781305
assert(nargs == 4);
12791306
return emit_pointerset(ctx, argv);
12801307

1281-
case add_ptr: {
1282-
++Emitted_add_ptr;
1308+
case add_ptr:
1309+
case sub_ptr:
1310+
++Emitted_pointerarith;
12831311
assert(nargs == 2);
1284-
if (!jl_is_cpointer_type(argv[0].typ) || jl_has_free_typevars(argv[0].typ) ||
1285-
argv[1].typ != (jl_value_t*)jl_ulong_type)
1286-
return emit_runtime_call(ctx, f, argv, nargs);
1287-
Value *ptr = emit_unbox(ctx, ctx.types().T_ptr, argv[0], argv[0].typ);
1288-
Value *off = emit_unbox(ctx, ctx.types().T_size, argv[1], argv[1].typ);
1289-
Value *ans = ctx.builder.CreateGEP(getInt8Ty(ctx.builder.getContext()), ptr, off);
1290-
return mark_julia_type(ctx, ans, false, argv[0].typ);
1291-
}
1292-
case sub_ptr: {
1293-
++Emitted_sub_ptr;
1294-
assert(nargs == 2);
1295-
if (!jl_is_cpointer_type(argv[0].typ) || jl_has_free_typevars(argv[0].typ) ||
1296-
argv[1].typ != (jl_value_t*)jl_ulong_type)
1297-
return emit_runtime_call(ctx, f, argv, nargs);
1298-
Value *ptr = emit_unbox(ctx, ctx.types().T_ptr, argv[0], argv[0].typ);
1299-
Value *off = emit_unbox(ctx, ctx.types().T_size, argv[1], argv[1].typ);
1300-
Value *ans = ctx.builder.CreateGEP(getInt8Ty(ctx.builder.getContext()), ptr,
1301-
ctx.builder.CreateNeg(off));
1302-
return mark_julia_type(ctx, ans, false, argv[0].typ);
1303-
}
1312+
return emit_pointerarith(ctx, f, argv);
13041313

13051314
case atomic_fence:
13061315
++Emitted_atomic_fence;

0 commit comments

Comments
 (0)