Re: Special Memory Constraint [was Re: Indirect memory addresses vs. lra]

2019-08-20 Thread Richard Biener
On Tue, Aug 20, 2019 at 9:07 AM John Darrington
 wrote:
>
> On Tue, Aug 20, 2019 at 08:56:39AM +0200, Richard Biener wrote:
>
>  > Most of these suggestions involve adding some sort of virtual registers
>  > So I hacked the machine description to add two new registers Z1 and Z2
>  > with the same mode as X and Y.
>  >
>  > Obviously the assembler balks at this.  However the compiler still
>  > ICEs at the same place as before.
>  >
>  > So this suggests that our original diagnosis, viz: there are not enough
>  > address registers was not accurate, and in fact there is some other
>  > problem?
>
>  That sounds likely.  Given you have indirect addressing you could
>  simulate N virtual regs by placing them in a virtual reg table in memory
>  and accessed via a fixed address register (assuming all instructions
>  that would need an address reg also can take that indirect from memory).
>
> That was my plan.  Accordingly, extending the md to provide N additional
> regs (N currently = 2) was the first step.  Having doubled the number
> of available address registers, I had expected this would fix most of the
> ICEs (but cause a lot of assembler errors).
>
> However it hasn't eliminated any ICEs.  lra is still complaining
> "unable to find a register to spill" So the plan seems to have fallen
> over at the first hurdle.  Why can it still not spill registers despite
> having a lot more of them?

You really have to sit down and trace the LRA code with a debugger
to tell...  unfortunately the dumps aren't verbose enough to tell.
Usually after spilling the insn constraints can still not be satisfied,
the main question is usually why.

Richard.

> J'


Re: Special Memory Constraint [was Re: Indirect memory addresses vs. lra]

2019-08-20 Thread John Darrington
On Tue, Aug 20, 2019 at 08:56:39AM +0200, Richard Biener wrote:

 > Most of these suggestions involve adding some sort of virtual registers
 > So I hacked the machine description to add two new registers Z1 and Z2
 > with the same mode as X and Y.
 >
 > Obviously the assembler balks at this.  However the compiler still
 > ICEs at the same place as before.
 >
 > So this suggests that our original diagnosis, viz: there are not enough
 > address registers was not accurate, and in fact there is some other
 > problem?
 
 That sounds likely.  Given you have indirect addressing you could
 simulate N virtual regs by placing them in a virtual reg table in memory
 and accessed via a fixed address register (assuming all instructions
 that would need an address reg also can take that indirect from memory).
 
That was my plan.  Accordingly, extending the md to provide N additional
regs (N currently = 2) was the first step.  Having doubled the number
of available address registers, I had expected this would fix most of the 
ICEs (but cause a lot of assembler errors).

However it hasn't eliminated any ICEs.  lra is still complaining 
"unable to find a register to spill" So the plan seems to have fallen
over at the first hurdle.  Why can it still not spill registers despite
having a lot more of them?

J'


Re: Special Memory Constraint [was Re: Indirect memory addresses vs. lra]

2019-08-20 Thread Richard Biener
On Mon, Aug 19, 2019 at 8:06 PM John Darrington
 wrote:
>
> On Mon, Aug 19, 2019 at 10:07:11AM -0500, Segher Boessenkool wrote:
>
>  > ? As I remember there were a few other ideas from Richard Biener and
>  > Segher Boessenkool.? I also proposed to add a new address register 
> which
>  > will be always a fixed stack memory slot at the end. Unfortunately I am
>  > not familiar with the target and the port to say in details how to do
>  > it.? But I think it is worth to try.
>
>  The m68hc11 port used the fake Z register approach, and I believe it had
>  some special machine pass to get rid of it right before assembler output.
>
>  (r171302 is when it was removed -- last version was
>  
> https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/config/m68hc11/m68hc11.c;h=1e414102c3f1fed985e4fb8db7954342e965190b;hb=bae8bb65d842d7ffefe990c1f0ac004491f3c105#l4061
>  for the machine reorg stuff).
>
>  No idea how well it works...  But it's only needed if you are forced to
>  have a frame pointer IIUC?
>
>
>  Segher
>
>
> Most of these suggestions involve adding some sort of virtual registers
> So I hacked the machine description to add two new registers Z1 and Z2
> with the same mode as X and Y.
>
> Obviously the assembler balks at this.  However the compiler still
> ICEs at the same place as before.
>
> So this suggests that our original diagnosis, viz: there are not enough
> address registers was not accurate, and in fact there is some other
> problem?

