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]

[tree-ssa] Fix CCP bug exposed by 099.go


This fixes a CCP bug exposed by 099.go.  There's two underlying issues.

First, if a statement had virtual definitions and the first time we 
simulated the statement we got either an UNDEFINED or CONSTANT result,
then we would fail to re-simulate the statement if its operands 
changed.   vdefs really don't tell us anything useful about the
result of the statement and the existence of vdefs shouldn't inhibit
re-simulation of an instruction.

Second, if we passed an undefined value as an argument to a function
call, then we considered the function call itself to produce an undefined
value.  That is wrong.  Just because we pass in an undefined value doesn't
mean the function actually uses the value.  Function calls are immediately
assumed to produce VARYING results.

This makes 099.go from spec95 work again.  Whee.

	* tree-ssa-ccp.c (visit_stmt): Do not set DONT_SIMULATE_AGAIN
	just because a statement as virtual definitions.
	(likely_value): A CALL_EXPR is assumed to return a VARYING
	result, regardless of its operands.

Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-ccp.c,v
retrieving revision 1.1.2.89
diff -c -3 -p -r1.1.2.89 tree-ssa-ccp.c
*** tree-ssa-ccp.c	16 Sep 2003 03:08:08 -0000	1.1.2.89
--- tree-ssa-ccp.c	16 Sep 2003 23:43:44 -0000
*************** visit_stmt (tree stmt)
*** 580,586 ****
    ops = vdef_ops (stmt);
    if (ops)
      {
-       DONT_SIMULATE_AGAIN (stmt) = 1;
        for (i = 0; i < VARRAY_ACTIVE_SIZE (ops); i++)
  	def_to_varying (VDEF_RESULT (VARRAY_TREE (ops, i)));
      }
--- 580,585 ----
*************** likely_value (tree stmt)
*** 1251,1256 ****
--- 1250,1266 ----
       won't fold to a constant value.  */
    ann = stmt_ann (stmt);
    if (ann->makes_aliased_loads || ann->has_volatile_ops)
+     return VARYING;
+ 
+   /* A CALL_EXPR is assumed to be varying.  This may be overly conservative,
+      in the presence of const and pure calls.  */
+   if (TREE_CODE (stmt) == CALL_EXPR
+       || (TREE_CODE (stmt) == MODIFY_EXPR
+ 	  && TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR)
+       || (TREE_CODE (stmt) == RETURN_EXPR
+ 	  && TREE_OPERAND (stmt, 0)
+ 	  && TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR
+ 	  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (stmt, 0), 1)) == CALL_EXPR))
      return VARYING;
  
    get_stmt_operands (stmt);







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