-
Notifications
You must be signed in to change notification settings - Fork 267
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
Inline code for function calls in interpreter #5330
Conversation
Comments
Looking pretty good so far! Though less dramatic than I hoped. I'll be curious to see it with the same treatment applied to foreign function calls (not sure if you're planning separate PR for that), I'm guessing that will make the JSON decoding and other benchmarks that use a lot of foreign calls go faster. Note that trunk is going to be worse the more code you have loaded, since the But this isn't terribly realistic since (for instance) Unison Cloud nodes are kept running and are loading new code all the time. And most users aren't bouncing UCM willy nilly. |
78c569f
to
43544ad
Compare
43544ad
to
ebb4956
Compare
| Just n <- M.lookup exceptionRef rfTy, | ||
-- TODO: Should I special-case this raise ref and pass it down from the top rather than always looking it up? |
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.
cc @dolio What do you think about this particular case?
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.
I doubt special casing this will make much difference anywhere. This is essentially just the top level handler for exceptions, which will kill the interpreter with an error message when it's invoked.
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.
Nice progress, I'll let @dolio weigh in. I'm assuming you're going to do the analogous ForeignCall
optimization as a separate PR?
One note: I think releases should still build everything with -O2
though, including parser-typechecker. We aren't really sure how much it matters there, but we also don't have a good way of testing it, so I'm inclined to leave it alone.
If you want to switch up the release process to support building with different flags than the default then that's cool, but I don't think it does that currently. Or you could do this in a separate PR.
Reading through some of this, something occurred to me. Is there even a reason for us to number the term references at this point? I guess it's a little more economical to make numbers for the references and store the latter once for e.g. compiled data. But for actual code functionality, we just make up numbers for the references, then get rid of the numbers by making things circular, right? |
resolveCombs mayExisting combs = | ||
-- Fixed point lookup; | ||
-- We make sure not to force resolved Combs or we'll loop forever. | ||
let ~resolved = |
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.
This ~
doesn't actually do anything. let
is irrefutable by default unless perhaps the Strict
extension is enabled, which I wouldn't recommend, because what it actually does can be rather confusing.
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.
I can remove it if you like, I'm mostly using it as a sign-post since Haskell doesn't have explicit let-recs 😢
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.
Okay, I've read through this. I don't see any major issues. It looks about like what I was expecting.
I left a couple comments about minor things, but that's it.
And yes, I'll do the Foreign Funcs as a separate PR so we can track each performance change individually. |
Yeah I think you're right, though tbh it's probably more work to remove them than it's worth at this point, I don't think they're doing any harm 🤷🏼♂️ |
Yeah, I wouldn't try to remove the numbering I guess. Actually, the CI failures look suspicious. The mac one reports a stack overflow on the |
There's an infinite loop when testing equality on recursive functions; I'm guessing we're naively crawling through and checking equality on all contained sections; probably just need to lower back to combix's when checking equality. Don't worry, we won't merge until CI is passing 😄 Failure case:
|
Oh, right. Actually, you should just not derive For that matter, I guess the |
Haha, yeah I had the exact same ideas 😄 |
b9b4ff2
to
aca3e15
Compare
We've passed the nimbus test-suite now as well ✅ |
Overview
Previously we stored only references to the code we wanted to jump to in things like function calls/applications even though the code each reference referred to was known at the time we translate to MCode.
This change statically resolves each reference to the code it refers to at code generation time, avoiding lookups at runtime.
Implementation notes
comb
type such that we can build the computations usingCombIx
, then "tie the knot" and resolve toCombs
using a fixed point.Also downgrades parser-typechecker toReverted by Paul's request-O1
by Dan's suggestion, O2 is pretty intense (and slow) and can probably be sequestered off to just the runtime package now that it's split off to improve build times.Interesting/controversial decisions
Test coverage
Benchmarks:
@pchiusano/misc-benchmarks/chris:.suite
@mitchellwrosen/mbta/@mitchellwrosen/branch-for-chris:.runTheBenchmark
Loose ends
Nope.