Skip to content

Refactor compiler method lookup interface#36743

Merged
Keno merged 1 commit intomasterfrom
kf/methodtableapi
Jul 22, 2020
Merged

Refactor compiler method lookup interface#36743
Keno merged 1 commit intomasterfrom
kf/methodtableapi

Conversation

@Keno
Copy link
Copy Markdown
Member

@Keno Keno commented Jul 20, 2020

The primary motivation here is to clean up the notion of
"looking up a method in the method table" into a single
object that can be passed around. At the moment, it's
all a bit murky, with fairly large state objects being
passed around everywhere and implicit accesses to the
global environment. In my AD use case, I need to be a
bit careful to make sure the various inference and
optimization steps are looking things up in the correct
tables/caches, so being very explicit about where things
need to be looked up is quite helpful.

In particular, I would like to clean up the optimizer, to
not require the big OptimizationState which is currently
a bit of a mix of things that go into IRCode and information
needed for method lookup/edge tracking. That isn't part of
this PR, but will build on top of it.

More generally, with a bunch of the recent compiler work,
I've been trying to define more crisp boundaries between
the various components of the system, giving them clearer
interfaces, and at least a little bit of documentation.
The compiler is a very powerful bit of technology, but I
think people having been avoiding it, because the code
looks a bit scary. I'm hoping some of these cleanups will
make it easier for people to understand what's going on.
Here in particular, I'm using findall(sig, table) as
the predicate for method lookup. The idea being that
people familiar with the findall(predicate, collection)
idiom from regular julia will have a good intuitive
understanding of what's happening (a collection is searched
for a predicate), an array of matches is returned, etc.
Of course, it's not a perfect fit, but I think these
kinds of mental aids can be helpful in making it easier
for people to read compiler code (similar to how #35831
used getindex as the verb for cache lookup). While
I was at it, I also cleaned up the use of out-parameters
which leaked through too much of the underlying C API
and replaced them by a proper struct of results.

@Keno Keno requested review from JeffBezanson, maleadt and vtjnash July 20, 2020 23:07
@Keno Keno force-pushed the kf/methodtableapi branch from b0c667e to 5841b3a Compare July 21, 2020 21:52
@Keno
Copy link
Copy Markdown
Member Author

Keno commented Jul 21, 2020

Realized jl_gf_invoke_lookup also needs the method table. It wasn't quite clear to me what the correct verb should be for that query, but I ended up settling on findsup. In particular the method it looks for is the least upper bound/supremum among the methods that covers the requested signature (under the subtype/specificity relation) and in particular also the supremum of the subset of methods returned by findall so it seemed fitting. findsup isn't (currently) a verb we have in our find/search API, but findmax wasn't quite accurate, since the method found need not be the maximal element returned by findall. I considered keeping it as which or invoke_lookup or something, but that just seems circular to me "how is invoke implemented? "well, it looks up the method to invoke" ". I think findsup is fairly explicit about what the query actually is, which I think would be helpful to people reading the compiler source and trying to understand how things work. @JeffBezanson I'd like your opinion on this naming, since you've probably thought about the right names for these kinds of things most.

