@@ -4072,21 +4072,38 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
40724072        }
40734073    }
40744074
4075-     else  if  (( f == BUILTIN (_apply_iterate) && nargs == 3 ) && ctx. vaSlot  >  0 ) {
4075+     else  if  (f == BUILTIN (_apply_iterate) && nargs == 3 ) {
40764076        //  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);
40814082#ifdef  _P64
4082-                 nva = ctx.builder .CreateTrunc (nva, getInt32Ty (ctx.builder .getContext ()));
4083+                      nva = ctx.builder .CreateTrunc (nva, getInt32Ty (ctx.builder .getContext ()));
40834084#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+                 }
40884090            }
40894091        }
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" 
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+         }
40904107    }
40914108
40924109    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,
41004117        }
41014118    }
41024119
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+ 
41034141    else  if  (f == BUILTIN (throw ) && nargs == 1 ) {
41044142        Value *arg1 = boxed (ctx, argv[1 ]);
41054143        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,
45994637        return  emit_f_opfield (ctx, ret, f, argv, nargs, nullptr );
46004638    }
46014639
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+ 
46024654    else  if  (f == BUILTIN (nfields) && nargs == 1 ) {
46034655        const  jl_cgval_t  &obj = argv[1 ];
46044656        if  (ctx.vaSlot  > 0 ) {
0 commit comments