From mboxrd@z Thu Jan 1 00:00:00 1970 From: Geoff Keating To: Franz.Sirl-kernel@lauterbach.com Cc: amylaar@cygnus.co.uk, law@cygnus.com, ghazi@snafu.Rutgers.EDU, davem@cobaltmicro.com, egcs@egcs.cygnus.com Subject: Re: PIC register allocation by reload (Was: Re: egcs-1.2 stuff) Date: Mon, 31 May 1999 21:36:00 -0000 Message-ID: <199905062115.HAA00514@geoffk.wattle.id.au> References: <4431.922654685@upchuck> <4.2.0.37.19990506223045.036924c0@mail.lauterbach.com> X-SW-Source: 1999-05n/msg00175.html Message-ID: <19990531213600.mDI3o8h6OH-uZXn8bthz9xotJOEbjx0V840ZTPwbe6w@z> > Date: Thu, 06 May 1999 22:36:17 +0200 > From: Franz Sirl > Cc: law@cygnus.com, ghazi@snafu.Rutgers.EDU, davem@cobaltmicro.com, > egcs@egcs.cygnus.com, geoffk@ozemail.com.au > > At 19:46 30.04.99 , Joern Rennecke wrote: > > > > > > In message <199903281412.JAA02308@caip.rutgers.edu>you write: > > > > I think we should address the -fpic/-fPIC failures on the sparc. > > > > This would affect glibc or really any shared library. IIRC, Dave had a > > > > preliminary fix early last fall around the time we split the 1.1.x > > > > branch. For some reason it never went in. (?) > > > If it's the problem I think it is then it's unlikely we'll have a general > > > solution in time for egcs-1.2. > > > > > > Lazy allocation of the PIC register is a bad bad idea right now. It's > > going > > > to consistently lose. If we want this to work 100% reliably for > > egcs-1.2, then > > > the backend is going to need to pre-allocate the register early and > > take the > > > performance hit. This effects multiple ports that have tried to do lazy > > > allocation of the PIC register (for example the ppc). Yes. > > > Then someone will need to block out some significant time post egcs-1.2 > > to fix > > > the problem correctly. It's not a simple problem to fix. Yes. > >I think that, if no PIC register is preallocated and we find during > >reload that we need one after all, we should just load it with a secondary > >reload (by defining SECONDARY_RELOAD_INPUT_CLASS and reload_in[sd]i > >appropriately). > >We should check that reload inheritance works for the temporarily > >allocated PIC register. Then we should get actually better code than if > >we allocated the PIC register for the entire function. Regrettably, it's more complex than that. It's not just the case of suddenly discovering that a routine, which previously didn't have a PIC register, needs one. It's also the case when a routine which already has a PIC register finds that it needs to access it in more and/or different places than before. The example I have of this is attached below. Look at register 26; it is the PIC register, yet it gets stomped just after label '.L5'; and there's a flow of control from there to just after label '.L13' where the PIC register is used. Compile under 1.1.1, targetting powerpc-linux with '-O -fpic'. The problem here is triggered by reload deciding to do some constant rearrangement because of a REG_EQUIV note: it sees this (insn 264 261 266 (set (reg:SI 117) (unspec[ (symbol_ref:SI ("@h_malloc")) (reg:SI 128) ] 8)) 398 {*movsi_got_internal} (nil) (expr_list:REG_EQUIV (symbol_ref:SI ("@h_malloc")) (nil))) and decides that it can then simplify this insn: (insn 160 158 162 (set (reg:SI 120) (mem:SI (reg:SI 117))) 402 {movsi+1} (nil) (nil)) by rewriting it as (insn 160 158 162 (set (reg:SI 120) (symbol_ref:SI ("@h_malloc"))) (nil) (nil)) because register 117 is equivalent to the symbol_ref; but it actually ends up as (insn 160 158 162 (set (reg:SI 120) (unspec[ (symbol_ref:SI ("@h_malloc")) (reg:SI 128) ] 8)) 398 {*movsi_got_internal} (nil) (nil)) and suddenly there's a new use of register 128 that wasn't there before, and this causes global alloc to fail. Similar problems happen with floating-point constants. Is this testcase already in the test suite? It's stripped-down code from kaffe's implementation of GNU zip. If you want a temporary fix, I've previously posted a solution which ensures that reload will never ask for a new occurrence of the PIC register. It should be in the egcs-patches archive. If you use this, then there is no need to do anything else. It would need to be ported to sparc if it is needed there (the port consists of defining two preprocessor variables in sparc.h). The patch operates by forcing reload to never spill constants to memory (only when -fpic, of course). It works OK on powerpc, but on sparc it might need some more code in the machine description to make life easier for the crippled reload---I would be glad to help here. On powerpc, I'm not sure that you can use reload in the way suggested. I suspect there are cases in which it won't be able to reload the link register, for instance when folding switch statements. > Hmm, would this solution possibly be OK for 1.2? It really would be great > if this was solved once and forever, so if you have some code to try I'm > willing to test it on PPC. Certainly, if there's code already written I'm happy to run it against my test suite. -- Geoffrey Keating ===File ~/gcc-bugs/test11.s================================= .file "test11.c" gcc2_compiled.: .globl memset .section ".text" .align 2 .type doit,@function doit: stwu 1,-176(1) mflr 0 stw 14,104(1) stw 15,108(1) stw 16,112(1) stw 17,116(1) stw 18,120(1) stw 19,124(1) stw 20,128(1) stw 21,132(1) stw 22,136(1) stw 23,140(1) stw 24,144(1) stw 25,148(1) stw 26,152(1) stw 27,156(1) stw 28,160(1) stw 29,164(1) stw 30,168(1) stw 31,172(1) stw 0,180(1) bl _GLOBAL_OFFSET_TABLE_@local-4 mflr 26 mr 18,3 mr 16,4 mr 17,5 mr 22,6 addi 3,1,72 li 4,0 li 5,16 crxor 6,6,6 bl memset@plt addi 3,1,8 li 4,0 li 5,60 crxor 6,6,6 bl memset@plt li 31,0 li 3,0 li 27,0 addi 25,1,12 li 30,1 addi 19,1,72 li 14,1 li 15,0 addi 20,1,88 .L5: li 26,0 slwi 21,30,2 .L9: cmplw 0,30,31 bc 4,1,.L11 addi 23,26,1 addi 0,30,-1 slwi 24,0,2 .L12: slwi 0,27,2 lwzx 31,25,0 addi 27,27,1 mr 9,31 cmplw 0,31,23 bc 4,1,.L13 add 11,19,21 cmplwi 0,31,1 bc 12,1,.L13 .L18: slwi 0,9,2 lwzx 0,11,0 cmplw 0,31,0 bc 12,1,.L13 addi 9,9,1 cmplwi 0,9,1 bc 4,1,.L18 .L13: slwi 0,27,2 stwx 9,25,0 lwz 10,h_malloc@got(26) lwz 0,0(10) slw 3,14,18 mtlr 0 blrl stw 3,0(22) addi 22,3,4 stw 15,4(3) stwx 3,24,20 cmplw 0,30,31 bc 12,1,.L12 .L11: mr 28,16 mr 29,17 stw 28,0(3) stw 29,4(3) addi 26,26,1 cmplwi 0,26,6 bc 4,1,.L9 addi 30,30,1 cmplwi 0,30,2 bc 4,1,.L5 lwz 0,180(1) mtlr 0 lwz 14,104(1) lwz 15,108(1) lwz 16,112(1) lwz 17,116(1) lwz 18,120(1) lwz 19,124(1) lwz 20,128(1) lwz 21,132(1) lwz 22,136(1) lwz 23,140(1) lwz 24,144(1) lwz 25,148(1) lwz 26,152(1) lwz 27,156(1) lwz 28,160(1) lwz 29,164(1) lwz 30,168(1) lwz 31,172(1) la 1,176(1) blr .Lfe1: .size doit,.Lfe1-doit .align 2 .globl is_ok .type is_ok,@function is_ok: stwu 1,-16(1) mflr 0 stw 0,20(1) li 3,0 crxor 6,6,6 bl exit@plt .Lfe2: .size is_ok,.Lfe2-is_ok .align 2 .globl main .type main,@function main: stwu 1,-16(1) mflr 0 stw 0,20(1) bl _GLOBAL_OFFSET_TABLE_@local-4 mflr 9 lwz 11,h_malloc@got(9) lwz 9,is_ok@got(9) stw 9,0(11) li 3,0 li 4,0 li 5,0 li 6,0 bl doit@local bl abort@plt .Lfe3: .size main,.Lfe3-main .comm h_malloc,4,4 .ident "GCC: (GNU) egcs-2.91.54 19980816 (gcc2 ss-980609 experimental)" ============================================================ ===File ~/gcc-bugs/test11.c================================= typedef struct _huft { unsigned e; struct _huft* t; } huft; huft* (*h_malloc)(unsigned); static void doit( unsigned p2, unsigned p3, huft *p4, huft** t) { unsigned a, h, j, k, w; unsigned *xp, *l; unsigned lx[2*7+1], v[2*2]; huft *q; huft r; huft *u[2]; memset(v, 0, sizeof(v)); memset(lx, 0, sizeof(lx)); w = 0; q = 0; h = 0; l = lx+1; for (k=1; k <= 2; k++) for (a=0; a < 7; a++) { while (k > w) { w = l[h++]; j = w; if (w > a + 1) { xp = v + k; while (j < 2 && w <= xp[j]) ++j; } l[h] = j; q = h_malloc(1<t); *t = 0; u[k-1] = q; } r.e = p3; r.t = p4; q[0] = r; } } huft *is_ok(unsigned x) { exit(0); } int main() { h_malloc = is_ok; doit(0, 0, 0, 0); abort(); } ============================================================