That sounds likely.  Given you have indirect addressing you could
simulate N virtual regs by placing them in a virtual reg table in memory
and accessed via a fixed address register (assuming all instructions
that would need an address reg also can take that indirect from memory).

Richard.

> J'
>
> --
> Avoid eavesdropping.  Send strong encrypted email.
> PGP Public key ID: 1024D/2DE827B3
> fingerprint = 8797 A26D 0854 2EAB 0285  A290 8A67 719C 2DE8 27B3
> See http://sks-keyservers.net or any PGP keyserver for public key.
>


Re: Special Memory Constraint [was Re: Indirect memory addresses vs. lra]

2019-08-19 Thread John Darrington
On Mon, Aug 19, 2019 at 10:07:11AM -0500, Segher Boessenkool wrote:

 > ? As I remember there were a few other ideas from Richard Biener and 
 > Segher Boessenkool.? I also proposed to add a new address register which 
 > will be always a fixed stack memory slot at the end. Unfortunately I am 
 > not familiar with the target and the port to say in details how to do 
 > it.? But I think it is worth to try.
 
 The m68hc11 port used the fake Z register approach, and I believe it had
 some special machine pass to get rid of it right before assembler output.
 
 (r171302 is when it was removed -- last version was
 
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/config/m68hc11/m68hc11.c;h=1e414102c3f1fed985e4fb8db7954342e965190b;hb=bae8bb65d842d7ffefe990c1f0ac004491f3c105#l4061
 for the machine reorg stuff).
 
 No idea how well it works...  But it's only needed if you are forced to
 have a frame pointer IIUC?
 
 
 Segher


Most of these suggestions involve adding some sort of virtual registers
So I hacked the machine description to add two new registers Z1 and Z2 
with the same mode as X and Y.

Obviously the assembler balks at this.  However the compiler still
ICEs at the same place as before.

So this suggests that our original diagnosis, viz: there are not enough
address registers was not accurate, and in fact there is some other
problem?

J'

-- 
Avoid eavesdropping.  Send strong encrypted email.
PGP Public key ID: 1024D/2DE827B3 
fingerprint = 8797 A26D 0854 2EAB 0285  A290 8A67 719C 2DE8 27B3
See http://sks-keyservers.net or any PGP keyserver for public key.



Re: Special Memory Constraint [was Re: Indirect memory addresses vs. lra]

2019-08-19 Thread Segher Boessenkool
On Mon, Aug 19, 2019 at 09:14:22AM -0400, Vladimir Makarov wrote:
> On 2019-08-19 3:35 a.m., John Darrington wrote:
> >On Fri, Aug 16, 2019 at 10:50:13AM -0400, Vladimir Makarov wrote:
> >  No I meant something like that
> >  
> >  (define_special_memory_constraint "a" ...)
> >  (define_predicate "my_special_predicate" ...
> > 
> >   {
> > if (lra_in_progress_p)
> >   return REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER && 
> >   reg_renumber[REGNO(op)] < 0;
> > return true if memory with sp addressing;
> >  })
> >  
> >  I think LRA spills pseudo-register and it will be memory addressed 
> >  by sp
> >  at the end of LRA.
> >
> >What I've done is this:
> >
> >(define_predicate "my_special_predicate"
> > (match_operand 0 "memory_operand")
> >  {
> >debug_rtx (op);
> >gcc_assert (MEM_P (op));
> >op = XEXP (op, 0);
> >if (GET_CODE (op) == PLUS)
> >  op = XEXP (op, 0);
> >
> >if (lra_in_progress)
> >  {
> >fprintf (stderr, "%s:%d\n", __FILE__, __LINE__);
> >return REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER && 
> >reg_renumber[REGNO(op)] < 0;
> >  }
> >
> >
> >if (REG_P (op))
> >  {
> >int regno = REGNO (op);
> >return (regno == 10); // register is the stack pointer
> >  }
> >
> >return true;
> >  })
> >
> >  (and many variations)  Unfortunately, any moderately complicated input
> >  still results in a (mem (reg) ) insn repeatedly entering the
> >  lra_in_progress case and returning false, and eventually terminating with
> >  
> >  "internal compiler error: maximum number of generated reload insns per 
> >  insn achieved (90)"
> >
> >
> >Any other ideas?
>   As I remember there were a few other ideas from Richard Biener and 
> Segher Boessenkool.  I also proposed to add a new address register which 
> will be always a fixed stack memory slot at the end. Unfortunately I am 
> not familiar with the target and the port to say in details how to do 
> it.  But I think it is worth to try.

