From: Ingo Molnar Date: Mon, 3 Mar 2008 11:38:52 +0000 (+0100) Subject: x86: add optimized inlining X-Git-Tag: v2.6.26-rc1~1043^2~1 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=60a3cdd0639473c79c253bc08c8ef8f882cca107;p=linux-2.6 x86: add optimized inlining add CONFIG_OPTIMIZE_INLINING=y. allow gcc to optimize the kernel image's size by uninlining functions that have been marked 'inline'. Previously gcc was forced by Linux to always-inline these functions via a gcc attribute: #define inline inline __attribute__((always_inline)) Especially when the user has already selected CONFIG_OPTIMIZE_FOR_SIZE=y this can make a huge difference in kernel image size (using a standard Fedora .config): text data bss dec hex filename 5613924 562708 3854336 10030968 990f78 vmlinux.before 5486689 562708 3854336 9903733 971e75 vmlinux.after that's a 2.3% text size reduction (!). Signed-off-by: Ingo Molnar --- diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 239fd9fba0..5b1979a45a 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -257,3 +257,16 @@ config CPA_DEBUG Do change_page_attr() self-tests every 30 seconds. endmenu + +config OPTIMIZE_INLINING + bool "Allow gcc to uninline functions marked 'inline'" + default y + help + This option determines if the kernel forces gcc to inline the functions + developers have marked 'inline'. Doing so takes away freedom from gcc to + do what it thinks is best, which is desirable for the gcc 3.x series of + compilers. The gcc 4.x series have a rewritten inlining algorithm and + disabling this option will generate a smaller kernel there. Hopefully + this algorithm is so good that allowing gcc4 to make the decision can + become the default in the future, until then this option is there to + test gcc for this. diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index 3df340b54e..ad7ddaaff5 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig @@ -1421,6 +1421,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_FRAME_POINTER is not set +CONFIG_OPTIMIZE_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index eef98cb00c..2d6f5b2809 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -1346,6 +1346,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_FRAME_POINTER is not set +CONFIG_OPTIMIZE_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index fe23792f05..340bc5d927 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -28,9 +28,15 @@ #define __must_be_array(a) \ BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0]))) -#define inline inline __attribute__((always_inline)) -#define __inline__ __inline__ __attribute__((always_inline)) -#define __inline __inline __attribute__((always_inline)) +/* + * Force always-inline if the user requests it so via the .config: + */ +#if !defined(CONFIG_OPTIMIZE_INLINING) && (__GNUC__ >= 4) +# define inline inline __attribute__((always_inline)) +# define __inline__ __inline__ __attribute__((always_inline)) +# define __inline __inline __attribute__((always_inline)) +#endif + #define __deprecated __attribute__((deprecated)) #define __packed __attribute__((packed)) #define __weak __attribute__((weak))