Skip to content

Commit cdd101e

Browse files
committed
more fixes
1 parent 5da4dce commit cdd101e

File tree

8 files changed

+75
-49
lines changed

8 files changed

+75
-49
lines changed

base/compiler/ssair/inlining.jl

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,10 +1286,18 @@ function process_simple!(todo::Vector{Pair{Int,Any}}, ir::IRCode, idx::Int, stat
12861286
end
12871287
end
12881288

1289-
if (sig.f !== Core.invoke && sig.f !== Core.finalizer && sig.f !== modifyfield!) &&
1290-
is_builtin(optimizer_lattice(state.interp), sig)
1291-
# No inlining for builtins (other invoke/apply/typeassert/finalizer)
1292-
return nothing
1289+
if is_builtin(optimizer_lattice(state.interp), sig)
1290+
let f = sig.f
1291+
if (f !== Core.invoke &&
1292+
f !== Core.finalizer &&
1293+
f !== modifyfield! &&
1294+
f !== Core.modifyglobal! &&
1295+
f !== Core.memoryrefmodify! &&
1296+
f !== atomic_pointermodify)
1297+
# No inlining defined for most builtins (just invoke/apply/typeassert/finalizer), so attempt an early exit for them
1298+
return nothing
1299+
end
1300+
end
12931301
end
12941302

12951303
# Special case inliners for regular functions

src/ccall.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ static void interpret_symbol_arg(jl_codectx_t &ctx, native_sym_arg_t &out, jl_va
669669

670670
// --- code generator for cglobal ---
671671

672-
static jl_cgval_t emit_runtime_call(jl_codectx_t &ctx, JL_I::intrinsic f, const jl_cgval_t *argv, size_t nargs);
672+
static jl_cgval_t emit_runtime_call(jl_codectx_t &ctx, JL_I::intrinsic f, ArrayRef<jl_cgval_t> argv, size_t nargs);
673673

674674
static jl_cgval_t emit_cglobal(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
675675
{
@@ -684,7 +684,7 @@ static jl_cgval_t emit_cglobal(jl_codectx_t &ctx, jl_value_t **args, size_t narg
684684
rt = static_eval(ctx, args[2]);
685685
if (rt == NULL) {
686686
JL_GC_POP();
687-
jl_cgval_t argv[2] = {jl_cgval_t(), jl_cgval_t()};
687+
jl_cgval_t argv[2];
688688
argv[0] = emit_expr(ctx, args[1]);
689689
argv[1] = emit_expr(ctx, args[2]);
690690
return emit_runtime_call(ctx, JL_I::cglobal, argv, nargs);

src/codegen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5113,7 +5113,7 @@ static jl_cgval_t emit_invoke_modify(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_
51135113
else if (jl_typetagis(f.constant, jl_intrinsic_type)) {
51145114
JL_I::intrinsic fi = (intrinsic)*(uint32_t*)jl_data_ptr(f.constant);
51155115
if (fi == JL_I::atomic_pointermodify && jl_intrinsic_nargs((int)fi) == nargs - 1)
5116-
return emit_atomic_pointerop(ctx, fi, argv.data(), nargs - 1, &lival);
5116+
return emit_atomic_pointerop(ctx, fi, ArrayRef<jl_cgval_t>(argv).drop_front(), nargs - 1, &lival);
51175117
}
51185118

51195119
if (it != builtin_func_map().end()) {

src/datatype.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,7 +1680,7 @@ JL_DLLEXPORT void jl_unlock_field(jl_mutex_t *v) JL_NOTSAFEPOINT
16801680
JL_UNLOCK_NOGC(v);
16811681
}
16821682

1683-
static inline char *lock(char *p, jl_value_t *parent, int needlock, enum atomic_kind isatomic)
1683+
static inline char *lock(char *p, jl_value_t *parent, int needlock, enum atomic_kind isatomic) JL_NOTSAFEPOINT
16841684
{
16851685
if (needlock) {
16861686
if (isatomic == isatomic_object) {
@@ -1694,7 +1694,7 @@ static inline char *lock(char *p, jl_value_t *parent, int needlock, enum atomic_
16941694
return p;
16951695
}
16961696

1697-
static inline void unlock(char *p, jl_value_t *parent, int needlock, enum atomic_kind isatomic)
1697+
static inline void unlock(char *p, jl_value_t *parent, int needlock, enum atomic_kind isatomic) JL_NOTSAFEPOINT
16981698
{
16991699
if (needlock) {
17001700
if (isatomic == isatomic_object) {

src/intrinsics.cpp

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ static jl_datatype_t *staticeval_bitstype(const jl_cgval_t &targ)
535535
return NULL;
536536
}
537537

538-
static jl_cgval_t emit_runtime_call(jl_codectx_t &ctx, JL_I::intrinsic f, const jl_cgval_t *argv, size_t nargs)
538+
static jl_cgval_t emit_runtime_call(jl_codectx_t &ctx, JL_I::intrinsic f, ArrayRef<jl_cgval_t> argv, size_t nargs)
539539
{
540540
Function *func = prepare_call(runtime_func()[f]);
541541
SmallVector<Value *, 0> argvalues(nargs);
@@ -547,7 +547,7 @@ static jl_cgval_t emit_runtime_call(jl_codectx_t &ctx, JL_I::intrinsic f, const
547547
}
548548

549549
// put a bits type tag on some value (despite the name, this doesn't necessarily actually change anything about the value however)
550-
static jl_cgval_t generic_bitcast(jl_codectx_t &ctx, const jl_cgval_t *argv)
550+
static jl_cgval_t generic_bitcast(jl_codectx_t &ctx, ArrayRef<jl_cgval_t> argv)
551551
{
552552
// Give the arguments names //
553553
const jl_cgval_t &bt_value = argv[0];
@@ -650,7 +650,7 @@ static jl_cgval_t generic_bitcast(jl_codectx_t &ctx, const jl_cgval_t *argv)
650650
static jl_cgval_t generic_cast(
651651
jl_codectx_t &ctx,
652652
intrinsic f, Instruction::CastOps Op,
653-
const jl_cgval_t *argv, bool toint, bool fromint)
653+
ArrayRef<jl_cgval_t> argv, bool toint, bool fromint)
654654
{
655655
auto &TT = ctx.emission_context.TargetTriple;
656656
auto &DL = ctx.emission_context.DL;
@@ -707,12 +707,12 @@ static jl_cgval_t generic_cast(
707707
}
708708
}
709709

710-
static jl_cgval_t emit_runtime_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
710+
static jl_cgval_t emit_runtime_pointerref(jl_codectx_t &ctx, ArrayRef<jl_cgval_t> argv)
711711
{
712712
return emit_runtime_call(ctx, pointerref, argv, 3);
713713
}
714714

715-
static jl_cgval_t emit_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
715+
static jl_cgval_t emit_pointerref(jl_codectx_t &ctx, ArrayRef<jl_cgval_t> argv)
716716
{
717717
const jl_cgval_t &e = argv[0];
718718
const jl_cgval_t &i = argv[1];
@@ -780,13 +780,13 @@ static jl_cgval_t emit_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
780780
}
781781
}
782782

783-
static jl_cgval_t emit_runtime_pointerset(jl_codectx_t &ctx, jl_cgval_t *argv)
783+
static jl_cgval_t emit_runtime_pointerset(jl_codectx_t &ctx, ArrayRef<jl_cgval_t> argv)
784784
{
785785
return emit_runtime_call(ctx, pointerset, argv, 4);
786786
}
787787

788788
// e[i] = x
789-
static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, jl_cgval_t *argv)
789+
static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, ArrayRef<jl_cgval_t> argv)
790790
{
791791
const jl_cgval_t &e = argv[0];
792792
const jl_cgval_t &x = argv[1];
@@ -853,7 +853,7 @@ static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, jl_cgval_t *argv)
853853
return e;
854854
}
855855

856-
static jl_cgval_t emit_atomicfence(jl_codectx_t &ctx, jl_cgval_t *argv)
856+
static jl_cgval_t emit_atomicfence(jl_codectx_t &ctx, ArrayRef<jl_cgval_t> argv)
857857
{
858858
const jl_cgval_t &ord = argv[0];
859859
if (ord.constant && jl_is_symbol(ord.constant)) {
@@ -869,7 +869,7 @@ static jl_cgval_t emit_atomicfence(jl_codectx_t &ctx, jl_cgval_t *argv)
869869
return emit_runtime_call(ctx, atomic_fence, argv, 1);
870870
}
871871

872-
static jl_cgval_t emit_atomic_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
872+
static jl_cgval_t emit_atomic_pointerref(jl_codectx_t &ctx, ArrayRef<jl_cgval_t> argv)
873873
{
874874
const jl_cgval_t &e = argv[0];
875875
const jl_cgval_t &ord = argv[1];
@@ -947,7 +947,7 @@ static jl_cgval_t emit_atomic_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
947947
// e[i] <= x (swap)
948948
// e[i] y => x (replace)
949949
// x(e[i], y) (modify)
950-
static jl_cgval_t emit_atomic_pointerop(jl_codectx_t &ctx, intrinsic f, const jl_cgval_t *argv, int nargs, const jl_cgval_t *modifyop)
950+
static jl_cgval_t emit_atomic_pointerop(jl_codectx_t &ctx, intrinsic f, ArrayRef<jl_cgval_t> argv, int nargs, const jl_cgval_t *modifyop)
951951
{
952952
bool issetfield = f == atomic_pointerset;
953953
bool isreplacefield = f == atomic_pointerreplace;
@@ -1084,7 +1084,7 @@ struct math_builder {
10841084
}
10851085
};
10861086

1087-
static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, Value **argvalues, size_t nargs,
1087+
static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, ArrayRef<Value*> argvalues, size_t nargs,
10881088
jl_datatype_t **newtyp, jl_value_t *xtyp);
10891089

10901090

@@ -1265,72 +1265,72 @@ static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **ar
12651265
case pointerref:
12661266
++Emitted_pointerref;
12671267
assert(nargs == 3);
1268-
return emit_pointerref(ctx, argv.data());
1268+
return emit_pointerref(ctx, argv);
12691269
case pointerset:
12701270
++Emitted_pointerset;
12711271
assert(nargs == 4);
1272-
return emit_pointerset(ctx, argv.data());
1272+
return emit_pointerset(ctx, argv);
12731273
case atomic_fence:
12741274
++Emitted_atomic_fence;
12751275
assert(nargs == 1);
1276-
return emit_atomicfence(ctx, argv.data());
1276+
return emit_atomicfence(ctx, argv);
12771277
case atomic_pointerref:
12781278
++Emitted_atomic_pointerref;
12791279
assert(nargs == 2);
1280-
return emit_atomic_pointerref(ctx, argv.data());
1280+
return emit_atomic_pointerref(ctx, argv);
12811281
case atomic_pointerset:
12821282
case atomic_pointerswap:
12831283
case atomic_pointermodify:
12841284
case atomic_pointerreplace:
12851285
++Emitted_atomic_pointerop;
1286-
return emit_atomic_pointerop(ctx, f, argv.data(), nargs, nullptr);
1286+
return emit_atomic_pointerop(ctx, f, argv, nargs, nullptr);
12871287
case bitcast:
12881288
++Emitted_bitcast;
12891289
assert(nargs == 2);
1290-
return generic_bitcast(ctx, argv.data());
1290+
return generic_bitcast(ctx, argv);
12911291
case trunc_int:
12921292
++Emitted_trunc_int;
12931293
assert(nargs == 2);
1294-
return generic_cast(ctx, f, Instruction::Trunc, argv.data(), true, true);
1294+
return generic_cast(ctx, f, Instruction::Trunc, argv, true, true);
12951295
case sext_int:
12961296
++Emitted_sext_int;
12971297
assert(nargs == 2);
1298-
return generic_cast(ctx, f, Instruction::SExt, argv.data(), true, true);
1298+
return generic_cast(ctx, f, Instruction::SExt, argv, true, true);
12991299
case zext_int:
13001300
++Emitted_zext_int;
13011301
assert(nargs == 2);
1302-
return generic_cast(ctx, f, Instruction::ZExt, argv.data(), true, true);
1302+
return generic_cast(ctx, f, Instruction::ZExt, argv, true, true);
13031303
case uitofp:
13041304
++Emitted_uitofp;
13051305
assert(nargs == 2);
1306-
return generic_cast(ctx, f, Instruction::UIToFP, argv.data(), false, true);
1306+
return generic_cast(ctx, f, Instruction::UIToFP, argv, false, true);
13071307
case sitofp:
13081308
++Emitted_sitofp;
13091309
assert(nargs == 2);
1310-
return generic_cast(ctx, f, Instruction::SIToFP, argv.data(), false, true);
1310+
return generic_cast(ctx, f, Instruction::SIToFP, argv, false, true);
13111311
case fptoui:
13121312
++Emitted_fptoui;
13131313
assert(nargs == 2);
1314-
return generic_cast(ctx, f, Instruction::FPToUI, argv.data(), true, false);
1314+
return generic_cast(ctx, f, Instruction::FPToUI, argv, true, false);
13151315
case fptosi:
13161316
++Emitted_fptosi;
13171317
assert(nargs == 2);
1318-
return generic_cast(ctx, f, Instruction::FPToSI, argv.data(), true, false);
1318+
return generic_cast(ctx, f, Instruction::FPToSI, argv, true, false);
13191319
case fptrunc:
13201320
++Emitted_fptrunc;
13211321
assert(nargs == 2);
1322-
return generic_cast(ctx, f, Instruction::FPTrunc, argv.data(), false, false);
1322+
return generic_cast(ctx, f, Instruction::FPTrunc, argv, false, false);
13231323
case fpext:
13241324
++Emitted_fpext;
13251325
assert(nargs == 2);
1326-
return generic_cast(ctx, f, Instruction::FPExt, argv.data(), false, false);
1326+
return generic_cast(ctx, f, Instruction::FPExt, argv, false, false);
13271327

13281328
case not_int: {
13291329
++Emitted_not_int;
13301330
assert(nargs == 1);
13311331
const jl_cgval_t &x = argv[0];
13321332
if (!jl_is_primitivetype(x.typ))
1333-
return emit_runtime_call(ctx, f, argv.data(), nargs);
1333+
return emit_runtime_call(ctx, f, argv, nargs);
13341334
Type *xt = INTT(bitstype_to_llvm(x.typ, ctx.builder.getContext(), true), DL);
13351335
Value *from = emit_unbox(ctx, xt, x, x.typ);
13361336
Value *ans = ctx.builder.CreateNot(from);
@@ -1342,7 +1342,7 @@ static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **ar
13421342
assert(nargs == 1);
13431343
const jl_cgval_t &x = argv[0];
13441344
if (!x.constant || !jl_is_datatype(x.constant))
1345-
return emit_runtime_call(ctx, f, argv.data(), nargs);
1345+
return emit_runtime_call(ctx, f, argv, nargs);
13461346
jl_datatype_t *dt = (jl_datatype_t*) x.constant;
13471347

13481348
// select the appropriated overloaded intrinsic
@@ -1352,7 +1352,7 @@ static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **ar
13521352
else if (dt == jl_float64_type)
13531353
intr_name += "f64";
13541354
else
1355-
return emit_runtime_call(ctx, f, argv.data(), nargs);
1355+
return emit_runtime_call(ctx, f, argv, nargs);
13561356

13571357
FunctionCallee intr = jl_Module->getOrInsertFunction(intr_name, getInt1Ty(ctx.builder.getContext()));
13581358
auto ret = ctx.builder.CreateCall(intr);
@@ -1365,14 +1365,14 @@ static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **ar
13651365

13661366
// verify argument types
13671367
if (!jl_is_primitivetype(xinfo.typ))
1368-
return emit_runtime_call(ctx, f, argv.data(), nargs);
1368+
return emit_runtime_call(ctx, f, argv, nargs);
13691369
Type *xtyp = bitstype_to_llvm(xinfo.typ, ctx.builder.getContext(), true);
13701370
if (float_func()[f])
13711371
xtyp = FLOATT(xtyp);
13721372
else
13731373
xtyp = INTT(xtyp, DL);
13741374
if (!xtyp)
1375-
return emit_runtime_call(ctx, f, argv.data(), nargs);
1375+
return emit_runtime_call(ctx, f, argv, nargs);
13761376
////Bool are required to be in the range [0,1]
13771377
////so while they are represented as i8,
13781378
////the operations need to be done in mod 1
@@ -1388,13 +1388,13 @@ static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **ar
13881388

13891389
if (f == shl_int || f == lshr_int || f == ashr_int) {
13901390
if (!jl_is_primitivetype(argv[1].typ))
1391-
return emit_runtime_call(ctx, f, argv.data(), nargs);
1391+
return emit_runtime_call(ctx, f, argv, nargs);
13921392
argt[1] = INTT(bitstype_to_llvm(argv[1].typ, ctx.builder.getContext(), true), DL);
13931393
}
13941394
else {
13951395
for (size_t i = 1; i < nargs; ++i) {
13961396
if (xinfo.typ != argv[i].typ)
1397-
return emit_runtime_call(ctx, f, argv.data(), nargs);
1397+
return emit_runtime_call(ctx, f, argv, nargs);
13981398
argt[i] = xtyp;
13991399
}
14001400
}
@@ -1407,7 +1407,7 @@ static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **ar
14071407

14081408
// call the intrinsic
14091409
jl_value_t *newtyp = xinfo.typ;
1410-
Value *r = emit_untyped_intrinsic(ctx, f, argvalues.data(), nargs, (jl_datatype_t**)&newtyp, xinfo.typ);
1410+
Value *r = emit_untyped_intrinsic(ctx, f, argvalues, nargs, (jl_datatype_t**)&newtyp, xinfo.typ);
14111411
// Turn Bool operations into mod 1 now, if needed
14121412
if (newtyp == (jl_value_t*)jl_bool_type && !r->getType()->isIntegerTy(1))
14131413
r = ctx.builder.CreateTrunc(r, getInt1Ty(ctx.builder.getContext()));
@@ -1417,7 +1417,7 @@ static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **ar
14171417
assert(0 && "unreachable");
14181418
}
14191419

1420-
static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, Value **argvalues, size_t nargs,
1420+
static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, ArrayRef<Value*> argvalues, size_t nargs,
14211421
jl_datatype_t **newtyp, jl_value_t *xtyp)
14221422
{
14231423
++EmittedUntypedIntrinsics;

src/julia.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,11 +1739,11 @@ JL_DLLEXPORT jl_datatype_t *jl_new_primitivetype(jl_value_t *name,
17391739
// constructors
17401740
JL_DLLEXPORT jl_value_t *jl_new_bits(jl_value_t *bt, const void *src);
17411741
JL_DLLEXPORT jl_value_t *jl_atomic_new_bits(jl_value_t *dt, const char *src);
1742-
JL_DLLEXPORT void jl_atomic_store_bits(char *dst, const jl_value_t *src, int nb);
1742+
JL_DLLEXPORT void jl_atomic_store_bits(char *dst, const jl_value_t *src, int nb) JL_NOTSAFEPOINT;
17431743
JL_DLLEXPORT jl_value_t *jl_atomic_swap_bits(jl_value_t *dt, char *dst, const jl_value_t *src, int nb);
1744-
JL_DLLEXPORT int jl_atomic_bool_cmpswap_bits(char *dst, const jl_value_t *expected, const jl_value_t *src, int nb);
1745-
JL_DLLEXPORT int jl_atomic_cmpswap_bits(jl_datatype_t *dt, jl_value_t *y, char *dst, const jl_value_t *expected, const jl_value_t *src, int nb);
1746-
JL_DLLEXPORT int jl_atomic_storeonce_bits(jl_datatype_t *dt, char *dst, const jl_value_t *src, int nb);
1744+
JL_DLLEXPORT int jl_atomic_bool_cmpswap_bits(char *dst, const jl_value_t *expected, const jl_value_t *src, int nb) JL_NOTSAFEPOINT;
1745+
JL_DLLEXPORT int jl_atomic_cmpswap_bits(jl_datatype_t *dt, jl_value_t *y, char *dst, const jl_value_t *expected, const jl_value_t *src, int nb) JL_NOTSAFEPOINT;
1746+
JL_DLLEXPORT int jl_atomic_storeonce_bits(jl_datatype_t *dt, char *dst, const jl_value_t *src, int nb) JL_NOTSAFEPOINT;
17471747
JL_DLLEXPORT jl_value_t *jl_new_struct(jl_datatype_t *type, ...);
17481748
JL_DLLEXPORT jl_value_t *jl_new_structv(jl_datatype_t *type, jl_value_t **args, uint32_t na);
17491749
JL_DLLEXPORT jl_value_t *jl_new_structt(jl_datatype_t *type, jl_value_t *tup);

test/compiler/effects.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ let effects = Base.infer_effects() do
446446
end
447447
@test !Core.Compiler.is_nothrow(effects)
448448
end
449-
@test_throws ErrorException setglobal!_nothrow_undefinedyet()
449+
@test_throws Union{ErrorException,TypeError} setglobal!_nothrow_undefinedyet() # TODO: what kind of error should this be?
450450

451451
# Nothrow for setfield!
452452
mutable struct SetfieldNothrow

test/compiler/inline.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,6 +1793,24 @@ let src = code_typed1((Atomic{Int},Union{Int,Float64})) do a, b
17931793
end
17941794
@test count(isinvokemodify(:mymax), src.code) == 2
17951795
end
1796+
global x_global_inc::Int = 1
1797+
let src = code_typed1(()) do
1798+
@atomic (@__MODULE__).x_global_inc += 1
1799+
end
1800+
@test count(isinvokemodify(:+), src.code) == 1
1801+
end
1802+
let src = code_typed1((Ptr{Int},)) do a
1803+
unsafe_modify!(a, +, 1)
1804+
end
1805+
@test count(isinvokemodify(:+), src.code) == 1
1806+
end
1807+
let src = code_typed1((AtomicMemoryRef{Int},)) do a
1808+
Core.memoryrefmodify!(a, +, 1, :sequentially_consistent, true)
1809+
end
1810+
@test count(isinvokemodify(:+), src.code) == 1
1811+
end
1812+
1813+
17961814

17971815
# apply `ssa_inlining_pass` multiple times
17981816
let interp = Core.Compiler.NativeInterpreter()

0 commit comments

Comments
 (0)