@@ -7,8 +7,7 @@ to re-consult the method table. This info is illegal on any statement that is
not a call to a generic function.
"""
struct MethodMatchInfo
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe this type should be combined with MethodLookupResult?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'm not quite sure yet. There's some additional information about method matches I may want to keep in the near future, that I think could go here nicely. My preference would be to keep this as is for now and if it turns out that information would be better somewhere else, we can always refactor this, since it's all internal.

Copy link
Copy Markdown
Member

@JeffBezanson JeffBezanson left a comment

Choose a reason for hiding this comment

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

Ahh, abstraction! 😍 😄

The primary motivation here is to clean up the notion of
"looking up a method in the method table" into a single
object that can be passed around. At the moment, it's
all a bit murky, with fairly large state objects being
passed around everywhere and implicit accesses to the
global environment. In my AD use case, I need to be a
bit careful to make sure the various inference and
optimization steps are looking things up in the correct
tables/caches, so being very explicit about where things
need to be looked up is quite helpful.

In particular, I would like to clean up the optimizer, to
not require the big `OptimizationState` which is currently
a bit of a mix of things that go into IRCode and information
needed for method lookup/edge tracking. That isn't part of
this PR, but will build on top of it.

More generally, with a bunch of the recent compiler work,
I've been trying to define more crisp boundaries between
the various components of the system, giving them clearer
interfaces, and at least a little bit of documentation.
The compiler is a very powerful bit of technology, but I
think people having been avoiding it, because the code
looks a bit scary. I'm hoping some of these cleanups will
make it easier for people to understand what's going on.
Here in particular, I'm using `findall(sig, table)` as
the predicate for method lookup. The idea being that
people familiar with the `findall(predicate, collection)`
idiom from regular julia will have a good intuitive
understanding of what's happening (a collection is searched
for a predicate), an array of matches is returned, etc.
Of course, it's not a perfect fit, but I think these
kinds of mental aids can be helpful in making it easier
for people to read compiler code (similar to how #35831
used `getindex` as the verb for cache lookup). While
I was at it, I also cleaned up the use of out-parameters
which leaked through too much of the underlying C API
and replaced them by a proper struct of results.
@Keno Keno force-pushed the kf/methodtableapi branch from 5841b3a to 3423bde Compare July 21, 2020 22:25
@Keno Keno closed this Jul 22, 2020
@Keno Keno reopened this Jul 22, 2020
@Keno Keno merged commit 1e6e656 into master Jul 22, 2020
@Keno Keno deleted the kf/methodtableapi branch July 22, 2020 21:49
Keno added a commit that referenced this pull request Jul 23, 2020
This was accidentally lost in #36743 while I was shuffling
aroudn what these methods actually return. However, we also
didn't have a test to catch that, so this adds such a test as
well.
Keno added a commit that referenced this pull request Jul 23, 2020
This was accidentally lost in #36743 while I was shuffling
aroudn what these methods actually return. However, we also
didn't have a test to catch that, so this adds such a test as
well.
simeonschaub pushed a commit to simeonschaub/julia that referenced this pull request Aug 11, 2020
The primary motivation here is to clean up the notion of
"looking up a method in the method table" into a single
object that can be passed around. At the moment, it's
all a bit murky, with fairly large state objects being
passed around everywhere and implicit accesses to the
global environment. In my AD use case, I need to be a
bit careful to make sure the various inference and
optimization steps are looking things up in the correct
tables/caches, so being very explicit about where things
need to be looked up is quite helpful.

In particular, I would like to clean up the optimizer, to
not require the big `OptimizationState` which is currently
a bit of a mix of things that go into IRCode and information
needed for method lookup/edge tracking. That isn't part of
this PR, but will build on top of it.

More generally, with a bunch of the recent compiler work,
I've been trying to define more crisp boundaries between
the various components of the system, giving them clearer
interfaces, and at least a little bit of documentation.
The compiler is a very powerful bit of technology, but I
think people having been avoiding it, because the code
looks a bit scary. I'm hoping some of these cleanups will
make it easier for people to understand what's going on.
Here in particular, I'm using `findall(sig, table)` as
the predicate for method lookup. The idea being that
people familiar with the `findall(predicate, collection)`
idiom from regular julia will have a good intuitive
understanding of what's happening (a collection is searched
for a predicate), an array of matches is returned, etc.
Of course, it's not a perfect fit, but I think these
kinds of mental aids can be helpful in making it easier
for people to read compiler code (similar to how JuliaLang#35831
used `getindex` as the verb for cache lookup). While
I was at it, I also cleaned up the use of out-parameters
which leaked through too much of the underlying C API
and replaced them by a proper struct of results.
simeonschaub pushed a commit to simeonschaub/julia that referenced this pull request Aug 11, 2020
This was accidentally lost in JuliaLang#36743 while I was shuffling
aroudn what these methods actually return. However, we also
didn't have a test to catch that, so this adds such a test as
well.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants