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:
@@ -967,41 +967,6 @@ static inline void lfsr_tag_trim2(
|
|||||||
lower_tag, upper_tag);
|
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(
|
static inline bool lfsr_tag_unreachable(
|
||||||
lfsr_tag_t alt, lfsr_rid_t weight,
|
lfsr_tag_t alt, lfsr_rid_t weight,
|
||||||
lfsr_srid_t lower_rid, lfsr_srid_t upper_rid,
|
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
|
// take black alt? needs a flip
|
||||||
// <b >b
|
// <b >b
|
||||||
// .-'| => .-'|
|
// .-'| => .-'|
|
||||||
@@ -3067,6 +2982,51 @@ trunk:;
|
|||||||
lfs_swap32(&jump, &branch_);
|
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
|
// do bounds want to take different paths? begin diverging
|
||||||
if (!diverged
|
if (!diverged
|
||||||
// eagerly diverge on lower trunk
|
// eagerly diverge on lower trunk
|
||||||
|
|||||||
Reference in New Issue
Block a user