This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: unit-at-a-time build failure on arm-elf


rearnsha at arm dot com said:
> The new unit-at-once code is causing a build failure on an arm-elf
> cross  when building newlib.

> cc1 -fpreprocessed ldtoa.i -quiet -dumpbase ldtoa.c -auxbase ldtoa -g
> -O2  -fno-builtin -o ldtoa.s GNU C version 3.4 20030221 (experimental)
> (arm-elf)
>         compiled by GNU C version 2.96 20000731 (Red Hat Linux 7.1
> 2.96-98). /home/rearnsha/gnusrc/egcs-cross/newlib/libc/stdlib/ldtoa.c:
> In function  `asctoeg': /home/rearnsha/gnusrc/egcs-cross/newlib/libc/
> stdlib/ldtoa.c:3561: internal  compiler error: in verify_local_live_at_
> start, at flow.c:590 Please submit a full bug report,

> The pre-processed source is attached. 

I've just spent a couple of hours digging into this one and I'm not sure 
what the solution here is going to be.  The problem seems to be creeping 
in during basic block reordering.

if_convert is generating a basic block of the form

	...	// unconditional insns not mentioning r0
	(gtu CC 0) r0 = xxx
	(if_then_else (gtu CC 0) (label) (pc))

Now r0 is dead if we fall through, but live if we take the branch, so the 
bb's liveness information is

 global-live-at-start:  some_regs_not_r0
 global-live-at-end:	r0 some_other_regs_not_r0

Now the branch reordering pass is for some reason splitting the final 
cond-jump  above into a separate block, when we calculate the register 
life info for this we then get

bb A
	...	// unconditional insns not altering r0
	(gtu CC 0) r0 = xxx

 global-live-at-start:  r0 some_regs_not_r0
 global-live-at-end:	r0 some_other_regs_not_r0

bb B
	(label)
	(if_then_else (gtu CC 0) (label) (pc))

 global-live-at-start:  r0 some_other_regs_not_r0
 global-live-at-end:	r0 some_other_regs_not_r0

This is believable, for this configuration.  bb B neither sets nor uses 
r0, so if it's possibly live at the end (it is on one successor, but not 
on another) then we must mark it live at the start; *but note that we 
can't mark it conditionally live*, so we mark r0 as unconditionally live 
at the end of bb A and must now propagate that up to the beginning.

The problems really manifest themselves during the second half of 
bb_reorder.  In that phase we kill the label and merge the two blocks back 
together again.  However, this time we don't recalculate the register life 
information of the merged block, so we fail to notice that r0 should now 
be marked as dead on entry.  The net result is that we then abort during 
scheduling because the life info is incorrect.

So how do we approach this?  I'm not entirely sure, but I suspect that 
whatever we do, short of maintaining full conditional life information at 
block boundaries, is going to be some sort of hack -- I'd be happy to be 
proved wrong though :-)

R.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]