From 8aebb37b51f16dc3c6c92e62c15a4be3f80b76a0 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 9 May 2024 13:16:47 -0500 Subject: [PATCH] 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... --- lfs.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lfs.c b/lfs.c index b73138f3..81366945 100644 --- a/lfs.c +++ b/lfs.c @@ -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())