public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Unable to generate reloads
@ 2001-09-21  6:09 Lars Brinkhoff
  2001-09-21 21:16 ` Joern Rennecke
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Lars Brinkhoff @ 2001-09-21  6:09 UTC (permalink / raw)
  To: gcc

In my back end, there is an instruction that can load a value from
memory (or another register) and then conditionally jump depending on
how the value compares with zero.  The instruction is recognized by
the combine pass and is defined like this:

(define_insn "*load_and_jump"
  [(set (pc)
	(if_then_else (match_operator 0 "comparison_operator"
		       [(match_operand:SI 2 "reg_or_mem_operand" "rm")
		        (const_int 0)])
	 (label_ref (match_operand 3 "" ""))
	 (pc)))
   (set (match_operand:SI 1 "register_operand" "=r")
	(match_dup 2))]
  ...)

A few files in the testsuite generate the "Unable to generate reloads
for:" error for this instruction.  Example:

testsuite/gcc.c-torture/compile/920625-1.c:279: Unable to generate reloads for:
(jump_insn 45 4975 5103 (parallel[ 
            (set (pc)
                (if_then_else (ge (reg:SI 1217)
                        (const_int 0 [0x0]))
                    (label_ref 48)
                    (pc)))
            (set (reg/v:SI 30)
                (reg:SI 1217))
        ] ) 68 {*move_and_skipsi} (nil)
    (expr_list:REG_DEAD (reg:SI 1217)
        (expr_list:REG_BR_PROB (const_int 8900 [0x22c4])
            (nil))))

How do I avoid this error?

-- 
Lars Brinkhoff          http://lars.nocrew.org/     Linux, GCC, PDP-10
Brinkhoff Consulting    http://www.brinkhoff.se/    programming

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Unable to generate reloads
  2001-09-21  6:09 Unable to generate reloads Lars Brinkhoff
@ 2001-09-21 21:16 ` Joern Rennecke
  2001-09-24  2:41   ` Lars Brinkhoff
  2001-09-21 21:26 ` Joern Rennecke
  2001-09-24  6:37 ` Lars Brinkhoff
  2 siblings, 1 reply; 9+ messages in thread
From: Joern Rennecke @ 2001-09-21 21:16 UTC (permalink / raw)
  To: Lars Brinkhoff; +Cc: gcc

> testsuite/gcc.c-torture/compile/920625-1.c:279: Unable to generate reloads for:
> (jump_insn 45 4975 5103 (parallel[ 
>             (set (pc)
>                 (if_then_else (ge (reg:SI 1217)
>                         (const_int 0 [0x0]))
>                     (label_ref 48)
>                     (pc)))
>             (set (reg/v:SI 30)
>                 (reg:SI 1217))
>         ] ) 68 {*move_and_skipsi} (nil)
>     (expr_list:REG_DEAD (reg:SI 1217)
>         (expr_list:REG_BR_PROB (const_int 8900 [0x22c4])
>             (nil))))
> 
> How do I avoid this error?

It depends.  How many GENERAL_REGS spill registers are available?
What are the allocations / equivalences for pseudos 30 and 1217,
and what addressing modes are available to address them?
Dou you need secondary reload registers and / or secondary memory?
What are the values of the pertaining register elimination offsets at this
point, if there are any?

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Unable to generate reloads
  2001-09-21  6:09 Unable to generate reloads Lars Brinkhoff
  2001-09-21 21:16 ` Joern Rennecke
@ 2001-09-21 21:26 ` Joern Rennecke
  2001-09-24  6:37 ` Lars Brinkhoff
  2 siblings, 0 replies; 9+ messages in thread
From: Joern Rennecke @ 2001-09-21 21:26 UTC (permalink / raw)
  To: Lars Brinkhoff; +Cc: gcc

> How do I avoid this error?

P.S.:  if you have a HAVE_cc0 port, don't use that pattern.  It can't be
made to work.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Unable to generate reloads
  2001-09-21 21:16 ` Joern Rennecke
@ 2001-09-24  2:41   ` Lars Brinkhoff
  0 siblings, 0 replies; 9+ messages in thread
From: Lars Brinkhoff @ 2001-09-24  2:41 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: gcc

