[PATCH 2/4] Core support for --combine -fwhole-program

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds a config option for COMBINE_COMPILE, adds the __global
tag to compiler.h and makes EXPORT_SYMBOL automatically use it. It also
contains a crappy Makefile hack which uses -fwhole-program --combine for
all multi-obj .o files -- anything which was 
	obj-m := foo.o
	foo-objs := bar.o wibble.o 
... should now use gcc -o foo.o --combine -fwhole-program bar.c wibble.c

The makefile hack is known not to work properly for generated C files in
out-of-source-tree builds, and for multi-obj files where one of the
sources is _assembly_ instead of C. It's good enough for the proof of
concept, until someone more clueful can do it properly though. It would
be useful to make built-in.o build with --combine from _everything_
which uses standard CFLAGS, rather than doing just what I've done here.

For example only; do not apply as-is. 

diff --git a/include/asm-i386/linkage.h b/include/asm-i386/linkage.h
index f4a6eba..8b06e3e 100644
--- a/include/asm-i386/linkage.h
+++ b/include/asm-i386/linkage.h
@@ -1,7 +1,7 @@
 #ifndef __ASM_LINKAGE_H
 #define __ASM_LINKAGE_H
 
-#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
+#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) __global
 #define FASTCALL(x)	x __attribute__((regparm(3)))
 #define fastcall	__attribute__((regparm(3)))
 
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 9b4f110..ed4cf0c 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -156,4 +156,10 @@ #ifndef __attribute_const__
 # define __attribute_const__	/* unimplemented */
 #endif
 
+#ifdef CONFIG_COMBINED_COMPILE
+#define __global __attribute__((externally_visible,used))
+#else
+#define __global
+#endif
+
 #endif /* __LINUX_COMPILER_H */
diff --git a/include/linux/linkage.h b/include/linux/linkage.h
index 932021f..d78eec9 100644
--- a/include/linux/linkage.h
+++ b/include/linux/linkage.h
@@ -10,7 +10,7 @@ #define CPP_ASMLINKAGE
 #endif
 
 #ifndef asmlinkage
-#define asmlinkage CPP_ASMLINKAGE
+#define asmlinkage __global CPP_ASMLINKAGE
 #endif
 
 #ifndef prevent_tail_call
diff --git a/include/linux/module.h b/include/linux/module.h
index 0dfb794..725e5df 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -175,7 +175,7 @@ #ifdef CONFIG_MODVERSIONS
 #define __CRC_SYMBOL(sym, sec)					\
 	extern void *__crc_##sym __attribute__((weak));		\
 	static const unsigned long __kcrctab_##sym		\
-	__attribute_used__					\
+	__attribute_used__ __global				\
 	__attribute__((section("__kcrctab" sec), unused))	\
 	= (unsigned long) &__crc_##sym;
 #else
@@ -184,13 +184,15 @@ #endif
 
 /* For every exported symbol, place a struct in the __ksymtab section */
 #define __EXPORT_SYMBOL(sym, sec)				\
-	extern typeof(sym) sym;					\
+	extern typeof(sym) sym __global;		\
 	__CRC_SYMBOL(sym, sec)					\
 	static const char __kstrtab_##sym[]			\
