Bug 194327 - Problems with --combine in kernel compilation.
Problems with --combine in kernel compilation.
Status: CLOSED RAWHIDE
Product: Fedora
Classification: Fedora
Component: gcc (Show other bugs)
5
All Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
:
Depends On:
Blocks: OLPCTracker
  Show dependency treegraph
 
Reported: 2006-06-07 07:59 EDT by David Woodhouse
Modified: 2007-11-30 17:11 EST (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2007-09-22 12:46:42 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
Test case on PowerPC (1.66 MB, application/octet-stream)
2006-08-13 06:01 EDT, David Woodhouse
no flags Details
Test case on i386 (1.45 MB, application/octet-stream)
2006-08-13 06:07 EDT, David Woodhouse
no flags Details


External Trackers
Tracker ID Priority Status Summary Last Updated
GNU Compiler Collection 27898 None None None Never
GNU Compiler Collection 27899 None None None Never
GNU Compiler Collection 28706 None None None Never
GNU Compiler Collection 28712 None None None Never
GNU Compiler Collection 28744 None None None Never
GNU Compiler Collection 28755 None None None Never
GNU Compiler Collection 28779 None None None Never

  None (edit)
Description David Woodhouse 2006-06-07 07:59:51 EDT
For the OLPC project, we're trying to reduce the kernel code size. One way of
doing this is to build kernel objects with '-fwhole-program --combine'

Unfortunately, while just '-fwhole-program' works if we use the ugly trick of a
C file which #includes all the other C files, we have problems with '--combine'.

It doesn't manage to correctly notice that unions containing anonymous
structures are identical, so it thinks that function prototypes involving those
unions are 'confliction' -- GCC PR #27898.

It also complains about global register variables which each file defines
identially -- GCC PR #27899

Adding to Red Hat bugzilla so that it can be added to the OLPC tracker bug.
Comment 1 David Woodhouse 2006-06-15 08:18:11 EDT
For reference, this is the kind of improvement in size we get, by using
-fwhole-program and the ugly #include trick:

   text    data     bss     dec     hex filename
 117428    7832     320  125580   1ea8c jffs2-allinone.o
 122192    9056     328  131576   201f8 fs/jffs2/jffs2.o

We really can't do the #include trick for anything more than testing though --
we need to have --combine working before we can sensibly do this for real.
Comment 2 David Woodhouse 2006-07-19 17:20:12 EDT
Alex provided a patch for PR27898 --
http://gcc.gnu.org/ml/gcc-patches/2006-07/msg00187.html

Is this in mainline yet? In our current packages?
Comment 3 David Woodhouse 2006-08-13 06:01:14 EDT
Created attachment 134096 [details]
Test case on PowerPC

This is an example of the kind of thing we actually want to do -- build a whole
subdirectory with --combine. Even with Alex's patch for PR27898 it fails in
various ways...

include/asm/paca.h:23: warning: register used for two global register variables

In file included from include/linux/sched.h:51,
		 from fs/jffs2/build.c:16:
include/linux/rbtree.h:139: error: conflicting types for ‘rb_insert_color’
include/linux/rbtree.h:139: error: previous declaration of
‘rb_insert_color’ was here
include/linux/rbtree.h:140: error: conflicting types for ‘rb_erase’
include/linux/rbtree.h:140: error: previous declaration of ‘rb_erase’ was
here
include/linux/rbtree.h:143: error: conflicting types for ‘rb_next’
include/linux/rbtree.h:143: error: previous declaration of ‘rb_next’ was
here
include/linux/rbtree.h:144: error: conflicting types for ‘rb_prev’
include/linux/rbtree.h:144: error: previous declaration of ‘rb_prev’ was
here
include/linux/rbtree.h:145: error: conflicting types for ‘rb_first’
include/linux/rbtree.h:145: error: previous declaration of ‘rb_first’ was
here
include/linux/rbtree.h:146: error: conflicting types for ‘rb_last’
include/linux/rbtree.h:146: error: previous declaration of ‘rb_last’ was
here
include/linux/rbtree.h:150: error: conflicting types for ‘rb_replace_node’
include/linux/rbtree.h:150: error: previous declaration of
‘rb_replace_node’ was here
include/linux/irq_cpustat.h:20: error: conflicting types for ‘irq_stat’
include/linux/irq_cpustat.h:20: error: previous declaration of ‘irq_stat’
was here
include/linux/fs.h:460: error: conflicting types for ‘mapping_tagged’
include/linux/fs.h:460: error: previous declaration of ‘mapping_tagged’ was
here
include/linux/fs.h:993: error: conflicting types for ‘generic_osync_inode’
include/linux/fs.h:993: error: previous declaration of
‘generic_osync_inode’ was here
 ...
Comment 4 David Woodhouse 2006-08-13 06:07:58 EDT
Created attachment 134097 [details]
Test case on i386

Similar test case on i386. Note interesting behaviour when just trying to
combine read.c and write.c:

/opt/crosstool/gcc-4.1.0-glibc-2.3.6/i686-unknown-linux-gnu/bin/i686-unknown-linux-gnu-gcc
-m32  -fno-strict-aliasing -fno-common -Os -fomit-frame-pointer
-fasynchronous-unwind-tables -g -msoft-float -mpreferred-stack-boundary=2  
-mregparm=3 -ffreestanding  -c -o readwrite.o read.i write.i --combine
In file included from include/linux/thread_info.h:22,
		 from include/linux/preempt.h:11,
		 from include/linux/spinlock.h:51,
		 from include/linux/wait.h:26,
		 from include/linux/fs.h:224,
		 from fs/jffs2/write.c:16:
include/asm/thread_info.h:96: warning: register used for two global register
variables
fs/jffs2/write.c:712: internal compiler error: in splice_child_die, at
dwarf2out.c:5492
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.

That may be my self-built cross-compiler though.
Comment 5 David Woodhouse 2006-08-13 06:24:40 EDT
Much of what I quoted in comment #3 seems to be explained by GCC PR28706.
Comment 6 David Woodhouse 2006-08-13 06:46:40 EDT
If I remove the alignment on struct rb_node from read.i and write.i I can
reproduce the failure mode of comment #4 on my PowerPC native build...

pmac /pmac/git/jffs2-play-2.6/jffs2-combine-ppc $ cc -m64 -fno-strict-aliasing
-fno-common  -Os -fomit-frame-pointer  -msoft-float -pipe -mminimal-toc
-mtraceback=none  -mcall-aixdesc -mtune=power4 -mno-altivec -funit-at-a-time
-mstring -Wa,-maltivec -c -o readwrite.o read.i write.i --combine -Daligned\(x\)=
In file included from include/asm/current.h:16,
                 from include/linux/wait.h:27,
                 from include/linux/fs.h:223,
                 from fs/jffs2/write.c:16:
include/asm/paca.h:23: warning: register used for two global register variables
fs/jffs2/write.c:673: internal compiler error: in splice_child_die, at
dwarf2out.c:5492
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://bugzilla.redhat.com/bugzilla> for instructions.

Removing '-g' from the compiler flags unsurprisingly fixes it.

This is current (4.1.1-1.fc5) Fedora 5 GCC with Alex's patch for PR27898 applied.
Comment 7 David Woodhouse 2006-08-13 11:08:39 EDT
Passing every .i file through s/aligned/ignore/g actually makes it work now on
PPC. When combined with -fwhole-program I get object files which are 20% smaller
than the original...

120552    9000     328  129880   1fb58 jffs2-normal.o
106688    7032     304  114024   1bd68 jffs2-combine.o
 97332    5824     304  103460   19424 jffs2-combine-whole-program.o

(Including all files from one and using -fwhole-program was only getting me a 5%
reduction, which seems slightly more reasonable -- and that's still about the
same if I do the same s/aligned/ignore/ and build the same way. I'll have to
test the '--combine -fwhole-program' version once PR28706 is fixed and see if it
actually works.)

The i386 version still has (at least) one problem:
include/asm/processor.h:100: error: conflicting types for 'doublefault_tss'
include/asm/processor.h:100: error: previous declaration of 'doublefault_tss'
was here
include/asm/processor.h:101: error: conflicting types for 'per_cpu__init_tss'
include/asm/processor.h:101: error: previous declaration of 'per_cpu__init_tss'
was here
Comment 8 David Woodhouse 2006-08-13 19:27:37 EDT
> The i386 version still has (at least) one problem:
> include/asm/processor.h:100: error: conflicting types for 'doublefault_tss'
> include/asm/processor.h:100: error: previous declaration of 'doublefault_tss'
> was here
> include/asm/processor.h:101: error: conflicting types for 'per_cpu__init_tss'
> include/asm/processor.h:101: error: previous declaration of 'per_cpu__init_tss'
> was here

That's PR27812. 

Comment 9 Jakub Jelinek 2006-08-14 13:41:31 EDT
I've posted a patch for PR287{06,12}.
Comment 11 David Woodhouse 2006-08-15 06:32:01 EDT
Perfect, thanks. With your patch and Alex's applied, I can now build modules
with only the 'register used for two global register variables' warnings
(PR27899), which I believe is harmless.

The standard build, for example, of fs/jffs2 on i386 (gcc 4.1.0) gives me this:
  80179     688     176   81043   13c93 fs/jffs2/built-in.o
With -fwhole-program --combine I get this:
  77555     688     188   78431   1325f fs/jffs2/built-in.o

Strangely, that latter result is the same whether I add -funit-at-a-time or
-fno-unit-at-a-time to CFLAGS. 
Comment 12 Jakub Jelinek 2007-09-22 12:46:42 EDT
If you still have issues with rawhide gcc, please reopen.
The global reg warning isn't solved there, but it can be ignored I guess.

Note You need to log in before you can comment on or make changes to this bug.