[tree-ssa] Further improve EQ_EXPR_VALUE handling

law@redhat.com law@redhat.com
Thu Sep 25 17:52:00 GMT 2003



Given:

struct rtx_def;
typedef struct rtx_def *rtx;
struct rtx_def
{
  int bb;
};
static int *block_to_bb;
static int target_bb;
static int
rgn_rank (rtx insn1, rtx insn2)
{
  if (block_to_bb[insn1->bb] != block_to_bb[insn2->bb])
    if (block_to_bb[insn2->bb] == target_bb
        && block_to_bb[insn1->bb] != target_bb)
      return 1;
}


This is effectively

  if (a != b)
    if (b == c)
      if (a != c)
        return 1

by recording B as the current value for C and C as the current value for B,
then we can easily determine that a != c.  I'll be checking in a test for
this momentarily.

Note this is safe since we don't do any loops when looking up things
in the const_and_copies table.


This patch also cleans up a few tests which used SSA_VAR_P to just check
for SSA_NAMEs..


	* tree-ssa-dom.c (optimize_block): When EQ_EXPR_VALUE has the
	form DEST = SRC where both DEST and SRC are SSA_NAMEs also
	record SRC = DEST into the const and copies table.

	* tree-ssa-dom.c (optimize_block): Change tests which checked
	for SSA_VAR_P to only allow SSA_NAMEs.
	(get_value_for, set_value_for): Likewise.
	(lookup_avail_expr, get_eq_expr_value): Likewise.

Index: tree-ssa-dom.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dom.c,v
retrieving revision 1.1.2.47
diff -c -3 -p -r1.1.2.47 tree-ssa-dom.c
*** tree-ssa-dom.c	25 Sep 2003 05:34:39 -0000	1.1.2.47
--- tree-ssa-dom.c	25 Sep 2003 17:34:44 -0000
*************** optimize_block (basic_block bb, tree par
*** 444,449 ****
--- 444,474 ----
        VARRAY_PUSH_TREE (block_const_and_copies, dest);
        VARRAY_PUSH_TREE (block_const_and_copies, prev_value);
  
+       /* If the source is also an SSA_NAME, then we want to record
+ 	 DEST as the current value for SRC as well.  This allow us
+ 	 to detect that a == c will always be true in code like the
+ 	 following:
+ 
+ 	   if (a == b)
+ 	     {
+ 	       if (b == c)
+ 		 {
+ 		    if (a == c)
+ 		      {
+ 		      }
+ 		 }
+ 	     }
+ 
+ 	 This actually happens in real code.  */
+       if (TREE_CODE (src) == SSA_NAME)
+ 	{
+ 	  prev_value = get_value_for (src, const_and_copies);
+ 	  set_value_for (src, dest, const_and_copies);
+ 
+ 	  VARRAY_PUSH_TREE (block_const_and_copies, src);
+ 	  VARRAY_PUSH_TREE (block_const_and_copies, prev_value);
+ 	}
+ 
        /* If the new value is a constant, then look at DEST's defining
  	 statement.  If DEST was defined as the result of a typecast,
  	 we may be able to record additional equivalences.  */
*************** optimize_block (basic_block bb, tree par
*** 601,609 ****
  #endif
  
  	  /* The alternative may be associated with a constant, so verify
! 	     it is an SSA_VAR before doing anything with it.  */
  	  orig_p = &PHI_ARG_DEF (phi, hint);
! 	  if (! SSA_VAR_P (*orig_p))
  	    continue;
  
  	  /* If we have *ORIG_P in our constant/copy table, then replace
--- 626,634 ----
  #endif
  
  	  /* The alternative may be associated with a constant, so verify
! 	     it is an SSA_NAME before doing anything with it.  */
  	  orig_p = &PHI_ARG_DEF (phi, hint);
! 	  if (TREE_CODE (*orig_p) != SSA_NAME)
  	    continue;
  
  	  /* If we have *ORIG_P in our constant/copy table, then replace
*************** optimize_stmt (block_stmt_iterator si, v
*** 1090,1096 ****
  
  	/* If the operand is not an ssa variable, then there is nothing
  	   to do.  */
! 	if (! SSA_VAR_P (*op_p))
  	  continue;
  
  	/* If the operand has a known constant value or it is known to be a
--- 1115,1121 ----
  
  	/* If the operand is not an ssa variable, then there is nothing
  	   to do.  */
! 	if (TREE_CODE (*op_p) != SSA_NAME)
  	  continue;
  
  	/* If the operand has a known constant value or it is known to be a
*************** get_value_for (tree var, htab_t table)
*** 1522,1528 ****
    struct var_value_d *vm_p, vm;
  
  #if defined ENABLE_CHECKING
!   if (!SSA_VAR_P (var))
      abort ();
  #endif
  
--- 1547,1553 ----
    struct var_value_d *vm_p, vm;
  
  #if defined ENABLE_CHECKING
!   if (TREE_CODE (var) != SSA_NAME)
      abort ();
  #endif
  
*************** set_value_for (tree var, tree value, hta
*** 1541,1547 ****
    void **slot;
  
  #if defined ENABLE_CHECKING
!   if (!SSA_VAR_P (var))
      abort ();
  #endif
  
--- 1566,1572 ----
    void **slot;
  
  #if defined ENABLE_CHECKING
!   if (TREE_CODE (var) != SSA_NAME)
      abort ();
  #endif
  
*************** lookup_avail_expr (tree stmt,
*** 1621,1627 ****
  
    /* See if the LHS appears in the CONST_AND_COPIES table.  If it does, then
       use the value from the const_and_copies table.  */
!   if (SSA_VAR_P (lhs))
      {
        temp = get_value_for (lhs, const_and_copies);
        if (temp)
--- 1646,1652 ----
  
    /* See if the LHS appears in the CONST_AND_COPIES table.  If it does, then
       use the value from the const_and_copies table.  */
!   if (TREE_CODE (lhs) == SSA_NAME)
      {
        temp = get_value_for (lhs, const_and_copies);
        if (temp)
*************** get_eq_expr_value (tree if_stmt, int tru
*** 1686,1692 ****
  
    /* If the conditional is a single variable 'X', return 'X = 1' for
       the true arm and 'X = 0' on the false arm.   */
!   if (SSA_VAR_P (cond))
      return build (MODIFY_EXPR, TREE_TYPE (cond), cond,
  		  (true_arm ? integer_one_node : integer_zero_node));
  
--- 1711,1717 ----
  
    /* If the conditional is a single variable 'X', return 'X = 1' for
       the true arm and 'X = 0' on the false arm.   */
!   if (TREE_CODE (cond) == SSA_NAME)
      return build (MODIFY_EXPR, TREE_TYPE (cond), cond,
  		  (true_arm ? integer_one_node : integer_zero_node));
  




More information about the Gcc-patches mailing list