rbyd: Refined jump > branch pruning hack

Now that we have this jump > branch trick in our back pocket, we can
undo most of the y-pruning/diverged-pruning separation.

In theory all we need is to conditionally recolor based on if jump is >
branch.

---

Well, in theory at least. This seems to increase the number of test
failures, but it's unclear if this is due to jump > branch being an
incorrect assumption or some other bug exposed by the change in logic:

  test_rbyd+balance before:  300/385878 failed
  test_rbyd+balance after:  1671/385878 failed (+457.0%)

But it does save code:

           code          stack          ctx
  before: 38880           2624          640
  after:  38584 (-0.8%)   2624 (+0.0%)  640 (+0.0%)
This commit is contained in:
Christopher Haster
2025-01-26 14:35:48 -06:00
parent c89c846329
commit 8e919df1b8
+132 -150
View File
@@ -3624,54 +3624,6 @@ trunk:;
LFS_SWAP(lfs_size_t, &jump, &branch_); LFS_SWAP(lfs_size_t, &jump, &branch_);
} }
// TODO redoc?
// prune?
if (lfsr_tag_isred(p[0].alt)) {
// prune unreachable red alts
// <b >b
// .-'| .-'|
// <y | | |
// .-------'| | | |
// | <r | => | >b
// | .----' | .--------|-'|
// | | <b | <b |
// | | .----'| | .----'| |
// 1 2 3 4 4 1 2 3 4 4 1
if (lfsr_tag_unreachable(
p[0].alt, p[0].weight,
lower_rid, upper_rid,
lower_tag, upper_tag)
&& p[0].jump >= branch_) {
LFS_DEBUG("%04x->%04x: yprune",
branch, lfsr_rbyd_eoff(rbyd));
alt &= ~LFSR_TAG_R;
lfsr_rbyd_p_pop(p);
// prune other unreachable alts
// <b >b
// .-'| .-'|
// <y | | <b
// .-------'| | .-----------|-'|
// | <r | => | | |
// | .----' | | | |
// | | <b | <b |
// | | .----'| | .----'| |
// 1 2 3 4 4 1 2 3 4 4 2
} else if (lfsr_tag_unreachable2(
alt, weight,
p[0].alt, p[0].weight,
lower_rid, upper_rid,
lower_tag, upper_tag)
&& jump >= branch_) {
LFS_DEBUG("%04x->%04x: rprune",
branch, lfsr_rbyd_eoff(rbyd));
alt = p[0].alt & ~LFSR_TAG_R;
weight = p[0].weight;
jump = p[0].jump;
lfsr_rbyd_p_pop(p);
}
}
// TODO need this? does this ever get triggered? // TODO need this? does this ever get triggered?
// both diverging? collapse // both diverging? collapse
// <r >b // <r >b
@@ -3865,41 +3817,40 @@ trunk:;
// branch = branch_; // branch = branch_;
// continue; // continue;
goto maybetrim; // goto maybetrim;
} }
// diverged? // diverged?
// : :
// <b => nb // <b => nb
// .-'| .--' // .-'| .--'
// 3 4 3 4 x // 3 4 3 4 x
} else if (diverged) { } else if (diverged) {
diverging = lfsr_tag_diverging2( // diverging = lfsr_tag_diverging2(
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, // a_rid, a_tag,
b_rid, b_tag); // b_rid, b_tag);
diverging_red = lfsr_tag_isred(p[0].alt) // diverging_red = lfsr_tag_isred(p[0].alt)
&& lfsr_tag_diverging( // && lfsr_tag_diverging(
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,
b_rid, b_tag); // b_rid, b_tag);
// TODO I think this logic is wrong, what's correct here? // // TODO I think this logic is wrong, what's correct here?
if (diverging_red) { // if (diverging_red) {
LFS_DEBUG("%04x->%04x: div r trimming", // LFS_DEBUG("%04x->%04x: div r trimming",
branch, lfsr_rbyd_eoff(rbyd)); // branch, lfsr_rbyd_eoff(rbyd));
// trim so alt is pruned // // trim so alt is pruned
lfsr_tag_trim( // lfsr_tag_trim(
p[0].alt, p[0].weight, // p[0].alt, p[0].weight,
&lower_rid, &upper_rid, // &lower_rid, &upper_rid,
&lower_tag, &upper_tag); // &lower_tag, &upper_tag);
p[0].weight = 0; // p[0].weight = 0;
//
lfsr_rbyd_p_pop(p); // lfsr_rbyd_p_pop(p);
//
// TODO prune? (trim?) // // TODO prune? (trim?)
} // }
diverging = lfsr_tag_diverging2( diverging = lfsr_tag_diverging2(
alt, weight, alt, weight,
@@ -3907,9 +3858,9 @@ trunk:;
lower_rid, upper_rid, lower_rid, upper_rid,
a_rid, a_tag, a_rid, a_tag,
b_rid, b_tag); b_rid, b_tag);
if (diverging if (diverging) {
&& (!lfsr_tag_isred(alt) // && (!lfsr_tag_isred(alt)
|| lfsr_tag_isred(p[0].alt))) { // || lfsr_tag_isred(p[0].alt))) {
LFS_DEBUG("%04x->%04x: div b trimming", LFS_DEBUG("%04x->%04x: div b trimming",
branch, lfsr_rbyd_eoff(rbyd)); branch, lfsr_rbyd_eoff(rbyd));
// trim so alt is pruned // trim so alt is pruned
@@ -3918,79 +3869,109 @@ trunk:;
&lower_rid, &upper_rid, &lower_rid, &upper_rid,
&lower_tag, &upper_tag); &lower_tag, &upper_tag);
weight = 0; weight = 0;
}
}
maybetrim:; // prune red alts
// prune other unreachable alts if (lfsr_tag_isred(p[0].alt)
// <b >b && lfsr_tag_unreachable(
// .-'| .-'| p[0].alt, p[0].weight,
// <y | | <b lower_rid, upper_rid,
// .-------'| | .-----------|-'| lower_tag, upper_tag)) {
// | <r | => | | | // prune unreachable recolorable alts
// | .----' | | | | // <r => <b
// | | <b | <b | // .----'| .----'|
// | | .----'| | .----'| | // | <b | |
// 1 2 3 4 4 1 2 3 4 4 2 // | .-'| | .--'
if (lfsr_tag_unreachable2( // 1 2 3 1 2 3 x
alt, weight, // this includes unreachable yellow alts in yellow splits
p[0].alt, p[0].weight, // <b >b
lower_rid, upper_rid, // .-'| .-'|
lower_tag, upper_tag)) { // <y | | |
// prune unreachable recolorable alts // .-------'| | | |
// : : // | <r | => | >b
// <r => <b // | .----' | .--------|-'|
// .----'| .-------'| // | | <b | <b |
// | <b | | // | | .----'| | .----'| |
// | .-'| | .-----' // 1 2 3 4 4 1 2 3 4 4 1
// 1 2 3 1 2 3 x LFS_DEBUG("%04x->%04x: yprune",
if (lfsr_tag_isred(p[0].alt)) { branch, lfsr_rbyd_eoff(rbyd));
LFS_DEBUG("%04x->%04x: rtrim", if (p[0].jump > branch) {
branch, lfsr_rbyd_eoff(rbyd)); alt &= ~LFSR_TAG_R;
alt = p[0].alt & ~LFSR_TAG_R; }
weight = p[0].weight; lfsr_rbyd_p_pop(p);
jump = p[0].jump; }
lfsr_rbyd_p_pop(p);
// TODO redoc // prune black alts
// TODO does this ever get hit? if (lfsr_tag_unreachable2(
// prune unreachable root alts and red alts alt, weight,
// : : p[0].alt, p[0].weight,
// <r => <b lower_rid, upper_rid,
// .----'| .----'| lower_tag, upper_tag)) {
// | <b | | // prune unreachable recolorable alts
// | .-'| | .--' // <r => <b
// 3 4 5 3 4 5 x // .----'| .-------'|
} else if (!p[0].alt) { //|| lfsr_tag_isred(alt)) { // | <b | |
LFS_DEBUG("%04x->%04x: ztrim", // | .-'| | .-----'
branch, lfsr_rbyd_eoff(rbyd)); // 1 2 3 1 2 3 x
branch = branch_; // this includes unreachable red alts in yellow splits
continue; // <b >b
// .-'| .-'|
// mark unreachable non-root black alts as unreachable, // <y | | <b
// we can't prune these or we risk breaking the color // .-------'| | .-----------|-'|
// balance of our tree, but if we push a red up later we // | <r | => | | |
// can get rid of them // | .----' | | | |
// : : // | | <b | <b |
// <b => nb // | | .----'| | .----'| |
// .-'| .--' // 1 2 3 4 4 1 2 3 4 4 2
// 3 4 3 4 x if (lfsr_tag_isred(p[0].alt)) {
} else if (!lfsr_tag_isred(alt)) { LFS_DEBUG("%04x->%04x: rprune",
LFS_DEBUG("%04x->%04x: btrim", branch, lfsr_rbyd_eoff(rbyd));
branch, lfsr_rbyd_eoff(rbyd)); alt = (p[0].alt & ~LFSR_TAG_R) | (alt & LFSR_TAG_R);
alt = LFSR_TAG_ALT( if (jump > branch) {
LFSR_TAG_B, alt &= ~LFSR_TAG_R;
LFSR_TAG_LE,
(diverged && !(a_rid < b_rid || a_tag < b_tag))
? d_tag
: lower_tag);
// TODO hmmmmm?
LFS_ASSERT(weight == 0);
//weight = 0;
// we don't need to, but setting jump=0 asserts this
// alt is unreachable while also minimizing the the
// encoding
jump = 0;
}
} }
weight = p[0].weight;
jump = p[0].jump;
lfsr_rbyd_p_pop(p);
// TODO redoc
// TODO does this ever get hit?
// prune unreachable root alts and red alts
// <r => <b
// .----'| .----'|
// | <b | |
// | .-'| | .--'
// 3 4 5 3 4 5 x
} else if (!p[0].alt) { //|| lfsr_tag_isred(alt)) {
LFS_DEBUG("%04x->%04x: ztrim",
branch, lfsr_rbyd_eoff(rbyd));
branch = branch_;
continue;
// mark unreachable non-root black alts as unreachable (
// jump=0), we can't prune these right now or we risk
// breaking the color balance of our tree, but if we
// push up a red edge later we can get rid of these
// <b => nb
// .-'| .--'
// 3 4 3 4 x
} else if (!lfsr_tag_isred(alt)) {
LFS_DEBUG("%04x->%04x: btrim",
branch, lfsr_rbyd_eoff(rbyd));
alt = LFSR_TAG_ALT(
LFSR_TAG_B,
LFSR_TAG_LE,
(diverged && !(a_rid < b_rid || a_tag < b_tag))
? d_tag
: lower_tag);
// TODO hmmmmm?
LFS_ASSERT(weight == 0);
//weight = 0;
// we don't need to, but setting jump=0 asserts this
// alt is unreachable while also minimizing the the
// encoding
jump = 0;
} }
} }
@@ -4011,6 +3992,7 @@ trunk:;
if (branch_ < branch) { if (branch_ < branch) {
LFS_DEBUG("%04x->%04x: ysplit b", LFS_DEBUG("%04x->%04x: ysplit b",
branch, lfsr_rbyd_eoff(rbyd)); branch, lfsr_rbyd_eoff(rbyd));
// TODO this shouldn't happen?
// TODO hwat, >= solves this?? // TODO hwat, >= solves this??
if (jump == branch){ if (jump == branch){
LFS_DEBUG("%04x->%04x: ysplit b jump == branch", LFS_DEBUG("%04x->%04x: ysplit b jump == branch",