Compilation 在IRTools dynamo中提取自己的IR

Compilation 在IRTools dynamo中提取自己的IR,compilation,julia,Compilation,Julia,我正在尝试编写一个dynamo,它将在内部使用调用它的方法的IR。作为一个简化示例,keep_ir(f,args…应返回(f(args…),ir(f,args…) 我尝试了以下方法: IRTools.@dynamo function keep_ir(f, args...) old_ir = IRTools.IR(f, args...) new_ir = IRTools.empty(old_ir) foreach(arg -> IRTools.argument!(ne

我正在尝试编写一个dynamo,它将在内部使用调用它的方法的IR。作为一个简化示例,
keep_ir(f,args…
应返回
(f(args…),ir(f,args…)

我尝试了以下方法:

IRTools.@dynamo function keep_ir(f, args...)
    old_ir = IRTools.IR(f, args...)
    new_ir = IRTools.empty(old_ir)
    foreach(arg -> IRTools.argument!(new_ir), IRTools.arguments(old_ir))
    foreach(((v, stmt),) -> push!(new_ir, stmt.expr), old_ir)

    arg_types = [IRTools.xcall(Core, :Typeof, arg) for arg in IRTools.arguments(old_ir)]
    original_ir = push!(new_ir, IRTools.xcall(IRTools, :IR,
                                              IRTools.xcall(IRTools, :meta,
                                                            IRTools.xcall(Core, :apply_type,
                                                                          :(Base.Tuple),
                                                                          arg_types...))))
    old_rv = IRTools.branches(IRTools.block(old_ir, 1))[end]
    new_rv = push!(new_ir, IRTools.xcall(:tuple, old_rv.args[1], original_ir))
    IRTools.return!(new_ir, new_rv)
    @show new_ir # for debugging
    return new_ir
end
但它失败了,出现了一个客观错误:

julia> ff(x, y) = 4x + y^2, x
ff (generic function with 1 method)

julia> keep_ir(ff, 1, 20)
new_ir = 1: (%1, %2, %3)
  %4 = 4 * %2
  %5 = Core.apply_type(Base.Val, 2)
  %6 = (%5)()
  %7 = Base.literal_pow(Main.:^, %3, %6)
  %8 = %4 + %7
  %9 = Core.tuple(%8, %2)
  %10 = Base.Tuple
  %11 = Core.Typeof(%1)
  %12 = Core.Typeof(%2)
  %13 = Core.Typeof(%3)
  %14 = Core.apply_type(%10, %11, %12, %13)
  %15 = IRTools.meta(%14)
  %16 = IRTools.IR(%15)
  %17 = Base.tuple(%9, %16)
  return %17

ERROR: error compiling keep_ir: unsupported or misplaced expression "." in function keep_ir
Stacktrace:
 [1] top-level scope at REPL[76]:1
caused by [exception 1]
unsupported or misplaced expression "." in function keep_ir
Stacktrace:
 [1] top-level scope at REPL[76]:1

它构造的IR在我看来很好,不过…

您不需要在运行时重新构造IR,只需在编译时将其作为值拼接:

using IRTools
using IRTools: @dynamo, IR, returnvalue, block, xcall, return!

@dynamo function keepir(args...)
  ir = IR(args...)
  ir2 = copy(ir)
  ret = push!(ir, xcall(:tuple, returnvalue(block(ir, 1)), ir2))
  return!(ir, ret)
  return ir
end

ff(x, y) = 4x + y^2, x

keepir(ff, 2, 3) # => ((17, 2), IR(...))

FWIW,您看到的错误可能来自您在IR中输入的表达式
:(Base.Tuple)
。如果您使用
GlobalRef(Base,:Tuple)
来代替它,它应该会起作用。

好吧,这是一个很明显的例子,我没有看到树而看到森林!但我总是犹豫是否将复杂的非
Expr
值放入将要编译的表达式中。。。真的没有什么可疑的吗?