Joern Rennecke <amylaar@onetel.net.uk> writes:
> > testsuite/gcc.c-torture/compile/920625-1.c:279: Unable to generate reloads for:
> > (jump_insn 45 4975 5103 (parallel[ 
> >             (set (pc)
> >                 (if_then_else (ge (reg:SI 1217)
> >                         (const_int 0 [0x0]))
> >                     (label_ref 48)
> >                     (pc)))
> >             (set (reg/v:SI 30)
> >                 (reg:SI 1217))
> >         ] ) 68 {*move_and_skipsi} (nil)
> >     (expr_list:REG_DEAD (reg:SI 1217)
> >         (expr_list:REG_BR_PROB (const_int 8900 [0x22c4])
> >             (nil))))
> > How do I avoid this error?
> It depends.  How many GENERAL_REGS spill registers are available?

There are 16 GENERAL_REGS, and at the point of error, n_spills = 0.

> What are the allocations / equivalences for pseudos 30 and 1217,

reg_renumber[30] = -1
reg_renumber[1217] = -1
reg_equiv_mem[30] = (mem:SI (plus:SI (reg/f:SI 15) (const_int -312)))
reg_equiv_mem[1217] = (mem:SI (plus:SI (reg/f:SI 15) (const_int -16)))

(reg/f:SI 15) is the stack pointer.

> and what addressing modes are available to address them?

reg:SI, (plus:SI reg:SI const_int), and (mem:SI (plus:SI reg:SI const_int))
are all valid addresses when the const_int offset is small enough.

> Dou you need secondary reload registers and / or secondary memory?

No, all registers can be moved directly to/from memory and other
register.

> What are the values of the pertaining register elimination offsets
> at this point, if there are any?

reg_eliminate[0] =
{ from = 13, to = 15, initial_offset = -2216, can_eliminate = 1,
  can_eliminate_previous = 1, offset = -2216, previous_offset = -2216,
  ref_outside_mem = 0, from_frx = 0x3002a018, to_rtx = 0x3001a000 }

> P.S.:  if you have a HAVE_cc0 port, don't use that pattern.  It can't be
> made to work.

No, it's not a HAVE_cc0 port.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Unable to generate reloads
  2001-09-21  6:09 Unable to generate reloads Lars Brinkhoff
  2001-09-21 21:16 ` Joern Rennecke
  2001-09-21 21:26 ` Joern Rennecke
@ 2001-09-24  6:37 ` Lars Brinkhoff
  2001-09-24 13:10   ` Geoff Keating
  2 siblings, 1 reply; 9+ messages in thread
From: Lars Brinkhoff @ 2001-09-24  6:37 UTC (permalink / raw)
  To: gcc

Lars Brinkhoff <lars@nocrew.org> writes:
> In my back end, there is an instruction that can load a value from
> memory (or another register) and then conditionally jump depending on
> how the value compares with zero:
> 
> (define_insn "*move_and_skipsi"
>   [(set (pc)
> 	(if_then_else (match_operator 0 "comparison_operator"
> 		       [(match_operand:SI 2 "reg_or_mem_operand" "rm")
> 		        (const_int 0)])
> 	 (label_ref (match_operand 3 "" ""))
> 	 (pc)))
>    (set (match_operand:SI 1 "register_operand" "=r")
> 	(match_dup 2))]
>   ...)
> 
> A few files in the testsuite generate the "Unable to generate reloads
> for:" error for this instruction.  Example:
> 
> testsuite/gcc.c-torture/compile/920625-1.c:279: Unable to generate reloads for:
> (jump_insn 45 4975 5103 (parallel[ 
>             (set (pc)
>                 (if_then_else (ge (reg:SI 1217)
>                         (const_int 0 [0x0]))
>                     (label_ref 48)
>                     (pc)))
>             (set (reg/v:SI 30)
>                 (reg:SI 1217))
>         ] ) 68 {*move_and_skipsi} (nil)
>     (expr_list:REG_DEAD (reg:SI 1217)
>         (expr_list:REG_BR_PROB (const_int 8900 [0x22c4])
>             (nil))))

It seems that the explanation to this is in reload.c:find_reloads:

  /* JUMP_INSNs and CALL_INSNs are not allowed to have any output reloads;
     neither are insns that SET cc0.  Insns that use CC0 are not allowed
     to have any input reloads.  */
  if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN)
    no_output_reloads = 1;

If the register being loaded (pseudo 30 above) didn't get a hard
register, the instruction fails later in find_reloads:

	      /* Alternative loses if it requires a type of reload not
		 permitted for this insn.  We can always reload SCRATCH
		 and objects with a REG_UNUSED note.  */
	      else if (GET_CODE (operand) != SCRATCH
		       && modified[i] != RELOAD_READ && no_output_reloads
		       && ! find_reg_note (insn, REG_UNUSED, operand))
		bad = 1;