The m68hc11 port used the fake Z register approach, and I believe it had
some special machine pass to get rid of it right before assembler output.

(r171302 is when it was removed -- last version was
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/config/m68hc11/m68hc11.c;h=1e414102c3f1fed985e4fb8db7954342e965190b;hb=bae8bb65d842d7ffefe990c1f0ac004491f3c105#l4061
for the machine reorg stuff).

No idea how well it works...  But it's only needed if you are forced to
have a frame pointer IIUC?


Segher


Re: Special Memory Constraint [was Re: Indirect memory addresses vs. lra]

2019-08-19 Thread Vladimir Makarov



On 2019-08-19 3:35 a.m., John Darrington wrote:

On Fri, Aug 16, 2019 at 10:50:13AM -0400, Vladimir Makarov wrote:
  
  
  No I meant something like that
  
  (define_special_memory_constraint "a" ...)

  (define_predicate "my_special_predicate" ...

   {
 if (lra_in_progress_p)
   return REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER && 
reg_renumber[REGNO(op)] < 0;
 return true if memory with sp addressing;
  })
  
  I think LRA spills pseudo-register and it will be memory addressed by sp

  at the end of LRA.

What I've done is this:

(define_predicate "my_special_predicate"
(match_operand 0 "memory_operand")
  {
debug_rtx (op);
gcc_assert (MEM_P (op));
op = XEXP (op, 0);
if (GET_CODE (op) == PLUS)
  op = XEXP (op, 0);

if (lra_in_progress)
  {
fprintf (stderr, "%s:%d\n", __FILE__, __LINE__);
return REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER && 
reg_renumber[REGNO(op)] < 0;
  }


if (REG_P (op))
  {
int regno = REGNO (op);
return (regno == 10); // register is the stack pointer
  }

return true;
  })

  (and many variations)  Unfortunately, any moderately complicated input
  still results in a (mem (reg) ) insn repeatedly entering the
  lra_in_progress case and returning false, and eventually terminating with
  
  "internal compiler error: maximum number of generated reload insns per insn achieved (90)"



Any other ideas?
  As I remember there were a few other ideas from Richard Biener and 
Segher Boessenkool.  I also proposed to add a new address register which 
will be always a fixed stack memory slot at the end. Unfortunately I am 
not familiar with the target and the port to say in details how to do 
it.  But I think it is worth to try.


Re: Special Memory Constraint [was Re: Indirect memory addresses vs. lra]

2019-08-19 Thread John Darrington
On Fri, Aug 16, 2019 at 10:50:13AM -0400, Vladimir Makarov wrote:
 
 
 No I meant something like that
 
 (define_special_memory_constraint "a" ...)
 (define_predicate "my_special_predicate" ...

  {
if (lra_in_progress_p)
  return REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER && 
reg_renumber[REGNO(op)] < 0;
return true if memory with sp addressing;
 })
 
 I think LRA spills pseudo-register and it will be memory addressed by sp
 at the end of LRA.

What I've done is this:

(define_predicate "my_special_predicate"
(match_operand 0 "memory_operand")
 {
   debug_rtx (op);
   gcc_assert (MEM_P (op));
   op = XEXP (op, 0);
   if (GET_CODE (op) == PLUS)
 op = XEXP (op, 0);

   if (lra_in_progress)
 {
   fprintf (stderr, "%s:%d\n", __FILE__, __LINE__);
   return REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER && 
reg_renumber[REGNO(op)] < 0;
 }


   if (REG_P (op))
 {
   int regno = REGNO (op);
   return (regno == 10); // register is the stack pointer
 }

   return true;
 })

 (and many variations)  Unfortunately, any moderately complicated input
 still results in a (mem (reg) ) insn repeatedly entering the
 lra_in_progress case and returning false, and eventually terminating with
 
 "internal compiler error: maximum number of generated reload insns per insn 
achieved (90)"


Any other ideas?

J'


Re: Special Memory Constraint [was Re: Indirect memory addresses vs. lra]

2019-08-16 Thread Vladimir Makarov



On 2019-08-16 7:23 a.m., John Darrington wrote:

On Thu, Aug 15, 2019 at 02:23:45PM -0400, Vladimir Makarov wrote:

  > I tried this solution earlier.  But unfortunately it makes things 
