On 1/24/25 6:23 PM, Jerome Forissier wrote:
On 1/24/25 17:23, Marek Vasut wrote:
On 1/24/25 4:57 PM, Jerome Forissier wrote:
On 1/24/25 11:35, Marek Vasut wrote:
On 1/24/25 10:10 AM, Jerome Forissier wrote:
+#define INITCALL(_call) \
+ do { \
+ if (_call()) { \
+ printf("%s(): initcall %s() failed\n", __func__, \
+ #_call); \
+ hang(); \
+ } \
+ } while (0)
Can this be turned into some static inline function too , so typechecking would
be retained ? Maybe the function can be passed in a function pointer to call ?
Doing the below totally kills the space gain (-160 bytes instead of -2281
on zynqmp_kria_defconfig, with LTO).
Does the compiler not inline the functions perhaps ?
It does. inline vs __always_inline makes no difference. The assembly
code is pretty difficult to understand in any case (macro or static
inline function). There are pieces of called functions all over the
place inside initcall_run_f() which is to be expected with LTO I
suppose.
And it prevents from printing the
function name in case of error, which is nicer than an address
(especially with relocation at play).
That function name can be passed in using __func__ as a parameter.
True. That being said, the type-checking argument does not seem
decisive here, and although I too prefer to use static inline
functions over macros when possible, it looks like we have no choice
in this case.
Can you try this kind of thing (might need some tweaking):
"
static void check_and_fail(int *ret) {
if (*ret) {
printf("failed\n");
hang();
}
}
static inline void INITCALL(int (*_call)(void))
{
int ret __attribute__((__cleanup__(check_and_fail))) = _call();
}
"
(maybe it really is the passing of pointer to _call() function into the
INITCALL() function which confuses gcc into not inlining this right, but
let's find out)