diff mbox series

[v2,1/2] kconfig.h: Add IF_ENABLED() macro

Message ID 20201213235447.138271-1-paul@crapouillou.net
State New
Headers show
Series [v2,1/2] kconfig.h: Add IF_ENABLED() macro | expand

Commit Message

Paul Cercueil Dec. 13, 2020, 11:54 p.m. UTC
IF_ENABLED(CONFIG_FOO, ptr) evaluates to (ptr) if CONFIG_FOO is set to 'y'
or 'm', NULL otherwise. The (ptr) argument must be a pointer.

The IF_ENABLED() macro can be very useful to help GCC drop dead code.

For instance, consider the following:

    #ifdef CONFIG_FOO_SUSPEND
    static int foo_suspend(struct device *dev)
    {
       ...
    }
    #endif

    static struct pm_ops foo_ops = {
	#ifdef CONFIG_FOO_SUSPEND
        .suspend = foo_suspend,
	#endif
    };

While this works, the foo_suspend() macro is compiled conditionally,
only when CONFIG_FOO_SUSPEND is set. This is problematic, as there could
be a build bug in this function, we wouldn't have a way to know unless
the config option is set.

An alternative is to declare foo_suspend() always, but mark it as maybe
unused:

    static int __maybe_unused foo_suspend(struct device *dev)
    {
       ...
    }

    static struct pm_ops foo_ops = {
	#ifdef CONFIG_FOO_SUSPEND
        .suspend = foo_suspend,
	#endif
    };

Again, this works, but the __maybe_unused attribute is required to
instruct the compiler that the function may not be referenced anywhere,
and is safe to remove without making a fuss about it. This makes the
programmer responsible for tagging the functions that can be
garbage-collected.

With this patch, it is now possible to write the following:

    static int foo_suspend(struct device *dev)
    {
       ...
    }

    static struct pm_ops foo_ops = {
        .suspend = IF_ENABLED(CONFIG_FOO_SUSPEND, foo_suspend),
    };

The foo_suspend() function will now be automatically dropped by the
compiler, and it does not require any specific attribute.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---

Notes:
    v2: Only add IF_ENABLED() and don't verify that the argument is a
        pointer; since the second argument of the ?: ternary operator
    	is NULL, the compiler should issue an error if the other
    	argument is not a pointer.

 include/linux/kconfig.h | 6 ++++++
 1 file changed, 6 insertions(+)

Comments

Linus Walleij Dec. 14, 2020, 9:05 a.m. UTC | #1
On Mon, Dec 14, 2020 at 12:54 AM Paul Cercueil <paul@crapouillou.net> wrote:

> IF_ENABLED(CONFIG_FOO, ptr) evaluates to (ptr) if CONFIG_FOO is set to 'y'
> or 'm', NULL otherwise. The (ptr) argument must be a pointer.
>
> The IF_ENABLED() macro can be very useful to help GCC drop dead code.

I can apply this with the other patch to the pinctrl subsystem if Arnd or
someone else who is good at KConfig provides an ACK.

Yours,
Linus Walleij
Paul Cercueil Jan. 11, 2021, 8:45 a.m. UTC | #2
Hi,

Le lun. 14 déc. 2020 à 10:05, Linus Walleij 
<linus.walleij@linaro.org> a écrit :
> On Mon, Dec 14, 2020 at 12:54 AM Paul Cercueil <paul@crapouillou.net> 
> wrote:
> 
>>  IF_ENABLED(CONFIG_FOO, ptr) evaluates to (ptr) if CONFIG_FOO is set 
>> to 'y'
>>  or 'm', NULL otherwise. The (ptr) argument must be a pointer.
>> 
>>  The IF_ENABLED() macro can be very useful to help GCC drop dead 
>> code.
> 
> I can apply this with the other patch to the pinctrl subsystem if 
> Arnd or
> someone else who is good at KConfig provides an ACK.

Arnd? Any feedback?

Cheers,
-Paul
Arnd Bergmann Jan. 15, 2021, 11:47 a.m. UTC | #3
On Mon, Jan 11, 2021 at 9:45 AM Paul Cercueil <paul@crapouillou.net> wrote:
>
> Hi,
>
> Le lun. 14 déc. 2020 à 10:05, Linus Walleij
> <linus.walleij@linaro.org> a écrit :
> > On Mon, Dec 14, 2020 at 12:54 AM Paul Cercueil <paul@crapouillou.net>
> > wrote:
> >
> >>  IF_ENABLED(CONFIG_FOO, ptr) evaluates to (ptr) if CONFIG_FOO is set
> >> to 'y'
> >>  or 'm', NULL otherwise. The (ptr) argument must be a pointer.
> >>
> >>  The IF_ENABLED() macro can be very useful to help GCC drop dead
> >> code.

Looks great! Thanks a lot for getting this sorted.

> > I can apply this with the other patch to the pinctrl subsystem if
> > Arnd or someone else who is good at KConfig provides an ACK.

Yes, please do.

Acked-by: Arnd Bergmann <arnd@arndb.de>
Linus Walleij Jan. 18, 2021, 3:14 p.m. UTC | #4
Both patches applied!

Yours,
Linus Walleij
diff mbox series

Patch

diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h
index 9d12c970f18f..e78e17a76dc9 100644
--- a/include/linux/kconfig.h
+++ b/include/linux/kconfig.h
@@ -72,4 +72,10 @@ 
  */
 #define IS_ENABLED(option) __or(IS_BUILTIN(option), IS_MODULE(option))
 
+/*
+ * IF_ENABLED(CONFIG_FOO, ptr) evaluates to (ptr) if CONFIG_FOO is set to 'y'
+ * or 'm', NULL otherwise.
+ */
+#define IF_ENABLED(option, ptr) (IS_ENABLED(option) ? (ptr) : NULL)
+
 #endif /* __LINUX_KCONFIG_H */