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]

[patch] postreload.c: Teach move2add how to handle single_set.


Hi,

Attached is a patch to teach move2add how to handle single_set as a
part of merge from my MODE_CC version of h8300 port.  (Note that
move2add only handle naked SETS.)

The meat of the change is to use single_set (insn) instead of
PATTERN (insn), which you can find in the second hunk of the patch.

If some transformation (to either PLUS or STRICT_LOW_PART) is
prepared, we try to install the change to the location of the original
set.  For example, if the original insn has a pattern like

(parallel [(set (reg X) (const_int Y))
           (clobber (reg Z))])

the new pattern would look like

(parallel [(set (reg X) (plus (reg X) (const_int Y')))
           (clobber (reg Z))])

or

(parallel [(set (strict_low_part (reg X)) (const_int Y''))
           (clobber (reg Z))])

Since this patch accepts single sets, we now need to keep track of
side effects outside of single sets, such as clobbers of hard
registers.  With this patch, reload_cse_move2add() delegates all the
book keeping work of reg_luid and its friends to move2add_note_store.
(See removal of two "continue" statements.)

Among the book keeping work, STRICT_LOW_PART is the only thing that
reload_cse_move2add handles but move2add_note_store does not, so I
added this feature to move2add_note_store.

The rest of the patch replaces "pat" with "set" for clarity.

Tested on i686-pc-linux-gnu.  OK to apply?

Kazu Hirata

2004-02-26  Kazu Hirata  <kazu@cs.umass.edu>

	* postreload.c (reload_cse_move2add): Support single sets.
	Delegate all the book keeping work to move2add_note_store.
	(move2add_note_store): Handle STRICT_LOW_PART.

Index: postreload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/postreload.c,v
retrieving revision 2.14
diff -c -r2.14 postreload.c
*** postreload.c	26 Feb 2004 23:19:27 -0000	2.14
--- postreload.c	27 Feb 2004 03:59:05 -0000
***************
*** 1190,1196 ****
    move2add_luid = 2;
    for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++)
      {
!       rtx pat, note;
  
        if (GET_CODE (insn) == CODE_LABEL)
  	{
--- 1190,1196 ----
    move2add_luid = 2;
    for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++)
      {
!       rtx set, note;
  
        if (GET_CODE (insn) == CODE_LABEL)
  	{
***************
*** 1203,1217 ****
  	}
        if (! INSN_P (insn))
  	continue;
-       pat = PATTERN (insn);
        /* For simplicity, we only perform this optimization on
! 	 straightforward SETs.  */
!       if (GET_CODE (pat) == SET
! 	  && GET_CODE (SET_DEST (pat)) == REG)
  	{
! 	  rtx reg = SET_DEST (pat);
  	  int regno = REGNO (reg);
! 	  rtx src = SET_SRC (pat);
  
  	  /* Check if we have valid information on the contents of this
  	     register in the mode of REG.  */
--- 1203,1216 ----
  	}
        if (! INSN_P (insn))
  	continue;
        /* For simplicity, we only perform this optimization on
! 	 single sets.  */
!       set = single_set (insn);
!       if (set && GET_CODE (SET_DEST (set)) == REG)
  	{
! 	  rtx reg = SET_DEST (set);
  	  int regno = REGNO (reg);
! 	  rtx src = SET_SRC (set);
  
  	  /* Check if we have valid information on the contents of this
  	     register in the mode of REG.  */
***************
*** 1250,1262 ****
  			 (reg)), would be discarded.  Maybe we should
  			 try a truncMN pattern?  */
  		      if (INTVAL (src) == reg_offset [regno])
! 			validate_change (insn, &SET_SRC (pat), reg, 0);
  		    }
  		  else if (rtx_cost (new_src, PLUS) < rtx_cost (src, SET)
  			   && have_add2_insn (reg, new_src))
  		    {
  		      rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src);
! 		      validate_change (insn, &SET_SRC (pat), tem, 0);
  		    }
  		  else
  		    {
--- 1249,1261 ----
  			 (reg)), would be discarded.  Maybe we should
  			 try a truncMN pattern?  */
  		      if (INTVAL (src) == reg_offset [regno])
! 			validate_change (insn, &SET_SRC (set), reg, 0);
  		    }
  		  else if (rtx_cost (new_src, PLUS) < rtx_cost (src, SET)
  			   && have_add2_insn (reg, new_src))
  		    {
  		      rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src);
! 		      validate_change (insn, &SET_SRC (set), tem, 0);
  		    }
  		  else
  		    {
***************
*** 1281,1296 ****
  					     gen_rtx_STRICT_LOW_PART (VOIDmode,
  								      narrow_reg),
  					     narrow_src);
! 			      if (validate_change (insn, &PATTERN (insn),
! 						   new_set, 0))
  				break;
  			    }
  			}
  		    }
- 		  reg_set_luid[regno] = move2add_luid;
- 		  reg_mode[regno] = GET_MODE (reg);
- 		  reg_offset[regno] = INTVAL (src);
- 		  continue;
  		}
  
  	      /* Try to transform (set (REGX) (REGY))
--- 1280,1290 ----
  					     gen_rtx_STRICT_LOW_PART (VOIDmode,
  								      narrow_reg),
  					     narrow_src);
! 			      if (validate_replace_rtx (set, new_set, insn))
  				break;
  			    }
  			}
  		    }
  		}
  
  	      /* Try to transform (set (REGX) (REGY))
***************
*** 1348,1360 ****
  					       newpat, 0);
  			}
  		      if (success)
! 			delete_insn (insn);
! 		      insn = next;
! 		      reg_mode[regno] = GET_MODE (reg);
! 		      reg_offset[regno] =
! 			trunc_int_for_mode (added_offset + base_offset,
! 					    GET_MODE (reg));
! 		      continue;
  		    }
  		}
  	    }
--- 1342,1351 ----
  					       newpat, 0);
  			}
  		      if (success)
! 			{
! 			  delete_insn (insn);
! 			  insn = next;
! 			}
  		    }
  		}
  	    }
***************
*** 1445,1450 ****
--- 1436,1457 ----
  
    regno += REGNO (dst);
  
+   if (SCALAR_INT_MODE_P (mode)
+       && hard_regno_nregs[regno][mode] == 1 && GET_CODE (set) == SET
+       && GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
+     {
+       rtx src = SET_SRC (set);
+ 
+       if (reg_set_luid[regno] > move2add_last_label_luid
+ 	  && MODES_OK_FOR_MOVE2ADD (GET_MODE (dst), reg_mode[regno])
+ 	  && GET_CODE (src) == CONST_INT && reg_base_reg[regno] < 0)
+ 	{
+ 	  reg_set_luid[regno] = move2add_luid;
+ 	  reg_offset[regno] &= ~GET_MODE_MASK (mode);
+ 	  reg_offset[regno] |= INTVAL (src) & GET_MODE_MASK (mode);
+ 	  return;
+ 	}
+     }
    if (SCALAR_INT_MODE_P (mode)
        && hard_regno_nregs[regno][mode] == 1 && GET_CODE (set) == SET
        && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT


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