add a config option for -Os compilation
Subsystems (2)
PATCH 1/1 add a config option for -Os compilation
The patch below adds a config option OPTIMIZE_FOR_SIZE for telling gcc to use -Os instead of -O2. Besides this, it removes constructs on architectures that had a -Os hardcoded in their Makefiles.
It works for me, I'm currently running a 2.6.0-test5 compild with this option enabled and there are no obvious problems.
The last time I sent this to linux-kernel there were one positive and zero negative reactions.
diffstat output:
Makefile | 8 +++++++- arch/arm/Makefile | 2 -- arch/h8300/Makefile | 2 +- init/Kconfig | 9 +++++++++ 4 files changed, 17 insertions(+), 4 deletions(-)
Please apply
Adrian
init/Kconfig renamed from init/Kconfig.old +9 -0
@@ -65,6 +65,15 @@ menu "General setup" +config OPTIMIZE_FOR_SIZE + bool "Optimize for size" if EXPERIMENTAL + default n + help + Enabling this option will pass "-Os" instead of "-O2" to gcc + resulting in a smaller kernel. + + If unsure, say N. + config SWAP bool "Support for paging of anonymous memory" depends on MMU
Makefile renamed from Makefile.old +7 -1
@@ -223,7 +223,7 @@ NOSTDINC_FLAGS = -nostdinc -iwithprefix include CPPFLAGS := -D__KERNEL__ -Iinclude -CFLAGS := -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ +CFLAGS := -Wall -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common AFLAGS := -D__ASSEMBLY__
@@ -370,6 +370,12 @@ # --------------------------------------------------------------------------- +ifdef CONFIG_OPTIMIZE_FOR_SIZE +CFLAGS += -Os +else +CFLAGS += -O2 +endif + ifndef CONFIG_FRAME_POINTER CFLAGS += -fomit-frame-pointer endif
arch/arm/Makefile renamed from arch/arm/Makefile.old +0 -2
@@ -14,8 +14,6 @@ GZFLAGS :=-9 #CFLAGS +=-pipe -CFLAGS :=$(CFLAGS:-O2=-Os) - ifeq ($(CONFIG_FRAME_POINTER),y) CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog endif
arch/h8300/Makefile renamed from arch/h8300/Makefile.old +1 -1
@@ -34,7 +34,7 @@ ldflags-$(CONFIG_CPU_H8S) := -mh8300self CFLAGS += $(cflags-y) -CFLAGS += -mint32 -fno-builtin -Os +CFLAGS += -mint32 -fno-builtin CFLAGS += -g CFLAGS += -D__linux__ CFLAGS += -DUTS_SYSNAME=\"uClinux\"
Quoted 3 lines · Adrian Bunk
The patch below adds a config option
OPTIMIZE_FOR_SIZEfor telling gcc to use -Os instead of -O2. Besides this, it removes constructs on architectures that had a -Os hardcoded in their Makefiles.
I'd rather retain the -Os default for ARM please. (The init/Kconfig defaults it to 'n' for everything.)
Signature · 5 lines
Russell King ([email protected]) http://www.arm.linux.org.uk/personal/ Linux kernel maintainer of: 2.6 ARM Linux - http://www.arm.linux.org.uk/ 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/ 2.6 Serial core
Quoted 7 lines · Russell King
Quoted 3 lines · Adrian Bunk
The patch below adds a config option
OPTIMIZE_FOR_SIZEfor telling gcc to use -Os instead of -O2. Besides this, it removes constructs on architectures that had a -Os hardcoded in their Makefiles.I'd rather retain the -Os default for ARM please. (The init/Kconfig defaults it to 'n' for everything.)
Below is the patch with the ARM part omitted.
cu
Adrian
init/Kconfig renamed from init/Kconfig.old +9 -0
@@ -65,6 +65,15 @@ menu "General setup" +config OPTIMIZE_FOR_SIZE + bool "Optimize for size" if EXPERIMENTAL + default n + help + Enabling this option will pass "-Os" instead of "-O2" to gcc + resulting in a smaller kernel. + + If unsure, say N. + config SWAP bool "Support for paging of anonymous memory" depends on MMU
Makefile renamed from Makefile.old +7 -1
@@ -223,7 +223,7 @@ NOSTDINC_FLAGS = -nostdinc -iwithprefix include CPPFLAGS := -D__KERNEL__ -Iinclude -CFLAGS := -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ +CFLAGS := -Wall -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common AFLAGS := -D__ASSEMBLY__
@@ -370,6 +370,12 @@ # --------------------------------------------------------------------------- +ifdef CONFIG_OPTIMIZE_FOR_SIZE +CFLAGS += -Os +else +CFLAGS += -O2 +endif + ifndef CONFIG_FRAME_POINTER CFLAGS += -fomit-frame-pointer endif
arch/h8300/Makefile renamed from arch/h8300/Makefile.old +1 -1
@@ -34,7 +34,7 @@ ldflags-$(CONFIG_CPU_H8S) := -mh8300self CFLAGS += $(cflags-y) -CFLAGS += -mint32 -fno-builtin -Os +CFLAGS += -mint32 -fno-builtin CFLAGS += -g CFLAGS += -D__linux__ CFLAGS += -DUTS_SYSNAME=\"uClinux\"
Quoted 10 lines · Adrian Bunk
Quoted 7 lines · Russell King
Quoted 3 lines · Adrian Bunk
The patch below adds a config option
OPTIMIZE_FOR_SIZEfor telling gcc to use -Os instead of -O2. Besides this, it removes constructs on architectures that had a -Os hardcoded in their Makefiles.I'd rather retain the -Os default for ARM please. (The init/Kconfig defaults it to 'n' for everything.)
Below is the patch with the ARM part omitted.
But it doesn't make sense - you include a generic configuration option which people will see, yet it makes no effect on ARM - seems to be rather silly putting it there in the first place.
Also, do users particularly care what -Os and -O2 mean?
Maybe you need to change init/Kconfig to be something like the following, and reinstate the change to the ARM makefile:
config OPTIMIZE_FOR_SIZE
bool "Optimize for size" if EXPERIMENTAL
default n if !ARM
default y if ARM
help
Enabling this option will cause the compiler to reduce the code size of the kernel by disabling certain optimisations. However, the resulting kernel may run faster due to more efficient cache utilisation.
If unsure, say N.
Signature · 5 lines
Russell King ([email protected]) http://www.arm.linux.org.uk/personal/ Linux kernel maintainer of: 2.6 ARM Linux - http://www.arm.linux.org.uk/ 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/ 2.6 Serial core
Quoted 6 lines · Russell King
But it doesn't make sense - you include a generic configuration option which people will see, yet it makes no effect on ARM - seems to be rather silly putting it there in the first place.
Also, do users particularly care what -Os and -O2 mean?
The "If unsure, say N." should take care of it. People who really need small kernels usually know what -Os means.
Quoted 7 lines
Maybe you need to change init/Kconfig to be something like the following, and reinstate the change to the ARM makefile:
config
OPTIMIZE_FOR_SIZE
bool "Optimize for size" if EXPERIMENTAL
default n if !ARM
default y if ARM
That's a good idea.
The patch below does this for ARM and H8300.
Since there was no H8300 symbol, I added it to arch/h8300/Kconfig similar to the symbols on other architectures.
Quoted 6 lines
help
Enabling this option will cause the compiler to reduce the code size of the kernel by disabling certain optimisations. However, the resulting kernel may run faster due to more efficient cache utilisation.
...
I don't like this part, it would cause confusion. -O2 is more widely tested, and though if there might be small improvements on some CPUs with some compiler versions, it's untested whether -Os might cause worse performance of some fast path code in any area of the kernel. OPTIMIZE_FOR_SIZE should, although of low risk, be an "only use it if you know what you are doing" option.
diffstat output for the patch below:
Makefile | 8 +++++++- arch/arm/Makefile | 2 -- arch/h8300/Kconfig | 4 ++++ arch/h8300/Makefile | 2 +- init/Kconfig | 10 ++++++++++ 5 files changed, 22 insertions(+), 4 deletions(-)
cu
Adrian
init/Kconfig renamed from init/Kconfig.old +10 -0
@@ -65,6 +65,16 @@ menu "General setup" +config OPTIMIZE_FOR_SIZE + bool "Optimize for size" if EXPERIMENTAL + default y if ARM || H8300 + default n + help + Enabling this option will pass "-Os" instead of "-O2" to gcc + resulting in a smaller kernel. + + If unsure, say N. + config SWAP bool "Support for paging of anonymous memory" depends on MMU
Makefile renamed from Makefile.old +7 -1
@@ -274,7 +274,7 @@ CPPFLAGS := -D__KERNEL__ -Iinclude \ $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) -CFLAGS := -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ +CFLAGS := -Wall -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common AFLAGS := -D__ASSEMBLY__
@@ -421,6 +421,12 @@ # --------------------------------------------------------------------------- +ifdef CONFIG_OPTIMIZE_FOR_SIZE +CFLAGS += -Os +else +CFLAGS += -O2 +endif + ifndef CONFIG_FRAME_POINTER CFLAGS += -fomit-frame-pointer endif
arch/arm/Makefile renamed from arch/arm/Makefile.old +0 -2
@@ -14,8 +14,6 @@ GZFLAGS :=-9 #CFLAGS +=-pipe -CFLAGS :=$(CFLAGS:-O2=-Os) - ifeq ($(CONFIG_FRAME_POINTER),y) CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog endif
arch/h8300/Kconfig renamed from arch/h8300/Kconfig.old +4 -0
@@ -5,6 +5,10 @@ mainmenu "uClinux/h8300 (w/o MMU) Kernel Configuration" +config H8300 + bool + default y + config MMU bool default n
arch/h8300/Makefile renamed from arch/h8300/Makefile.old +1 -1
@@ -34,7 +34,7 @@ ldflags-$(CONFIG_CPU_H8S) := -mh8300self CFLAGS += $(cflags-y) -CFLAGS += -mint32 -fno-builtin -Os +CFLAGS += -mint32 -fno-builtin CFLAGS += -g CFLAGS += -D__linux__ CFLAGS += -DUTS_SYSNAME=\"uClinux\"
Quoted 6 lines · Adrian Bunk
init/Kconfig renamed from init/Kconfig.old +0
-0@@ -65,6 +65,16 @@ menu "General setup"
init/Kconfig line 77
Quoted 10 lines
init/Kconfig renamed from init/Kconfig.old +10
-0+config OPTIMIZE_FOR_SIZE + bool "Optimize for size" if EXPERIMENTAL + default y if ARM || H8300 + default n + help + Enabling this option will pass "-Os" instead of "-O2" to gcc + resulting in a smaller kernel. + + If unsure, say N. +
This is a general file, and it is wrong to include architecture specific knowledge here.
I recall that Roman Zippel introduced "enable" for exactly this purpose.
I looked into Documentation/kbuild/kconfig-language.txt but did not see it documented - Roman?
Another comment about the naming of the config symbol.
We keep getting more config symbols controlling options to GCC. A naming scheme like: CONFIG_CC_OPTIMIZE_FOR_SIZE, CONFIG_CC_DEBUG_INFO is preferable since it give better context information. Let's start with this option, and rename the others later.
Sam
Quoted 7 lines · Sam Ravnborg
Quoted 6 lines · Adrian Bunk
init/Kconfig renamed from init/Kconfig.old +0
-0@@ -65,6 +65,16 @@ menu "General setup"
Quoted 13 lines
init/Kconfig line 77
Quoted 10 lines
init/Kconfig renamed from init/Kconfig.old +10
-0+config OPTIMIZE_FOR_SIZE + bool "Optimize for size" if EXPERIMENTAL + default y if ARM || H8300 + default n + help + Enabling this option will pass "-Os" instead of "-O2" to gcc + resulting in a smaller kernel. + + If unsure, say N. +This is a general file, and it is wrong to include architecture specific knowledge here.
In which case we need to replicate the option in each of the per- architecture files. That seems a bit wasteful though.
I don't think "select" will hack it in this case though.
Signature · 4 lines
Russell King ([email protected]) http://www.arm.linux.org.uk/personal/ Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/ 2.6 Serial core
Quoted 7 lines · Sam Ravnborg
Quoted 6 lines · Adrian Bunk
init/Kconfig renamed from init/Kconfig.old +0
-0@@ -65,6 +65,16 @@ menu "General setup"
Quoted 15 lines
init/Kconfig line 77
Quoted 10 lines
init/Kconfig renamed from init/Kconfig.old +10
-0+config OPTIMIZE_FOR_SIZE + bool "Optimize for size" if EXPERIMENTAL + default y if ARM || H8300 + default n + help + Enabling this option will pass "-Os" instead of "-O2" to gcc + resulting in a smaller kernel. + + If unsure, say N. +This is a general file, and it is wrong to include architecture specific knowledge here.
I recall that Roman Zippel introduced "enable" for exactly this purpose.
...
I can't see how this would help in this situation, we need a default, not a dependency (OPTIMIZE_FOR_SIZE=n should be possible on ARM).
It's not the only option that sets defaults depending on the architecture and I can't see why it should be a bad thing.
Quoted 5 lines
Another comment about the naming of the config symbol.
We keep getting more config symbols controlling options to GCC. A naming scheme like:CONFIG_CC_OPTIMIZE_FOR_SIZE,CONFIG_CC_DEBUG_INFOis preferable since it give better context information. Let's start with this option, and rename the others later.
Below is the patch with CONFIG_CC_OPTIMIZE_FOR_SIZE.
Quoted 1 line
Sam
cu
Adrian
init/Kconfig renamed from init/Kconfig.old +10 -0
@@ -65,6 +65,16 @@ menu "General setup" +config CC_OPTIMIZE_FOR_SIZE + bool "Optimize for size" if EXPERIMENTAL + default y if ARM || H8300 + default n + help + Enabling this option will pass "-Os" instead of "-O2" to gcc + resulting in a smaller kernel. + + If unsure, say N. + config SWAP bool "Support for paging of anonymous memory" depends on MMU
Makefile renamed from Makefile.old +7 -1
@@ -274,7 +274,7 @@ CPPFLAGS := -D__KERNEL__ -Iinclude \ $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) -CFLAGS := -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ +CFLAGS := -Wall -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common AFLAGS := -D__ASSEMBLY__
@@ -421,6 +421,12 @@ # --------------------------------------------------------------------------- +ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE +CFLAGS += -Os +else +CFLAGS += -O2 +endif + ifndef CONFIG_FRAME_POINTER CFLAGS += -fomit-frame-pointer endif
arch/arm/Makefile renamed from arch/arm/Makefile.old +0 -2
@@ -14,8 +14,6 @@ GZFLAGS :=-9 #CFLAGS +=-pipe -CFLAGS :=$(CFLAGS:-O2=-Os) - ifeq ($(CONFIG_FRAME_POINTER),y) CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog endif
arch/h8300/Kconfig renamed from arch/h8300/Kconfig.old +4 -0
@@ -5,6 +5,10 @@ mainmenu "uClinux/h8300 (w/o MMU) Kernel Configuration" +config H8300 + bool + default y + config MMU bool default n
arch/h8300/Makefile renamed from arch/h8300/Makefile.old +1 -1
@@ -34,7 +34,7 @@ ldflags-$(CONFIG_CPU_H8S) := -mh8300self CFLAGS += $(cflags-y) -CFLAGS += -mint32 -fno-builtin -Os +CFLAGS += -mint32 -fno-builtin CFLAGS += -g CFLAGS += -D__linux__ CFLAGS += -DUTS_SYSNAME=\"uClinux\"
Quoted 1 line · Adrian Bunk
The patch below adds a config option
OPTIMIZE_FOR_SIZEfor telling gcc to use -Os instead of -O2. Besides this, it removes constructs on architectures that had a -Os hardcoded in their Makefiles.
Someone told me that -Os is actually faster than -O2 for Athlons, is that true?
Quoted 7 lines · Wade
Quoted 3 lines · Adrian Bunk
The patch below adds a config option
OPTIMIZE_FOR_SIZEfor telling gcc to use -Os instead of -O2. Besides this, it removes constructs on architectures that had a -Os hardcoded in their Makefiles.Someone told me that -Os is actually faster than -O2 for Athlons, is that true?
On gcc 2.95 -Os was faster for most stuff. I would intuitively expect the best result to be a mix varied by function but I don't think gcc has the support to do that.
I've also not benched gcc 3.2 -Os v -O2 at real workloads - thats a nice little project for someone.
--Alan Cox <[email protected]> wrote (on Sunday, September 14, 2003 15:57:49 +0100):
Quoted 9 lines · Wade
Quoted 7 lines
Quoted 3 lines · Adrian Bunk
The patch below adds a config option
OPTIMIZE_FOR_SIZEfor telling gcc to use -Os instead of -O2. Besides this, it removes constructs on architectures that had a -Os hardcoded in their Makefiles.Someone told me that -Os is actually faster than -O2 for Athlons, is that true?
Quoted 6 lines
On gcc 2.95 -Os was faster for most stuff. I would intuitively expect the best result to be a mix varied by function but I don't think gcc has the support to do that.
I've also not benched gcc 3.2 -Os v -O2 at real workloads - thats a nice little project for someone.
I think it depends heavily on the chip - I tried 2.95 and 3.3. For me, -Os was slower for both, but I have a 2MB L2 cache. If you have a 128K celeron or something, I'm sure it'd be faster.
M.