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

mirgen: improve scope-only block support #928

Merged

Conversation

zerbina
Copy link
Collaborator

@zerbina zerbina commented Sep 27, 2023

Summary

Don't emit mnkBlock MIR nodes for nkBlockStmt/nkBlockExpr nodes
(block statements/expression) are not used for control-flow. This
reduces the size of the produced MIR code and means that neither
compiler-generated scope-only blocks nor block statements/
expression not targeted by break statements reach the code
generators.

Most notably, the code generated by the JavaScript code generator
improves, in terms of size.

Details

Detection of blocks-used-for-control-flow is done via testing for the
sfUsed flag: if present, the nkBlockStmt/nkBlockExpr is treated
as used for control-flow, otherwise it's treated as only opening a
scope. This is only a conservative approximation, however, and blocks
where the label is marked as used through other means (or by appearing
in a break within a compiles) will be mis-detected.

So that the detection also works for transf-injected breaks and
blocks, all nkBreakStmt AST in transf / closureiters /
lambdalifting
is now generated via the new newBreakStmt procedure in lowerings,
which marks the provided label as used.

When mirgen.genBlock gets passed an nkBlockExpr/nkBlockStmt node
where the label symbol is not marked as used, it only emits the
mnkScope block necessary for correct variable lifetimes. Since
cnkBlockStmt are only generated for mnkBlock nodes by cgirgen,
this means that the block statements are omitted in the final generated
code too.

Finally, transf.transformBlock is improved, and a necessary fix is
applied:

  • instead of introducing a new label with newLabel during inlining,
    the original symbol is copied and adjusted. This ensures that the
    symbol flags (e.g., whether the symbol is used) are kept
  • the label symbol is no longer pushed to the breakSyms stack in the
    inlining case. This was/is unnecessary, as inlined AST is already
    transformed, and so none of the nkBreakStmt nodes within are
    processed
  • the non-inlining case doesn't use transformSons, but transforms
    the body AST directly. While having no practical effect at the
    moment, this means that the label slot is no longer treated as a
    symbol-in-a-usage-position

No mnkBlock nodes being emitted for scope-only blocks is also visible
in the --expandArc output, so the tests depending on the output are
adjusted.

The new `newBreakStmt` procedure creates the AST for the statement, and
it marks the label symbol as used.
Instead, copy the existing one, preserving the original flags. This is
important for the upcoming `mnkBlock` generation improvements, as the
latter is going to rely on the `sfUsed` flag.

In addition, `transformBlock` is refactored.
Based on the presence of the label's `sfUsed` flag, don't emit an
`mnkBlock` tree when the `nkBlockStmt` is only used for scoping.
@zerbina zerbina added refactor Implementation refactor compiler/backend Related to backend system of the compiler labels Sep 27, 2023
@zerbina zerbina added this to the MIR phase milestone Sep 27, 2023
Copy link
Collaborator

@saem saem left a comment

Choose a reason for hiding this comment

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

i like the straightforward nature of using the used flag on the label-sym, and the conosolidated break construction cleans up a fair bit of code.

@saem
Copy link
Collaborator

saem commented Sep 27, 2023

/merge

@github-actions
Copy link

Merge requested by: @saem

Contents after the first section break of the PR description has been removed and preserved below:


Notes for Reviewers

@chore-runner chore-runner bot added this pull request to the merge queue Sep 27, 2023
Merged via the queue into nim-works:devel with commit 0bfdb11 Sep 27, 2023
18 checks passed
@zerbina zerbina deleted the better-scope-only-blocks-support branch September 29, 2023 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/backend Related to backend system of the compiler refactor Implementation refactor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants