Runtime: ReadyToRun: Tailcalls not supported

Created on 14 May 2016  路  17Comments  路  Source: dotnet/runtime

Compiling F# code with crossgen I see:

Not implemented (Exception from HRESULT: 0x80004001 (E_NOTIMPL)) while compiling method [email protected]
ReadyToRun: Explicit tailcalls not supported

We should ensure that .tail is supported.

Kevin

theme:tail-call

area-ReadyToRun-coreclr enhancement tenet-performance

Most helpful comment

@jkotas Thanks for the details. I have to agree that it's really, really critical for F# on .NET Core to get this sorted out - both "crossgen" and tailcalls on Unix.

Among other things, many parts of the F# compiler toolchain itself depend on indirect tailcalls being taken, especially when processing large inputs.

All 17 comments

So I'm wondering why this is this not supported? NGEN has always supported tailcalls (at least in recent years). And there have always been many tests to ensure CLR support for tailcalls didn't regress :/

Do we have any info on the ramifications of this, or what's needed to support it?

Thanks

The fundamental problem with slow tailcalls is that we need more sane way to implement them.

  • For R2R on Windows, it is needed to have a reasonable ABI that we can maintain version resiliency for. (We will fallback to JIT for them.)
  • For Unix (https://github.com/dotnet/coreclr/issues/2556), it is needed to avoid writing 1000+ lines of dynamically emitted assembly code that will be a giant bug farm. (They will be turned into regular calls on Unix.)

cc @janvorli since he is going to look into this.

We may be able to enable the fast tailcalls for R2R, but it requires teaching delay load fixups about them (the delay load fixups are not able to reliably find the indirection cell used by the tailcall - tried it in dotnet/coreclr#4984).

@jkotas Thanks for the details. I have to agree that it's really, really critical for F# on .NET Core to get this sorted out - both "crossgen" and tailcalls on Unix.

Among other things, many parts of the F# compiler toolchain itself depend on indirect tailcalls being taken, especially when processing large inputs.

We may be able to enable the fast tailcalls for R2R, but it requires teaching delay load fixups about them

We should look into fixing this for .NET 5. It is becoming more of a problem.

Is tailcalling fcalls any easier than regular methods? Or it is largely the same problem?

It is same problem.

@mangod9 I think this is too risky for .NET 5. We should fix put it on the feature schedule for .NET 6.

yup will move.

@cartermp Just checking, how signficant a hit is this, e.g. for F# compiler startup etc.?

@dsyme I expect its fairly significant, but I don't think we would have time to ensure the right quality of fix before we fork for .NET 5.0. I hope that we can address some of these somewhat niche, and fairly small feature items early in the .NET 6 timeframe so that we can rely on the longer release process to validate the work. OTOH, if @cartermp can provide evidence that this is crucial for the release, we can address the problem.

@KevinRansom @cartermp Does this regress anything in the F# experience of .NET overall or is it status quo?

Just checking we're not about to encounter 6sec compiler startups except where we're already encountering them (we obviously haven't previously encountered these when using NGEN, and I _think_ .NET Core compiler only gets hit on first use?)

Nothing has regressed, however, thanks to the tailcall work, done over the last year. We have a chance at getting this fixed eventually. I agree with David a feature over the next release to wire up the tailcall work to ready to run would be outstanding.

Are you sure there won't be a difference between the compiler startup time for .NET 5 with ready to run and .NET 4.8 with NGEN? Because .NET 5 won't have NGEN, correct?

Yes, I think nothing has regressed compared to how it has always been for F# and .NET Core. So getting this into a good place would be great, but feels like a .NET 6 kind of thing (or at least some release after 5 is out).

Since F# is already crossgen'd I don't think we're in a decent place.

@SirBogman , F# on the coreclr will perform as it always has, on the desktop there will still be a net48 build. F# on the sdk is crossgened, which obviously builds on ready to run. So there is a small startup cost while the coreclr compiles the dynamic il generated to support the tailcall code, however, we have been paying that cost for the last 5 years, so it's bearable.

I hope this clears things up

Kevin

Thanks all for confirming

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jkotas picture jkotas  路  3Comments

nalywa picture nalywa  路  3Comments

bencz picture bencz  路  3Comments

iCodeWebApps picture iCodeWebApps  路  3Comments

chunseoklee picture chunseoklee  路  3Comments