@@ -4072,21 +4072,38 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
4072
4072
}
4073
4073
}
4074
4074
4075
- else if (( f == BUILTIN (_apply_iterate) && nargs == 3 ) && ctx. vaSlot > 0 ) {
4075
+ else if (f == BUILTIN (_apply_iterate) && nargs == 3 ) {
4076
4076
// turn Core._apply_iterate(iter, f, Tuple) ==> f(Tuple...) using the jlcall calling convention if Tuple is the va allocation
4077
- if (LoadInst *load = dyn_cast_or_null<LoadInst>(argv[3 ].V )) {
4078
- if (load->getPointerOperand () == ctx.slots [ctx.vaSlot ].boxroot && ctx.argArray ) {
4079
- Value *theF = boxed (ctx, argv[2 ]);
4080
- Value *nva = emit_n_varargs (ctx);
4077
+ if (ctx.vaSlot > 0 ) {
4078
+ if (LoadInst *load = dyn_cast_or_null<LoadInst>(argv[3 ].V )) {
4079
+ if (load->getPointerOperand () == ctx.slots [ctx.vaSlot ].boxroot && ctx.argArray ) {
4080
+ Value *theF = boxed (ctx, argv[2 ]);
4081
+ Value *nva = emit_n_varargs (ctx);
4081
4082
#ifdef _P64
4082
- nva = ctx.builder .CreateTrunc (nva, getInt32Ty (ctx.builder .getContext ()));
4083
+ nva = ctx.builder .CreateTrunc (nva, getInt32Ty (ctx.builder .getContext ()));
4083
4084
#endif
4084
- Value *theArgs = emit_ptrgep (ctx, ctx.argArray , ctx.nReqArgs * sizeof (jl_value_t *));
4085
- Value *r = ctx.builder .CreateCall (prepare_call (jlapplygeneric_func), { theF, theArgs, nva });
4086
- *ret = mark_julia_type (ctx, r, true , jl_any_type);
4087
- return true ;
4085
+ Value *theArgs = emit_ptrgep (ctx, ctx.argArray , ctx.nReqArgs * sizeof (jl_value_t *));
4086
+ Value *r = ctx.builder .CreateCall (prepare_call (jlapplygeneric_func), { theF, theArgs, nva });
4087
+ *ret = mark_julia_type (ctx, r, true , jl_any_type);
4088
+ return true ;
4089
+ }
4088
4090
}
4089
4091
}
4092
+ // optimization for _apply_iterate when there is one argument and it is a SimpleVector
4093
+ const jl_cgval_t &arg = argv[3 ];
4094
+ if (arg.typ == (jl_value_t *)jl_simplevector_type) {
4095
+ Value *theF = boxed (ctx, argv[2 ]);
4096
+ Value *svec_val = boxed (ctx, arg);
4097
+ Value *svec_len = ctx.builder .CreateAlignedLoad (ctx.types ().T_size , decay_derived (ctx, svec_val), Align (ctx.types ().sizeof_ptr ));
4098
+ #ifdef _P64
4099
+ svec_len = ctx.builder .CreateTrunc (svec_len, getInt32Ty (ctx.builder .getContext ()));
4100
+ #endif
4101
+ Value *svec_data = emit_ptrgep (ctx, emit_pointer_from_objref (ctx, svec_val), ctx.types ().sizeof_ptr );
4102
+ OperandBundleDef OpBundle (" jl_roots" , svec_val);
4103
+ Value *r = ctx.builder .CreateCall (prepare_call (jlapplygeneric_func), { theF, svec_data, svec_len }, OpBundle);
4104
+ *ret = mark_julia_type (ctx, r, true , jl_any_type);
4105
+ return true ;
4106
+ }
4090
4107
}
4091
4108
4092
4109
else if (f == BUILTIN (tuple)) {
@@ -4100,6 +4117,27 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
4100
4117
}
4101
4118
}
4102
4119
4120
+ else if (f == BUILTIN (svec)) {
4121
+ if (nargs == 0 ) {
4122
+ *ret = mark_julia_const (ctx, (jl_value_t *)jl_emptysvec);
4123
+ return true ;
4124
+ }
4125
+ Value *svec = emit_allocobj (ctx, ctx.types ().sizeof_ptr * (nargs + 1 ), ctx.builder .CreateIntToPtr (emit_tagfrom (ctx, jl_simplevector_type), ctx.types ().T_pjlvalue ), true , julia_alignment ((jl_value_t *)jl_simplevector_type));
4126
+ Value *svec_derived = decay_derived (ctx, svec);
4127
+ ctx.builder .CreateAlignedStore (ConstantInt::get (ctx.types ().T_size , nargs), svec_derived, Align (ctx.types ().sizeof_ptr ));
4128
+ Value *svec_data = emit_ptrgep (ctx, svec_derived, ctx.types ().sizeof_ptr );
4129
+ ctx.builder .CreateMemSet (svec_data, ConstantInt::get (getInt8Ty (ctx.builder .getContext ()), 0 ), ctx.types ().sizeof_ptr * nargs, Align (ctx.types ().sizeof_ptr ));
4130
+ for (size_t i = 0 ; i < nargs; i++) {
4131
+ Value *elem = boxed (ctx, argv[i + 1 ]);
4132
+ Value *elem_ptr = emit_ptrgep (ctx, svec_derived, ctx.types ().sizeof_ptr * (i + 1 ));
4133
+ auto *store = ctx.builder .CreateAlignedStore (elem, elem_ptr, Align (ctx.types ().sizeof_ptr ));
4134
+ store->setOrdering (AtomicOrdering::Release);
4135
+ emit_write_barrier (ctx, svec, elem);
4136
+ }
4137
+ *ret = mark_julia_type (ctx, svec, true , jl_simplevector_type);
4138
+ return true ;
4139
+ }
4140
+
4103
4141
else if (f == BUILTIN (throw ) && nargs == 1 ) {
4104
4142
Value *arg1 = boxed (ctx, argv[1 ]);
4105
4143
raise_exception (ctx, arg1);
@@ -4599,6 +4637,20 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
4599
4637
return emit_f_opfield (ctx, ret, f, argv, nargs, nullptr );
4600
4638
}
4601
4639
4640
+ else if (f == BUILTIN (_svec_len) && nargs == 1 ) {
4641
+ const jl_cgval_t &obj = argv[1 ];
4642
+ Value *len;
4643
+ if (obj.constant && jl_is_svec (obj.constant )) {
4644
+ len = ConstantInt::get (ctx.types ().T_size , jl_svec_len (obj.constant ));
4645
+ }
4646
+ else {
4647
+ Value *svec_val = decay_derived (ctx, boxed (ctx, obj));
4648
+ len = ctx.builder .CreateAlignedLoad (ctx.types ().T_size , svec_val, Align (ctx.types ().sizeof_ptr ));
4649
+ }
4650
+ *ret = mark_julia_type (ctx, len, false , jl_long_type);
4651
+ return true ;
4652
+ }
4653
+
4602
4654
else if (f == BUILTIN (nfields) && nargs == 1 ) {
4603
4655
const jl_cgval_t &obj = argv[1 ];
4604
4656
if (ctx.vaSlot > 0 ) {
0 commit comments