+	asm("__kstrtab_" #sym)					\
 	__attribute__((section("__ksymtab_strings")))		\
 	= MODULE_SYMBOL_PREFIX #sym;                    	\
 	static const struct kernel_symbol __ksymtab_##sym	\
-	__attribute_used__					\
+	asm("__ksymtab_" #sym)					\
+	__attribute_used__ __global				\
 	__attribute__((section("__ksymtab" sec), unused))	\
 	= { (unsigned long)&sym, __kstrtab_##sym }
 
@@ -208,8 +210,8 @@ #ifdef CONFIG_UNUSED_SYMBOLS
 #define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused")
 #define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl")
 #else
-#define EXPORT_UNUSED_SYMBOL(sym)
-#define EXPORT_UNUSED_SYMBOL_GPL(sym)
+#define EXPORT_UNUSED_SYMBOL(sym) extern typeof(sym) sym  __global
+#define EXPORT_UNUSED_SYMBOL_GPL(sym) extern typeof(sym) sym  __global
 #endif
 
 #endif
@@ -470,11 +472,12 @@ void module_add_driver(struct module *, 
 void module_remove_driver(struct device_driver *);
 
 #else /* !CONFIG_MODULES... */
-#define EXPORT_SYMBOL(sym)
-#define EXPORT_SYMBOL_GPL(sym)
-#define EXPORT_SYMBOL_GPL_FUTURE(sym)
-#define EXPORT_UNUSED_SYMBOL(sym)
-#define EXPORT_UNUSED_SYMBOL_GPL(sym)
+
+#define EXPORT_SYMBOL(sym) extern typeof(sym) sym __global
+#define EXPORT_SYMBOL_GPL(sym) EXPORT_SYMBOL(sym)
+#define EXPORT_SYMBOL_GPL_FUTURE(sym) EXPORT_SYMBOL(sym)
+#define EXPORT_UNUSED_SYMBOL(sym) EXPORT_SYMBOL(sym)
+#define EXPORT_UNUSED_SYMBOL_GPL(sym) EXPORT_SYMBOL(sym)
 
 /* Given an address, look for it in the exception tables. */
 static inline const struct exception_table_entry *
diff --git a/init/Kconfig b/init/Kconfig
index a099fc6..b19cfd1 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -468,6 +468,16 @@ config MODULE_FORCE_UNLOAD
 	  rmmod).  This is mainly for kernel developers and desperate users.
 	  If unsure, say N.
 
+config COMBINED_COMPILE
+        bool "Compile multiple source files at once"
+	help
+	  GCC can perform optimisation between different C files by
+	  using its '--combine' option to compile them all at once. By
+	  also adding the '-fwhole-program' option to make global symbols
+	  static, further optimisations are made possible. Say N unless you
+	  have a version of GCC in which at least PR27898, PR28706, PR28712,
+	  PR28744 and PR28779 are fixed.
+	
 config MODVERSIONS
 	bool "Module versioning support"
 	depends on MODULES
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 3cb445c..2f2075d 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -128,6 +128,12 @@ modname = $(basetarget)
 $(multi-objs-y:.o=.s)   : modname = $(modname-multi)
 $(multi-objs-y:.o=.lst) : modname = $(modname-multi)
 
+ifdef CONFIG_COMBINED_COMPILE
+$(multi-used-m)		: modkern_cflags += $(CFLAGS_MODULE) -fwhole-program --combine $(sort $(addprefix $(srctree)/$(obj)/,$($(subst $(obj)/,,$(@:.o=-y)):.o=.c) $($(subst $(obj)/,,$(@:.o=-objs)):.o=.c)))
+
+$(multi-used-y)		: CFLAGS += -fwhole-program --combine $(sort $(addprefix $(srctree)/$(obj)/,$($(subst $(obj)/,,$(@:.o=-y)):.o=.c) $($(subst $(obj)/,,$(@:.o=-objs)):.o=.c)))
+endif
+
 quiet_cmd_cc_s_c = CC $(quiet_modtag)  $@
 cmd_cc_s_c       = $(CC) $(c_flags) -fverbose-asm -S -o $@ $<
 
@@ -283,6 +289,23 @@ cmd_link_l_target = rm -f $@; $(AR) $(EX
 targets += $(lib-target)
 endif
 
+ifdef CONFIG_COMBINED_COMPILE
+# We would rather have a list of rules like
+# 	foo.o: $(foo-objs)
+# but that's not so easy, so we rather make all composite objects depend
+# on the set of all their parts
+
+$(multi-used-y) : %.o: $(srctree)/dummy.c $(multi-objs-y:.o=.c) FORCE
+	$(call cmd,force_checksrc)
+	$(call if_changed_rule,cc_o_c)
+
+$(multi-used-m) : %.o: $(srctree)/dummy.c $(multi-objs-m:.o=.c) FORCE
+	$(call cmd,force_checksrc)
+	$(call if_changed_rule,cc_o_c)
+	@{ echo $(@:.o=.ko); echo $(link_multi_deps); } > $(MODVERDIR)/$(@F:.o=.mod)
+
+targets += $(multi-used-y) $(multi-used-m)
+else
 #
 # Rule to link composite objects
 #
@@ -313,7 +336,7 @@ # on the set of all their parts
 	@{ echo $(@:.o=.ko); echo $(link_multi_deps); } > $(MODVERDIR)/$(@F:.o=.mod)
 
 targets += $(multi-used-y) $(multi-used-m)
-
+endif
 
 # Descending
 # ---------------------------------------------------------------------------

-- 
dwmw2

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux