|
93 | 93 | // RefAs with ExternInternalize and ExternExternalize are not considered casts |
94 | 94 | // when obtaining fallthroughs, and so are ignored. |
95 | 95 | // |
96 | | -// TODO: 1. Look past individual basic blocks? This may be worth considering |
97 | | -// given the pattern of a cast appearing in an if condition that is |
98 | | -// then used in an if arm, for example, where simple dominance shows |
99 | | -// the cast can be reused. |
100 | | -// TODO: 2. Look at LocalSet as well and not just Get. That would add some |
101 | | -// overlap with the other passes mentioned above (SimplifyLocals and |
102 | | -// RedundantSetElimination also track sets and can switch a get to use |
103 | | -// a better set's index when that refines the type). But once we do the |
104 | | -// first two TODOs above then we'd be adding some novel things here, |
105 | | -// as we could optimize "backwards" as well (TODO 1) and past basic |
106 | | -// blocks (TODO 2, though RedundantSetElimination does that as well). |
107 | | -// However, we should consider whether improving those other passes |
108 | | -// might make more sense (as it would help more than casts, if we could |
109 | | -// make them operate "backwards" and/or past basic blocks). |
110 | | -// |
| 96 | +// TODO: Look past individual basic blocks? This may be worth considering |
| 97 | +// given the pattern of a cast appearing in an if condition that is |
| 98 | +// then used in an if arm, for example, where simple dominance shows |
| 99 | +// the cast can be reused. |
111 | 100 |
|
112 | 101 | #include "ir/effects.h" |
113 | 102 | #include "ir/linear-execution.h" |
@@ -453,20 +442,30 @@ struct BestCastFinder : public LinearExecutionWalker<BestCastFinder> { |
453 | 442 | void visitRefCast(RefCast* curr) { handleRefinement(curr); } |
454 | 443 |
|
455 | 444 | void handleRefinement(Expression* curr) { |
456 | | - auto* fallthrough = Properties::getFallthrough(curr, options, *getModule()); |
| 445 | + auto* teeFallthrough = Properties::getFallthrough( |
| 446 | + curr, options, *getModule(), Properties::FallthroughBehavior::NoTeeBrIf); |
| 447 | + if (auto* tee = teeFallthrough->dynCast<LocalSet>()) { |
| 448 | + updateBestCast(curr, tee->index); |
| 449 | + } |
| 450 | + auto* fallthrough = |
| 451 | + Properties::getFallthrough(teeFallthrough, options, *getModule()); |
457 | 452 | if (auto* get = fallthrough->dynCast<LocalGet>()) { |
458 | | - auto*& bestCast = mostCastedGets[get->index]; |
459 | | - if (!bestCast) { |
460 | | - // This is the first. |
461 | | - bestCast = curr; |
462 | | - return; |
463 | | - } |
| 453 | + updateBestCast(curr, get->index); |
| 454 | + } |
| 455 | + } |
464 | 456 |
|
465 | | - // See if we are better than the current best. |
466 | | - if (curr->type != bestCast->type && |
467 | | - Type::isSubType(curr->type, bestCast->type)) { |
468 | | - bestCast = curr; |
469 | | - } |
| 457 | + void updateBestCast(Expression* curr, Index index) { |
| 458 | + auto*& bestCast = mostCastedGets[index]; |
| 459 | + if (!bestCast) { |
| 460 | + // This is the first. |
| 461 | + bestCast = curr; |
| 462 | + return; |
| 463 | + } |
| 464 | + |
| 465 | + // See if we are better than the current best. |
| 466 | + if (curr->type != bestCast->type && |
| 467 | + Type::isSubType(curr->type, bestCast->type)) { |
| 468 | + bestCast = curr; |
470 | 469 | } |
471 | 470 | } |
472 | 471 | }; |
|
0 commit comments