summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-02-18 16:37:55 -0800
committerDavid S. Miller <davem@nuts.davemloft.net>2004-02-18 16:37:55 -0800
commite852f3182f3ea80239e1b46eecadf57604c39bd9 (patch)
treeb0c570edce79b6922ca958aae16de73b00bb1c81
parent56cf70578f93237aab62d02fd14071d998338e06 (diff)
[PATCH] Add CONFIG for -mregparm=3
From: Andi Kleen <ak@muc.de>, me. Using -mregparm=3 shrinks the kernel further: (compiled with gcc 3.4, without -funit-at-a-time, using the later and together with -Os shrinks .text even more, making over 700KB difference) 4129346 708629 207240 5045215 4cfbdf vmlinux 3892905 708629 207240 4808774 496046 vmlinux-regparm This one helps even more, >236KB .text difference. Clearly worth the effort. This patch adds an option to use -mregparm=3 while compiling the kernel. I did an LTP run and it showed no additional failures over an non regparm kernel. According to some gcc developers it should be safe to use in all gccs that are still supports (2.95 and up) I didn't make it the default because it will break all binary only modules (although they can be fixed by adding a wrapper that calls them with "asmlinkage"). Actually it may be a good idea to make this default with 2.7.1 or somesuch. We add new kbuild infrastructure: the command scripts/gcc-version.sh $(CC) will print out the version of gcc in a canonical 4-digit form suitable for performing numerical tests against. DESC arch/i386/Makefile,scripts/gcc-version.sh,Makefile small fixes EDESC From: Serge Belyshev <33554432@mtu-net.ru> arch/i386/Makefile: * omitted $(KBUILD_SRC)/ in script call. scripts/gcc-version.sh: * GNU tail no longer supports 'tail -1' syntax. We should consider adding -fweb option: vanilla: $ size vmlinux text data bss dec hex filename 3056270 526780 386056 3969106 3c9052 vmlinux with -fweb: $ size vmlinux text data bss dec hex filename 3049523 526780 386056 3962359 3c75f7 vmlinux Also note 0.1 ... 1.0% speedup in various benchmarks. This option is not enabled by default at -O2 because it (like -fomit-frame-pointer) makes debugging impossible.
-rw-r--r--arch/i386/Kconfig13
-rw-r--r--arch/i386/Makefile5
-rw-r--r--include/asm-i386/module.h8
-rw-r--r--scripts/gcc-version.sh14
4 files changed, 39 insertions, 1 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index e61cddb589f9..454ec7d88050 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -838,6 +838,19 @@ config BOOT_IOREMAP
depends on (((X86_SUMMIT || X86_GENERICARCH) && NUMA) || (X86 && EFI))
default y
+config REGPARM
+ bool "Use register arguments (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ default n
+ help
+ Compile the kernel with -mregparm=3. This uses an different ABI
+ and passes the first three arguments of a function call in registers.
+ This will probably break binary only modules.
+
+ This feature is only enabled for gcc-3.0 and later - earlier compilers
+ generate incorrect output with certain kernel constructs when
+ -mregparm=3 is used.
+
endmenu
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 335c566bb691..82c38e1acc4d 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -51,6 +51,11 @@ cflags-$(CONFIG_MVIAC3_2) += $(call check_gcc,-march=c3-2,-march=i686)
# AMD Elan support
cflags-$(CONFIG_X86_ELAN) += -march=i486
+# -mregparm=3 works ok on gcc-3.0 and later
+#
+GCC_VERSION := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC))
+cflags-$(CONFIG_REGPARM) += $(shell if [ $(GCC_VERSION) -ge 0300 ] ; then echo "-mregparm=3"; fi ;)
+
CFLAGS += $(cflags-y)
# Default subarch .c files
diff --git a/include/asm-i386/module.h b/include/asm-i386/module.h
index 14ea6eb3f298..d8aabc88fa43 100644
--- a/include/asm-i386/module.h
+++ b/include/asm-i386/module.h
@@ -54,6 +54,12 @@ struct mod_arch_specific
#error unknown processor family
#endif
-#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY
+#ifdef CONFIG_REGPARM
+#define MODULE_REGPARM "REGPARM "
+#else
+#define MODULE_REGPARM ""
+#endif
+
+#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM
#endif /* _ASM_I386_MODULE_H */
diff --git a/scripts/gcc-version.sh b/scripts/gcc-version.sh
new file mode 100644
index 000000000000..bb4fbeab8320
--- /dev/null
+++ b/scripts/gcc-version.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# gcc-version gcc-command
+#
+# Prints the gcc version of `gcc-command' in a canonical 4-digit form
+# such as `0295' for gcc-2.95, `0303' for gcc-3.3, etc.
+#
+
+compiler="$*"
+
+MAJOR=$(echo __GNUC__ | $compiler -E -xc - | tail -n 1)
+MINOR=$(echo __GNUC_MINOR__ | $compiler -E -xc - | tail -n 1)
+printf "%02d%02d\\n" $MAJOR $MINOR
+