Re: Trying to convert to LRA, running into an ICE (infinite reload loop)
On 08/28/2018 05:40 PM, Segher Boessenkool wrote: > On Mon, Aug 20, 2018 at 11:01:29AM -0600, Jeff Law wrote: >> On 08/20/2018 10:50 AM, Paul Koning wrote: >>> The internals manual seems to say that memory subregs are an old mechanism >>> that should still work, give or take. If indeed it breaks LRA perhaps the >>> documentation should be updated to say that it is an obsolete mechanism >>> that no longer works and needs to be disabled. >> It's definitely not something we encourage. But many of the older ports >> allow them. >> >> Essentially we know that subreg-mem will always need reloading. We want >> to expose those insns to the first scheduling pass, so we don't create >> them when the port has any scheduling bits defined. Even just a dummy >> "everything is one cycle" description is sufficient. >> >> I'm not aware of anything that says you can't do subreg-mem with LRA. >> It may be the case that you're dealing with the first port that's >> tripped over this. > > So it seems getting rid of subreg of mem does not fix the problems Paul > was having. > > Still. Can we get rid of it completely? Is there any reason left to > allow subreg of mem? Can't hurt to try. Even some of the ancient ports that likely used to exploit it (m68k) have pipeline descriptions and thus no longer depend on it in any way shape or form. I'd look favorably on a patch to kill (subreg (mem)). Make sure to update the docs at the same time. Jeff
Re: Trying to convert to LRA, running into an ICE (infinite reload loop)
On Mon, Aug 20, 2018 at 11:01:29AM -0600, Jeff Law wrote: > On 08/20/2018 10:50 AM, Paul Koning wrote: > > The internals manual seems to say that memory subregs are an old mechanism > > that should still work, give or take. If indeed it breaks LRA perhaps the > > documentation should be updated to say that it is an obsolete mechanism > > that no longer works and needs to be disabled. > It's definitely not something we encourage. But many of the older ports > allow them. > > Essentially we know that subreg-mem will always need reloading. We want > to expose those insns to the first scheduling pass, so we don't create > them when the port has any scheduling bits defined. Even just a dummy > "everything is one cycle" description is sufficient. > > I'm not aware of anything that says you can't do subreg-mem with LRA. > It may be the case that you're dealing with the first port that's > tripped over this. So it seems getting rid of subreg of mem does not fix the problems Paul was having. Still. Can we get rid of it completely? Is there any reason left to allow subreg of mem? Segher
Re: Trying to convert to LRA, running into an ICE (infinite reload loop)
> On Aug 20, 2018, at 7:17 AM, Segher Boessenkool > wrote: > > On Tue, Aug 14, 2018 at 03:32:01PM -0400, Paul Koning wrote: >> I'm trying to convert the pdp11 target to use LRA. >> >> A lot of it "just works". But one of the test suite files fails in a way >> that I can't figure out at all. I'm hoping for some help or hints to track >> down the cause and come up with a fix. >> >> The failing program is testsuite/gcc.c-torture/compile/ifreg.c: > > [ snip ] > >> I don't know how to read that, and I don't know what to look for to find a >> cause or a cure. Apart from turning on LRA, the code I'm running is what's >> in the repository, if anyone wants to look at the md file or other bits to >> offer suggestions. > > I think this is because the PDP port still has subregs of memory. You > can get rid of that by defining some (trivial) scheduling. I did so, and insn-attr-common.h now says: #define INSN_SCHEDULING But the bug is still there, unchanged. The input insn that sends LRA into an infinite loop isn't a memory subreg; the ira dump file shows it this way: (insn 18 22 19 2 (set (subreg:HI (reg/v:DI 26 [ b ]) 0) (const_int 0 [0])) "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} (nil)) So a subreg set to zero. And in the reload dump it shows this way: (insn 18 22 25 2 (set (reg:HI 32) (const_int 0 [0])) "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} (nil)) which makes sense given that the register width (word width) is 2. But that's the insn that is then followed by an infinite number of register copy operations. paul
Re: Trying to convert to LRA, running into an ICE (infinite reload loop)
On 08/20/2018 10:50 AM, Paul Koning wrote: > > >> On Aug 20, 2018, at 7:17 AM, Segher Boessenkool >> wrote: >> >> On Tue, Aug 14, 2018 at 03:32:01PM -0400, Paul Koning wrote: >>> I'm trying to convert the pdp11 target to use LRA. >>> >>> A lot of it "just works". But one of the test suite files fails in a way >>> that I can't figure out at all. I'm hoping for some help or hints to track >>> down the cause and come up with a fix. >>> >>> The failing program is testsuite/gcc.c-torture/compile/ifreg.c: >> >> [ snip ] >> >>> I don't know how to read that, and I don't know what to look for to find a >>> cause or a cure. Apart from turning on LRA, the code I'm running is what's >>> in the repository, if anyone wants to look at the md file or other bits to >>> offer suggestions. >> >> I think this is because the PDP port still has subregs of memory. You >> can get rid of that by defining some (trivial) scheduling. > > I don't know what the port does that enables memory subregs. If I read > gccint correctly, just turning on scheduling should make them go away? Ok, > adding scheduling was on my list anyway; pdp11s with float are dual pipe > machines so it's actually a meaningful thing to do. > > The internals manual seems to say that memory subregs are an old mechanism > that should still work, give or take. If indeed it breaks LRA perhaps the > documentation should be updated to say that it is an obsolete mechanism that > no longer works and needs to be disabled. It's definitely not something we encourage. But many of the older ports allow them. Essentially we know that subreg-mem will always need reloading. We want to expose those insns to the first scheduling pass, so we don't create them when the port has any scheduling bits defined. Even just a dummy "everything is one cycle" description is sufficient. I'm not aware of anything that says you can't do subreg-mem with LRA. It may be the case that you're dealing with the first port that's tripped over this. jeff
Re: Trying to convert to LRA, running into an ICE (infinite reload loop)
> On Aug 20, 2018, at 7:17 AM, Segher Boessenkool > wrote: > > On Tue, Aug 14, 2018 at 03:32:01PM -0400, Paul Koning wrote: >> I'm trying to convert the pdp11 target to use LRA. >> >> A lot of it "just works". But one of the test suite files fails in a way >> that I can't figure out at all. I'm hoping for some help or hints to track >> down the cause and come up with a fix. >> >> The failing program is testsuite/gcc.c-torture/compile/ifreg.c: > > [ snip ] > >> I don't know how to read that, and I don't know what to look for to find a >> cause or a cure. Apart from turning on LRA, the code I'm running is what's >> in the repository, if anyone wants to look at the md file or other bits to >> offer suggestions. > > I think this is because the PDP port still has subregs of memory. You > can get rid of that by defining some (trivial) scheduling. I don't know what the port does that enables memory subregs. If I read gccint correctly, just turning on scheduling should make them go away? Ok, adding scheduling was on my list anyway; pdp11s with float are dual pipe machines so it's actually a meaningful thing to do. The internals manual seems to say that memory subregs are an old mechanism that should still work, give or take. If indeed it breaks LRA perhaps the documentation should be updated to say that it is an obsolete mechanism that no longer works and needs to be disabled. paul
Re: Trying to convert to LRA, running into an ICE (infinite reload loop)
On Tue, Aug 14, 2018 at 03:32:01PM -0400, Paul Koning wrote: > I'm trying to convert the pdp11 target to use LRA. > > A lot of it "just works". But one of the test suite files fails in a way > that I can't figure out at all. I'm hoping for some help or hints to track > down the cause and come up with a fix. > > The failing program is testsuite/gcc.c-torture/compile/ifreg.c: [ snip ] > I don't know how to read that, and I don't know what to look for to find a > cause or a cure. Apart from turning on LRA, the code I'm running is what's > in the repository, if anyone wants to look at the md file or other bits to > offer suggestions. I think this is because the PDP port still has subregs of memory. You can get rid of that by defining some (trivial) scheduling. Segher
Re: Trying to convert to LRA, running into an ICE (infinite reload loop)
> On Aug 15, 2018, at 1:01 AM, Jeff Law wrote: > > On 08/14/2018 01:32 PM, Paul Koning wrote: >> I'm trying to convert the pdp11 target to use LRA. >> >> A lot of it "just works". But one of the test suite files fails in a way >> that I can't figure out at all. I'm hoping for some help or hints to track >> down the cause and come up with a fix. >> >> The failing program is testsuite/gcc.c-torture/compile/ifreg.c: >> >> union foo >> { >> float f; >> int i; >> }; >> >> foo (int a, float c) >> { >> union foo b; >> b.i = a; >> return b.f + c; >> } >> >> When compiled in LRA mode, I get this: >> >> during RTL pass: reload >> dump file: ifreg.c.274r.reload >> ../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c: In function ‘foo’: >> ../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c:12:1: internal >> compiler error: Max. number of generated reload insns per insn is achieved >> (90) >> >> I fiddled a bit with the mov patterns, for example disabling the >> patterns that work on multi-word values (SI and DI mode, since pdp11 word is >> HImode). That doesn't fix (or create) the failure, though the specific >> insns change as a result. >> >> What I see going in to reload (from the "ira" dump file) is: >> >> (note 5 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) >> (note 2 5 4 2 NOTE_INSN_DELETED) >> (note 4 2 22 2 NOTE_INSN_FUNCTION_BEG) >> (insn 22 4 18 2 (clobber (reg/v:DI 26 [ b ])) >> "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 -1 >> (nil)) >> (insn 18 22 19 2 (set (subreg:HI (reg/v:DI 26 [ b ]) 0) >>(const_int 0 [0])) >> "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} >> (nil)) >> (insn 19 18 20 2 (set (subreg:HI (reg/v:DI 26 [ b ]) 2) >>(const_int 0 [0])) >> "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} >> (nil)) >> ... >> >> Reload shows this: >> >> (note 5 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) >> (note 2 5 4 2 NOTE_INSN_DELETED) >> (note 4 2 22 2 NOTE_INSN_FUNCTION_BEG) >> (insn 22 4 18 2 (clobber (reg/v:DI 26 [ b ])) >> "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 -1 >> (nil)) >> (insn 18 22 25 2 (set (reg:HI 32) >>(const_int 0 [0])) >> "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} >> (nil)) >> (insn 25 18 26 2 (set (reg:HI 33) >>(reg:HI 32)) >> "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} >> (nil)) >> (insn 26 25 27 2 (set (reg:HI 34) >>(reg:HI 33)) >> "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} >> (nil)) >> (insn 27 26 28 2 (set (reg:HI 35) >>(reg:HI 34)) >> "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} >> (nil)) >> ... with insns that do nothing, like the one above, repeating until it gives >> up. >> >> At the top of the dump file where LRA is reporting what it's doing, I see >> this: >> >> ** Local #1: ** >> >> Spilling non-eliminable hard regs: 6 >> New elimination table: >> Can eliminate 15 to 6 (offset=10, prev_offset=0) >> Can eliminate 15 to 5 (offset=4, prev_offset=0) >> Can eliminate 14 to 6 (offset=8, prev_offset=0) >> Can eliminate 14 to 5 (offset=0, prev_offset=0) >>0 Non input pseudo reload: reject++ >> alt=0,overall=7,losers=1,rld_nregs=1 >>0 Non input pseudo reload: reject++ >> alt=1,overall=7,losers=1,rld_nregs=1 >>alt=2: Bad operand -- refuse >>alt=3: Bad operand -- refuse >> Choosing alt 0 in insn 18: (0) =rR (1) rRN {movhi} > We've selected alternative 0 for insn 18. I believe that's the rRN -> > =rR alternative. Yes, specifically it matches the "N" source constraint (literal zero operand). >> Creating newreg=32, assigning class GENERAL_REGS to r32 > The insn did not match its constraints. So some kind of reload is > needed. We allocate a new reload register r32. > >> 18: r32:HI=0 >>Inserting insn reload after: > And we try to initialize r32 to 0. Which of course needs another reload. > > I suspect LRA is somehow missing that the operand could live in memory. Not exactly memory, the source operand is constant 0 and the resulting machine instruction will be a "clr". The puzzle is why it doesn't see it as matching when (a) it clearly does and (b) LRA knew that because it told us so in that first match (it chose alternative zero). What should I look at next to try to figure out why LRA is getting confused? paul
Re: Trying to convert to LRA, running into an ICE (infinite reload loop)
On 08/14/2018 01:32 PM, Paul Koning wrote: > I'm trying to convert the pdp11 target to use LRA. > > A lot of it "just works". But one of the test suite files fails in a way > that I can't figure out at all. I'm hoping for some help or hints to track > down the cause and come up with a fix. > > The failing program is testsuite/gcc.c-torture/compile/ifreg.c: > > union foo > { > float f; > int i; > }; > > foo (int a, float c) > { > union foo b; > b.i = a; > return b.f + c; > } > > When compiled in LRA mode, I get this: > > during RTL pass: reload > dump file: ifreg.c.274r.reload > ../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c: In function ‘foo’: > ../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c:12:1: internal compiler > error: Max. number of generated reload insns per insn is achieved (90) > > I fiddled a bit with the mov patterns, for example disabling the > patterns that work on multi-word values (SI and DI mode, since pdp11 word is > HImode). That doesn't fix (or create) the failure, though the specific insns > change as a result. > > What I see going in to reload (from the "ira" dump file) is: > > (note 5 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) > (note 2 5 4 2 NOTE_INSN_DELETED) > (note 4 2 22 2 NOTE_INSN_FUNCTION_BEG) > (insn 22 4 18 2 (clobber (reg/v:DI 26 [ b ])) > "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 -1 > (nil)) > (insn 18 22 19 2 (set (subreg:HI (reg/v:DI 26 [ b ]) 0) > (const_int 0 [0])) > "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} > (nil)) > (insn 19 18 20 2 (set (subreg:HI (reg/v:DI 26 [ b ]) 2) > (const_int 0 [0])) > "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} > (nil)) > ... > > Reload shows this: > > (note 5 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) > (note 2 5 4 2 NOTE_INSN_DELETED) > (note 4 2 22 2 NOTE_INSN_FUNCTION_BEG) > (insn 22 4 18 2 (clobber (reg/v:DI 26 [ b ])) > "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 -1 > (nil)) > (insn 18 22 25 2 (set (reg:HI 32) > (const_int 0 [0])) > "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} > (nil)) > (insn 25 18 26 2 (set (reg:HI 33) > (reg:HI 32)) > "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} > (nil)) > (insn 26 25 27 2 (set (reg:HI 34) > (reg:HI 33)) > "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} > (nil)) > (insn 27 26 28 2 (set (reg:HI 35) > (reg:HI 34)) > "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} > (nil)) > ... with insns that do nothing, like the one above, repeating until it gives > up. > > At the top of the dump file where LRA is reporting what it's doing, I see > this: > > ** Local #1: ** > > Spilling non-eliminable hard regs: 6 > New elimination table: > Can eliminate 15 to 6 (offset=10, prev_offset=0) > Can eliminate 15 to 5 (offset=4, prev_offset=0) > Can eliminate 14 to 6 (offset=8, prev_offset=0) > Can eliminate 14 to 5 (offset=0, prev_offset=0) > 0 Non input pseudo reload: reject++ > alt=0,overall=7,losers=1,rld_nregs=1 > 0 Non input pseudo reload: reject++ > alt=1,overall=7,losers=1,rld_nregs=1 > alt=2: Bad operand -- refuse > alt=3: Bad operand -- refuse >Choosing alt 0 in insn 18: (0) =rR (1) rRN {movhi} We've selected alternative 0 for insn 18. I believe that's the rRN -> =rR alternative. > Creating newreg=32, assigning class GENERAL_REGS to r32 The insn did not match its constraints. So some kind of reload is needed. We allocate a new reload register r32. >18: r32:HI=0 > Inserting insn reload after: And we try to initialize r32 to 0. Which of course needs another reload. I suspect LRA is somehow missing that the operand could live in memory. Jeff
Trying to convert to LRA, running into an ICE (infinite reload loop)
I'm trying to convert the pdp11 target to use LRA. A lot of it "just works". But one of the test suite files fails in a way that I can't figure out at all. I'm hoping for some help or hints to track down the cause and come up with a fix. The failing program is testsuite/gcc.c-torture/compile/ifreg.c: union foo { float f; int i; }; foo (int a, float c) { union foo b; b.i = a; return b.f + c; } When compiled in LRA mode, I get this: during RTL pass: reload dump file: ifreg.c.274r.reload ../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c: In function ‘foo’: ../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c:12:1: internal compiler error: Max. number of generated reload insns per insn is achieved (90) I fiddled a bit with the mov patterns, for example disabling the patterns that work on multi-word values (SI and DI mode, since pdp11 word is HImode). That doesn't fix (or create) the failure, though the specific insns change as a result. What I see going in to reload (from the "ira" dump file) is: (note 5 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) (note 2 5 4 2 NOTE_INSN_DELETED) (note 4 2 22 2 NOTE_INSN_FUNCTION_BEG) (insn 22 4 18 2 (clobber (reg/v:DI 26 [ b ])) "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 -1 (nil)) (insn 18 22 19 2 (set (subreg:HI (reg/v:DI 26 [ b ]) 0) (const_int 0 [0])) "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} (nil)) (insn 19 18 20 2 (set (subreg:HI (reg/v:DI 26 [ b ]) 2) (const_int 0 [0])) "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} (nil)) ... Reload shows this: (note 5 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) (note 2 5 4 2 NOTE_INSN_DELETED) (note 4 2 22 2 NOTE_INSN_FUNCTION_BEG) (insn 22 4 18 2 (clobber (reg/v:DI 26 [ b ])) "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 -1 (nil)) (insn 18 22 25 2 (set (reg:HI 32) (const_int 0 [0])) "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} (nil)) (insn 25 18 26 2 (set (reg:HI 33) (reg:HI 32)) "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} (nil)) (insn 26 25 27 2 (set (reg:HI 34) (reg:HI 33)) "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} (nil)) (insn 27 26 28 2 (set (reg:HI 35) (reg:HI 34)) "../../gcc/gcc/testsuite/gcc.c-torture/compile/ifreg.c":10 21 {movhi} (nil)) ... with insns that do nothing, like the one above, repeating until it gives up. At the top of the dump file where LRA is reporting what it's doing, I see this: ** Local #1: ** Spilling non-eliminable hard regs: 6 New elimination table: Can eliminate 15 to 6 (offset=10, prev_offset=0) Can eliminate 15 to 5 (offset=4, prev_offset=0) Can eliminate 14 to 6 (offset=8, prev_offset=0) Can eliminate 14 to 5 (offset=0, prev_offset=0) 0 Non input pseudo reload: reject++ alt=0,overall=7,losers=1,rld_nregs=1 0 Non input pseudo reload: reject++ alt=1,overall=7,losers=1,rld_nregs=1 alt=2: Bad operand -- refuse alt=3: Bad operand -- refuse Choosing alt 0 in insn 18: (0) =rR (1) rRN {movhi} Creating newreg=32, assigning class GENERAL_REGS to r32 18: r32:HI=0 Inserting insn reload after: 25: r26:DI#0=r32:HI 0 Non input pseudo reload: reject++ 1 Non pseudo reload: reject++ Cycle danger: overall += LRA_MAX_REJECT alt=0,overall=608,losers=1,rld_nregs=1 0 Non input pseudo reload: reject++ alt=1: Bad operand -- refuse alt=2: Bad operand -- refuse alt=3: Bad operand -- refuse Choosing alt 0 in insn 25: (0) =rR (1) rRN {movhi} Creating newreg=33, assigning class GENERAL_REGS to r33 25: r33:HI=r32:HI Inserting insn reload after: 26: r26:DI#0=r33:HI 0 Non input pseudo reload: reject++ 1 Non pseudo reload: reject++ Cycle danger: overall += LRA_MAX_REJECT alt=0,overall=608,losers=1,rld_nregs=1 0 Non input pseudo reload: reject++ alt=1: Bad operand -- refuse alt=2: Bad operand -- refuse alt=3: Bad operand -- refuse Choosing alt 0 in insn 26: (0) =rR (1) rRN {movhi} Creating newreg=34, assigning class GENERAL_REGS to r34 26: r34:HI=r33:HI Inserting insn reload after: 27: r26:DI#0=r34:HI ... I don't know how to read that, and I don't know what to look for to find a cause or a cure. Apart from turning on LRA, the code I'm running is what's in the repository, if anyone wants to look at the md file or other bits to offer suggestions. paul