This is the mail archive of the gcc-patches@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] |
Other format: | [Raw text] |
On Wed, Dec 11, 2013 at 1:13 AM, Richard Sandiford <rdsandiford@googlemail.com> wrote: > Richard Henderson <rth@redhat.com> writes: >> On 12/10/2013 10:44 AM, Richard Sandiford wrote: >>> Sorry, I don't understand. I never said it was invalid. I said >>> (subreg:SF (reg:V4SF X) 1) was invalid if (reg:V4SF X) represents >>> a single register. On a little-endian target, the offset cannot be >>> anything other than 0 in that case. >>> >>> So the CANNOT_CHANGE_MODE_CLASS code above seems to be checking for >>> something that is always invalid, regardless of the target. That kind >>> of situation should be rejected by target-independent code instead. >> >> But, we want to disable the subreg before we know whether or not (reg:V4SF X) >> will be allocated to a single hard register. That is something that we can't >> know in target-independent code before register allocation. > > I was thinking that if we've got a class, we've also got things like > CLASS_MAX_NREGS. Maybe that doesn't cope with padding properly though. > But even in the padding cases an offset-based check in C_C_M_C could > be derived from other information. > > subreg_get_info handles padding with: > > nregs_xmode = HARD_REGNO_NREGS_WITH_PADDING (xregno, xmode); > if (GET_MODE_INNER (xmode) == VOIDmode) > xmode_unit = xmode; > else > xmode_unit = GET_MODE_INNER (xmode); > gcc_assert (HARD_REGNO_NREGS_HAS_PADDING (xregno, xmode_unit)); > gcc_assert (nregs_xmode > == (GET_MODE_NUNITS (xmode) > * HARD_REGNO_NREGS_WITH_PADDING (xregno, xmode_unit))); > gcc_assert (hard_regno_nregs[xregno][xmode] > == (hard_regno_nregs[xregno][xmode_unit] > * GET_MODE_NUNITS (xmode))); > > /* You can only ask for a SUBREG of a value with holes in the middle > if you don't cross the holes. (Such a SUBREG should be done by > picking a different register class, or doing it in memory if > necessary.) An example of a value with holes is XCmode on 32-bit > x86 with -m128bit-long-double; it's represented in 6 32-bit registers, > 3 for each part, but in memory it's two 128-bit parts. > Padding is assumed to be at the end (not necessarily the 'high part') > of each unit. */ > if ((offset / GET_MODE_SIZE (xmode_unit) + 1 > < GET_MODE_NUNITS (xmode)) > && (offset / GET_MODE_SIZE (xmode_unit) > != ((offset + GET_MODE_SIZE (ymode) - 1) > / GET_MODE_SIZE (xmode_unit)))) > { > info->representable_p = false; > rknown = true; > } > > and I wouldn't really want to force targets to individually reproduce > that kind of logic at the class level. If the worst comes to the worst > we could cache the difficult cases. > My case is x86 CANNOT_CHANGE_MODE_CLASS only needs to know if the subreg byte is zero or not. It doesn't care about mode padding. You are concerned about information passed to CANNOT_CHANGE_MODE_CLASS is too expensive for target to process. It isn't the case for x86. Am I correct that mode can't change if subreg byte is non-zero? A target can just check subreg byte != 0, like my patch does. Here is a patch to add SUBREG_BYTE to CANNOT_CHANGE_MODE_CLASS. Tested on Linux/x86-64. Does it look OK? Thanks. -- H.J. --- 2013-12-11 H.J. Lu <hongjiu.lu@intel.com> * combine.c (subst): Pass subreg byte to REG_CANNOT_CHANGE_MODE_P. (simplify_set): Likewise. * emit-rtl.c (validate_subreg): Likewise. * recog.c (register_operand): Likewise. * rtlanal.c (simplify_subreg_regno): Likewise. * hard-reg-set.h (REG_CANNOT_CHANGE_MODE_P): Add SUBREG_BYTE and pass it to CANNOT_CHANGE_MODE_CLASS. * regcprop.c (mode_change_ok): Pass unknown subreg byte to REG_CANNOT_CHANGE_MODE_P. * reginfo.c (record_subregs_of_mode): Pass unknown subreg byte to CANNOT_CHANGE_MODE_CLASS. * postreload.c (reload_cse_simplify_set): Pass subreg byte to CANNOT_CHANGE_MODE_CLASS. (reload_cse_simplify_operands): Likewise. * reload.c (push_reload): Likewise. * reload1.c (choose_reload_regs): Pass subreg byte to REG_CANNOT_CHANGE_MODE_P. (inherit_piecemeal_p): Pass unknown subreg byte to REG_CANNOT_CHANGE_MODE_P. * config/aarch64/aarch64.h (CANNOT_CHANGE_MODE_CLASS): Add and ignore subreg byte. * config/alpha/alpha.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/arm/arm.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/ia64/ia64.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/m32c/m32c.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/mep/mep.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/mips/mips.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/msp430/msp430.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/pa/pa32-regs.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/pa/pa64-regs.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/pdp11/pdp11.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/rs6000/rs6000.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/s390/s390.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/score/score.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/sh/sh.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/sparc/sparc.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/spu/spu.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/i386/i386-protos.h (ix86_cannot_change_mode_class): Add an unsigned int argument. * config/i386/i386.c (ix86_cannot_change_mode_class): Take subreg byte. Return true only if subreg byte is non-zero. * config/i386/i386.h (CANNOT_CHANGE_MODE_CLASS): Add SUBREG_BYTE and pass it to ix86_cannot_change_mode_class. * doc/rtl.texi: Add subreg_byte to CANNOT_CHANGE_MODE_CLASS. * doc/tm.texi.in: Likewise. * doc/tm.texi: Regenerated.
Attachment:
0001-Add-subreg_byte-to-CANNOT_CHANGE_MODE_CLASS.patch
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |