From d3e09b082f39146b23c46b05e20a95f6a1d2caf3 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Mon, 8 Apr 2024 14:12:24 -0500 Subject: [PATCH] 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. --- lfs.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/lfs.c b/lfs.c index 80aab478..0dc8f7f4 100644 --- a/lfs.c +++ b/lfs.c @@ -2888,14 +2888,12 @@ trunk:; 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 lfsr_alt_t p[3] = {{0}, {0}, {0}}; - // keep track of the last incoming branch for yellow splits 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 while (true) { @@ -2949,16 +2947,16 @@ trunk:; b_rid, b_tag)))) { d_state = lfsr_d_diverge(d_state); - // diverged red? flip + // diverging red? flip if (lfsr_tag_isred(p[0].alt) - && (lfsr_tag_follow( + && lfsr_tag_follow( p[0].alt, p[0].weight, lower_rid, upper_rid, a_rid, a_tag) ^ lfsr_tag_follow( p[0].alt, p[0].weight, lower_rid, upper_rid, - b_rid, b_tag))) { + b_rid, b_tag)) { if (lfsr_tag_isparallel(alt, p[0].alt)) { lfsr_tag_flip2(&alt, &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)) { - // flip if (lfsr_tag_isgt(alt)) { lfsr_tag_flip2( &alt, &weight, @@ -3003,8 +3000,6 @@ trunk:; lower_rid, upper_rid); lfs_swap32(&jump, &branch_); } - - // trim lfsr_tag_trim2( alt, weight, p[0].alt, p[0].weight, @@ -3025,15 +3020,18 @@ trunk:; continue; } - // trim unreachable diverged alts so they end up pruned + // force diverged alts to be pruned } else if (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) ^ lfsr_tag_follow2( alt, weight, p[0].alt, p[0].weight, lower_rid, upper_rid, - a_rid, a_tag))) { + b_rid, b_tag)) { if (lfsr_tag_follow2( alt, weight, p[0].alt, p[0].weight,