rbyd-rr: Fixed issue where red alts were just not being pruned
Not sure how I missed this earlier, but we aren't pruning unreachable/
unavoidable red alts.
There are two cases where we can use red alts to prune. Both cases
effectively collapse a 3-node into a 2-node, while converting isolated
black alts into altns effectively collase a 2-node into a 1-node:
.---> a rm me
| .-> b red prune .-> b <-- we weren't handling
-r-b-> c => ---b-> c this case correctly
.---> a .---> a
| .-> b rm me red prune |
-r-b-> c => -b---> c
.-> a rm me v------ altn
.-b-> b black flatten .-b-> b
| .-> c => | .-> c
-b-b-> d -b-b-> d
Humorously, we were handling the arguably more difficult case of pruning
a black alt following a red alt correctly. But we weren't handling the
case when a red alt itself needs to be pruned.
Fortunately this code is identical to pruning root alts (also arguably a
more tricky case!), so we can just extend the relevant if statement to
cover the case of an unreachable/unavoidable red alt.
And small code change means small code change:
code stack
before: 34288 2864
after: 34304 (+0.0%) 2864 (+0.0%)
This commit is contained in:
@@ -3048,20 +3048,22 @@ again:;
|
|||||||
lfs_swap32(&jump, &branch_);
|
lfs_swap32(&jump, &branch_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// collapse unreachable red alts
|
// prune unreachable red-black alts
|
||||||
if (lfsr_tag_isred(p_alts[0])) {
|
if (lfsr_tag_isred(p_alts[0])) {
|
||||||
alt = p_alts[0] & ~LFSR_TAG_R;
|
alt = p_alts[0] & ~LFSR_TAG_R;
|
||||||
weight = p_weights[0];
|
weight = p_weights[0];
|
||||||
jump = p_jumps[0];
|
jump = p_jumps[0];
|
||||||
lfsr_rbyd_p_pop(p_alts, p_weights, p_jumps);
|
lfsr_rbyd_p_pop(p_alts, p_weights, p_jumps);
|
||||||
|
|
||||||
// collapse unreachable root alts
|
// prune unreachable red alts
|
||||||
} else if (!p_alts[0] && !lfsr_d_isdiverged(d_state)) {
|
} else if (lfsr_tag_isred(alt)
|
||||||
|
// prune unreachable black alts if root
|
||||||
|
|| (!p_alts[0] && !lfsr_d_isdiverged(d_state))) {
|
||||||
branch = branch_;
|
branch = branch_;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// make unreachable non-root black alts alt-nevers, if we
|
// convert unreachable non-root black alts into alt-nevers,
|
||||||
// prune these it would break the coloring of our tree
|
// if we prune these it would break the coloring of our tree
|
||||||
} else {
|
} else {
|
||||||
alt = LFSR_TAG_ALT(LFSR_TAG_LE, LFSR_TAG_B, 0);
|
alt = LFSR_TAG_ALT(LFSR_TAG_LE, LFSR_TAG_B, 0);
|
||||||
weight = 0;
|
weight = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user