From 216881ede374ce2392579f39ac686c365a108255 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Fri, 10 May 2024 18:16:16 -0500 Subject: [PATCH] Changed all LFSR_DATA/ATTR macros to create lvalues I think what may be going on with the unexpected stack cost related to struct passing, is something to do with scoping and how it interacts with function inlining + shrink wrapping. Compound-literals have a scope limited by the current statement, and while temporary structs _should_ have a scope limited to the current expressions, maybe this scope is getting messed up due to function inlining? Still smells like a compiler bug, but if this is true, wrapping the struct-generating function calls with compound-literals should be more robust at preventing unexpected stack increases in the future. As a plus, this makes all LFSR_DATA/ATTR macros lvalues, which is nice for consistency. --- Unfortunately, it does seem like GCC 11 is not able to elide moving compound-literals all that well. Repeatedly nesting trivial compound-literals results in a measurable increase in code cost, even though it should theoretically be a noop with optimizations. This results in an unfortunate code size increase: code stack before: 33780 2640 after: 33868 (+0.3%) 2640 (+0.0%) But at some point you have to give up trying to work around insufficiencies in the compiler. I'll take 100 bytes of code over 100 bytes of stack any day. --- lfs.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lfs.c b/lfs.c index 087881c3..35522594 100644 --- a/lfs.c +++ b/lfs.c @@ -1415,7 +1415,7 @@ static int lfsr_bd_progdata(lfs_t *lfs, #define LFSR_LEB128_DSIZE 5 #define LFSR_DATA_LEB128_(_word, _buffer) \ - lfsr_data_fromleb128(_word, _buffer) + (*(lfsr_data_t[1]){lfsr_data_fromleb128(_word, _buffer)}) #define LFSR_DATA_LEB128(_word) \ LFSR_DATA_LEB128_(_word, (uint8_t[LFSR_LEB128_DSIZE]){0}) @@ -1433,7 +1433,7 @@ static inline lfsr_data_t lfsr_data_fromleb128(uint32_t word, #define LFSR_LLEB128_DSIZE 4 #define LFSR_DATA_LLEB128_(_word, _buffer) \ - lfsr_data_fromlleb128(_word, _buffer) + (*(lfsr_data_t[1]){lfsr_data_fromlleb128(_word, _buffer)}) #define LFSR_DATA_LLEB128(_word) \ LFSR_DATA_LLEB128_(_word, (uint8_t[LFSR_LLEB128_DSIZE]){0}) @@ -1472,7 +1472,7 @@ typedef struct lfsr_attr { .cat=_cat}) #define LFSR_ATTR(_tag, _delta, _data) \ - lfsr_attr(_tag, _delta, *(lfsr_data_t[1]){_data}) + (*(lfsr_attr_t[1]){lfsr_attr(_tag, _delta, _data)}) static inline lfsr_attr_t lfsr_attr( lfsr_tag_t tag, lfsr_srid_t delta, lfsr_data_t data) { @@ -1776,7 +1776,7 @@ typedef struct lfsr_ecksum { #define LFSR_ECKSUM_DSIZE (4+4) #define LFSR_DATA_ECKSUM_(_ecksum, _buffer) \ - lfsr_data_fromecksum(_ecksum, _buffer) + (*(lfsr_data_t[1]){lfsr_data_fromecksum(_ecksum, _buffer)}) #define LFSR_DATA_ECKSUM(_ecksum) \ LFSR_DATA_ECKSUM_(_ecksum, (uint8_t[LFSR_ECKSUM_DSIZE]){0}) @@ -1833,7 +1833,7 @@ static int lfsr_data_readecksum(lfs_t *lfs, lfsr_data_t *data, #define LFSR_BPTR_DSIZE (4+5+4+4+4) #define LFSR_DATA_BPTR_(_bptr, _buffer) \ - lfsr_data_frombptr(_bptr, _buffer) + (*(lfsr_data_t[1]){lfsr_data_frombptr(_bptr, _buffer)}) #define LFSR_DATA_BPTR(_bptr) \ LFSR_DATA_BPTR_(_bptr, (uint8_t[LFSR_BPTR_DSIZE]){0}) @@ -2045,7 +2045,7 @@ static inline bool lfsr_grm_isrm(const lfsr_grm_t *grm, lfsr_smid_t mid) { } #define LFSR_DATA_GRM_(_grm, _buffer) \ - lfsr_data_fromgrm(_grm, _buffer) + (*(lfsr_data_t[1]){lfsr_data_fromgrm(_grm, _buffer)}) #define LFSR_DATA_GRM(_grm) \ LFSR_DATA_GRM_(_grm, (uint8_t[LFSR_GRM_DSIZE]){0}) @@ -4120,7 +4120,7 @@ static inline int lfsr_btree_cmp( #define LFSR_BRANCH_DSIZE (5+4+4) #define LFSR_DATA_BRANCH_(_branch, _buffer) \ - lfsr_data_frombranch(_branch, _buffer) + (*(lfsr_data_t[1]){lfsr_data_frombranch(_branch, _buffer)}) #define LFSR_DATA_BRANCH(_branch) \ LFSR_DATA_BRANCH_(_branch, (uint8_t[LFSR_BRANCH_DSIZE]){0}) @@ -4193,7 +4193,7 @@ static int lfsr_data_readbranch(lfs_t *lfs, lfsr_data_t *data, #define LFSR_BTREE_DSIZE (5+LFSR_BRANCH_DSIZE) #define LFSR_DATA_BTREE_(_btree, _buffer) \ - lfsr_data_frombtree(_btree, _buffer) + (*(lfsr_data_t[1]){lfsr_data_frombtree(_btree, _buffer)}) #define LFSR_DATA_BTREE(_btree) \ LFSR_DATA_BTREE_(_btree, (uint8_t[LFSR_BTREE_DSIZE]){0}) @@ -5264,7 +5264,7 @@ static inline int lfsr_shrub_cmp( #define LFSR_SHRUB_DSIZE (5+4) #define LFSR_DATA_SHRUB_(_rbyd, _buffer) \ - lfsr_data_fromshrub(_rbyd, _buffer) + (*(lfsr_data_t[1]){lfsr_data_fromshrub(_rbyd, _buffer)}) #define LFSR_DATA_SHRUB(_rbyd) \ LFSR_DATA_SHRUB_(_rbyd, (uint8_t[LFSR_SHRUB_DSIZE]){0}) @@ -5469,7 +5469,7 @@ static inline bool lfsr_mptr_ismrootanchor(const lfsr_mptr_t *mptr) { #define LFSR_MPTR_DSIZE (5+5) #define LFSR_DATA_MPTR_(_mptr, _buffer) \ - lfsr_data_frommptr(_mptr, _buffer) + (*(lfsr_data_t[1]){lfsr_data_frommptr(_mptr, _buffer)}) #define LFSR_DATA_MPTR(_mptr) \ LFSR_DATA_MPTR_(_mptr, (uint8_t[LFSR_MPTR_DSIZE]){0}) @@ -8064,7 +8064,7 @@ typedef struct lfsr_geometry { #define LFSR_GEOMETRY_DSIZE (4+5) #define LFSR_DATA_GEOMETRY_(_geometry, _buffer) \ - lfsr_data_fromgeometry(_geometry, _buffer) + (*(lfsr_data_t[1]){lfsr_data_fromgeometry(_geometry, _buffer)}) #define LFSR_DATA_GEOMETRY(_geometry) \ LFSR_DATA_GEOMETRY_(_geometry, (uint8_t[LFSR_GEOMETRY_DSIZE]){0})