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]

Re: [tree-ssa] Enable SSA DCE by default [patch]


On Sat, 08 Feb 2003, Richard Henderson wrote:

> On Sat, Feb 08, 2003 at 11:51:53PM -0500, Diego Novillo wrote:
> > - DCE was not considering VA_ARG_EXPRs inherently live.
> 
> That shouldn't be.  If you've modeled the first argument
> as in-out, then you should be able to detect when the 
> first argument is live afterward.
> 
Found the problem.  The semi-pruned heuristics we added last week
were messing up.  Virtual definitions not only represent a
non-killing store, they also imply a use of the previous version of
the same variable.  That's why we weren't marking the operand for
VA_ARG_EXPR live in the following case:

-----------------------------------------------------------------------------
     1	va_arg (ap);
     2	...
     3	switch (...)
     4	{
     5	  case ...:
     6	    va_arg (ap);
     7	    break;
     8	
     9	  case ...:
    10	    va_arg (ap);
    11	    break;
    12	  ...
    13	}
    14	...
    15	va_arg (ap);
-----------------------------------------------------------------------------

At the closing brace of the switch, we were not adding a PHI term
for 'ap' because none of the VDEFs for 'ap' inside the switch
were marking it as non-local to their respective blocks.
Therefore, the only live definition of 'ap' at line 15 was the
original definition made at line 1.

This patch fixes the problem by properly examining the operand of
VDEFs for non-locality.  The patch also fixes a buglet in
find_vars_r and SSA_VAR_P: we were allowing INDIRECT_REFs of non
_DECLs to be considered as regular variables.

Bootstrapped and tested x86 and PPC.


Diego.



	* tree-dfa.c (find_vars_r): Assume that the RHS of an INDIRECT_REF,
	that is also an SSA variable, is a VAR_DECL.
	(get_virtual_var): Handle INDIRECT_REF nodes that are not valid SSA
	variables.

	* tree-ssa-dce.c (stmt_useful_p): Revert kludge in previous commit.
	VA_ARG_EXPR nodes are not inherently live.

	* tree-ssa.c (mark_def_sites): Don't process the LHS of assignments
	twice.
	The operand of a virtual definition constitutes a use of the
	variable which should be considered a non-local if it had not been
	killed inside the block.

	* tree.h (SSA_VAR_P): Only return true for INDIRECT_REFs if their
	operand is a _DECL node.


Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.75
diff -d -u -p -r1.1.4.75 tree-dfa.c
--- tree-dfa.c	9 Feb 2003 04:45:17 -0000	1.1.4.75
+++ tree-dfa.c	10 Feb 2003 04:03:53 -0000
@@ -2148,12 +2148,12 @@ find_vars_r (tp, walk_subtrees, data)
       var = *tp;
       sym = get_base_symbol (var);
 
-      /* If VAR is an INDIRECT_REF node for a VAR_DECL pointer, rewrite *TP
-	 with the first INDIRECT_REF we found (if any).  We need to share
-	 INDIRECT_REF nodes because we treat them as regular variables and
-	 several passes rely on pointer equality for testing if two variables
-	 are the same.  */
-      if (TREE_CODE (var) == INDIRECT_REF && DECL_P (TREE_OPERAND (var, 0)))
+      /* If VAR is an INDIRECT_REF node rewrite *TP with the first
+	 INDIRECT_REF we found (if any).  We need to share INDIRECT_REF
+	 nodes because we treat them as regular variables and several
+	 passes rely on pointer equality for testing if two variables are
+	 the same.  */
+      if (TREE_CODE (var) == INDIRECT_REF)
 	{
 	  deref = indirect_ref (sym);
 	  if (deref)
@@ -2327,7 +2327,9 @@ get_virtual_var (var)
   while (code == ARRAY_REF
          || code == COMPONENT_REF
 	 || code == REALPART_EXPR
-	 || code == IMAGPART_EXPR)
+	 || code == IMAGPART_EXPR
+	 || (code == INDIRECT_REF
+	     && !DECL_P (TREE_OPERAND (var, 0))))
     {
       var = TREE_OPERAND (var, 0);
       code = TREE_CODE (var);
Index: tree-ssa-dce.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dce.c,v
retrieving revision 1.1.2.26
diff -d -u -p -r1.1.2.26 tree-ssa-dce.c
--- tree-ssa-dce.c	9 Feb 2003 04:45:18 -0000	1.1.2.26
+++ tree-ssa-dce.c	10 Feb 2003 04:03:53 -0000
@@ -299,13 +299,7 @@ stmt_useful_p (stmt)
       || (TREE_CODE (stmt) == LABEL_EXPR)
       || (TREE_CODE (stmt) == CALL_EXPR)
       || ((TREE_CODE (stmt) == MODIFY_EXPR)
-	  && (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR))
-      /* FIXME: Hmph, VA_ARG_EXPR has side effects that the dataflow
-	 routines don't register.  This was causing cp/error.c to be
-	 miscompiled with DCE enabled.  */
-      || (TREE_CODE (stmt) == VA_ARG_EXPR)
-      || ((TREE_CODE (stmt) == MODIFY_EXPR)
-	  && (TREE_CODE (TREE_OPERAND (stmt, 1)) == VA_ARG_EXPR)))
+	  && (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR)))
     return true;
 
   /* GOTO_EXPR nodes to nonlocal labels need to be kept (This fixes
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.50
diff -d -u -p -r1.1.4.50 tree-ssa.c
--- tree-ssa.c	9 Feb 2003 04:45:18 -0000	1.1.4.50
+++ tree-ssa.c	10 Feb 2003 04:03:53 -0000
@@ -313,10 +313,6 @@ mark_def_sites (idom)
 
 	  get_stmt_operands (stmt);
 
-	  dest = def_op (stmt);
-	  if (dest)
-	    set_def_block (*dest, bb);
-
 	  /* If a variable is used before being set, then the variable
 	     is live across a block boundary, so add it to NONLOCAL_VARS.  */
 	  ops = use_ops (stmt);
