Skip to content

Commit baf1c50

Browse files
authored
Fix varargs calls (#188)
* Fix calls to Varargs functions * Add check_varargs to internal docs * Replace check_varargs with which(sig).isva
1 parent 42036af commit baf1c50

File tree

2 files changed

+72
-4
lines changed

2 files changed

+72
-4
lines changed

src/copyable_task.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,13 @@ function build_callable(sig::Type{<:Tuple})
8484
return fresh_copy(mc_cache[key])
8585
else
8686
ir = Base.code_ircode_by_type(sig)[1][1]
87+
# Check whether this is a varargs call.
88+
isva = which(sig).isva
8789
bb, refs, types = derive_copyable_task_ir(BBCode(ir))
8890
unoptimised_ir = IRCode(bb)
8991
optimised_ir = optimise_ir!(unoptimised_ir)
9092
mc_ret_type = callable_ret_type(sig, types)
91-
mc = misty_closure(mc_ret_type, optimised_ir, refs...; do_compile=true)
93+
mc = misty_closure(mc_ret_type, optimised_ir, refs...; isva=isva, do_compile=true)
9294
mc_cache[key] = mc
9395
return mc, refs[end]
9496
end
@@ -315,7 +317,7 @@ end
315317
"""
316318
set_taped_globals!(t::TapedTask, new_taped_globals)::Nothing
317319
318-
Set the `taped_globals` of `t` to `new_taped_globals`. Any calls to
320+
Set the `taped_globals` of `t` to `new_taped_globals`. Any calls to
319321
[`get_taped_globals`](@ref) in future calls to `consume(t)` (either directly, or implicitly
320322
via iteration) will see this new value.
321323
"""
@@ -573,7 +575,7 @@ function derive_copyable_task_ir(ir::BBCode)::Tuple{BBCode,Tuple,Vector{Any}}
573575
# We enforced above the condition that the final statement in a basic block must not
574576
# produce. This ensures that the final split does not produce. While not strictly
575577
# necessary, this simplifies the implementation (see below).
576-
#
578+
#
577579
# As a result of the above, a basic block will be associated to exactly one split if it
578580
# does not contain any statements which may produce.
579581
#
@@ -595,7 +597,7 @@ function derive_copyable_task_ir(ir::BBCode)::Tuple{BBCode,Tuple,Vector{Any}}
595597
# Owing to splitting blocks up, we will need to re-label some `GotoNode`s and
596598
# `GotoIfNot`s. To understand this, consider the following block, whose original `ID`
597599
# we assume to be `ID(old_id)`.
598-
# ID(new_id) - %1 = φ(ID(3) => ...)
600+
# ID(new_id) - %1 = φ(ID(3) => ...)
599601
# ID(new_id) - %3 = call_which_must_not_produce(...)
600602
# ID(new_id) - %4 = produce(%3)
601603
# ID(old_id) - GotoNode(ID(5))

src/test_utils.jl

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,38 @@ function test_cases()
170170
[true, 1],
171171
none,
172172
),
173+
Testcase(
174+
"nested with args (static)",
175+
nothing,
176+
(static_nested_outer_args,),
177+
nothing,
178+
[:a, :b, false],
179+
none,
180+
),
181+
Testcase(
182+
"nested with args (static + used)",
183+
nothing,
184+
(static_nested_outer_use_produced_args,),
185+
nothing,
186+
[:a, :b, 1],
187+
none,
188+
),
189+
Testcase(
190+
"nested with args (dynamic)",
191+
nothing,
192+
(dynamic_nested_outer_args, Ref{Any}(nested_inner_args)),
193+
nothing,
194+
[:a, :b, false],
195+
none,
196+
),
197+
Testcase(
198+
"nested with args (dynamic + used)",
199+
nothing,
200+
(dynamic_nested_outer_use_produced_args, Ref{Any}(nested_inner_args)),
201+
nothing,
202+
[:a, :b, 1],
203+
none,
204+
),
173205
Testcase(
174206
"callable struct", nothing, (CallableStruct(5), 4), nothing, [5, 4, 9], allocs
175207
),
@@ -334,6 +366,40 @@ function dynamic_nested_outer_use_produced(f::Ref{Any})
334366
return nothing
335367
end
336368

369+
@noinline function nested_inner_args(xs...)
370+
for x in xs
371+
produce(x)
372+
end
373+
return 1
374+
end
375+
376+
Libtask.might_produce(::Type{<:Tuple{typeof(nested_inner_args),Any}}) = true
377+
Libtask.might_produce(::Type{<:Tuple{typeof(nested_inner_args),Any,Vararg}}) = true
378+
379+
function static_nested_outer_args()
380+
nested_inner_args(:a, :b)
381+
produce(false)
382+
return nothing
383+
end
384+
385+
function static_nested_outer_use_produced_args()
386+
y = nested_inner_args(:a, :b)
387+
produce(y)
388+
return nothing
389+
end
390+
391+
function dynamic_nested_outer_args(f::Ref{Any})
392+
f[](:a, :b)
393+
produce(false)
394+
return nothing
395+
end
396+
397+
function dynamic_nested_outer_use_produced_args(f::Ref{Any})
398+
y = f[](:a, :b)
399+
produce(y)
400+
return nothing
401+
end
402+
337403
struct CallableStruct{T}
338404
x::T
339405
end

0 commit comments

Comments
 (0)