rbyd-rr: Rearranged pruning to only need lfsr_tag_unreachable*

An excellent example of the sort of simplification that eagerly flipping
gives us.

By flipping _before_ pruning, all unavoidable alts are transformed into
unreachable. This lets us check for one condition instead of two:

           code          stack
  before: 34320           2864
  after:  34224 (-0.3%)   2864 (+0.0%)

                     code          frame          stack
  appendattr before: 2280            216            568
  appendattr after:  2190 (-3.9%)    216 (+0.0%)    568 (+0.0%)
This commit is contained in:
Christopher Haster
2024-04-14 21:20:51 -05:00
parent 8f8dd9f981
commit 82ddb33510
+45 -85
View File
@@ -967,41 +967,6 @@ static inline void lfsr_tag_trim2(
lower_tag, upper_tag);
}
static inline bool lfsr_tag_unavoidable(
lfsr_tag_t alt, lfsr_rid_t weight,
lfsr_srid_t lower_rid, lfsr_srid_t upper_rid,
lfsr_tag_t lower_tag, lfsr_tag_t upper_tag) {
if (lfsr_tag_isgt(alt)) {
return lfsr_tag_follow(
alt, weight,
lower_rid, upper_rid,
lower_rid-1, lower_tag+1);
} else {
return lfsr_tag_follow(
alt, weight,
lower_rid, upper_rid,
upper_rid-1, upper_tag-1);
}
}
static inline bool lfsr_tag_unavoidable2(
lfsr_tag_t alt, lfsr_rid_t weight,
lfsr_tag_t alt2, lfsr_rid_t weight2,
lfsr_srid_t lower_rid, lfsr_srid_t upper_rid,
lfsr_tag_t lower_tag, lfsr_tag_t upper_tag) {
if (lfsr_tag_isred(alt2)) {
lfsr_tag_trim(
alt2, weight2,
&lower_rid, &upper_rid,
&lower_tag, &upper_tag);
}
return lfsr_tag_unavoidable(
alt, weight,
lower_rid, upper_rid,
lower_tag, upper_tag);
}
static inline bool lfsr_tag_unreachable(
lfsr_tag_t alt, lfsr_rid_t weight,
lfsr_srid_t lower_rid, lfsr_srid_t upper_rid,
@@ -2980,56 +2945,6 @@ trunk:;
}
}
// prune?
// <b >b
// .-'| .-'|
// <y | | |
// .-------'| | | |
// | <r | => | <b
// | .----' | .-----------|-'|
// | | <b | <b |
// | | .----'| | .----'| |
// 1 2 3 4 4 1 2 3 4 4 2
if (lfsr_tag_unavoidable2(
alt, weight,
p[0].alt, p[0].weight,
lower_rid, upper_rid,
lower_tag, upper_tag)
|| lfsr_tag_unreachable2(
alt, weight,
p[0].alt, p[0].weight,
lower_rid, upper_rid,
lower_tag, upper_tag)) {
// note if only yellow pruning this could be much simpler
if (lfsr_tag_unavoidable2(
alt, weight,
p[0].alt, p[0].weight,
lower_rid, upper_rid,
lower_tag, upper_tag)) {
lfs_swap32(&jump, &branch_);
}
// prune unreachable red-black alts
if (lfsr_tag_isred(p[0].alt)) {
alt = p[0].alt & ~LFSR_TAG_R;
weight = p[0].weight;
jump = p[0].jump;
lfsr_p_pop(p);
// prune unreachable root alts and red alts
} else if (!p[0].alt || lfsr_tag_isred(alt)) {
branch = branch_;
continue;
// convert unreachable non-root black alts into alt-nevers,
// if we prune these it would break the coloring of our tree
} else {
alt = LFSR_TAG_ALT(LFSR_TAG_LE, LFSR_TAG_B, 0);
weight = 0;
jump = 0;
}
}
// take black alt? needs a flip
// <b >b
// .-'| => .-'|
@@ -3067,6 +2982,51 @@ trunk:;
lfs_swap32(&jump, &branch_);
}
// prune?
// <b >b
// .-'| .-'|
// <y | | |
// .-------'| | | |
// | <r | => | <b
// | .----' | .-----------|-'|
// | | <b | <b |
// | | .----'| | .----'| |
// 1 2 3 4 4 1 2 3 4 4 2
if (lfsr_tag_isred(p[0].alt)
&& lfsr_tag_unreachable(
p[0].alt, p[0].weight,
lower_rid, upper_rid,
lower_tag, upper_tag)) {
alt &= ~LFSR_TAG_R;
lfsr_p_pop(p);
}
if (lfsr_tag_unreachable2(
alt, weight,
p[0].alt, p[0].weight,
lower_rid, upper_rid,
lower_tag, upper_tag)) {
// prune unreachable red-black alts
if (lfsr_tag_isred(p[0].alt)) {
alt = p[0].alt & ~LFSR_TAG_R;
weight = p[0].weight;
jump = p[0].jump;
lfsr_p_pop(p);
// prune unreachable root alts and red alts
} else if (!p[0].alt || lfsr_tag_isred(alt)) {
branch = branch_;
continue;
// convert unreachable non-root black alts into alt-nevers,
// if we prune these it would break the coloring of our tree
} else {
alt = LFSR_TAG_ALT(LFSR_TAG_LE, LFSR_TAG_B, 0);
weight = 0;
jump = 0;
}
}
// do bounds want to take different paths? begin diverging
if (!diverged
// eagerly diverge on lower trunk