@@ -325,7 +321,7 @@ mark_def_sites (idom)
 	      tree *use = VARRAY_GENERIC_PTR (ops, i);
 	      int uid = var_ann (*use)->uid;
 
-	      if (! TEST_BIT (killed_vars, uid))
+	      if (!TEST_BIT (killed_vars, uid))
 	        SET_BIT (nonlocal_vars, uid);
 	    }
 	  
@@ -336,24 +332,38 @@ mark_def_sites (idom)
 	      tree use = VARRAY_GENERIC_PTR (ops, i);
 	      int uid = var_ann (use)->uid;
 
-	      if (! TEST_BIT (killed_vars, uid))
+	      if (!TEST_BIT (killed_vars, uid))
 	        SET_BIT (nonlocal_vars, uid);
 	    }
 
-	  /* Now process the single destination of this statement. 
-
-	     Note that virtual definitions are irrelavent for
-	     computing NONLOCAL_VARs and KILLED_VARS, so they are
-	     ignored here.  */
+	  /* Now process the definition made by this statement.  */
+	  dest = def_op (stmt);
 	  if (dest)
-	    SET_BIT (killed_vars, var_ann (*dest)->uid);
+	    {
+	      set_def_block (*dest, bb);
+	      SET_BIT (killed_vars, var_ann (*dest)->uid);
+	    }
 
+	  /* Note that virtual definitions are irrelevant for computing
+	     KILLED_VARS because a VDEF does not constitute a killing
+	     definition of the variable.  However, the operand of a virtual
+	     definitions is a use of the variable, so it may affect
+	     NONLOCAL_VARS.  */
 	  ops = vdef_ops (stmt);
 	  for (i = 0; ops && i < VARRAY_ACTIVE_SIZE (ops); i++)
-	    set_def_block (VDEF_RESULT (VARRAY_TREE (ops, i)), bb);
+	    {
+	      tree vdef = VARRAY_TREE (ops, i);
+	      int uid = var_ann (VDEF_OP (vdef))->uid;
+
+	      set_def_block (VDEF_RESULT (vdef), bb);
+	      if (!TEST_BIT (killed_vars, uid))
+		SET_BIT (nonlocal_vars, uid);
+	    }
 	}
     }
+
   free (killed_vars);
+
   return nonlocal_vars;
 }
 
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.44
diff -d -u -p -r1.342.2.44 tree.h
--- tree.h	3 Feb 2003 17:08:43 -0000	1.342.2.44
+++ tree.h	10 Feb 2003 04:03:53 -0000
@@ -1534,7 +1534,8 @@ struct tree_type GTY(())
    decls, SSA names and INDIRECT_REF nodes.  */
 #define SSA_VAR_P(NODE) (SSA_DECL_P (NODE) \
     			 || TREE_CODE (NODE) == SSA_NAME \
-    			 || TREE_CODE (NODE) == INDIRECT_REF)
+    			 || (TREE_CODE (NODE) == INDIRECT_REF \
+			     && DECL_P (TREE_OPERAND (NODE, 0))))
 
 /* This is the name of the object as written by the user.
    It is an IDENTIFIER_NODE.  */


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