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]

SECONDARY_MEMORY_NEEDED fix


Hi,
this has shown up during adding the x86_64 TImode support.  There was
instruction moving data from xmm register subregged to DImode into integer
register and didn't get proper reload, as reload is checking secondary memory
just for regs, not for subregs.  I am not 100% sure whether the subregs are not
expected to be elliminated somewhere else, but they don't seem to be.

Again this applies to both 3.2 and mainline tree and bootstraps both.

Honza

Po srp 26 20:30:47 CEST 2002  Jan Hubicka  <jh@suse.cz>
	* reload.c (push_reload): Handle subregs and secondary memory.
	* reload1.c (gen_reload): Likewise.
*** 3/gcc-3.2/gcc/reload.c	Thu Jun 13 18:08:12 2002
--- gcc-3.2/gcc/reload.c	Mon Aug 26 20:19:03 2002
*************** push_reload (in, out, inloc, outloc, cla
*** 1283,1294 ****
  	 So add an additional reload.  */
  
  #ifdef SECONDARY_MEMORY_NEEDED
!       /* If a memory location is needed for the copy, make one.  */
!       if (in != 0 && GET_CODE (in) == REG
! 	  && REGNO (in) < FIRST_PSEUDO_REGISTER
! 	  && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (in)),
! 				      class, inmode))
! 	get_secondary_mem (in, inmode, opnum, type);
  #endif
  
        i = n_reloads;
--- 1283,1301 ----
  	 So add an additional reload.  */
  
  #ifdef SECONDARY_MEMORY_NEEDED
!       {
! 	unsigned int regno = FIRST_PSEUDO_REGISTER;
! 	if (in && REG_P (in))
! 	   regno = REGNO (in);
! 	else if (in && GET_CODE (in) == SUBREG)
! 	   regno = REGNO (SUBREG_REG (in));
! 
! 	/* If a memory location is needed for the copy, make one.  */
! 	if (regno < FIRST_PSEUDO_REGISTER
! 	    && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (regno),
! 					class, inmode))
! 	  get_secondary_mem (in, inmode, opnum, type);
!       }
  #endif
  
        i = n_reloads;
*************** push_reload (in, out, inloc, outloc, cla
*** 1314,1324 ****
        n_reloads++;
  
  #ifdef SECONDARY_MEMORY_NEEDED
!       if (out != 0 && GET_CODE (out) == REG
! 	  && REGNO (out) < FIRST_PSEUDO_REGISTER
! 	  && SECONDARY_MEMORY_NEEDED (class, REGNO_REG_CLASS (REGNO (out)),
! 				      outmode))
! 	get_secondary_mem (out, outmode, opnum, type);
  #endif
      }
    else
--- 1321,1339 ----
        n_reloads++;
  
  #ifdef SECONDARY_MEMORY_NEEDED
!       {
! 	unsigned int regno = FIRST_PSEUDO_REGISTER;
! 	if (out && REG_P (out))
! 	   regno = REGNO (out);
! 	else if (out && GET_CODE (out) == SUBREG)
! 	   regno = REGNO (SUBREG_REG (out));
! 
! 	/* If a memory location is needed for the copy, make one.  */
! 	if (regno < FIRST_PSEUDO_REGISTER
! 	    && SECONDARY_MEMORY_NEEDED (class, REGNO_REG_CLASS (regno),
! 					outmode))
! 	  get_secondary_mem (out, outmode, opnum, type);
! 	}
  #endif
      }
    else
*** 3/gcc-3.2/gcc/reload1.c	Wed May 22 01:42:54 2002
--- gcc-3.2/gcc/reload1.c	Mon Aug 26 20:11:39 2002
*************** gen_reload (out, in, opnum, type)
*** 7354,7359 ****
--- 7354,7362 ----
  {
    rtx last = get_last_insn ();
    rtx tem;
+   int inregno = FIRST_PSEUDO_REGISTER;
+   int outregno = FIRST_PSEUDO_REGISTER;
+ 
  
    /* If IN is a paradoxical SUBREG, remove it and try to put the
       opposite SUBREG on OUT.  Likewise for a paradoxical SUBREG on OUT.  */
*************** gen_reload (out, in, opnum, type)
*** 7368,7373 ****
--- 7371,7385 ----
  	   && (tem = gen_lowpart_common (GET_MODE (SUBREG_REG (out)), in)) != 0)
      out = SUBREG_REG (out), in = tem;
  
+   if (REG_P (in))
+     inregno = REGNO (in);
+   else if (GET_CODE (in) == SUBREG)
+     inregno = REGNO (SUBREG_REG (in));
+   if (REG_P (out))
+     outregno = REGNO (out);
+   else if (GET_CODE (out) == SUBREG)
+     outregno = REGNO (SUBREG_REG (out));
+ 
    /* How to do this reload can get quite tricky.  Normally, we are being
       asked to reload a simple operand, such as a MEM, a constant, or a pseudo
       register that didn't get a hard register.  In that case we can just
*************** gen_reload (out, in, opnum, type)
*** 7516,7535 ****
  
  #ifdef SECONDARY_MEMORY_NEEDED
    /* If we need a memory location to do the move, do it that way.  */
!   else if (GET_CODE (in) == REG && REGNO (in) < FIRST_PSEUDO_REGISTER
! 	   && GET_CODE (out) == REG && REGNO (out) < FIRST_PSEUDO_REGISTER
! 	   && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (in)),
! 				       REGNO_REG_CLASS (REGNO (out)),
  				       GET_MODE (out)))
      {
        /* Get the memory to use and rewrite both registers to its mode.  */
        rtx loc = get_secondary_mem (in, GET_MODE (out), opnum, type);
  
        if (GET_MODE (loc) != GET_MODE (out))
! 	out = gen_rtx_REG (GET_MODE (loc), REGNO (out));
  
        if (GET_MODE (loc) != GET_MODE (in))
! 	in = gen_rtx_REG (GET_MODE (loc), REGNO (in));
  
        gen_reload (loc, in, opnum, type);
        gen_reload (out, loc, opnum, type);
--- 7528,7547 ----
  
  #ifdef SECONDARY_MEMORY_NEEDED
    /* If we need a memory location to do the move, do it that way.  */
!   else if (inregno < FIRST_PSEUDO_REGISTER
! 	   && outregno < FIRST_PSEUDO_REGISTER
! 	   && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (inregno),
! 				       REGNO_REG_CLASS (outregno),
  				       GET_MODE (out)))
      {
        /* Get the memory to use and rewrite both registers to its mode.  */
        rtx loc = get_secondary_mem (in, GET_MODE (out), opnum, type);
  
        if (GET_MODE (loc) != GET_MODE (out))
! 	out = gen_rtx_REG (GET_MODE (loc), outregno);
  
        if (GET_MODE (loc) != GET_MODE (in))
! 	in = gen_rtx_REG (GET_MODE (loc), inregno);
  
        gen_reload (loc, in, opnum, type);
        gen_reload (out, loc, opnum, type);


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