Skip to content
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

use specialized code when compiling opaque closure expressions #43320

Merged
merged 1 commit into from
Feb 11, 2022

Conversation

JeffBezanson
Copy link
Sponsor Member

Before, we compiled the unoptimized IR of the function on this code path; with this we instead use the optimized version that we probably created when optimizing the enclosing function.

before:

julia> using Base.Experimental: @opaque

julia> ff() = @opaque (n::Int)->(s=0; for i = 1:n; s+= i; end; s)
ff (generic function with 1 method)

julia> g = ff();

julia> @time g(1000000)
  0.097487 seconds (4.00 M allocations: 76.278 MiB, 12.50% gc time)

after:

julia> @time g(1000000)
  0.000004 seconds (1 allocation: 16 bytes)

This also normalizes the code a bit by using jl_specializations_get_linfo instead of manually allocating a MethodInstance.

The next step is to invoke the optimizer and compiler from jl_new_opaque_closure so we can do this at run time as well. After that, it would also be nice to avoid recursive codegen (calling emit_function), and make this work more like other call sites.

@JeffBezanson JeffBezanson added the compiler:codegen Generation of LLVM IR and native code label Dec 3, 2021
src/codegen.cpp Outdated Show resolved Hide resolved
@JeffBezanson
Copy link
Sponsor Member Author

Updated to restore the specptr field, and also added run-time specialization support. Not 100% sure I got the calling convention stuff right.

jl_svecset(sig_args, 1+i, jl_tparam(argt, i));
}
sigtype = (jl_value_t*)jl_apply_tuple_type_v(jl_svec_data(sig_args), nsig);
jl_method_instance_t *mi = jl_specializations_get_linfo((jl_method_t*)source, sigtype, jl_emptysvec);
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Keno may need to review and comment. I thought this function returns the same method-instance each time for a given sigtype, but that the ability to optimize an OC is depending on each copy of the OC potentially having different code depending on where it was initially allocated.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, we don't currently have the code to that in the optimizer thought. I figured we would do that by allocating a non-cached MethodInstance in the optimizer and putting that in there with the appropriate typed IR. I think that would make this OK, because this specialization cache is then the version that doesn't have any capture optimization done to it.

@JeffBezanson
Copy link
Sponsor Member Author

Fixed the const_return case, plus put in a very temporary hack to make varargs work again. I'm working on a more thorough refactoring that will allow us to use only the isva flag on the Method, which will make OpaqueClosure much easier to work with internally.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Dec 4, 2021

We have existing front end support for syntactic varargs with variable-derived bounds, but I think Keno had a reason for choosing to do it this way instead?

@JeffBezanson
Copy link
Sponsor Member Author

We discussed it --- whether the signature is vararg needs to be determined at runtime, but whether the method code is vararg (i.e. automatically turns its last argument into a tuple) can be static.

invoke specialization when an OC is created at run time
@JeffBezanson JeffBezanson merged commit 5cb0f14 into master Feb 11, 2022
@JeffBezanson JeffBezanson deleted the jb/ocspecialized branch February 11, 2022 16:47
@DilumAluthge
Copy link
Member

DilumAluthge commented Feb 12, 2022

Looks like this PR broke analyzegc. Example log: https://buildkite.com/julialang/julia-master/builds/8670#01c69ec1-5528-44f7-99d5-4136a73d5d3d

/cache/build/default-amdci4-4/julialang/julia-master/src/interpreter.c:728:5: error: Passing non-rooted value as argument to function that may GC [julia.GCChecker]

@DilumAluthge
Copy link
Member

@Keno See the analyzegc failure above.

@DilumAluthge
Copy link
Member

Just so we don't forget, I went ahead and opened #44147.

vtjnash added a commit that referenced this pull request Feb 12, 2022
vtjnash added a commit that referenced this pull request Feb 12, 2022
#43320)" (#44149)

This reverts commit 5cb0f14 due to failing on CI (analyzegc).
ericphanson added a commit to ericphanson/julia that referenced this pull request Feb 13, 2022
@JeffBezanson JeffBezanson restored the jb/ocspecialized branch February 14, 2022 20:44
antoine-levitt pushed a commit to antoine-levitt/julia that referenced this pull request Feb 17, 2022
…Lang#43320)

invoke specialization when an OC is created at run time
antoine-levitt pushed a commit to antoine-levitt/julia that referenced this pull request Feb 17, 2022
LilithHafner pushed a commit to LilithHafner/julia that referenced this pull request Feb 22, 2022
…Lang#43320)

invoke specialization when an OC is created at run time
LilithHafner pushed a commit to LilithHafner/julia that referenced this pull request Feb 22, 2022
LilithHafner pushed a commit to LilithHafner/julia that referenced this pull request Mar 8, 2022
…Lang#43320)

invoke specialization when an OC is created at run time
LilithHafner pushed a commit to LilithHafner/julia that referenced this pull request Mar 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:codegen Generation of LLVM IR and native code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants