Switched to passing lfsr_data_t by value again

Thanks to poor compound literal optimization, it's actually cheaper to
pass lfsr_data_t by value everywhere, than to make all LFSR_DATA_*
macros lvalues:

  before: 34340           2896
  after:  34292 (-0.1%)   2896 (+0.0%)

Why are these two design choices linked? If lfsr_data_t is
pass-by-address, the rvalue/lvalue disinction is important because we
need to take the address of LFSR_DATA_* macros. If lfsr_data_t is
pass-by-value, rvalue/lvalue doesn't really matter because we, well,
pass by value.

To be honest, this is a bit of an excuse for better lfsr_data_t
ergonomics. It _is_ generally worse code-size wise to pass lfsr_data_t
by value, because most ABI optimizations stop at 2 words and
lfsr_data_t requires 3 words. But always passing lfsr_data_t by value
even if it is suboptimal makes for more consistent internal interfaces.

This also helps side-step a mistake I made earlier where I though
cat/fromimm/fromleb128 were the only LFSR_DATA_* macros that needed to
be lvalues to be consistent. THERE ARE MANY MORE LFSR_DATA_* macros,
every LFSR_DATA_FROMBLAH macro to be specific, and the resulting code
cost would be MUCH WORSE.

---

This also add lfsr_sprout_t to complement lfsr_bptr_t/lfsr_shrub_t/etc.
Unlike lfsr_data_t, lfsr_sprout_t _is_ pass-by-address

Actually that's the only difference, haha. lfsr_sprout_t is a typedef.

Though to be fair, by being pass-by-addres, lfsr_sprout_t keeps the
internal sprout/shrub/bptr/btree inferfaces consistent, and saves a bit
of code.
This commit is contained in:
Christopher Haster
2024-02-24 00:20:49 -06:00
parent 94f7d2549f
commit 35a4934178
4 changed files with 703 additions and 713 deletions
+3 -1
View File
@@ -483,6 +483,8 @@ typedef struct lfs_file {
const struct lfs_file_config *cfg;
} lfs_file_t;
typedef lfsr_data_t lfsr_sprout_t;
typedef struct lfsr_bptr {
lfsr_data_t data;
lfs_size_t cksize;
@@ -510,7 +512,7 @@ typedef struct lfsr_bshrub {
//
union {
lfs_soff_t size;
lfsr_data_t bsprout;
lfsr_sprout_t bsprout;
lfsr_bptr_t bptr;
lfsr_shrub_t bshrub;
lfsr_btree_t btree;