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
JIT: enable implicit tail calls from inlined code #9405
JIT: enable implicit tail calls from inlined code #9405
Conversation
@JosephTremoulet PTAL Jit-diff data (only diffs in corelib because R2R currently inhibits tail calls):
|
Tail call opts are not enabled in debug builds, so even w/o looking in the logs, the ARM64 failures are almost certainly unrelated. Looking at the logs shows some kind of scripting issue.
|
CLANG_FORMAT_COMMENT_ANCHOR; | ||
|
||
#if FEATURE_TAILCALL_OPT | ||
opts.compTailCallLoopOpt = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible/interesting (at some point in the future) to recognize tail calls back to an inlinee and make them loops?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it would be possible. We already track the ancestral inline context for each call site, so we can tell when a call site recursively invokes an inlinee. What we'd need in addition is the following:
- track the logical entry point for the inlinee in the inline context, so we know where to target the loop branch.
- disable direct sub for inlinees in tail position, since the arguments are now potentially starg.
With that I think we could generalize the loop tail call opt to handle inlined cases, and I think a tail call loop opt is potentially much more impactful then a tail call alone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more thing: we currently won't tail call if the root method is noinline, but that block doesn't make sense for these inlinee loop tail call opts, so we should track calls in tail position in addition to calls eligible to be made into tail calls.
Looks good. |
@JosephTremoulet I vaguely recall you had a way of getting fragile ngen codegen in jit-diffs. If not, we should potentially add that as an option. Or get SPMI online and ensure it has a proper mix of jit/ngen/r2r instances. @sivarv good point about desktop. Do you recall what the fix was for the app compat issue? |
No, I've just used jit-produced asm when I wanted to be extra sure I was looking at diffs matching benchmark execution. You may be remembering that I opened dotnet/jitutils#75, but I haven't implemented it. It should be trivial to implement if crossgen has a --fragile flag, but if it has one it seems to be hidden...
That would be great! |
Inlines of calls from implicit tail call sites should allow recognition of inlinee implicit tail call sites. The jit recognizes implicit tail call sites during importation, but the inlinee compiler instance did not have compTailCallOpt set and so never recognized these instances. Fix this and update the logic to detect the transitively implicit tail calls. Now that these sites are recognized, morph needs a fix to tunnel through repeated casts for tail calls, since each level of inlining might add a cast. All these casts should be identical. Note under R2R tail calls are not yet recognized (see ZapInfo::canTailCall). Closes #9349.
crossgen has a I would patch jit-dasm/jit-diff but I'm stuck on an older version.... |
@AndyAyersMS - desktop appcompat failure was due to a particular class of implicit tail calls (the ones with shared return). See FEATURE_TAILCALL_OPT_SHARED_RETURN in jit.h, it is defined as 1 for CoreCLR and 0 on desktop. |
Tried running desktop SPMI. Unfortunately it fails on exactly the methods we'd like to examine, since there are new calls to |
Desktop also running into asserts because for desktop Which means, they won't be recognized on desktop.... |
9af0cf8
to
3387edc
Compare
Updated (& rebased) to only kick in if we support shared returns. Verified no diff on desktop. |
Looks good. |
Inlines of calls from implicit tail call sites should allow recognition of inlinee implicit tail call sites. The jit recognizes implicit tail call sites during importation, but the inlinee compiler instance did not have compTailCallOpt set and so never recognized these instances. Fix this and update the logic to detect the transitively implicit tail calls. Now that these sites are recognized, morph needs a fix to tunnel through repeated casts for tail calls, since each level of inlining might add a cast. All these casts should be identical. Note under R2R tail calls are not yet recognized (see ZapInfo::canTailCall). Enable only under FEATURE_TAILCALL_OPT_SHARED_RETURN since the inline tail call sites are not likely to be in BBJ_RETURN blocks. Closes #9349.
Inlines of calls from implicit tail call sites should allow recognition of inlinee implicit tail call sites. The jit recognizes implicit tail call sites during importation, but the inlinee compiler instance did not have compTailCallOpt set and so never recognized these instances. Fix this and update the logic to detect the transitively implicit tail calls. Now that these sites are recognized, morph needs a fix to tunnel through repeated casts for tail calls, since each level of inlining might add a cast. All these casts should be identical. Note under R2R tail calls are not yet recognized (see ZapInfo::canTailCall). Enable only under FEATURE_TAILCALL_OPT_SHARED_RETURN since the inline tail call sites are not likely to be in BBJ_RETURN blocks. Closes #9349.
Inlines of calls from implicit tail call sites should allow recognition of inlinee implicit tail call sites. The jit recognizes implicit tail call sites during importation, but the inlinee compiler instance did not have compTailCallOpt set and so never recognized these instances. Fix this and update the logic to detect the transitively implicit tail calls. Now that these sites are recognized, morph needs a fix to tunnel through repeated casts for tail calls, since each level of inlining might add a cast. All these casts should be identical. Note under R2R tail calls are not yet recognized (see ZapInfo::canTailCall). Enable only under FEATURE_TAILCALL_OPT_SHARED_RETURN since the inline tail call sites are not likely to be in BBJ_RETURN blocks. Closes dotnet/coreclr#9349. Commit migrated from dotnet/coreclr@1a8cb67
Inlines of calls from implicit tail call sites should allow recognition
of inlinee implicit tail call sites.
The jit recognizes implicit tail call sites during importation,
but the inlinee compiler instance did not have compTailCallOpt set
and so never recognized these instances. Fix this and update the logic
to detect the transitively implicit tail calls.
Now that these sites are recognized, morph needs a fix to tunnel through
repeated casts for tail calls, since each level of inlining might add a
cast. All these casts should be identical.
Note under R2R tail calls are not yet recognized (see ZapInfo::canTailCall).
Closes #9349.