-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Julep: Expr provenance when lowering #31162
Comments
I've wanted this for a long time, though ideally with lowering from |
That would be great too, but I'd guess that's a much harder change. If this were Julia code I'd guess this one would be pretty easy, just adding |
The place this is immediately noticeable is in the debugger(s) when stepping through calls to kwarg methods; it would be great to be able to detect that all the "preparatory" steps are associated with a single call. Unfortunately there is a certain amount of diversity here: julia> a = [4,2,3,1];
julia> m = @which sort(a)
sort(v::AbstractArray{T,1} where T) in Base.Sort at sort.jl:742
julia> Base.uncompressed_ast(m)
CodeInfo(
1 ─ %1 = (Core.NamedTuple)()
│ %2 = (Base.pairs)(%1)
│ %3 = (Base.Sort.:(#sort#8))(%2, #self#, v)
└── return %3
)
julia> m = first(methods(getfield(Base.Sort, Symbol("#sort#8"))))
#sort#8(kws, ::Any, v::AbstractArray{T,1} where T) in Base.Sort at sort.jl:742
julia> Base.uncompressed_ast(m)
CodeInfo(
1 ─ %1 = (Base.Sort.copymutable)(v)
│ %2 = (Base.NamedTuple)()
│ %3 = (Base.merge)(%2, kws)
│ %4 = (Base.isempty)(%3)
└── goto #3 if not %4
2 ─ %6 = (Base.Sort.sort!)(%1)
└── return %6
3 ─ %8 = (Core.kwfunc)(Base.Sort.sort!)
│ %9 = (%8)(%3, Base.Sort.sort!, %1)
└── return %9
)
julia> g(a) = sort(a; rev=true)
g (generic function with 1 method)
julia> Base.uncompressed_ast(first(methods(g)))
CodeInfo(
1 ─ %1 = (:rev,)
│ %2 = (Core.apply_type)(Core.NamedTuple, %1)
│ %3 = (Core.tuple)(true)
│ %4 = (%2)(%3)
│ %5 = (Core.kwfunc)(Main.sort)
│ %6 = (%5)(%4, Main.sort, a)
└── return %6
) That's diverse enough that I'm a bit fearful about making guesses. I think I can write a pattern-matcher (there's already a limited one) that will pick up most of these and yet not get confused with explicitly-written operations like julia> f() = (x=1,)
f (generic function with 1 method)
julia> Base.uncompressed_ast(first(methods(f)))
CodeInfo(
1 ─ %1 = (:x,)
│ %2 = (Core.apply_type)(Core.NamedTuple, %1)
│ %3 = (Core.tuple)(1)
│ %4 = (%2)(%3)
└── return %4
) but I worry it might be a little magical. Even if there's nothing stored for use by |
When lowering code we have line-number provenance, but I want expression-provenance too.
I'd love it if
resulted in something along the lines of
src
here doesn't contain any "new" expressions, just references to the nested contents ofex
, specifically the object you've recursed into at the moment you inserted the corresponding line inthunk
. It's essentially a log of "what I'm working on now."You can sometimes get this from the line number info, but as this example partially demonstrates it's fragile (not guaranteed to return complete expressions) and incomplete (might correspond to a block independent of expressions). Moreover, if there aren't any
LineNumberNodes
inex
, it's impossible. In contrast, the log approach seems quite robust.I'd implement this myself except for the fact that the key part of this work is in scheme, and I simply don't have time to develop the relevant mastery. I should therefore say I'm not particularly picky about the exact contents of each entry in
src
, this is just to convey the general idea.There are interesting questions about whether logs should have sub-logs for the lowered bodies of methods and other internal
:thunk
expressions. Rather than returningsrc
one could simply make this part ofCodeInfo
, and then the sub-logs would happen naturally. If one went that way, then there's question of whether this information should survive compression and later retrieval withuncompressed_ast
. (I'm guessing that's not on the table as I think it would substantially slow Julia's startup due to pointer relocation.) I'm fine with having this information being transient; getting it out just when lowering manually would be a big win.The text was updated successfully, but these errors were encountered: