Bounds error in dynamo with dummy metadata
I know I shouldn't build IR from scratch, but I really wonder why the following happens:
julia> plus_dummy(x, y) = nothing
plus_dummy (generic function with 1 method)
julia> @dynamo function foo(X, Y)
ir = IR(typeof(plus_dummy), X, Y)
@show ir
@show _args = IRTools.arguments(ir)
s = push!(ir, xcall(:+, _args[end-1], _args[end]))
@show ir
return!(ir, s)
@show ir
return ir
end
julia> foo(1, 2)
ir = 1: (%1, %2, %3)
return :(Main.nothing)
_args = IRTools.arguments(ir) = Any[%1, %2, %3]
ir = 1: (%1, %2, %3)
%4 = %2 + %3
return :(Main.nothing)
ir = 1: (%1, %2, %3)
%4 = %2 + %3
return %4
ERROR: BoundsError: attempt to access (1, 2)
at index [3]
Stacktrace:
[1] foo(::Int64, ::Int64) at /home/philipp/.julia/packages/IRTools/Fl3dY/src/reflection/dynamo.jl:44
[2] top-level scope at REPL[7]:1
The lowered code gives a good idea:
julia> @code_lowered foo(1, 2)
CodeInfo(
1 ─ Base.getfield(args, 1)
│ %2 = Base.getfield(args, 2)
│ %3 = Base.getfield(args, 3)
│ %4 = %2 + %3
└── return %4
)
The IR for plus_dummy is expecting three arguments (itself, x and y) but the dynamo actually only takes two (X and Y). If you delete the self argument it works fine:
@dynamo function foo(X, Y)
ir = IR(typeof(plus_dummy), X, Y)
_args = IRTools.arguments(ir)
deletearg!(block(ir, 1), 1)
s = push!(ir, xcall(:+, _args[end-1], _args[end]))
return!(ir, s)
return ir
end
I know I shouldn't build IR from scratch
FWIW, I don't see any reason why we shouldn't support this well. I think I'd ideally write this as
@dynamo function foo(X, Y)
ir = IR()
args = argument!(ir)
x = push!(ir, xcall(:getindex, args, 1))
y = push!(ir, xcall(:getindex, args, 2))
return!(ir, xcall(:+, x, y))
end
The only thing we need is (1) a standardised calling convention for IR without metadata (here I'm assuming that all args are passed in a single args tuple) and (2) some machinery to convert such IR to a codeinfo (which would look a lot like what you've done here, just inside the @dynamo).