This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
A question about push_reload()
- From: Rask Ingemann Lambertsen <rask at sygehus dot dk>
- To: gcc at gcc dot gnu dot org
- Date: Mon, 21 May 2007 18:50:55 +0200
- Subject: A question about push_reload()
I think push_reload() is doing something weird with this insn:
Breakpoint 1, find_reloads (insn=0xb7f7e348, replace=0, ind_levels=0, live_known=0, reload_reg_p=0x8878a7c) at ../../../cvssrc/gcc/gcc/reload.c:2535
2535 {
(gdb) call debug_rtx(insn)
(insn 12 10 16 2 /tmp/ashiftsi3_1.c:3 (parallel [
(set (subreg:HI (reg:SI 2 a [orig:20 D.1497 ] [20]) 0)
(ashift:HI (reg:HI 8 si [orig:26 x ] [26])
(const_int 1 [0x1])))
(clobber (reg:CC 13 cc))
]) 353 {*ashlhi3} (nil)
(expr_list:REG_DEAD (reg:HI 8 si [orig:26 x ] [26])
(expr_list:REG_UNUSED (reg:CC 13 cc)
(insn_list:REG_RETVAL 13 (nil)))))
where operands 0 and 1 must match. The resulting reloads are:
Spilling for insn 12.
Using reg 8 for reload 0
Reloads for insn # 12
Reload order: 0
Reload 0: reload_in (HI) = (reg:HI 26 [ x ])
reload_out (SI) = (reg:SI 2 a [orig:20 D.1497 ] [20])
GENERAL_REGS, RELOAD_OTHER (opnum = 0)
reload_in_reg: (reg:HI 26 [ x ])
reload_out_reg: (reg:SI 2 a [orig:20 D.1497 ] [20])
reload_reg_rtx: (reg:SI 8 si)
;; Register dispositions:
20 in 2 21 in 8 22 in 9 23 in 2 24 in 0 25 in 0
It seems unnecessary to create a SImode output reload here and worse, it
clobbers (reg:HI 4 d) which is live ((reg:SI 2 a) is four registers):
(insn 40 10 12 2 /tmp/ashiftsi3_1.c:3 (set (reg:HI 8 si)
(mem/c:HI (plus:HI (reg/f:HI 10 bp)
(const_int -2 [0xfffffffe])) [0 S2 A8])) 9 {*movhi} (nil)
(nil))
(insn 12 40 41 2 /tmp/ashiftsi3_1.c:3 (parallel [
(set (reg:HI 8 si)
(ashift:HI (reg:HI 8 si)
(const_int 1 [0x1])))
(clobber (reg:CC 13 cc))
]) 353 {*ashlhi3} (nil)
(nil))
(insn 41 12 42 2 /tmp/ashiftsi3_1.c:3 (set (reg:HI 2 a [orig:20 D.1497 ] [20])
(reg:HI 8 si)) 9 {*movhi} (nil)
(nil))
(insn 42 41 14 2 /tmp/ashiftsi3_1.c:3 (set (reg:HI 4 d [ D.1497+2 ])
(reg:HI 9 di [+2 ])) 9 {*movhi} (nil)
(nil))
Register di was dead at this point, btw. The call to push_reload() seems
OK:
push_reload (in=0xb7f833b0, out=0xb7f7578c, inloc=0xb7f758bc, outloc=0xb7f758c8, class=GENERAL_REGS, inmode=HImode, outmode=HImode, strict_low=0, optional=0,
opnum=0, type=RELOAD_OTHER) at ../../../cvssrc/gcc/gcc/reload.c:929
(gdb) call debug_rtx(in)
(reg:HI 8 si [orig:26 x ] [26])
(gdb) call debug_rtx(out)
(subreg:HI (reg:SI 2 a [orig:20 D.1497 ] [20]) 0)
Starting at line 1097 of reload.c is the interesting part:
/* Similarly for paradoxical and problematical SUBREGs on the output.
Note that there is no reason we need worry about the previous value
of SUBREG_REG (out); even if wider than out,
storing in a subreg is entitled to clobber it all
(except in the case of STRICT_LOW_PART,
and in that case the constraint should label it input-output.) */
[...]
|| (REG_P (SUBREG_REG (out))
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
&& ((GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
&& (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
> UNITS_PER_WORD)
&& ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
/ UNITS_PER_WORD)
!= (int) hard_regno_nregs[REGNO (SUBREG_REG (out))]
[GET_MODE (SUBREG_REG (out))]))
|| ! HARD_REGNO_MODE_OK (subreg_regno (out), outmode)))
[...]
{
out_subreg_loc = outloc;
outloc = &SUBREG_REG (out);
out = *outloc;
#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
gcc_assert (!MEM_P (out)
|| GET_MODE_SIZE (GET_MODE (out))
<= GET_MODE_SIZE (outmode));
#endif
outmode = GET_MODE (out);
}
What is the condition with hard_regno_nregs[][] supposed to check?
In this particular case, we have:
GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) = 4
UNITS_PER_WORD = 2
hard_regno_nregs[2][SImode] = 4 (8-bit registers)
so the condition 4 / 2 != 4 is true and reload thinks the SUBREG is
problematical. I don't see what is problematical about it.
I tried to "svn blame" someone, but ended with:
------------------------------------------------------------------------
r363 | kenner | 1992-02-28 11:23:25 +0100 (fre, 28 feb 1992) | 2 lines
Initial revision
------------------------------------------------------------------------
--
Rask Ingemann Lambertsen