18
18
// Removes branches for which we go to where they go anyhow
19
19
//
20
20
21
+ #include " ir/branch-hints.h"
21
22
#include " ir/branch-utils.h"
22
23
#include " ir/cost.h"
23
24
#include " ir/drop.h"
@@ -396,6 +397,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
396
397
curr->condition , br->value , getPassOptions (), *getModule ())) {
397
398
if (!br->condition ) {
398
399
br->condition = curr->condition ;
400
+ BranchHints::copyTo (curr, br, getFunction ());
399
401
} else {
400
402
// In this case we can replace
401
403
// if (condition1) br_if (condition2)
@@ -427,6 +429,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
427
429
// That keeps the order of the two conditions as it was originally.
428
430
br->condition =
429
431
builder.makeSelect (br->condition , curr->condition , zero);
432
+ BranchHints::applyAndTo (curr, br, br, getFunction ());
430
433
}
431
434
br->finalize ();
432
435
replaceCurrent (Builder (*getModule ()).dropIfConcretelyTyped (br));
@@ -459,6 +462,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
459
462
Builder builder (*getModule ());
460
463
curr->condition = builder.makeSelect (
461
464
child->condition , curr->condition , builder.makeConst (int32_t (0 )));
465
+ BranchHints::applyAndTo (curr, child, curr, getFunction ());
462
466
curr->ifTrue = child->ifTrue ;
463
467
}
464
468
}
@@ -689,6 +693,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
689
693
brIf->condition = builder.makeUnary (EqZInt32, brIf->condition );
690
694
last->name = brIf->name ;
691
695
brIf->name = loop->name ;
696
+ BranchHints::flip (brIf, getFunction ());
692
697
return true ;
693
698
} else {
694
699
// there are elements in the middle,
@@ -709,6 +714,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
709
714
builder.makeIf (brIf->condition ,
710
715
builder.makeBreak (brIf->name ),
711
716
stealSlice (builder, block, i + 1 , list.size ()));
717
+ BranchHints::copyTo (brIf, list[i], getFunction ());
712
718
block->finalize ();
713
719
return true ;
714
720
}
@@ -1210,6 +1216,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
1210
1216
// we are an if-else where the ifTrue is a break without a
1211
1217
// condition, so we can do this
1212
1218
ifTrueBreak->condition = iff->condition ;
1219
+ BranchHints::copyTo (iff, ifTrueBreak, getFunction ());
1213
1220
ifTrueBreak->finalize ();
1214
1221
list[i] = Builder (*getModule ()).dropIfConcretelyTyped (ifTrueBreak);
1215
1222
ExpressionManipulator::spliceIntoBlock (curr, i + 1 , iff->ifFalse );
@@ -1224,6 +1231,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
1224
1231
*getModule ())) {
1225
1232
ifFalseBreak->condition =
1226
1233
Builder (*getModule ()).makeUnary (EqZInt32, iff->condition );
1234
+ BranchHints::copyFlippedTo (iff, ifFalseBreak, getFunction ());
1227
1235
ifFalseBreak->finalize ();
1228
1236
list[i] = Builder (*getModule ()).dropIfConcretelyTyped (ifFalseBreak);
1229
1237
ExpressionManipulator::spliceIntoBlock (curr, i + 1 , iff->ifTrue );
@@ -1256,7 +1264,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
1256
1264
Builder builder (*getModule ());
1257
1265
br1->condition =
1258
1266
builder.makeBinary (OrInt32, br1->condition , br2->condition );
1267
+ BranchHints::applyOrTo (br1, br2, br1, getFunction ());
1259
1268
ExpressionManipulator::nop (br2);
1269
+ BranchHints::clear (br2, getFunction ());
1260
1270
}
1261
1271
}
1262
1272
} else {
@@ -1396,9 +1406,12 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
1396
1406
// no other breaks to that name, so we can do this
1397
1407
if (!drop) {
1398
1408
assert (!br->value );
1399
- replaceCurrent (builder.makeIf (
1400
- builder.makeUnary (EqZInt32, br->condition ), curr));
1409
+ auto * iff = builder.makeIf (
1410
+ builder.makeUnary (EqZInt32, br->condition ), curr);
1411
+ replaceCurrent (iff);
1412
+ BranchHints::copyFlippedTo (br, iff, getFunction ());
1401
1413
ExpressionManipulator::nop (br);
1414
+ BranchHints::clear (br, getFunction ());
1402
1415
curr->finalize (curr->type );
1403
1416
} else {
1404
1417
// To use an if, the value must have no side effects, as in the
@@ -1409,8 +1422,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
1409
1422
if (EffectAnalyzer::canReorder (
1410
1423
passOptions, *getModule (), br->condition , br->value )) {
1411
1424
ExpressionManipulator::nop (list[0 ]);
1412
- replaceCurrent (
1413
- builder.makeIf (br->condition , br->value , curr));
1425
+ auto * iff = builder.makeIf (br->condition , br->value , curr);
1426
+ BranchHints::copyTo (br, iff, getFunction ());
1427
+ replaceCurrent (iff);
1414
1428
}
1415
1429
} else {
1416
1430
// The value has side effects, so it must always execute. We
@@ -1529,6 +1543,14 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
1529
1543
optimizeSetIf (getCurrentPointer ());
1530
1544
}
1531
1545
1546
+ // Flip an if's condition with an eqz, and flip its arms.
1547
+ void flip (If* iff) {
1548
+ std::swap (iff->ifTrue , iff->ifFalse );
1549
+ iff->condition =
1550
+ Builder (*getModule ()).makeUnary (EqZInt32, iff->condition );
1551
+ BranchHints::flip (iff, getFunction ());
1552
+ }
1553
+
1532
1554
void optimizeSetIf (Expression** currp) {
1533
1555
if (optimizeSetIfWithBrArm (currp)) {
1534
1556
return ;
@@ -1570,9 +1592,10 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
1570
1592
// Wonderful, do it!
1571
1593
Builder builder (*getModule ());
1572
1594
if (flipCondition) {
1573
- builder. flip (iff);
1595
+ flip (iff);
1574
1596
}
1575
1597
br->condition = iff->condition ;
1598
+ BranchHints::copyTo (iff, br, getFunction ());
1576
1599
br->finalize ();
1577
1600
set->value = two;
1578
1601
auto * block = builder.makeSequence (br, set);
@@ -1640,7 +1663,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
1640
1663
Builder builder (*getModule ());
1641
1664
LocalGet* get = iff->ifTrue ->dynCast <LocalGet>();
1642
1665
if (get && get->index == set->index ) {
1643
- builder. flip (iff);
1666
+ flip (iff);
1644
1667
} else {
1645
1668
get = iff->ifFalse ->dynCast <LocalGet>();
1646
1669
if (get && get->index != set->index ) {
@@ -1901,6 +1924,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
1901
1924
curr->type = Type::unreachable;
1902
1925
block->list .push_back (curr);
1903
1926
block->finalize ();
1927
+ BranchHints::clear (curr, getFunction ());
1904
1928
// The type changed, so refinalize.
1905
1929
refinalize = true ;
1906
1930
} else {
0 commit comments