@@ -4065,21 +4065,38 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
40654065 }
40664066 }
40674067
4068- else if (( f == BUILTIN (_apply_iterate) && nargs == 3 ) && ctx. vaSlot > 0 ) {
4068+ else if (f == BUILTIN (_apply_iterate) && nargs == 3 ) {
40694069 // turn Core._apply_iterate(iter, f, Tuple) ==> f(Tuple...) using the jlcall calling convention if Tuple is the va allocation
4070- if (LoadInst *load = dyn_cast_or_null<LoadInst>(argv[3 ].V )) {
4071- if (load->getPointerOperand () == ctx.slots [ctx.vaSlot ].boxroot && ctx.argArray ) {
4072- Value *theF = boxed (ctx, argv[2 ]);
4073- Value *nva = emit_n_varargs (ctx);
4070+ if (ctx.vaSlot > 0 ) {
4071+ if (LoadInst *load = dyn_cast_or_null<LoadInst>(argv[3 ].V )) {
4072+ if (load->getPointerOperand () == ctx.slots [ctx.vaSlot ].boxroot && ctx.argArray ) {
4073+ Value *theF = boxed (ctx, argv[2 ]);
4074+ Value *nva = emit_n_varargs (ctx);
40744075#ifdef _P64
4075- nva = ctx.builder .CreateTrunc (nva, getInt32Ty (ctx.builder .getContext ()));
4076+ nva = ctx.builder .CreateTrunc (nva, getInt32Ty (ctx.builder .getContext ()));
40764077#endif
4077- Value *theArgs = emit_ptrgep (ctx, ctx.argArray , ctx.nReqArgs * sizeof (jl_value_t *));
4078- Value *r = ctx.builder .CreateCall (prepare_call (jlapplygeneric_func), { theF, theArgs, nva });
4079- *ret = mark_julia_type (ctx, r, true , jl_any_type);
4080- return true ;
4078+ Value *theArgs = emit_ptrgep (ctx, ctx.argArray , ctx.nReqArgs * sizeof (jl_value_t *));
4079+ Value *r = ctx.builder .CreateCall (prepare_call (jlapplygeneric_func), { theF, theArgs, nva });
4080+ *ret = mark_julia_type (ctx, r, true , jl_any_type);
4081+ return true ;
4082+ }
40814083 }
40824084 }
4085+ // optimization for _apply_iterate when there is one argument and it is a SimpleVector
4086+ const jl_cgval_t &arg = argv[3 ];
4087+ if (arg.typ == (jl_value_t *)jl_simplevector_type) {
4088+ Value *theF = boxed (ctx, argv[2 ]);
4089+ Value *svec_val = boxed (ctx, arg);
4090+ Value *svec_len = ctx.builder .CreateAlignedLoad (ctx.types ().T_size , decay_derived (ctx, svec_val), Align (ctx.types ().sizeof_ptr ));
4091+ #ifdef _P64
4092+ svec_len = ctx.builder .CreateTrunc (svec_len, getInt32Ty (ctx.builder .getContext ()));
4093+ #endif
4094+ Value *svec_data = emit_ptrgep (ctx, emit_pointer_from_objref (ctx, svec_val), ctx.types ().sizeof_ptr );
4095+ OperandBundleDef OpBundle (" jl_roots" , svec_val);
4096+ Value *r = ctx.builder .CreateCall (prepare_call (jlapplygeneric_func), { theF, svec_data, svec_len }, OpBundle);
4097+ *ret = mark_julia_type (ctx, r, true , jl_any_type);
4098+ return true ;
4099+ }
40834100 }
40844101
40854102 else if (f == BUILTIN (tuple)) {
@@ -4093,6 +4110,26 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
40934110 }
40944111 }
40954112
4113+ else if (f == BUILTIN (svec)) {
4114+ if (nargs == 0 ) {
4115+ *ret = mark_julia_const (ctx, (jl_value_t *)jl_emptysvec);
4116+ return true ;
4117+ }
4118+ 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));
4119+ Value *svec_derived = decay_derived (ctx, svec);
4120+ ctx.builder .CreateAlignedStore (ConstantInt::get (ctx.types ().T_size , nargs), svec_derived, Align (ctx.types ().sizeof_ptr ));
4121+ Value *svec_data = emit_ptrgep (ctx, svec_derived, ctx.types ().sizeof_ptr );
4122+ ctx.builder .CreateMemSet (svec_data, ConstantInt::get (getInt8Ty (ctx.builder .getContext ()), 0 ), ctx.types ().sizeof_ptr * nargs, Align (ctx.types ().sizeof_ptr ));
4123+ for (size_t i = 0 ; i < nargs; i++) {
4124+ Value *elem = boxed (ctx, argv[i + 1 ]);
4125+ Value *elem_ptr = emit_ptrgep (ctx, svec_derived, ctx.types ().sizeof_ptr * (i + 1 ));
4126+ ctx.builder .CreateAlignedStore (elem, elem_ptr, Align (ctx.types ().sizeof_ptr ));
4127+ emit_write_barrier (ctx, svec, elem);
4128+ }
4129+ *ret = mark_julia_type (ctx, svec, true , jl_simplevector_type);
4130+ return true ;
4131+ }
4132+
40964133 else if (f == BUILTIN (throw ) && nargs == 1 ) {
40974134 Value *arg1 = boxed (ctx, argv[1 ]);
40984135 raise_exception (ctx, arg1);
@@ -4601,6 +4638,20 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
46014638 return emit_f_opfield (ctx, ret, f, argv, nargs, nullptr );
46024639 }
46034640
4641+ else if (f == BUILTIN (_svec_len) && nargs == 1 ) {
4642+ const jl_cgval_t &obj = argv[1 ];
4643+ Value *len;
4644+ if (obj.constant && jl_is_svec (obj.constant )) {
4645+ len = ConstantInt::get (ctx.types ().T_size , jl_svec_len (obj.constant ));
4646+ }
4647+ else {
4648+ Value *svec_val = decay_derived (ctx, boxed (ctx, obj));
4649+ len = ctx.builder .CreateAlignedLoad (ctx.types ().T_size , svec_val, Align (ctx.types ().sizeof_ptr ));
4650+ }
4651+ *ret = mark_julia_type (ctx, len, false , jl_long_type);
4652+ return true ;
4653+ }
4654+
46044655 else if (f == BUILTIN (nfields) && nargs == 1 ) {
46054656 const jl_cgval_t &obj = argv[1 ];
46064657 if (ctx.vaSlot > 0 ) {
0 commit comments