rbyd-rr: Adopted a struct-based p-alt fifo representation

So instead of:

  lfsr_tag_t p_alts[3];
  lfsr_rid_t p_weights[3];
  lfs_size_t p_jumps[3];

We now have:

  lfsr_alt_t p[3];

Note this is the only place where we use the new lfsr_alt_t type,
hopefully using such a general name doesn't create confusion down the
road...

I was mostly just curious which representation the compiler
(GCC 11.4 -mthumb) would handle better. In theory a struct
representation will result in more efficient memmoves, since we usually
operate on entire alts at a time when manipulting our fifo.

The original motivation for the separate arrays was to avoid alignment
issues with the 16-bit lfsr_tag_t, but this was apparently premature:

           code          stack
  before: 34644           2864
  after:  34480 (-0.5%)   2864 (+0.0%)

                     code          frame          stack
  appendattr before: 2452            216            568
  appendattr after:  2404 (-2.0%)    216 (+0.0%)    568 (+0.0%)

Actually, it's a bit strange that lfsr_rbyd_appendattr showed _no_ stack
changes... I wonder why that is?
This commit is contained in:
Christopher Haster
2024-04-08 02:31:24 -05:00
parent eb2c7a9a05
commit 54c8beee70
+121 -141
View File
@@ -2657,18 +2657,22 @@ static int lfsr_rbyd_prepareappend(lfs_t *lfs, lfsr_rbyd_t *rbyd) {
// helper functions for managing the 3-element fifo used in // helper functions for managing the 3-element fifo used in
// lfsr_rbyd_appendattr // lfsr_rbyd_appendattr
typedef struct lfsr_alt {
lfsr_tag_t alt;
lfsr_rid_t weight;
lfs_size_t jump;
} lfsr_alt_t;
static int lfsr_rbyd_p_flush(lfs_t *lfs, lfsr_rbyd_t *rbyd, static int lfsr_rbyd_p_flush(lfs_t *lfs, lfsr_rbyd_t *rbyd,
lfsr_tag_t p_alts[static 3], lfsr_alt_t p[static 3],
lfsr_rid_t p_weights[static 3],
lfs_size_t p_jumps[static 3],
int count) { int count) {
// write out some number of alt pointers in our queue // write out some number of alt pointers in our queue
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
if (p_alts[3-1-i]) { if (p[3-1-i].alt) {
// change to a relative jump at the last minute // change to a relative jump at the last minute
lfsr_tag_t alt = p_alts[3-1-i]; lfsr_tag_t alt = p[3-1-i].alt;
lfsr_rid_t weight = p_weights[3-1-i]; lfsr_rid_t weight = p[3-1-i].weight;
lfs_size_t jump = rbyd->eoff - p_jumps[3-1-i]; lfs_size_t jump = rbyd->eoff - p[3-1-i].jump;
int err = lfsr_rbyd_appendtag(lfs, rbyd, alt, weight, jump); int err = lfsr_rbyd_appendtag(lfs, rbyd, alt, weight, jump);
if (err) { if (err) {
@@ -2681,83 +2685,66 @@ static int lfsr_rbyd_p_flush(lfs_t *lfs, lfsr_rbyd_t *rbyd,
} }
static inline int lfsr_rbyd_p_push(lfs_t *lfs, lfsr_rbyd_t *rbyd, static inline int lfsr_rbyd_p_push(lfs_t *lfs, lfsr_rbyd_t *rbyd,
lfsr_tag_t p_alts[static 3], lfsr_alt_t p[static 3],
lfsr_rid_t p_weights[static 3],
lfs_size_t p_jumps[static 3],
lfsr_tag_t alt, lfsr_srid_t weight, lfs_size_t jump) { lfsr_tag_t alt, lfsr_srid_t weight, lfs_size_t jump) {
int err = lfsr_rbyd_p_flush(lfs, rbyd, p_alts, p_weights, p_jumps, 1); int err = lfsr_rbyd_p_flush(lfs, rbyd, p, 1);
if (err) { if (err) {
return err; return err;
} }
memmove(p_alts+1, p_alts, 2*sizeof(lfsr_tag_t)); memmove(p+1, p, 2*sizeof(lfsr_alt_t));
memmove(p_weights+1, p_weights, 2*sizeof(lfsr_rid_t)); p[0].alt = alt;
memmove(p_jumps+1, p_jumps, 2*sizeof(lfs_size_t)); p[0].weight = weight;
p_alts[0] = alt; p[0].jump = jump;
p_weights[0] = weight;
p_jumps[0] = jump;
return 0; return 0;
} }
static inline void lfsr_rbyd_p_pop( static inline void lfsr_rbyd_p_pop(
lfsr_tag_t p_alts[static 3], lfsr_alt_t p[static 3]) {
lfsr_rid_t p_weights[static 3], memmove(p, p+1, 2*sizeof(lfsr_alt_t));
lfs_size_t p_jumps[static 3]) { p[2].alt = 0;
memmove(p_alts, p_alts+1, 2*sizeof(lfsr_tag_t));
memmove(p_weights, p_weights+1, 2*sizeof(lfsr_rid_t));
memmove(p_jumps, p_jumps+1, 2*sizeof(lfs_size_t));
p_alts[2] = 0;
p_weights[2] = 0;
p_jumps[2] = 0;
} }
static void lfsr_rbyd_p_recolor( static void lfsr_rbyd_p_recolor(
lfsr_tag_t p_alts[static 3], lfsr_alt_t p[static 3]) {
lfsr_rid_t p_weights[static 3],
lfs_size_t p_jumps[static 3]) {
// propagate a red edge upwards // propagate a red edge upwards
p_alts[0] &= ~LFSR_TAG_R; p[0].alt &= ~LFSR_TAG_R;
if (p_alts[1]) { if (p[1].alt) {
p_alts[1] |= LFSR_TAG_R; p[1].alt |= LFSR_TAG_R;
// alt-never? we can prune this now // alt-never? we can prune this now
if (lfsr_tag_isn(p_alts[1])) { if (lfsr_tag_isn(p[1].alt)) {
p_alts[1] = p_alts[2]; p[1] = p[2];
p_weights[1] = p_weights[2]; p[2].alt = 0;
p_jumps[1] = p_jumps[2];
p_alts[2] = 0;
p_weights[2] = 0;
p_jumps[2] = 0;
// reorder so that top two edges always go in the same direction // reorder so that top two edges always go in the same direction
} else if (lfsr_tag_isred(p_alts[2])) { } else if (lfsr_tag_isred(p[2].alt)) {
if (lfsr_tag_isparallel(p_alts[1], p_alts[2])) { if (lfsr_tag_isparallel(p[1].alt, p[2].alt)) {
// no reorder needed // no reorder needed
} else if (lfsr_tag_isparallel(p_alts[0], p_alts[2])) { } else if (lfsr_tag_isparallel(p[0].alt, p[2].alt)) {
lfsr_tag_t alt_ = p_alts[1]; lfsr_tag_t alt_ = p[1].alt;
lfsr_rid_t weight_ = p_weights[1]; lfsr_rid_t weight_ = p[1].weight;
lfs_size_t jump_ = p_jumps[1]; lfs_size_t jump_ = p[1].jump;
p_alts[1] = p_alts[0] | LFSR_TAG_R; p[1].alt = p[0].alt | LFSR_TAG_R;
p_weights[1] = p_weights[0]; p[1].weight = p[0].weight;
p_jumps[1] = p_jumps[0]; p[1].jump = p[0].jump;
p_alts[0] = alt_ & ~LFSR_TAG_R; p[0].alt = alt_ & ~LFSR_TAG_R;
p_weights[0] = weight_; p[0].weight = weight_;
p_jumps[0] = jump_; p[0].jump = jump_;
} else if (lfsr_tag_isparallel(p_alts[0], p_alts[1])) { } else if (lfsr_tag_isparallel(p[0].alt, p[1].alt)) {
lfsr_tag_t alt_ = p_alts[2]; lfsr_tag_t alt_ = p[2].alt;
lfsr_rid_t weight_ = p_weights[2]; lfsr_rid_t weight_ = p[2].weight;
lfs_size_t jump_ = p_jumps[2]; lfs_size_t jump_ = p[2].jump;
p_alts[2] = p_alts[1] | LFSR_TAG_R; p[2].alt = p[1].alt | LFSR_TAG_R;
p_weights[2] = p_weights[1]; p[2].weight = p[1].weight;
p_jumps[2] = p_jumps[1]; p[2].jump = p[1].jump;
p_alts[1] = p_alts[0] | LFSR_TAG_R; p[1].alt = p[0].alt | LFSR_TAG_R;
p_weights[1] = p_weights[0]; p[1].weight = p[0].weight;
p_jumps[1] = p_jumps[0]; p[1].jump = p[0].jump;
p_alts[0] = alt_ & ~LFSR_TAG_R; p[0].alt = alt_ & ~LFSR_TAG_R;
p_weights[0] = weight_; p[0].weight = weight_;
p_jumps[0] = jump_; p[0].jump = jump_;
} else { } else {
LFS_UNREACHABLE(); LFS_UNREACHABLE();
} }
@@ -2905,9 +2892,7 @@ again:;
lfsr_tag_t tag_ = 0; lfsr_tag_t tag_ = 0;
// queue of pending alts we can emulate rotations with // queue of pending alts we can emulate rotations with
lfsr_tag_t p_alts[3] = {0, 0, 0}; lfsr_alt_t p[3] = {{0}, {0}, {0}};
lfsr_rid_t p_weights[3] = {0, 0, 0};
lfs_size_t p_jumps[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;
@@ -2915,7 +2900,7 @@ again:;
// descend down tree, building alt pointers // descend down tree, building alt pointers
while (true) { while (true) {
// keep track of incoming branch // keep track of incoming branch
if (lfsr_tag_isblack(p_alts[0])) { if (lfsr_tag_isblack(p[0].alt)) {
y_branch = branch; y_branch = branch;
} }
@@ -2941,70 +2926,70 @@ again:;
// diverging black? // diverging black?
&& (((lfsr_tag_isblack(alt) && (((lfsr_tag_isblack(alt)
// give up if we find a yellow alt // give up if we find a yellow alt
|| lfsr_tag_isred(p_alts[0])) || lfsr_tag_isred(p[0].alt))
&& lfsr_tag_follow2( && lfsr_tag_follow2(
alt, weight, alt, weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid, lower_rid, upper_rid,
a_rid, a_tag) a_rid, a_tag)
^ lfsr_tag_follow2( ^ lfsr_tag_follow2(
alt, weight, alt, weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid, lower_rid, upper_rid,
b_rid, b_tag)) b_rid, b_tag))
// diverging red? // diverging red?
|| (lfsr_tag_isred(p_alts[0]) || (lfsr_tag_isred(p[0].alt)
&& lfsr_tag_follow( && lfsr_tag_follow(
p_alts[0], p_weights[0], 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_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid, lower_rid, upper_rid,
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 // diverged red? flip
if (lfsr_tag_isred(p_alts[0]) if (lfsr_tag_isred(p[0].alt)
&& (lfsr_tag_follow( && (lfsr_tag_follow(
p_alts[0], p_weights[0], 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_alts[0], p_weights[0], 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_alts[0])) { if (lfsr_tag_isparallel(alt, p[0].alt)) {
lfsr_tag_flip2(&alt, &weight, lfsr_tag_flip2(&alt, &weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid); lower_rid, upper_rid);
lfs_swap32(&jump, &branch_); lfs_swap32(&jump, &branch_);
} }
lfs_swap16(&p_alts[0], &alt); lfs_swap16(&p[0].alt, &alt);
lfs_swap32(&p_weights[0], &weight); lfs_swap32(&p[0].weight, &weight);
lfs_swap32(&p_jumps[0], &jump); lfs_swap32(&p[0].jump, &jump);
p_alts[0] |= LFSR_TAG_R; p[0].alt |= LFSR_TAG_R;
alt &= ~LFSR_TAG_R; alt &= ~LFSR_TAG_R;
// both diverging? collapse // both diverging? collapse
if (lfsr_tag_follow( if (lfsr_tag_follow(
p_alts[0], p_weights[0], 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_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid, lower_rid, upper_rid,
b_rid, b_tag)) { b_rid, b_tag)) {
LFS_ASSERT(!lfsr_tag_isparallel(alt, p_alts[0])); LFS_ASSERT(!lfsr_tag_isparallel(alt, p[0].alt));
lfsr_tag_flip2(&alt, &weight, lfsr_tag_flip2(&alt, &weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid); lower_rid, upper_rid);
lfs_swap32(&jump, &branch_); lfs_swap32(&jump, &branch_);
weight += p_weights[0]; weight += p[0].weight;
jump = p_jumps[0]; jump = p[0].jump;
lfsr_rbyd_p_pop(p_alts, p_weights, p_jumps); lfsr_rbyd_p_pop(p);
} }
} }
@@ -3014,7 +2999,7 @@ again:;
if (lfsr_tag_isgt(alt)) { if (lfsr_tag_isgt(alt)) {
lfsr_tag_flip2( lfsr_tag_flip2(
&alt, &weight, &alt, &weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid); lower_rid, upper_rid);
lfs_swap32(&jump, &branch_); lfs_swap32(&jump, &branch_);
} }
@@ -3022,13 +3007,12 @@ again:;
// trim // trim
lfsr_tag_trim2( lfsr_tag_trim2(
alt, weight, alt, weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
&lower_rid, &upper_rid, &lower_rid, &upper_rid,
&lower_tag, &upper_tag); &lower_tag, &upper_tag);
// stitch together both trunks // stitch together both trunks
err = lfsr_rbyd_p_push(lfs, rbyd, err = lfsr_rbyd_p_push(lfs, rbyd, p,
p_alts, p_weights, p_jumps,
LFSR_TAG_ALT(LFSR_TAG_LE, LFSR_TAG_B, d_tag), LFSR_TAG_ALT(LFSR_TAG_LE, LFSR_TAG_B, d_tag),
d_rid - (lower_rid - weight), d_rid - (lower_rid - weight),
jump); jump);
@@ -3047,17 +3031,17 @@ again:;
^ lfsr_tag_isgt(alt) ^ lfsr_tag_isgt(alt)
^ lfsr_tag_follow2( ^ lfsr_tag_follow2(
alt, weight, alt, weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid, lower_rid, upper_rid,
a_rid, a_tag))) { a_rid, a_tag))) {
if (lfsr_tag_follow2( if (lfsr_tag_follow2(
alt, weight, alt, weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid, lower_rid, upper_rid,
a_rid, a_tag)) { a_rid, a_tag)) {
lfsr_tag_flip2( lfsr_tag_flip2(
&alt, &weight, &alt, &weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid); lower_rid, upper_rid);
lfs_swap32(&jump, &branch_); lfs_swap32(&jump, &branch_);
} }
@@ -3081,32 +3065,32 @@ again:;
// 1 2 3 4 4 1 2 3 4 4 2 // 1 2 3 4 4 1 2 3 4 4 2
if (lfsr_tag_unavoidable2( if (lfsr_tag_unavoidable2(
alt, weight, alt, weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid, lower_rid, upper_rid,
lower_tag, upper_tag) lower_tag, upper_tag)
|| lfsr_tag_unreachable2( || lfsr_tag_unreachable2(
alt, weight, alt, weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid, lower_rid, upper_rid,
lower_tag, upper_tag)) { lower_tag, upper_tag)) {
// note if only yellow pruning this could be much simpler // note if only yellow pruning this could be much simpler
if (lfsr_tag_unavoidable2( if (lfsr_tag_unavoidable2(
alt, weight, alt, weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid, lower_rid, upper_rid,
lower_tag, upper_tag)) { lower_tag, upper_tag)) {
lfs_swap32(&jump, &branch_); lfs_swap32(&jump, &branch_);
} }
// prune unreachable red-black alts // prune unreachable red-black alts
if (lfsr_tag_isred(p_alts[0])) { if (lfsr_tag_isred(p[0].alt)) {
alt = p_alts[0] & ~LFSR_TAG_R; alt = p[0].alt & ~LFSR_TAG_R;
weight = p_weights[0]; weight = p[0].weight;
jump = p_jumps[0]; jump = p[0].jump;
lfsr_rbyd_p_pop(p_alts, p_weights, p_jumps); lfsr_rbyd_p_pop(p);
// prune unreachable root alts and red alts // prune unreachable root alts and red alts
} else if (!p_alts[0] || lfsr_tag_isred(alt)) { } else if (!p[0].alt || lfsr_tag_isred(alt)) {
branch = branch_; branch = branch_;
continue; continue;
@@ -3120,8 +3104,8 @@ again:;
} }
// two reds makes a yellow, split? // two reds makes a yellow, split?
if (lfsr_tag_isred(alt) && lfsr_tag_isred(p_alts[0])) { if (lfsr_tag_isred(alt) && lfsr_tag_isred(p[0].alt)) {
LFS_ASSERT(lfsr_tag_isparallel(alt, p_alts[0])); LFS_ASSERT(lfsr_tag_isparallel(alt, p[0].alt));
// if we take the red or yellow alt we can just point // if we take the red or yellow alt we can just point
// to the black alt // to the black alt
@@ -3134,24 +3118,24 @@ again:;
// 1 2 3 4 1 2 3 4 1 // 1 2 3 4 1 2 3 4 1
if (lfsr_tag_follow2( if (lfsr_tag_follow2(
alt, weight, alt, weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid, lower_rid, upper_rid,
a_rid, a_tag)) { a_rid, a_tag)) {
lfsr_tag_flip2(&alt, &weight, lfsr_tag_flip2(&alt, &weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid); lower_rid, upper_rid);
lfs_swap32(&jump, &branch_); lfs_swap32(&jump, &branch_);
lfs_swap16(&p_alts[0], &alt); lfs_swap16(&p[0].alt, &alt);
lfs_swap32(&p_weights[0], &weight); lfs_swap32(&p[0].weight, &weight);
lfs_swap32(&p_jumps[0], &jump); lfs_swap32(&p[0].jump, &jump);
alt &= ~LFSR_TAG_R; alt &= ~LFSR_TAG_R;
lfsr_tag_trim( lfsr_tag_trim(
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
&lower_rid, &upper_rid, &lower_rid, &upper_rid,
&lower_tag, &upper_tag); &lower_tag, &upper_tag);
lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps); lfsr_rbyd_p_recolor(p);
// otherwise we need to point to the yellow alt and // otherwise we need to point to the yellow alt and
// prune later // prune later
@@ -3166,15 +3150,15 @@ again:;
// 1 2 3 4 1 2 3 4 4 // 1 2 3 4 1 2 3 4 4
} else { } else {
LFS_ASSERT(y_branch != 0); LFS_ASSERT(y_branch != 0);
p_alts[0] = alt; p[0].alt = alt;
p_weights[0] += weight; p[0].weight += weight;
p_jumps[0] = y_branch; p[0].jump = y_branch;
lfsr_tag_trim( lfsr_tag_trim(
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
&lower_rid, &upper_rid, &lower_rid, &upper_rid,
&lower_tag, &upper_tag); &lower_tag, &upper_tag);
lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps); lfsr_rbyd_p_recolor(p);
branch = branch_; branch = branch_;
continue; continue;
@@ -3189,11 +3173,11 @@ again:;
// 1 2 1 2 1 // 1 2 1 2 1
if (lfsr_tag_follow2( if (lfsr_tag_follow2(
alt, weight, alt, weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid, lower_rid, upper_rid,
a_rid, a_tag)) { a_rid, a_tag)) {
lfsr_tag_flip2(&alt, &weight, lfsr_tag_flip2(&alt, &weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid); lower_rid, upper_rid);
lfs_swap32(&jump, &branch_); lfs_swap32(&jump, &branch_);
} }
@@ -3204,18 +3188,18 @@ again:;
// | <b => | >b // | <b => | >b
// | .-'| .--|-'| // | .-'| .--|-'|
// 1 2 3 1 2 3 1 // 1 2 3 1 2 3 1
if (lfsr_tag_isred(p_alts[0]) if (lfsr_tag_isred(p[0].alt)
&& lfsr_tag_follow(p_alts[0], p_weights[0], && lfsr_tag_follow(p[0].alt, p[0].weight,
lower_rid, upper_rid, lower_rid, upper_rid,
a_rid, a_tag)) { a_rid, a_tag)) {
lfs_swap16(&p_alts[0], &alt); lfs_swap16(&p[0].alt, &alt);
lfs_swap32(&p_weights[0], &weight); lfs_swap32(&p[0].weight, &weight);
lfs_swap32(&p_jumps[0], &jump); lfs_swap32(&p[0].jump, &jump);
p_alts[0] |= LFSR_TAG_R; p[0].alt |= LFSR_TAG_R;
alt &= ~LFSR_TAG_R; alt &= ~LFSR_TAG_R;
lfsr_tag_flip2(&alt, &weight, lfsr_tag_flip2(&alt, &weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
lower_rid, upper_rid); lower_rid, upper_rid);
lfs_swap32(&jump, &branch_); lfs_swap32(&jump, &branch_);
} }
@@ -3223,14 +3207,13 @@ again:;
// trim alts from our current bounds // trim alts from our current bounds
lfsr_tag_trim2( lfsr_tag_trim2(
alt, weight, alt, weight,
p_alts[0], p_weights[0], p[0].alt, p[0].weight,
&lower_rid, &upper_rid, &lower_rid, &upper_rid,
&lower_tag, &upper_tag); &lower_tag, &upper_tag);
} }
// push alt onto our queue // push alt onto our queue
err = lfsr_rbyd_p_push(lfs, rbyd, err = lfsr_rbyd_p_push(lfs, rbyd, p,
p_alts, p_weights, p_jumps,
alt, weight, jump); alt, weight, jump);
if (err) { if (err) {
return err; return err;
@@ -3249,7 +3232,7 @@ again:;
} }
// the last alt should always end up black // the last alt should always end up black
LFS_ASSERT(lfsr_tag_isblack(p_alts[0])); LFS_ASSERT(lfsr_tag_isblack(p[0].alt));
// diverged lower trunk? move on to upper trunk // diverged lower trunk? move on to upper trunk
if (d_state == LFSR_D_DIVERGEDLOWER) { if (d_state == LFSR_D_DIVERGEDLOWER) {
@@ -3259,8 +3242,7 @@ again:;
d_tag = lower_tag; d_tag = lower_tag;
// flush any pending alts // flush any pending alts
err = lfsr_rbyd_p_flush(lfs, rbyd, err = lfsr_rbyd_p_flush(lfs, rbyd, p, 3);
p_alts, p_weights, p_jumps, 3);
if (err) { if (err) {
return err; return err;
} }
@@ -3349,20 +3331,18 @@ again:;
} }
if (alt) { if (alt) {
err = lfsr_rbyd_p_push(lfs, rbyd, err = lfsr_rbyd_p_push(lfs, rbyd, p,
p_alts, p_weights, p_jumps,
alt, weight, branch); alt, weight, branch);
if (err) { if (err) {
return err; return err;
} }
// introduce a red edge // introduce a red edge
lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps); lfsr_rbyd_p_recolor(p);
} }
// flush any pending alts // flush any pending alts
err = lfsr_rbyd_p_flush(lfs, rbyd, err = lfsr_rbyd_p_flush(lfs, rbyd, p, 3);
p_alts, p_weights, p_jumps, 3);
if (err) { if (err) {
return err; return err;
} }