worse.  What happens is it libgcc cannot
  > even be built -- ICEs occur on a memory from  address reg insn such as:
  > (insn 117 2981 3697 5 (set (mem/f:PSI (plus:PSI (reg:PSI 1309)
  >  (const_int 102 [0x66])) [3 fs_129(D)->pc+0 S4 A8])
  >  (reg:PSI 1310)) 
"/home/jmd/Source/GCC2/libgcc/unwind-dw2.c":977:9 96 {movpsi}
  >
  I see.?? Then for the insn, you could try to create a pattern
  "memory,special memory constraint".?? The special memory constraint
  should satisfy only spilled pseudo (pseudo with reg_renumber == -1).?? I
  believe lra-constraints.c can spill the pseudo and the end you will have
  mem[disp1 + r8|r9|sp] = mem[disp1+sp].

You mean something like this:

(define_special_memory_constraint "a"
  "My special memory constraint"
  (match_operand 0 "my_special_predicate")
)

(define_predicate "my_special_predicate"
(match_operand 0 "memory_operand")
  {
   debug_rtx (op);
   if (MEM_P (op))
   {
 op = XEXP (op, 0);
 if (GET_CODE (op) == PLUS)
   {
op = XEXP (op, 0);
if (REG_P (op))
  {
fprintf (stderr, "Reg number is %d\n", REGNO (op));
if (REGNO (op) >= 0)
  return false;
  }
   }
   }
   return true;
})


No I meant something like that

(define_special_memory_constraint "a" ...)
(define_predicate "my_special_predicate" ...

 {
   if (lra_in_progress_p)
 return REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER && 
reg_renumber[REGNO(op)] < 0;
   return true if memory with sp addressing;
})

I think LRA spills pseudo-register and it will be memory addressed by sp 
at the end of LRA.



When I use this I get lots of the following ICEs

  "internal compiler error: maximum number of generated reload insns per insn 
achieved (90)"

It seems logical to me that this would happen since the constraint is not going 
to match any
operand with resolved registers.  Thus it will continually reload.

... which makes me think I've probably misunderstood what you are saying.

J'




Special Memory Constraint [was Re: Indirect memory addresses vs. lra]

2019-08-16 Thread John Darrington
On Thu, Aug 15, 2019 at 02:23:45PM -0400, Vladimir Makarov wrote:

 > I tried this solution earlier.  But unfortunately it makes things worse. 
 What happens is it libgcc cannot
 > even be built -- ICEs occur on a memory from  address reg insn such as:
 > (insn 117 2981 3697 5 (set (mem/f:PSI (plus:PSI (reg:PSI 1309)
 >  (const_int 102 [0x66])) [3 fs_129(D)->pc+0 S4 A8])
 >  (reg:PSI 1310)) 
"/home/jmd/Source/GCC2/libgcc/unwind-dw2.c":977:9 96 {movpsi}
 > 
 I see.?? Then for the insn, you could try to create a pattern
 "memory,special memory constraint".?? The special memory constraint
 should satisfy only spilled pseudo (pseudo with reg_renumber == -1).?? I
 believe lra-constraints.c can spill the pseudo and the end you will have
 mem[disp1 + r8|r9|sp] = mem[disp1+sp].

You mean something like this:

(define_special_memory_constraint "a"
 "My special memory constraint"
 (match_operand 0 "my_special_predicate")
)

(define_predicate "my_special_predicate"
(match_operand 0 "memory_operand")
 {
  debug_rtx (op);
  if (MEM_P (op))
  {
op = XEXP (op, 0);
if (GET_CODE (op) == PLUS)
  {
op = XEXP (op, 0);
if (REG_P (op))
  {
fprintf (stderr, "Reg number is %d\n", REGNO (op));
if (REGNO (op) >= 0)
  return false;
  }
  }
  }
  return true;
})

When I use this I get lots of the following ICEs

 "internal compiler error: maximum number of generated reload insns per 
insn achieved (90)"

It seems logical to me that this would happen since the constraint is not going 
to match any
operand with resolved registers.  Thus it will continually reload.

... which makes me think I've probably misunderstood what you are saying.

J'


-- 
Avoid eavesdropping.  Send strong encrypted email.
PGP Public key ID: 1024D/2DE827B3 
fingerprint = 8797 A26D 0854 2EAB 0285  A290 8A67 719C 2DE8 27B3
See http://sks-keyservers.net or any PGP keyserver for public key.