Adopted LFS_FORCEINLINE

May revisit this in the future, but this is the best solution I can
think of right now, that doesn't run into duplicate macro-argument
side-effect issues...

Statement expressions would be another solution, but that's even less
portable!

At the moment this is only used for functions that implement
LFSR_DATA_* and LFSR_RAT_* macros. These _need_ to be inlined to avoid a
large code-size explosion, and GCC seems to have issues with this.

For most of the other inlinable functions, relying on C99's inline +
compiler heuristics seems to be fine.

Code changes:

  before:          36304           2576          640
  no-forceinline:  36460 (+0.4%)   2664 (+3.4%)  640 (+0.0%)
  yes-forceinline: 36300 (-0.0%)   2576 (+0.0%)  640 (+0.0%)
This commit is contained in:
Christopher Haster
2025-02-05 01:08:19 -06:00
parent 4d02e5d646
commit b551569206
2 changed files with 21 additions and 9 deletions
+11 -9
View File
@@ -1663,8 +1663,10 @@ static inline lfs_size_t lfsr_data_size(lfsr_data_t data) {
}
// data slicing
// TODO what to do about this inlining situation?
__attribute__((always_inline))
#define LFSR_DATA_SLICE(_data, _off, _size) \
((struct {lfsr_data_t d;}){lfsr_data_fromslice(_data, _off, _size)}.d)
LFS_FORCEINLINE
static inline lfsr_data_t lfsr_data_fromslice(lfsr_data_t data,
lfs_ssize_t off, lfs_ssize_t size) {
// limit our off/size to data range, note the use of unsigned casts
@@ -1690,17 +1692,19 @@ static inline lfsr_data_t lfsr_data_fromslice(lfsr_data_t data,
return data;
}
#define LFSR_DATA_SLICE(_data, _off, _size) \
((struct {lfsr_data_t d;}){lfsr_data_fromslice(_data, _off, _size)}.d)
#define LFSR_DATA_TRUNCATE(_data, _size) \
((struct {lfsr_data_t d;}){lfsr_data_fromtruncate(_data, _size)}.d)
LFS_FORCEINLINE
static inline lfsr_data_t lfsr_data_fromtruncate(lfsr_data_t data,
lfs_size_t size) {
return LFSR_DATA_SLICE(data, -1, size);
}
#define LFSR_DATA_TRUNCATE(_data, _size) \
((struct {lfsr_data_t d;}){lfsr_data_fromtruncate(_data, _size)}.d)
#define LFSR_DATA_FRUNCATE(_data, _size) \
((struct {lfsr_data_t d;}){lfsr_data_fromfruncate(_data, _size)}.d)
LFS_FORCEINLINE
static inline lfsr_data_t lfsr_data_fromfruncate(lfsr_data_t data,
lfs_size_t size) {
return LFSR_DATA_SLICE(data,
@@ -1710,9 +1714,6 @@ static inline lfsr_data_t lfsr_data_fromfruncate(lfsr_data_t data,
-1);
}
#define LFSR_DATA_FRUNCATE(_data, _size) \
((struct {lfsr_data_t d;}){lfsr_data_fromfruncate(_data, _size)}.d)
// macros for le32/leb128/lleb128 encoding, these are useful for
// building rats
@@ -2023,6 +2024,7 @@ typedef struct lfsr_rat {
#define LFSR_RAT(_tag, _weight, _data) \
((struct {lfsr_rat_t a;}){lfsr_rat(_tag, _weight, _data)}.a)
LFS_FORCEINLINE
static inline lfsr_rat_t lfsr_rat(
lfsr_tag_t tag, lfsr_srid_t weight, lfsr_data_t data) {
// only simple data works here
+10
View File
@@ -229,6 +229,16 @@ extern "C"
#endif
// Some function attributes, no way around these
// Force a function to be inlined
#if !defined(LFS_NO_BUILTINS) && defined(__GNUC__)
#define LFS_FORCEINLINE __attribute__((always_inline))
#else
#define LFS_FORCEINLINE
#endif
// Builtin functions, these may be replaced by more efficient
// toolchain-specific implementations. LFS_NO_BUILTINS falls back to a more
// expensive basic C implementation for debugging purposes