Skip to content

Conversation

vouillon
Copy link
Contributor

Converts the following:

 (some.operation (ref.cast .. (local.tee $ref ..)) (local.get $ref) )

into:

 (some.operation (local.tee $temp (ref.cast .. (local.tee $ref ..)) ) (local.get $temp) )

This removes close to 10% of the casts in a test program (from 38113 casts down to 36119).

I also tried to improve the optimization that moves more refined casts earlier, but this does not seem very effective (it only eliminated 9 further casts), so I'm not sure it is worth it.

Converts the following: (some.operation (ref.cast .. (local.tee $ref ..)) (local.get $ref) ) into: (some.operation (local.tee $temp (ref.cast .. (local.tee $ref ..)) ) (local.get $temp) ) This removes close to 10% of the casts in a test program (from 38113 casts down to 36119). I also tried to improve the optimization that moves more refined casts earlier, but this does not seem very effective (it only eliminated 9 further casts), so I'm not sure it is worth it.
Copy link
Member

@kripken kripken left a comment

Choose a reason for hiding this comment

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

Good idea!

// blocks (TODO 2, though RedundantSetElimination does that as well).
// However, we should consider whether improving those other passes
// might make more sense (as it would help more than casts, if we could
// make them operate "backwards" and/or past basic blocks).
Copy link
Member

Choose a reason for hiding this comment

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

The first TODO is still relevant, isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, it is indeed only partially done (with connectAdjacentBlocks set to true).

void handleRefinement(Expression* curr) {
auto* teeFallthrough = Properties::getFallthrough(
curr, options, *getModule(), Properties::FallthroughBehavior::NoTeeBrIf);
if (auto* set = teeFallthrough->dynCast<LocalSet>()) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (auto* set = teeFallthrough->dynCast<LocalSet>()) {
if (auto* tee = teeFallthrough->dynCast<LocalSet>()) {

Also the isTee check below is not needed, as a fallthrough LocalSet must be a tee (because only a tee flows out a value that can fall through to some place).

return;
}
updateBestCast(curr, get->index);
return;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return;
updateBestCast(curr, set->index);
}
}
auto* fallthrough = Properties::getFallthrough(curr, options, *getModule());
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
auto* fallthrough = Properties::getFallthrough(curr, options, *getModule());
auto* fallthrough = Properties::getFallthrough(teeFallthrough, options, *getModule());

This saves a little work: we looked a little the first time, and the second time we don't need to re-do that work, and just continue from there.

@kripken kripken merged commit 3fd5c4f into WebAssembly:main Apr 18, 2024
@kripken
Copy link
Member

kripken commented Apr 18, 2024

I tested this on a large Java program and it removed 3.2% of casts. Nice work @vouillon !

@vouillon vouillon deleted the optimize-casts branch April 18, 2024 19:41
@gkdn gkdn mentioned this pull request Aug 31, 2024
jonludlam pushed a commit to jonludlam/js_of_ocaml that referenced this pull request May 15, 2025
This reverts commit 25315fb4d3231ecd0fdc07c57adec59f3e697dc3. No longer useful with WebAssembly/binaryen#6507
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants