Skip to content

Unnecessary Core.Box in closure referring to itself #40990

Closed
@Keno

Description

@Keno

Consider:

julia> function foo()
           back(a::Int) = 1
           back(a::Float64) = back(Int(a))
           back
       end
foo (generic function with 1 method)

julia> @code_lowered foo()
CodeInfo(
1 ─      back@_2 = Core.Box()
│   %2 = %new(Main.:(var"#back#3"), back@_2)
│        Core.setfield!(back@_2, :contents, %2)
│   %4 = Core.isdefined(back@_2, :contents)
└──      goto #3 if not %4
2 ─      goto #4
3 ─      Core.NewvarNode(:(back@_5))
└──      back@_5
4 ┄ %9 = Core.getfield(back@_2, :contents)
└──      return %9
)

This pattern is fairly common in ChainRules.jl, causing a number of unnecessary boxes there. I guess this is consistent with our usual scoping rules in that functions don't generally introduce their own name as an identifier in their body, so this needs to be captured from the outer scope, but perhaps lowering could recognize this situation?

Metadata

Metadata

Assignees

No one assigned

    Labels

    compiler:loweringSyntax lowering (compiler front end, 2nd stage)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions