rbyd-rr: Minor tweaks, adopted diverging check for diverged triming
Previously we used the direction of post-diverged alts to decide if they
need to be trimmed or not:
lfsr_d_isdiverged(d_state)
&& lfsr_d_isupper(d_state)
^ lfsr_tag_isgt(alt)
^ lfsr_tag_follow2(
alt, weight,
p[0].alt, p[0].weight,
lower_rid, upper_rid,
a_rid, a_tag)
But this working is a bit accidental. The real condition that needs to
be met for trimming is if our bounds continue to diverge on the alt:
lfsr_d_isdiverged(d_state)
&& lfsr_tag_follow2(
alt, weight,
p[0].alt, p[0].weight,
lower_rid, upper_rid,
a_rid, a_tag)
^ lfsr_tag_follow2(
alt, weight,
p[0].alt, p[0].weight,
lower_rid, upper_rid,
b_rid, b_tag)
This may seem more complicated, and does add code, but I'm hopeful it
can eventually lead to better code deduplication with the preceding
not-diverged -> diverged checks:
code stack
before: 34468 2864
after: 34492 (+0.1%) 2864 (+0.0%)
code frame stack
appendattr before: 2390 216 568
appendattr after: 2414 (+1.0%) 216 (+0.0%) 568 (+0.0%)
I've also been trying to simplify/deduplicate the diverging logic more,
but it's proven difficult. There's an annoying catch-22 where 1. we need
to trim diverging alts before applying color transformations, but 2. we
need to resolve yellow splits before triming diverging alts.
This commit is contained in:
@@ -2888,14 +2888,12 @@ trunk:;
|
|||||||
goto leaf;
|
goto leaf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// keep track of the tag we find at the end of the trunk
|
|
||||||
lfsr_tag_t tag_ = 0;
|
|
||||||
|
|
||||||
// queue of pending alts we can emulate rotations with
|
// queue of pending alts we can emulate rotations with
|
||||||
lfsr_alt_t p[3] = {{0}, {0}, {0}};
|
lfsr_alt_t p[3] = {{0}, {0}, {0}};
|
||||||
|
|
||||||
// keep track of the last incoming branch for yellow splits
|
// keep track of the last incoming branch for yellow splits
|
||||||
lfs_size_t y_branch = 0;
|
lfs_size_t y_branch = 0;
|
||||||
|
// keep track of the tag we find at the end of the trunk
|
||||||
|
lfsr_tag_t tag_ = 0;
|
||||||
|
|
||||||
// descend down tree, building alt pointers
|
// descend down tree, building alt pointers
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -2949,16 +2947,16 @@ trunk:;
|
|||||||
b_rid, b_tag)))) {
|
b_rid, b_tag)))) {
|
||||||
d_state = lfsr_d_diverge(d_state);
|
d_state = lfsr_d_diverge(d_state);
|
||||||
|
|
||||||
// diverged red? flip
|
// diverging red? flip
|
||||||
if (lfsr_tag_isred(p[0].alt)
|
if (lfsr_tag_isred(p[0].alt)
|
||||||
&& (lfsr_tag_follow(
|
&& lfsr_tag_follow(
|
||||||
p[0].alt, p[0].weight,
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
a_rid, a_tag)
|
a_rid, a_tag)
|
||||||
^ lfsr_tag_follow(
|
^ lfsr_tag_follow(
|
||||||
p[0].alt, p[0].weight,
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
b_rid, b_tag))) {
|
b_rid, b_tag)) {
|
||||||
if (lfsr_tag_isparallel(alt, p[0].alt)) {
|
if (lfsr_tag_isparallel(alt, p[0].alt)) {
|
||||||
lfsr_tag_flip2(&alt, &weight,
|
lfsr_tag_flip2(&alt, &weight,
|
||||||
p[0].alt, p[0].weight,
|
p[0].alt, p[0].weight,
|
||||||
@@ -2993,9 +2991,8 @@ trunk:;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// diverged upper? stitch together both trunks
|
// diverging upper? stitch together both trunks
|
||||||
if (lfsr_d_isupper(d_state)) {
|
if (lfsr_d_isupper(d_state)) {
|
||||||
// flip
|
|
||||||
if (lfsr_tag_isgt(alt)) {
|
if (lfsr_tag_isgt(alt)) {
|
||||||
lfsr_tag_flip2(
|
lfsr_tag_flip2(
|
||||||
&alt, &weight,
|
&alt, &weight,
|
||||||
@@ -3003,8 +3000,6 @@ trunk:;
|
|||||||
lower_rid, upper_rid);
|
lower_rid, upper_rid);
|
||||||
lfs_swap32(&jump, &branch_);
|
lfs_swap32(&jump, &branch_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// trim
|
|
||||||
lfsr_tag_trim2(
|
lfsr_tag_trim2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
p[0].alt, p[0].weight,
|
p[0].alt, p[0].weight,
|
||||||
@@ -3025,15 +3020,18 @@ trunk:;
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// trim unreachable diverged alts so they end up pruned
|
// force diverged alts to be pruned
|
||||||
} else if (lfsr_d_isdiverged(d_state)
|
} else if (lfsr_d_isdiverged(d_state)
|
||||||
&& (lfsr_d_isupper(d_state)
|
&& lfsr_tag_follow2(
|
||||||
^ lfsr_tag_isgt(alt)
|
alt, weight,
|
||||||
|
p[0].alt, p[0].weight,
|
||||||
|
lower_rid, upper_rid,
|
||||||
|
a_rid, a_tag)
|
||||||
^ lfsr_tag_follow2(
|
^ lfsr_tag_follow2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
p[0].alt, p[0].weight,
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
a_rid, a_tag))) {
|
b_rid, b_tag)) {
|
||||||
if (lfsr_tag_follow2(
|
if (lfsr_tag_follow2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
p[0].alt, p[0].weight,
|
p[0].alt, p[0].weight,
|
||||||
|
|||||||
Reference in New Issue
Block a user