@@ -7002,8 +7002,9 @@ static void allocate_gc_frame(jl_codectx_t &ctx, BasicBlock *b0, bool or_new=fal
7002
7002
// allocate a placeholder gc instruction
7003
7003
// this will require the runtime, but it gets deleted later if unused
7004
7004
ctx.topalloca = ctx.builder .CreateCall (prepare_call (or_new ? jladoptthread_func : jlpgcstack_func));
7005
- ctx.pgcstack = ctx.topalloca ;
7006
- ctx.pgcstack ->setName (" pgcstack" );
7005
+ ctx.topalloca ->setName (" pgcstack" );
7006
+ if (ctx.pgcstack == nullptr )
7007
+ ctx.pgcstack = ctx.topalloca ;
7007
7008
}
7008
7009
7009
7010
static Value *get_current_task (jl_codectx_t &ctx)
@@ -7150,16 +7151,17 @@ static void emit_specsig_to_specsig(
7150
7151
ctx.builder .SetInsertPoint (b0);
7151
7152
DebugLoc noDbg;
7152
7153
ctx.builder .SetCurrentDebugLocation (noDbg);
7153
- allocate_gc_frame (ctx, b0);
7154
7154
Function::arg_iterator AI = gf_thunk->arg_begin ();
7155
7155
SmallVector<jl_cgval_t , 0 > myargs (nargs);
7156
7156
if (cc == jl_returninfo_t ::SRet || cc == jl_returninfo_t ::Union)
7157
7157
++AI;
7158
7158
if (return_roots)
7159
7159
++AI;
7160
7160
if (JL_FEAT_TEST (ctx,gcstack_arg)) {
7161
+ ctx.pgcstack = AI;
7161
7162
++AI; // gcstack_arg
7162
7163
}
7164
+ allocate_gc_frame (ctx, b0);
7163
7165
for (size_t i = 0 ; i < nargs; i++) {
7164
7166
if (i == 0 && is_for_opaque_closure) {
7165
7167
// `jt` would be wrong here (it is the captures type), so is not used used for
@@ -7266,6 +7268,10 @@ static void emit_specsig_to_specsig(
7266
7268
break ;
7267
7269
}
7268
7270
}
7271
+ if (ctx.topalloca != ctx.pgcstack && ctx.topalloca ->use_empty ()) {
7272
+ ctx.topalloca ->eraseFromParent ();
7273
+ ctx.topalloca = nullptr ;
7274
+ }
7269
7275
}
7270
7276
7271
7277
void emit_specsig_to_fptr1 (
@@ -8122,6 +8128,10 @@ static void gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *abi, jl_va
8122
8128
CreateTrap (ctx.builder , false );
8123
8129
else
8124
8130
ctx.builder .CreateRet (boxed (ctx, retval));
8131
+ if (ctx.topalloca != ctx.pgcstack && ctx.topalloca ->use_empty ()) {
8132
+ ctx.topalloca ->eraseFromParent ();
8133
+ ctx.topalloca = nullptr ;
8134
+ }
8125
8135
}
8126
8136
8127
8137
static jl_returninfo_t get_specsig_function (jl_codegen_params_t ¶ms, Module *M, Value *fval, StringRef name, jl_value_t *sig, jl_value_t *jlrettype, bool is_opaque_closure,
@@ -8778,7 +8788,53 @@ static jl_llvm_functions_t
8778
8788
ctx.spvals_ptr = &*AI++;
8779
8789
}
8780
8790
}
8781
- // step 6. set up GC frame
8791
+ // step 6. set up GC frame and special arguments
8792
+ Function::arg_iterator AI = f->arg_begin ();
8793
+ SmallVector<AttributeSet, 0 > attrs (f->arg_size ()); // function declaration attributes
8794
+
8795
+ if (has_sret) {
8796
+ Argument *Arg = &*AI;
8797
+ ++AI;
8798
+ AttrBuilder param (ctx.builder .getContext (), f->getAttributes ().getParamAttrs (Arg->getArgNo ()));
8799
+ if (returninfo.cc == jl_returninfo_t ::Union) {
8800
+ param.addAttribute (Attribute::NonNull);
8801
+ // The `dereferenceable` below does not imply `nonnull` for non addrspace(0) pointers.
8802
+ param.addDereferenceableAttr (returninfo.union_bytes );
8803
+ param.addAlignmentAttr (returninfo.union_align );
8804
+ }
8805
+ else {
8806
+ const DataLayout &DL = jl_Module->getDataLayout ();
8807
+ Type *RT = Arg->getParamStructRetType ();
8808
+ TypeSize sz = DL.getTypeAllocSize (RT);
8809
+ Align al = DL.getPrefTypeAlign (RT);
8810
+ if (al > MAX_ALIGN)
8811
+ al = Align (MAX_ALIGN);
8812
+ param.addAttribute (Attribute::NonNull);
8813
+ // The `dereferenceable` below does not imply `nonnull` for non addrspace(0) pointers.
8814
+ param.addDereferenceableAttr (sz);
8815
+ param.addAlignmentAttr (al);
8816
+ }
8817
+ attrs[Arg->getArgNo ()] = AttributeSet::get (Arg->getContext (), param); // function declaration attributes
8818
+ }
8819
+ if (returninfo.return_roots ) {
8820
+ Argument *Arg = &*AI;
8821
+ ++AI;
8822
+ AttrBuilder param (ctx.builder .getContext (), f->getAttributes ().getParamAttrs (Arg->getArgNo ()));
8823
+ param.addAttribute (Attribute::NonNull);
8824
+ // The `dereferenceable` below does not imply `nonnull` for non addrspace(0) pointers.
8825
+ size_t size = returninfo.return_roots * sizeof (jl_value_t *);
8826
+ param.addDereferenceableAttr (size);
8827
+ param.addAlignmentAttr (Align (sizeof (jl_value_t *)));
8828
+ attrs[Arg->getArgNo ()] = AttributeSet::get (Arg->getContext (), param); // function declaration attributes
8829
+ }
8830
+ if (specsig && JL_FEAT_TEST (ctx, gcstack_arg)) {
8831
+ Argument *Arg = &*AI;
8832
+ ctx.pgcstack = Arg;
8833
+ ++AI;
8834
+ AttrBuilder param (ctx.builder .getContext ());
8835
+ attrs[Arg->getArgNo ()] = AttributeSet::get (Arg->getContext (), param);
8836
+ }
8837
+
8782
8838
allocate_gc_frame (ctx, b0);
8783
8839
Value *last_age = NULL ;
8784
8840
Value *world_age_field = NULL ;
@@ -8921,9 +8977,6 @@ static jl_llvm_functions_t
8921
8977
}
8922
8978
8923
8979
// step 8. move args into local variables
8924
- Function::arg_iterator AI = f->arg_begin ();
8925
- SmallVector<AttributeSet, 0 > attrs (f->arg_size ()); // function declaration attributes
8926
-
8927
8980
auto get_specsig_arg = [&](jl_value_t *argType, Type *llvmArgType, bool isboxed) {
8928
8981
if (type_is_ghost (llvmArgType)) { // this argument is not actually passed
8929
8982
return ghostValue (ctx, argType);
@@ -8956,47 +9009,6 @@ static jl_llvm_functions_t
8956
9009
return theArg;
8957
9010
};
8958
9011
8959
- if (has_sret) {
8960
- Argument *Arg = &*AI;
8961
- ++AI;
8962
- AttrBuilder param (ctx.builder .getContext (), f->getAttributes ().getParamAttrs (Arg->getArgNo ()));
8963
- if (returninfo.cc == jl_returninfo_t ::Union) {
8964
- param.addAttribute (Attribute::NonNull);
8965
- // The `dereferenceable` below does not imply `nonnull` for non addrspace(0) pointers.
8966
- param.addDereferenceableAttr (returninfo.union_bytes );
8967
- param.addAlignmentAttr (returninfo.union_align );
8968
- }
8969
- else {
8970
- const DataLayout &DL = jl_Module->getDataLayout ();
8971
- Type *RT = Arg->getParamStructRetType ();
8972
- TypeSize sz = DL.getTypeAllocSize (RT);
8973
- Align al = DL.getPrefTypeAlign (RT);
8974
- if (al > MAX_ALIGN)
8975
- al = Align (MAX_ALIGN);
8976
- param.addAttribute (Attribute::NonNull);
8977
- // The `dereferenceable` below does not imply `nonnull` for non addrspace(0) pointers.
8978
- param.addDereferenceableAttr (sz);
8979
- param.addAlignmentAttr (al);
8980
- }
8981
- attrs[Arg->getArgNo ()] = AttributeSet::get (Arg->getContext (), param); // function declaration attributes
8982
- }
8983
- if (returninfo.return_roots ) {
8984
- Argument *Arg = &*AI;
8985
- ++AI;
8986
- AttrBuilder param (ctx.builder .getContext (), f->getAttributes ().getParamAttrs (Arg->getArgNo ()));
8987
- param.addAttribute (Attribute::NonNull);
8988
- // The `dereferenceable` below does not imply `nonnull` for non addrspace(0) pointers.
8989
- size_t size = returninfo.return_roots * sizeof (jl_value_t *);
8990
- param.addDereferenceableAttr (size);
8991
- param.addAlignmentAttr (Align (sizeof (jl_value_t *)));
8992
- attrs[Arg->getArgNo ()] = AttributeSet::get (Arg->getContext (), param); // function declaration attributes
8993
- }
8994
- if (specsig && JL_FEAT_TEST (ctx, gcstack_arg)){
8995
- Argument *Arg = &*AI;
8996
- ++AI;
8997
- AttrBuilder param (ctx.builder .getContext ());
8998
- attrs[Arg->getArgNo ()] = AttributeSet::get (Arg->getContext (), param);
8999
- }
9000
9012
for (i = 0 ; i < nreq && i < vinfoslen; i++) {
9001
9013
jl_sym_t *s = slot_symbol (ctx, i);
9002
9014
jl_varinfo_t &vi = ctx.slots [i];
@@ -9964,7 +9976,7 @@ static jl_llvm_functions_t
9964
9976
}
9965
9977
}
9966
9978
9967
- if (ctx.topalloca ->use_empty ()) {
9979
+ if (ctx.topalloca != ctx. pgcstack && ctx. topalloca ->use_empty ()) {
9968
9980
ctx.topalloca ->eraseFromParent ();
9969
9981
ctx.topalloca = nullptr ;
9970
9982
}
0 commit comments