From 8e919df1b8dfd3573c029ffc47abed7b84171a81 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 26 Jan 2025 14:35:48 -0600 Subject: [PATCH] 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%) --- lfs.c | 282 +++++++++++++++++++++++++++------------------------------- 1 file changed, 132 insertions(+), 150 deletions(-) diff --git a/lfs.c b/lfs.c index 5a853d32..510ff175 100644 --- a/lfs.c +++ b/lfs.c @@ -3624,54 +3624,6 @@ trunk:; LFS_SWAP(lfs_size_t, &jump, &branch_); } - // TODO redoc? - // prune? - if (lfsr_tag_isred(p[0].alt)) { - // prune unreachable red alts - // b - // .-'| .-'| - // | >b - // | .----' | .--------|-'| - // | | = 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 - // .-'| .-'| - // | | | - // | .----' | | | | - // | | = 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? // both diverging? collapse // b @@ -3865,41 +3817,40 @@ trunk:; // branch = branch_; // continue; - goto maybetrim; +// goto maybetrim; } // diverged? - // : : // nb // .-'| .--' // 3 4 3 4 x } else if (diverged) { - diverging = lfsr_tag_diverging2( - alt, weight, - p[0].alt, p[0].weight, - lower_rid, upper_rid, - a_rid, a_tag, - b_rid, b_tag); - diverging_red = lfsr_tag_isred(p[0].alt) - && lfsr_tag_diverging( - p[0].alt, p[0].weight, - lower_rid, upper_rid, - a_rid, a_tag, - b_rid, b_tag); - // TODO I think this logic is wrong, what's correct here? - if (diverging_red) { - LFS_DEBUG("%04x->%04x: div r trimming", - branch, lfsr_rbyd_eoff(rbyd)); - // trim so alt is pruned - lfsr_tag_trim( - p[0].alt, p[0].weight, - &lower_rid, &upper_rid, - &lower_tag, &upper_tag); - p[0].weight = 0; - - lfsr_rbyd_p_pop(p); - - // TODO prune? (trim?) - } +// diverging = lfsr_tag_diverging2( +// alt, weight, +// p[0].alt, p[0].weight, +// lower_rid, upper_rid, +// a_rid, a_tag, +// b_rid, b_tag); +// diverging_red = lfsr_tag_isred(p[0].alt) +// && lfsr_tag_diverging( +// p[0].alt, p[0].weight, +// lower_rid, upper_rid, +// a_rid, a_tag, +// b_rid, b_tag); +// // TODO I think this logic is wrong, what's correct here? +// if (diverging_red) { +// LFS_DEBUG("%04x->%04x: div r trimming", +// branch, lfsr_rbyd_eoff(rbyd)); +// // trim so alt is pruned +// lfsr_tag_trim( +// p[0].alt, p[0].weight, +// &lower_rid, &upper_rid, +// &lower_tag, &upper_tag); +// p[0].weight = 0; +// +// lfsr_rbyd_p_pop(p); +// +// // TODO prune? (trim?) +// } diverging = lfsr_tag_diverging2( alt, weight, @@ -3907,9 +3858,9 @@ trunk:; lower_rid, upper_rid, a_rid, a_tag, b_rid, b_tag); - if (diverging - && (!lfsr_tag_isred(alt) - || lfsr_tag_isred(p[0].alt))) { + if (diverging) { +// && (!lfsr_tag_isred(alt) +// || lfsr_tag_isred(p[0].alt))) { LFS_DEBUG("%04x->%04x: div b trimming", branch, lfsr_rbyd_eoff(rbyd)); // trim so alt is pruned @@ -3918,79 +3869,109 @@ trunk:; &lower_rid, &upper_rid, &lower_tag, &upper_tag); weight = 0; + } + } - maybetrim:; - // prune other unreachable alts - // b - // .-'| .-'| - // | | | - // | .----' | | | | - // | | %04x: rtrim", - 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); + // prune red alts + if (lfsr_tag_isred(p[0].alt) + && lfsr_tag_unreachable( + p[0].alt, p[0].weight, + lower_rid, upper_rid, + lower_tag, upper_tag)) { + // prune unreachable recolorable alts + // b + // .-'| .-'| + // | >b + // | .----' | .--------|-'| + // | | %04x: yprune", + branch, lfsr_rbyd_eoff(rbyd)); + if (p[0].jump > branch) { + alt &= ~LFSR_TAG_R; + } + lfsr_rbyd_p_pop(p); + } - // TODO redoc - // TODO does this ever get hit? - // prune unreachable root alts and red alts - // : : - // %04x: ztrim", - branch, lfsr_rbyd_eoff(rbyd)); - branch = branch_; - continue; - - // mark unreachable non-root black alts as unreachable, - // we can't prune these or we risk breaking the color - // balance of our tree, but if we push a red up later we - // can get rid of them - // : : - // 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; - } + // prune black alts + if (lfsr_tag_unreachable2( + alt, weight, + p[0].alt, p[0].weight, + lower_rid, upper_rid, + lower_tag, upper_tag)) { + // prune unreachable recolorable alts + // b + // .-'| .-'| + // | | | + // | .----' | | | | + // | | %04x: rprune", + branch, lfsr_rbyd_eoff(rbyd)); + alt = (p[0].alt & ~LFSR_TAG_R) | (alt & LFSR_TAG_R); + if (jump > branch) { + alt &= ~LFSR_TAG_R; } + 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 + // %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 + // 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) { LFS_DEBUG("%04x->%04x: ysplit b", branch, lfsr_rbyd_eoff(rbyd)); + // TODO this shouldn't happen? // TODO hwat, >= solves this?? if (jump == branch){ LFS_DEBUG("%04x->%04x: ysplit b jump == branch",