Simplified the diverged state machine in lfsr_rbyd_appendattr
Just made d_pruned its own variable. Encoding d_pruned into the state
machine is overkill.
We're not on the hot-path, so stack usage is not a premium, and even if
we were this is a single bool that could probably fit in some padding
somewhere. And the compiler is going to likely be better at optimizing
with a simpler encoding.
Code changes:
code stack
before: 33988 2864
after: 33968 (+0.0%) 2864 (+0.0%)
This commit is contained in:
@@ -2693,46 +2693,21 @@ static void lfsr_rbyd_p_recolor(
|
|||||||
|
|
||||||
// diverged state machine for range appends
|
// diverged state machine for range appends
|
||||||
enum {
|
enum {
|
||||||
LFSR_D_NOTDIVERGING = 0x0,
|
LFSR_D_NOTDIVERGING = 0,
|
||||||
LFSR_D_DIVERGINGLOWER = 0x2,
|
LFSR_D_DIVERGINGLOWER = 1,
|
||||||
LFSR_D_DIVERGINGUPPER = 0x3,
|
LFSR_D_DIVERGINGUPPER = 2,
|
||||||
LFSR_D_DIVERGEDLOWER = 0x4,
|
LFSR_D_DIVERGEDLOWER = 3,
|
||||||
LFSR_D_DIVERGEDUPPER = 0x5,
|
LFSR_D_DIVERGEDUPPER = 4,
|
||||||
LFSR_D_PRUNEDLOWER = 0x6,
|
|
||||||
LFSR_D_PRUNEDUPPER = 0x7,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool lfsr_d_isdiverged(uint8_t d_state) {
|
static inline bool lfsr_d_isdiverged(uint8_t d_state) {
|
||||||
return d_state >= LFSR_D_DIVERGEDLOWER;
|
return d_state >= LFSR_D_DIVERGEDLOWER;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool lfsr_d_isupper(uint8_t d_state) {
|
|
||||||
return d_state & 0x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool lfsr_d_islower(uint8_t d_state) {
|
|
||||||
return !(d_state & 0x1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool lfsr_d_ispruned(uint8_t d_state) {
|
|
||||||
return d_state >= LFSR_D_PRUNEDLOWER;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint8_t lfsr_d_diverge(uint8_t d_state) {
|
static inline uint8_t lfsr_d_diverge(uint8_t d_state) {
|
||||||
LFS_ASSERT(d_state != LFSR_D_NOTDIVERGING);
|
LFS_ASSERT(d_state != LFSR_D_NOTDIVERGING);
|
||||||
return (!lfsr_d_isdiverged(d_state))
|
LFS_ASSERT(!lfsr_d_isdiverged(d_state));
|
||||||
? d_state + (LFSR_D_DIVERGEDLOWER - LFSR_D_DIVERGINGLOWER)
|
return d_state + (LFSR_D_DIVERGEDLOWER - LFSR_D_DIVERGINGLOWER);
|
||||||
: d_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint8_t lfsr_d_prune(uint8_t d_state) {
|
|
||||||
LFS_ASSERT(lfsr_d_isdiverged(d_state));
|
|
||||||
return d_state | 0x2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint8_t lfsr_d_unprune(uint8_t d_state) {
|
|
||||||
LFS_ASSERT(lfsr_d_isdiverged(d_state));
|
|
||||||
return d_state & ~0x2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// core rbyd algorithm
|
// core rbyd algorithm
|
||||||
@@ -2825,6 +2800,7 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
uint8_t d_state = (a_rid != b_rid || a_tag != b_tag)
|
uint8_t d_state = (a_rid != b_rid || a_tag != b_tag)
|
||||||
? LFSR_D_DIVERGINGLOWER
|
? LFSR_D_DIVERGINGLOWER
|
||||||
: LFSR_D_NOTDIVERGING;
|
: LFSR_D_NOTDIVERGING;
|
||||||
|
bool d_pruned = false;
|
||||||
lfs_size_t d_branch = rbyd->eoff;
|
lfs_size_t d_branch = rbyd->eoff;
|
||||||
lfsr_tag_t d_tag = 0;
|
lfsr_tag_t d_tag = 0;
|
||||||
lfsr_srid_t d_rid = 0;
|
lfsr_srid_t d_rid = 0;
|
||||||
@@ -2904,7 +2880,7 @@ again:;
|
|||||||
d_state = lfsr_d_diverge(d_state);
|
d_state = lfsr_d_diverge(d_state);
|
||||||
|
|
||||||
// stitch together diverged branches
|
// stitch together diverged branches
|
||||||
if (lfsr_d_isupper(d_state) && d_tag) {
|
if (d_state == LFSR_D_DIVERGEDUPPER && d_tag) {
|
||||||
err = lfsr_rbyd_p_push(lfs, rbyd,
|
err = lfsr_rbyd_p_push(lfs, rbyd,
|
||||||
p_alts, p_weights, p_jumps,
|
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),
|
||||||
@@ -2935,7 +2911,7 @@ again:;
|
|||||||
// prune because of diverged paths?
|
// prune because of diverged paths?
|
||||||
|| d_state == LFSR_D_DIVERGINGLOWER
|
|| d_state == LFSR_D_DIVERGINGLOWER
|
||||||
|| (lfsr_d_isdiverged(d_state)
|
|| (lfsr_d_isdiverged(d_state)
|
||||||
&& lfsr_d_isupper(d_state)
|
&& (d_state == LFSR_D_DIVERGEDUPPER)
|
||||||
^ lfsr_tag_isgt(alt)
|
^ lfsr_tag_isgt(alt)
|
||||||
^ lfsr_tag_follow2(
|
^ lfsr_tag_follow2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
@@ -2969,7 +2945,7 @@ again:;
|
|||||||
// propagate pruning to yellow splits to avoid issues
|
// propagate pruning to yellow splits to avoid issues
|
||||||
// with tail-recursive recoloring
|
// with tail-recursive recoloring
|
||||||
if (lfsr_d_isdiverged(d_state)) {
|
if (lfsr_d_isdiverged(d_state)) {
|
||||||
d_state = lfsr_d_prune(d_state);
|
d_pruned = true;
|
||||||
}
|
}
|
||||||
y_branch = branch;
|
y_branch = branch;
|
||||||
branch = branch_;
|
branch = branch_;
|
||||||
@@ -3010,7 +2986,7 @@ again:;
|
|||||||
&lower_rid, &upper_rid,
|
&lower_rid, &upper_rid,
|
||||||
&lower_tag, &upper_tag);
|
&lower_tag, &upper_tag);
|
||||||
p_alts[0] &= ~LFSR_TAG_R;
|
p_alts[0] &= ~LFSR_TAG_R;
|
||||||
if (!lfsr_d_ispruned(d_state)) {
|
if (!d_pruned) {
|
||||||
lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps);
|
lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3036,7 +3012,7 @@ again:;
|
|||||||
&lower_rid, &upper_rid,
|
&lower_rid, &upper_rid,
|
||||||
&lower_tag, &upper_tag);
|
&lower_tag, &upper_tag);
|
||||||
p_alts[0] &= ~LFSR_TAG_R;
|
p_alts[0] &= ~LFSR_TAG_R;
|
||||||
if (!lfsr_d_ispruned(d_state)) {
|
if (!d_pruned) {
|
||||||
lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps);
|
lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3091,9 +3067,7 @@ again:;
|
|||||||
&lower_rid, &upper_rid,
|
&lower_rid, &upper_rid,
|
||||||
&lower_tag, &upper_tag);
|
&lower_tag, &upper_tag);
|
||||||
// no longer pruned
|
// no longer pruned
|
||||||
if (lfsr_d_isdiverged(d_state)) {
|
d_pruned = false;
|
||||||
d_state = lfsr_d_unprune(d_state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// push alt onto our queue
|
// push alt onto our queue
|
||||||
@@ -3126,7 +3100,7 @@ again:;
|
|||||||
goto again;
|
goto again;
|
||||||
|
|
||||||
// diverged lower trunk? we need an upper trunk too
|
// diverged lower trunk? we need an upper trunk too
|
||||||
} else if (lfsr_d_isdiverged(d_state) && lfsr_d_islower(d_state)) {
|
} else if (d_state == LFSR_D_DIVERGEDLOWER) {
|
||||||
// keep track of last alt on diverged trunk to stitch the trunks
|
// keep track of last alt on diverged trunk to stitch the trunks
|
||||||
// together with
|
// together with
|
||||||
d_state = LFSR_D_DIVERGINGUPPER;
|
d_state = LFSR_D_DIVERGINGUPPER;
|
||||||
@@ -3158,7 +3132,7 @@ again:;
|
|||||||
goto again;
|
goto again;
|
||||||
|
|
||||||
// diverged upper trunk? done diverging
|
// diverged upper trunk? done diverging
|
||||||
} else if (lfsr_d_isdiverged(d_state) && lfsr_d_isupper(d_state)) {
|
} else if (d_state == LFSR_D_DIVERGEDUPPER) {
|
||||||
// use the diverged rid bound for leaf weight calculation
|
// use the diverged rid bound for leaf weight calculation
|
||||||
lower_rid = d_rid;
|
lower_rid = d_rid;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user