Does this mean that I must add an alternative to operand 1 to store
into a memory location?

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Unable to generate reloads
  2001-09-24  6:37 ` Lars Brinkhoff
@ 2001-09-24 13:10   ` Geoff Keating
  0 siblings, 0 replies; 9+ messages in thread
From: Geoff Keating @ 2001-09-24 13:10 UTC (permalink / raw)
  To: Lars Brinkhoff; +Cc: gcc

Lars Brinkhoff <lars.spam@nocrew.org> writes:

> Lars Brinkhoff <lars@nocrew.org> writes:
> > In my back end, there is an instruction that can load a value from
> > memory (or another register) and then conditionally jump depending on
> > how the value compares with zero:
> > 
> > (define_insn "*move_and_skipsi"
> >   [(set (pc)
> > 	(if_then_else (match_operator 0 "comparison_operator"
> > 		       [(match_operand:SI 2 "reg_or_mem_operand" "rm")
> > 		        (const_int 0)])
> > 	 (label_ref (match_operand 3 "" ""))
> > 	 (pc)))
> >    (set (match_operand:SI 1 "register_operand" "=r")
> > 	(match_dup 2))]
> >   ...)
> > 
> > A few files in the testsuite generate the "Unable to generate reloads
> > for:" error for this instruction.  Example:
> > 
> > testsuite/gcc.c-torture/compile/920625-1.c:279: Unable to generate reloads for:
> > (jump_insn 45 4975 5103 (parallel[ 
> >             (set (pc)
> >                 (if_then_else (ge (reg:SI 1217)
> >                         (const_int 0 [0x0]))
> >                     (label_ref 48)
> >                     (pc)))
> >             (set (reg/v:SI 30)
> >                 (reg:SI 1217))
> >         ] ) 68 {*move_and_skipsi} (nil)
> >     (expr_list:REG_DEAD (reg:SI 1217)
> >         (expr_list:REG_BR_PROB (const_int 8900 [0x22c4])
> >             (nil))))
> 
> It seems that the explanation to this is in reload.c:find_reloads:
> 
>   /* JUMP_INSNs and CALL_INSNs are not allowed to have any output reloads;
>      neither are insns that SET cc0.  Insns that use CC0 are not allowed
>      to have any input reloads.  */
>   if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN)
>     no_output_reloads = 1;
> 
> If the register being loaded (pseudo 30 above) didn't get a hard
> register, the instruction fails later in find_reloads:
> 
> 	      /* Alternative loses if it requires a type of reload not
> 		 permitted for this insn.  We can always reload SCRATCH
> 		 and objects with a REG_UNUSED note.  */
> 	      else if (GET_CODE (operand) != SCRATCH
> 		       && modified[i] != RELOAD_READ && no_output_reloads
> 		       && ! find_reg_note (insn, REG_UNUSED, operand))
> 		bad = 1;
> 
> Does this mean that I must add an alternative to operand 1 to store
> into a memory location?

The problem is that reload doesn't know how to add instructions after
a jump---it would need to add them both at the destination of the
jump, and possibly after the jump if it is conditional.

So, you need to make sure that reload can never need to add any
instruction after the branch.

Yes, I think that adding an alternative for a memory location would fix
this problem.

-- 
- Geoffrey Keating <geoffk@geoffk.org>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Unable to generate reloads
  2002-03-18  7:23 ` Alan Lehotsky
@ 2002-03-19  5:09   ` Alexandre Courbot
  0 siblings, 0 replies; 9+ messages in thread
From: Alexandre Courbot @ 2002-03-19  5:09 UTC (permalink / raw)
  To: Alan Lehotsky; +Cc: GCC List


> reload comes into play when a pattern in the .md file matches an INSN in the
> function you are compiling, but the constraint letters DON'T match.   So, it
> would seem very likely that the define_insn pattern you have for QI moves
> doesn't have a pair of matching constraints that the source and destination
> are compatible with.

That was exactly this. The mem <- immediate case wasn't recognized by my
constraints - actually I misunderstood their use, which led me to this
error. After fixing this one, similar others appeared, but thanks to
your answer they have been easily fixed as well. Now the same program
does compile and generates an assembler code that makes sense, and -
most important - isns are more understandable to me ;)

Many thanks!
Alex.
-- 
http://www.gnurou.org


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Unable to generate reloads
  2002-03-18  6:15 Alexandre Courbot
@ 2002-03-18  7:23 ` Alan Lehotsky
  2002-03-19  5:09   ` Alexandre Courbot
  0 siblings, 1 reply; 9+ messages in thread
