-
-
Notifications
You must be signed in to change notification settings - Fork 672
Rework loop statement compilation / general cleanup #1046
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
Conversation
local.get $0 | ||
i32.const 0 | ||
local.get $1 | ||
i32.const 5 | ||
i32.eq | ||
select | ||
br_if $continue|0 | ||
br_if $for-continue|0 |
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 one is interesting in that it exits the block anyway. Wondering if Binaryen could somehow optimize all of this away.
Regarding the comment
another potential solution could be to recompile the body iff incompatible local states are detected, using the least common denominator. As long as all of this is encapsulated in its own flow (which we can throw away) that should be possible I guess, if only as a temporary solution. Needs some sort of diagnostics deduplication then. |
From a quick check there are just a few occasions in the code where this is relevant. To give an example, in var value: bool; // wrapped false
for (let i = 0; i < lastIndex; ++i) {
// whatever goes here assumes `value` is properly wrapped
value = load<bool>(dataStart + i); // potentially not wrapped
} In this case we only load 0 or 1, so it doesn't matter, but it illustrates what can go wrong. |
Gave the recompile approach a try in the last commit, but found problems with local null states in the process. Appears that |
This has turned into a largish flow and loop overhaul meanwhile. In particular I'm in the process of refactoring stuff to be less smart and more correct. Will have to see how that turns out. |
Last commit contains the progress I have so far, incl.
Still not perfect but it's just so easy to miss something when trying to take all the possible outcomes into account, especially where branch level tree-shaking kicks in and the goal is to use as few flows as possible. Overall direction remains to be less smart but correct, even if that means that untouched output doesn't look as good as before. |
end | ||
br $while-continue|0 | ||
end | ||
end |
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.
Strange one
i32.const 24 | ||
i32.shl | ||
i32.const 24 | ||
i32.shr_s |
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 is a for (let k: i8 = 0; k < 100; ++k)
loop detecting that incrementing an i8 can yield an unwrapped value, hence recompiling with unified wrap states (wrapped before, not wrapped after -> not wrapped) since unaware of the k < 100
limit. As such expected, but also an optimization opportunity.
In my initial testing I also noticed that the code example in #1038 leaked memory, but just now got around to look into that. Turned out that array literals were missing an autorelease, only affecting array literals not immediately assigned to a target, happening on const newFaces = this.buildFaces( nextVertex, /* missing = */ [ nextFace.edge!, nextFace.edge!.next! ]
);
// __release(missing) but not on const notMissing = [ nextFace.edge!, nextFace.edge!.next! ];
const newFaces = this.buildFaces( nextVertex, notMissing);
// __release(notMissing) |
There's just so much stuff that could need some modernization :) |
This is becoming somewhat unweildy, hence suggesting to merge and continue from there. Maybe some sort of general modernization PR. |
non-functional anyway, but can be easily revived from git history if ever becoming a thing
This is an attempt to tackle #1038 which yet again uncovered problems in how we compile
for
statements. It's still bad but we are missing the necessary infrastructure like a checker. See comments. Perfectly possible that it'll explode still - that flow stuff simply doesn't fit into my head all at once and I guess we'll need something better eventually.