Added LFSR_TAG_DIVERGEDDONE instead of reusing LFSR_TAG_RM in appendattr
I think this is a bit more readable.
Curiously, the bit flip and bit change resulted in a surprising code
cost, even though it removes a couple statements. I guess because the
sign bit is that much cheaper to predicate on?
code stack
before: 33980 2880
after: 34024 (+0.1%) 2880 (+0.0%)
This commit is contained in:
@@ -786,6 +786,7 @@ enum lfsr_tag {
|
|||||||
LFSR_TAG_DIVERGED = 0x4000,
|
LFSR_TAG_DIVERGED = 0x4000,
|
||||||
LFSR_TAG_DIVERGEDUPPER = 0x2000,
|
LFSR_TAG_DIVERGEDUPPER = 0x2000,
|
||||||
LFSR_TAG_DIVERGEDLOWER = 0x0000,
|
LFSR_TAG_DIVERGEDLOWER = 0x0000,
|
||||||
|
LFSR_TAG_DIVERGEDDONE = 0x1000,
|
||||||
};
|
};
|
||||||
|
|
||||||
// some other tag encodings with their own subfields
|
// some other tag encodings with their own subfields
|
||||||
@@ -875,6 +876,10 @@ static inline bool lfsr_tag_isdivergedlower(lfsr_tag_t tag) {
|
|||||||
return !(tag & LFSR_TAG_DIVERGEDUPPER);
|
return !(tag & LFSR_TAG_DIVERGEDUPPER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool lfsr_tag_isdivergeddone(lfsr_tag_t tag) {
|
||||||
|
return tag & LFSR_TAG_DIVERGEDDONE;
|
||||||
|
}
|
||||||
|
|
||||||
// alt operations
|
// alt operations
|
||||||
static inline bool lfsr_tag_isblack(lfsr_tag_t tag) {
|
static inline bool lfsr_tag_isblack(lfsr_tag_t tag) {
|
||||||
return !(tag & LFSR_TAG_R);
|
return !(tag & LFSR_TAG_R);
|
||||||
@@ -2732,9 +2737,6 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
other_tag_ = tag_;
|
other_tag_ = tag_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// mark as rmed until found
|
|
||||||
tag_ |= LFSR_TAG_RM;
|
|
||||||
other_tag_ |= LFSR_TAG_RM;
|
|
||||||
|
|
||||||
// keep track of bounds as we descend down the tree
|
// keep track of bounds as we descend down the tree
|
||||||
//
|
//
|
||||||
@@ -3021,15 +3023,15 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
|
|
||||||
// found end of tree?
|
// found end of tree?
|
||||||
} else {
|
} else {
|
||||||
// update the found tag/rid
|
// update the found tag/rid, marking as done while preserving
|
||||||
//
|
// any diverged state
|
||||||
// note we:
|
tag_ = LFSR_TAG_DIVERGEDDONE
|
||||||
// - clear valid bit, marking the tag as found
|
| lfsr_tag_mode(tag_)
|
||||||
// - preserve diverged state
|
| alt;
|
||||||
tag_ = lfsr_tag_mode(tag_ & ~LFSR_TAG_RM) | alt;
|
|
||||||
|
|
||||||
// done?
|
// done?
|
||||||
if (!lfsr_tag_hasdiverged(tag_) || !lfsr_tag_isrm(other_tag_)) {
|
if (!lfsr_tag_hasdiverged(tag_)
|
||||||
|
|| lfsr_tag_isdivergeddone(other_tag_)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3051,8 +3053,9 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
LFS_ASSERT(lfsr_tag_isblack(p_alts[0]));
|
LFS_ASSERT(lfsr_tag_isblack(p_alts[0]));
|
||||||
|
|
||||||
// if we diverged, merge the bounds
|
// if we diverged, merge the bounds
|
||||||
LFS_ASSERT(!lfsr_tag_isrm(tag_));
|
LFS_ASSERT(lfsr_tag_isdivergeddone(tag_));
|
||||||
LFS_ASSERT(!lfsr_tag_hasdiverged(tag_) || !lfsr_tag_isrm(other_tag_));
|
LFS_ASSERT(!lfsr_tag_hasdiverged(tag_)
|
||||||
|
|| lfsr_tag_isdivergeddone(other_tag_));
|
||||||
if (lfsr_tag_hasdiverged(tag_)) {
|
if (lfsr_tag_hasdiverged(tag_)) {
|
||||||
if (lfsr_tag_isdivergedlower(tag_)) {
|
if (lfsr_tag_isdivergedlower(tag_)) {
|
||||||
// finished on lower path
|
// finished on lower path
|
||||||
|
|||||||
Reference in New Issue
Block a user