compilation - 在 IRTools 发电机中提取自己的 IR
问题描述
我正在尝试编写一个IRTools发电机,它将在内部使用调用它的方法的 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,您看到的错误可能来自:(Base.Tuple)
您在 IR 中输入的表达式。如果您改用它应该可以工作GlobalRef(Base, :Tuple)
。
推荐阅读
- android - 为什么 ContentResolver 返回频道但为空 PreviewPrograms?
- powerquery - 独立电源查询工具
- rpm - 如何修复“第 28 行:CHOOSE:: command not found”
- python - 为什么我在下面的代码中收到 IndexError: list index out of range 错误?
- java - 无法访问模块“android.app.Activity”,它是“com.example.myapp”的超类
- laravel - Laravel Eloquent with() 关系 - 按 2 个不同的嵌套关系排序
- oracle - Oracle SQL - 来自/来自带有日期的表的日期
- python - 如何在 python 中使用 tweepy 访问带有不记名令牌的推文?
- python - Lambda 中的库存流日志连接
- spring-boot - Spring boot 和 Apache Kafka 通过 Docker compose 抛出 LEADER_NOT_AVAILABLE of topic 和 Send failed 错误