From: Alan Lehotsky @ 2002-03-18  7:23 UTC (permalink / raw)
  To: Alexandre Courbot; +Cc: GCC List

You really haven't provided enough information for a definitive diagnosis, but....

reload comes into play when a pattern in the .md file matches an INSN in the
function you are compiling, but the constraint letters DON'T match.   So, it
would seem very likely that the define_insn pattern you have for QI moves
doesn't have a pair of matching constraints that the source and destination
are compatible with.

In the case that the constraints don't match, reload has some heuristics that it uses
to transform the INSN into a sequence of insns using compatible constraints.  (Typically,
it tries something like moving the source operand to a register and then using the register
as the source of the move to memory - if you don't have any registers, that constraint is
going to fail miserably......

You might want to share the define_insn pattern with us, or just check to see that you have
a "m" constraint on the destination and a "i" constraint on the source (in the same position on
the comma-list of alternatives....)  Take a look at almost any existing machine's "movqi" pattern and
the associated define_insn that matches the emitted (SET (..) (...)) rtl.


At 3:14 PM +0100 3/18/02, Alexandre Courbot wrote:

>Hello everybody,
>
>I'm currently porting GCC to our architecture. I managed to get a basic
>MD completed so GCC does compile, but when trying to compile the
>following simple program:
>
>char c;
>
>int barfunc()
>{
>    c = 2;
>}
>
>But GCC complains:
>
>test.c: In function `barfunc':
>test.c:6: Unable to generate reloads for:
>
>(insn 9 8 10 (set (mem/f:QI (reg/f:SI 15) 0)
>        (const_int 2 [0x2])) 1 {movqi} (nil)
>    (expr_list:REG_DEAD (reg/f:SI 15)
>        (nil)))
>test.c:6: Internal compiler error in find_reloads, at reload.c:3486
>
From the manual, it looks like there is a problem with the register
>allocation or something like this, as it fails in the reload pass - but
>I still can't get what's wrong with it. It's the first time I mess with
>GCC, and a lot of its internals are still unclear to me. Although the
>machine I'm porting GCC to is register-less, I've defined 10 dummy
>hard-register for testing purposes. Does someone see something I missed
>and could give me a pointer to where the error could come from? Should I
>provide more information?

	
>
>Thank you for your time,
>Alex.
>--
>http://www.gnurou.org

-- 
------------------------------------------------------------------------

		    Quality Software Management
		http://home.earthlink.net/~qsmgmt
			apl@alum.mit.edu
			(978)287-0435 Voice
			(978)808-6836 Cell
			(978)287-0436 Fax

	Software Process Improvement and Management Consulting
	     Language Design and Compiler Implementation

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Unable to generate reloads
@ 2002-03-18  6:15 Alexandre Courbot
  2002-03-18  7:23 ` Alan Lehotsky
  0 siblings, 1 reply; 9+ messages in thread
From: Alexandre Courbot @ 2002-03-18  6:15 UTC (permalink / raw)
  To: GCC List

Hello everybody,

I'm currently porting GCC to our architecture. I managed to get a basic
MD completed so GCC does compile, but when trying to compile the
following simple program:

char c;

int barfunc()
{
    c = 2;
}

But GCC complains:

test.c: In function `barfunc':
test.c:6: Unable to generate reloads for:

(insn 9 8 10 (set (mem/f:QI (reg/f:SI 15) 0)
        (const_int 2 [0x2])) 1 {movqi} (nil)
    (expr_list:REG_DEAD (reg/f:SI 15)
        (nil)))
test.c:6: Internal compiler error in find_reloads, at reload.c:3486

From the manual, it looks like there is a problem with the register
allocation or something like this, as it fails in the reload pass - but
I still can't get what's wrong with it. It's the first time I mess with
GCC, and a lot of its internals are still unclear to me. Although the
machine I'm porting GCC to is register-less, I've defined 10 dummy
hard-register for testing purposes. Does someone see something I missed
and could give me a pointer to where the error could come from? Should I
provide more information?

Thank you for your time,
Alex.
-- 
http://www.gnurou.org


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2002-03-19 12:33 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-09-21  6:09 Unable to generate reloads Lars Brinkhoff
2001-09-21 21:16 ` Joern Rennecke
2001-09-24  2:41   ` Lars Brinkhoff
2001-09-21 21:26 ` Joern Rennecke
2001-09-24  6:37 ` Lars Brinkhoff
2001-09-24 13:10   ` Geoff Keating
2002-03-18  6:15 Alexandre Courbot
2002-03-18  7:23 ` Alan Lehotsky
2002-03-19  5:09   ` Alexandre Courbot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).