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]

Re: Unable to generate reloads



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>


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