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

feat(compiler)!: Selectively include functions in the global function table #1183

Merged
merged 3 commits into from
May 15, 2022

Conversation

ospencer
Copy link
Member

@ospencer ospencer commented Apr 8, 2022

This PR changes the module contract for first-class functions. Previously, modules put all functions in the global function table to allow any function to be called indirectly, just with a reference to the closure. Now, modules that want to be able to call a function indirectly are responsible for putting the function into the function table. This allows us to finally take advantage of tree shaking—Binaryen can completely drop unused functions 🎉

There are a couple more changes necessary to see the full effect, but with just this change, "hello world" programs are 10% smaller. Some early testing on those other changes has shown close to a 40% module size reduction.

Those other changes include some refactoring of how exports are handled, and completely avoiding closure allocation when it's not needed.

Draft because we need the fix from grain-lang/binaryen.ml#149, and after that there's one failing test due to WebAssembly/binaryen#4587.

@ospencer ospencer self-assigned this Apr 8, 2022
Base automatically changed from oscar/function-reexport to main April 21, 2022 21:46
@ospencer ospencer changed the base branch from main to phated/binaryen-107 May 11, 2022 19:25
Base automatically changed from phated/binaryen-107 to main May 12, 2022 16:47
@ospencer ospencer marked this pull request as ready for review May 12, 2022 16:53
Copy link
Member

@phated phated left a comment

Choose a reason for hiding this comment

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

This is awesome! A few questions but here's a preemptive approval!

compiler/src/codegen/compcore.re Show resolved Hide resolved
compiler/src/codegen/compcore.re Outdated Show resolved Hide resolved
compiler/src/middle_end/analyze_function_calls.re Outdated Show resolved Hide resolved
compiler/src/typed/translprim.re Outdated Show resolved Hide resolved
compiler/src/typed/env.re Show resolved Hide resolved
@phated phated requested a review from a team May 12, 2022 18:16
Copy link
Member

@marcusroberts marcusroberts left a comment

Choose a reason for hiding this comment

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

LGTM!

@@ -1303,6 +1351,55 @@ let transl_signature = (~functions, ~imports, signature) => {
)
};
}
| TSigType(tid, {type_kind: TDataVariant(cds)} as td, rs) => {
Copy link
Member

Choose a reason for hiding this comment

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

Just so I understand, can you clarify what this is doing? (In GitHub is fine)

Copy link
Member Author

Choose a reason for hiding this comment

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

Absolutely! It just exports the functions that were created for the types you defined in the module. It won't be necessary anymore when we're not creating functions to create variants.

Copy link
Member

@peblair peblair left a comment

Choose a reason for hiding this comment

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

Two minor requests for comments, but looks good otherwise!


let mark_ident_seen = id => {
switch (Ident_tbl.find_opt(direct_function_calls, id)) {
| Some(count) => Ident_tbl.replace(direct_function_calls, id, count + 1)
Copy link
Member

Choose a reason for hiding this comment

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

I think this +1/-1 logic could use a comment (since it's not immediately obvious what this table is tracking)

let has_indirect_call = id => {
switch (Ident_tbl.find_opt(direct_function_calls, id)) {
| Some(count) => count != 0
| None => true
Copy link
Member

Choose a reason for hiding this comment

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

Might warrant a comment why this defaults to true

@ospencer ospencer merged commit 67575f7 into main May 15, 2022
@ospencer ospencer deleted the oscar/func-table-refactor branch May 15, 2022 20:32
This was referenced May 15, 2022
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.

5 participants