Apparently GCC just really hates compound literals
I've been fiddling around with our LFSR_ATTR macro to try to understand
why making it an inline function costs so much, and it seems like it's
not actually the inline function, but the compound literal that is the
problem. Specifically, returning a compound literal from an inline
function results in surprisingly poor code/stack costs!
I don't really know why this happens. Compiler bug/oversight related to
lvalues/rvalues? Compound literals interfering with RVO? Unsure.
I tried a few other struct initializers just in case it was related to
constness, but it seems the problem is the compound literal:
Inlined comp-lit:
return (lfsr_attr_t){tag, delta, cat};
Inlined const comp-lit:
return (const lfsr_attr_t){tag, delta, cat};
Inlined no-init:
lfsr_attr_t attr;
attr.tag = tag;
attr.delta = delta;
attr.cat = cat;
return attr;
Inlined init:
lfsr_attr_t attr = {tag, delta, cat};
return attr;
Code/stack sizes:
code stack
macro (before): 33852 2776
inline comp-lit: 34140 (+0.9%) 2760 (-0.6%)
inline const comp-list: 34140 (+0.9%) 2760 (-0.6%)
inline no-init (after): 33812 (-0.1%) 2712 (-2.3%)
inline init: 33812 (-0.1%) 2712 (-2.3%)
The good news is this at least offers a route forward for crammed 15-bit
attrs.
I guess we should also go reasses other uses of compound literals in the
codebase...
This commit is contained in:
@@ -1577,7 +1577,17 @@ typedef struct lfsr_attr {
|
||||
} lfsr_attr_t;
|
||||
|
||||
#define LFSR_ATTR(_tag, _delta, _cat) \
|
||||
((lfsr_attr_t){_tag, _delta, _cat})
|
||||
lfsr_attr(_tag, _delta, _cat)
|
||||
|
||||
static inline lfsr_attr_t lfsr_attr(
|
||||
lfsr_tag_t tag, lfsr_srid_t delta, lfsr_cat_t cat) {
|
||||
// don't use a compound literal here, GCC hates it
|
||||
lfsr_attr_t attr;
|
||||
attr.tag = tag;
|
||||
attr.delta = delta;
|
||||
attr.cat = cat;
|
||||
return attr;
|
||||
}
|
||||
|
||||
#define LFSR_ATTR_NOOP() \
|
||||
LFSR_ATTR(LFSR_TAG_NULL, 0, LFSR_CAT_NULL())
|
||||
|
||||
Reference in New Issue
Block a user