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] ccp changes


Hello,

this patch contains some fixes and cleanups to ccp, initially motivated
by PR 29738 (which it also fixes, as a side effect):

1) Store-ccp puts UNKNOWN_VAL value in the lattice.  However, there does
   not seem to be any reason for that -- if the values of virtual
   operands at entry are initialized to VARYING and the remaining virtual
   ssa names to UNDEFINED, everything works just fine.  This patch
   removes UNKNOWN_VAL.
2) likely_value returns VARYING whenever there is a VARYING operand in
   the statement; this is different from what the comment before it
   claims, and it also is wrong (or at least overly conservative) --
   e.g., 0 * VARYING = 0, so we do not want to give up immediatelly when
   one of the operands is VARYING.  This patch makes likely_value
   behave as described in the comment (i.e., return UNDEFINED if there
   is at least one undefined operand, CONSTANT if there are no operands
   or at least one of the operands is constant, and VARYING otherwise).
3) In ccp_initialize, if a phi node has VARYING argument, we mark it
   as DONT_SIMULATE_AGAIN.  This is wrong, since we do not know whether
   the corresponding edge will be executable or not.  The patch removes
   the code responsible for this.

Bootstrapped & regtested on i686 and x86_64.

Zdenek

	PR tree-optimization/29738
	* tree-ssa-ccp.c: Remove UNKNOWN_VAL from comments.
	(ccp_lattice_t): Remove UNKNOWN_VAL.
	(dump_lattice_value, ccp_lattice_meet, ccp_visit_phi_node):
	Do not handle UNKNOWN_VAL.
	(get_default_value): Set initial value of virtual operands to
	VARYING.
	(get_value): Always use get_default_value on uninitialized
	operands.
	(set_value_varying, surely_varying_stmt_p): New functions.
	(set_lattice_value): Do not pass argument to get_value.
	Do not handle UNKNOWN_VAL.
	(likely_value): Follow the semantics described in the comment.
	(ccp_initialize): Use surely_varying_stmt_p.  Do not mark
	phi nodes DONT_SIMULATE_AGAIN.
	(ccp_fold): Do not pass argument to get_value.
	(fold_const_aggregate_ref, visit_assignment): Ditto.  Do not
	handle UNKNOWN_VAL.

	* gcc.dg/tree-ssa/ssa-ccp-14.c: New test.

Index: testsuite/gcc.dg/tree-ssa/ssa-ccp-14.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/ssa-ccp-14.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/ssa-ccp-14.c	(revision 0)
***************
*** 0 ****
--- 1,21 ----
+ /* PR tree-optimization/29738.  We used not to realize that "i" can never
+    become nonzero.  */
+ 
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-optimized" } */
+ 
+ int i;
+ 
+ void foo (void);
+ void bar (void)
+ {
+   int j;
+   i = 0;
+   for (j = 0; j < 10000; j++)
+     if (i)
+       foo ();
+ }
+ 
+ /* Everything except for the "i = 0" assignment should get removed.  */
+ /* { dg-final { scan-tree-dump-times "if" 0 "optimized"} } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */
Index: tree-ssa-ccp.c
===================================================================
*** tree-ssa-ccp.c	(revision 118542)
--- tree-ssa-ccp.c	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 29,36 ****
     with SSA names.  Given an SSA name V_i, it may take one of the
     following values:
  
!    	UNINITIALIZED	->  This is the default starting value.  V_i
! 			    has not been processed yet.
  
  	UNDEFINED	->  V_i is a local variable whose definition
  			    has not been processed yet.  Therefore we
--- 29,41 ----
     with SSA names.  Given an SSA name V_i, it may take one of the
     following values:
  
! 	UNINITIALIZED   ->  the initial state of the value.  This value
! 			    is replaced with a correct initial value
! 			    the first time the value is used, so the
! 			    rest of the pass does not need to care about
! 			    it.  Using this value simplifies initialization
! 			    of the pass, and prevents us from needlessly
! 			    scanning statements that are never reached.
  
  	UNDEFINED	->  V_i is a local variable whose definition
  			    has not been processed yet.  Therefore we
*************** Software Foundation, 51 Franklin Street,
*** 143,153 ****
     it would be wrong to replace the load from 'a.b' with '2', because
     '2' had been stored into a.a.
  
!    To support STORE-CCP, it is necessary to add a new value to the
!    constant propagation lattice.  When evaluating a load for a memory
!    reference we can no longer assume a value of UNDEFINED if we
!    haven't seen a preceding store to the same memory location.
!    Consider, for instance global variables:
  
     	int A;
  
--- 148,155 ----
     it would be wrong to replace the load from 'a.b' with '2', because
     '2' had been stored into a.a.
  
!    Note that the initial value of virtual operands is VARYING, not
!    UNDEFINED.  Consider, for instance global variables:
  
     	int A;
  
*************** Software Foundation, 51 Franklin Street,
*** 165,174 ****
  
     The value of A_2 cannot be assumed to be UNDEFINED, as it may have
     been defined outside of foo.  If we were to assume it UNDEFINED, we
!    would erroneously optimize the above into 'return 3;'.  Therefore,
!    when doing STORE-CCP, we introduce a fifth lattice value
!    (UNKNOWN_VAL), which overrides any other value when computing the
!    meet operation in PHI nodes.
  
     Though STORE-CCP is not too expensive, it does have to do more work
     than regular CCP, so it is only enabled at -O2.  Both regular CCP
--- 167,173 ----
  
     The value of A_2 cannot be assumed to be UNDEFINED, as it may have
     been defined outside of foo.  If we were to assume it UNDEFINED, we
!    would erroneously optimize the above into 'return 3;'.
  
     Though STORE-CCP is not too expensive, it does have to do more work
     than regular CCP, so it is only enabled at -O2.  Both regular CCP
*************** Software Foundation, 51 Franklin Street,
*** 214,222 ****
  /* Possible lattice values.  */
  typedef enum
  {
!   UNINITIALIZED = 0,
    UNDEFINED,
-   UNKNOWN_VAL,
    CONSTANT,
    VARYING
  } ccp_lattice_t;
--- 213,220 ----
  /* Possible lattice values.  */
  typedef enum
  {
!   UNINITIALIZED,
    UNDEFINED,
    CONSTANT,
    VARYING
  } ccp_lattice_t;
*************** dump_lattice_value (FILE *outf, const ch
*** 248,256 ****
      case VARYING:
        fprintf (outf, "%sVARYING", prefix);
        break;
-     case UNKNOWN_VAL:
-       fprintf (outf, "%sUNKNOWN_VAL", prefix);
-       break;
      case CONSTANT:
        fprintf (outf, "%sCONSTANT ", prefix);
        print_generic_expr (outf, val.value, dump_flags);
--- 246,251 ----
*************** ccp_decl_initial_min_invariant (tree t)
*** 317,332 ****
     4- Variables defined by statements other than assignments and PHI
        nodes are considered VARYING.
  
!    5- Variables that are not GIMPLE registers are considered
!       UNKNOWN_VAL, which is really a stronger version of UNDEFINED.
!       It's used to avoid the short circuit evaluation implied by
!       UNDEFINED in ccp_lattice_meet.  */
  
  static prop_value_t
  get_default_value (tree var)
  {
    tree sym = SSA_NAME_VAR (var);
!   prop_value_t val = { UNINITIALIZED, NULL_TREE, NULL_TREE };
  
    if (!do_store_ccp && !is_gimple_reg (var))
      {
--- 312,328 ----
     4- Variables defined by statements other than assignments and PHI
        nodes are considered VARYING.
  
!    5- Initial values of variables that are not GIMPLE registers are
!       considered VARYING.  */
  
  static prop_value_t
  get_default_value (tree var)
  {
    tree sym = SSA_NAME_VAR (var);
!   prop_value_t val;
!   
!   val.value = NULL_TREE;
!   val.mem_ref = NULL_TREE;
  
    if (!do_store_ccp && !is_gimple_reg (var))
      {
*************** get_default_value (tree var)
*** 360,374 ****
  	{
  	  /* Variables defined by an empty statement are those used
  	     before being initialized.  If VAR is a local variable, we
! 	     can assume initially that it is UNDEFINED.  If we are
! 	     doing STORE-CCP, function arguments and non-register
! 	     variables are initially UNKNOWN_VAL, because we cannot
! 	     discard the value incoming from outside of this function
! 	     (see ccp_lattice_meet for details).  */
  	  if (is_gimple_reg (sym) && TREE_CODE (sym) != PARM_DECL)
  	    val.lattice_val = UNDEFINED;
- 	  else if (do_store_ccp)
- 	    val.lattice_val = UNKNOWN_VAL;
  	  else
  	    val.lattice_val = VARYING;
  	}
--- 356,365 ----
  	{
  	  /* Variables defined by an empty statement are those used
  	     before being initialized.  If VAR is a local variable, we
! 	     can assume initially that it is UNDEFINED, otherwise we must
! 	     consider it VARYING.  */
  	  if (is_gimple_reg (sym) && TREE_CODE (sym) != PARM_DECL)
  	    val.lattice_val = UNDEFINED;
  	  else
  	    val.lattice_val = VARYING;
  	}
*************** get_default_value (tree var)
*** 376,384 ****
  	       || TREE_CODE (stmt) == PHI_NODE)
  	{
  	  /* Any other variable defined by an assignment or a PHI node
! 	     is considered UNDEFINED (or UNKNOWN_VAL if VAR is not a
! 	     GIMPLE register).  */
! 	  val.lattice_val = is_gimple_reg (sym) ? UNDEFINED : UNKNOWN_VAL;
  	}
        else
  	{
--- 367,374 ----
  	       || TREE_CODE (stmt) == PHI_NODE)
  	{
  	  /* Any other variable defined by an assignment or a PHI node
! 	     is considered UNDEFINED.  */
! 	  val.lattice_val = UNDEFINED;
  	}
        else
  	{
*************** get_default_value (tree var)
*** 391,410 ****
  }
  
  
! /* Get the constant value associated with variable VAR.  If
!    MAY_USE_DEFAULT_P is true, call get_default_value on variables that
!    have the lattice value UNINITIALIZED.  */
  
! static prop_value_t *
! get_value (tree var, bool may_use_default_p)
  {
    prop_value_t *val = &const_val[SSA_NAME_VERSION (var)];
!   if (may_use_default_p && val->lattice_val == UNINITIALIZED)
      *val = get_default_value (var);
  
    return val;
  }
  
  
  /* Set the value for variable VAR to NEW_VAL.  Return true if the new
     value is different from VAR's previous value.  */
--- 381,410 ----
  }
  
  
! /* Get the constant value associated with variable VAR.  */
  
! static inline prop_value_t *
! get_value (tree var)
  {
    prop_value_t *val = &const_val[SSA_NAME_VERSION (var)];
! 
!   if (val->lattice_val == UNINITIALIZED)
      *val = get_default_value (var);
  
    return val;
  }
  
+ /* Sets the value associated with VAR to VARYING.  */
+ 
+ static inline void
+ set_value_varying (tree var)
+ {
+   prop_value_t *val = &const_val[SSA_NAME_VERSION (var)];
+ 
+   val->lattice_val = VARYING;
+   val->value = NULL_TREE;
+   val->mem_ref = NULL_TREE;
+ }
  
  /* Set the value for variable VAR to NEW_VAL.  Return true if the new
     value is different from VAR's previous value.  */
*************** get_value (tree var, bool may_use_defaul
*** 412,459 ****
  static bool
  set_lattice_value (tree var, prop_value_t new_val)
  {
!   prop_value_t *old_val = get_value (var, false);
  
    /* Lattice transitions must always be monotonically increasing in
!      value.  We allow two exceptions:
!      
!      1- If *OLD_VAL and NEW_VAL are the same, return false to
! 	inform the caller that this was a non-transition.
! 
!      2- If we are doing store-ccp (i.e., DOING_STORE_CCP is true),
! 	allow CONSTANT->UNKNOWN_VAL.  The UNKNOWN_VAL state is a
! 	special type of UNDEFINED state which prevents the short
! 	circuit evaluation of PHI arguments (see ccp_visit_phi_node
! 	and ccp_lattice_meet).  */
    gcc_assert (old_val->lattice_val <= new_val.lattice_val
                || (old_val->lattice_val == new_val.lattice_val
  		  && old_val->value == new_val.value
! 		  && old_val->mem_ref == new_val.mem_ref)
! 	      || (do_store_ccp
! 		  && old_val->lattice_val == CONSTANT
! 		  && new_val.lattice_val == UNKNOWN_VAL));
  
    if (old_val->lattice_val != new_val.lattice_val)
      {
        if (dump_file && (dump_flags & TDF_DETAILS))
  	{
  	  dump_lattice_value (dump_file, "Lattice value changed to ", new_val);
! 	  fprintf (dump_file, ".  %sdding SSA edges to worklist.\n",
! 	           new_val.lattice_val != UNDEFINED ? "A" : "Not a");
  	}
  
        *old_val = new_val;
  
!       /* Transitions UNINITIALIZED -> UNDEFINED are never interesting
! 	 for propagation purposes.  In these cases return false to
! 	 avoid doing useless work.  */
!       return (new_val.lattice_val != UNDEFINED);
      }
  
    return false;
  }
  
- 
  /* Return the likely CCP lattice value for STMT.
  
     If STMT has no operands, then return CONSTANT.
--- 412,445 ----
  static bool
  set_lattice_value (tree var, prop_value_t new_val)
  {
!   prop_value_t *old_val = get_value (var);
  
    /* Lattice transitions must always be monotonically increasing in
!      value.  If *OLD_VAL and NEW_VAL are the same, return false to
!      inform the caller that this was a non-transition.  */
! 
    gcc_assert (old_val->lattice_val <= new_val.lattice_val
                || (old_val->lattice_val == new_val.lattice_val
  		  && old_val->value == new_val.value
! 		  && old_val->mem_ref == new_val.mem_ref));
  
    if (old_val->lattice_val != new_val.lattice_val)
      {
        if (dump_file && (dump_flags & TDF_DETAILS))
  	{
  	  dump_lattice_value (dump_file, "Lattice value changed to ", new_val);
! 	  fprintf (dump_file, ".  Adding SSA edges to worklist.\n");
  	}
  
        *old_val = new_val;
  
!       gcc_assert (new_val.lattice_val != UNDEFINED);
!       return true;
      }
  
    return false;
  }
  
  /* Return the likely CCP lattice value for STMT.
  
     If STMT has no operands, then return CONSTANT.
*************** set_lattice_value (tree var, prop_value_
*** 467,473 ****
  static ccp_lattice_t
  likely_value (tree stmt)
  {
!   bool found_constant;
    stmt_ann_t ann;
    tree use;
    ssa_op_iter iter;
--- 453,459 ----
  static ccp_lattice_t
  likely_value (tree stmt)
  {
!   bool has_constant_operand;
    stmt_ann_t ann;
    tree use;
    ssa_op_iter iter;
*************** likely_value (tree stmt)
*** 485,491 ****
        && !ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
      return VARYING;
  
- 
    /* A CALL_EXPR is assumed to be varying.  NOTE: This may be overly
       conservative, in the presence of const and pure calls.  */
    if (get_call_expr_in (stmt) != NULL_TREE)
--- 471,476 ----
*************** likely_value (tree stmt)
*** 494,499 ****
--- 479,485 ----
    /* Anything other than assignments and conditional jumps are not
       interesting for CCP.  */
    if (TREE_CODE (stmt) != MODIFY_EXPR
+       && !(TREE_CODE (stmt) == RETURN_EXPR && get_rhs (stmt) != NULL_TREE)
        && TREE_CODE (stmt) != COND_EXPR
        && TREE_CODE (stmt) != SWITCH_EXPR)
      return VARYING;
*************** likely_value (tree stmt)
*** 501,533 ****
    if (is_gimple_min_invariant (get_rhs (stmt)))
      return CONSTANT;
  
!   found_constant = false;
!   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE|SSA_OP_VUSE)
      {
!       prop_value_t *val = get_value (use, true);
! 
!       if (val->lattice_val == VARYING)
! 	return VARYING;
  
!       if (val->lattice_val == UNKNOWN_VAL)
! 	{
! 	  /* UNKNOWN_VAL is invalid when not doing STORE-CCP.  */
! 	  gcc_assert (do_store_ccp);
! 	  return UNKNOWN_VAL;
! 	}
  
        if (val->lattice_val == CONSTANT)
! 	found_constant = true;
      }
  
!   if (found_constant
!       || ZERO_SSA_OPERANDS (stmt, SSA_OP_USE)
!       || ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE))
      return CONSTANT;
  
!   return UNDEFINED;
  }
  
  
  /* Initialize local data structures for CCP.  */
  
--- 487,549 ----
    if (is_gimple_min_invariant (get_rhs (stmt)))
      return CONSTANT;
  
!   has_constant_operand = false;
!   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE | SSA_OP_VUSE)
      {
!       prop_value_t *val = get_value (use);
  
!       if (val->lattice_val == UNDEFINED)
! 	return UNDEFINED;
  
        if (val->lattice_val == CONSTANT)
! 	has_constant_operand = true;
      }
  
!   if (has_constant_operand
!       /* We do not consider virtual operands here -- load from read-only
! 	 memory may have only VARYING virtual operands, but still be
! 	 constant.  */
!       || ZERO_SSA_OPERANDS (stmt, SSA_OP_USE))
      return CONSTANT;
  
!   return VARYING;
  }
  
+ /* Returns true if STMT cannot be constant.  */
+ 
+ static bool
+ surely_varying_stmt_p (tree stmt)
+ {
+   /* If the statement has operands that we cannot handle, it cannot be
+      constant.  */
+   if (stmt_ann (stmt)->has_volatile_ops)
+     return true;
+ 
+   if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
+     {
+       if (!do_store_ccp)
+ 	return true;
+ 
+       /* We can only handle simple loads and stores.  */
+       if (!stmt_makes_single_load (stmt)
+ 	  && !stmt_makes_single_store (stmt))
+ 	return true;
+     }
+ 
+   /* If it contains a call, it is varying.  */
+   if (get_call_expr_in (stmt) != NULL_TREE)
+     return true;
+ 
+   /* Anything other than assignments and conditional jumps are not
+      interesting for CCP.  */
+   if (TREE_CODE (stmt) != MODIFY_EXPR
+       && !(TREE_CODE (stmt) == RETURN_EXPR && get_rhs (stmt) != NULL_TREE)
+       && TREE_CODE (stmt) != COND_EXPR
+       && TREE_CODE (stmt) != SWITCH_EXPR)
+     return true;
+ 
+   return false;
+ }
  
  /* Initialize local data structures for CCP.  */
  
*************** ccp_initialize (void)
*** 546,556 ****
  
        for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
          {
- 	  bool is_varying = false;
  	  tree stmt = bsi_stmt (i);
  
! 	  if (likely_value (stmt) == VARYING)
! 
  	    {
  	      tree def;
  	      ssa_op_iter iter;
--- 562,571 ----
  
        for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
          {
  	  tree stmt = bsi_stmt (i);
+ 	  bool is_varying = surely_varying_stmt_p (stmt);
  
! 	  if (is_varying)
  	    {
  	      tree def;
  	      ssa_op_iter iter;
*************** ccp_initialize (void)
*** 558,601 ****
  	      /* If the statement will not produce a constant, mark
  		 all its outputs VARYING.  */
  	      FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
! 		get_value (def, false)->lattice_val = VARYING;
! 
! 	      /* Never mark conditional jumps with DONT_SIMULATE_AGAIN,
! 		 otherwise the propagator will never add the outgoing
! 		 control edges.  */
! 	      if (TREE_CODE (stmt) != COND_EXPR
! 		  && TREE_CODE (stmt) != SWITCH_EXPR)
! 		is_varying = true;
  	    }
  
  	  DONT_SIMULATE_AGAIN (stmt) = is_varying;
  	}
      }
  
!   /* Now process PHI nodes.  */
    FOR_EACH_BB (bb)
      {
        tree phi;
  
        for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
  	{
! 	  int i;
! 	  tree arg;
! 	  prop_value_t *val = get_value (PHI_RESULT (phi), false);
! 
! 	  for (i = 0; i < PHI_NUM_ARGS (phi); i++)
! 	    {
! 	      arg = PHI_ARG_DEF (phi, i);
! 
! 	      if (TREE_CODE (arg) == SSA_NAME
! 		  && get_value (arg, false)->lattice_val == VARYING)
! 		{
! 		  val->lattice_val = VARYING;
! 		  break;
! 		}
! 	    }
! 
! 	  DONT_SIMULATE_AGAIN (phi) = (val->lattice_val == VARYING);
  	}
      }
  }
--- 573,601 ----
  	      /* If the statement will not produce a constant, mark
  		 all its outputs VARYING.  */
  	      FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
! 		{
! 		  if (is_varying)
! 		    set_value_varying (def);
! 		}
  	    }
  
  	  DONT_SIMULATE_AGAIN (stmt) = is_varying;
  	}
      }
  
!   /* Now process PHI nodes.  We never set DONT_SIMULATE_AGAIN on phi node,
!      since we do not know which edges are executable yet, except for
!      phi nodes for virtual operands when we do not do store ccp.  */
    FOR_EACH_BB (bb)
      {
        tree phi;
  
        for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
  	{
! 	  if (!do_store_ccp && !is_gimple_reg (PHI_RESULT (phi)))
! 	    DONT_SIMULATE_AGAIN (phi) = true;
! 	  else
! 	    DONT_SIMULATE_AGAIN (phi) = false;
  	}
      }
  }
*************** ccp_finalize (void)
*** 618,653 ****
     in VAL1.
  
     		any  M UNDEFINED   = any
- 		any  M UNKNOWN_VAL = UNKNOWN_VAL
  		any  M VARYING     = VARYING
  		Ci   M Cj	   = Ci		if (i == j)
  		Ci   M Cj	   = VARYING	if (i != j)
! 
!    Lattice values UNKNOWN_VAL and UNDEFINED are similar but have
!    different semantics at PHI nodes.  Both values imply that we don't
!    know whether the variable is constant or not.  However, UNKNOWN_VAL
!    values override all others.  For instance, suppose that A is a
!    global variable:
! 
! 		+------+
! 		|      |
! 		|     / \
! 		|    /   \
! 		|   |  A_1 = 4
! 		|    \   /
! 		|     \ /    
! 		| A_3 = PHI (A_2, A_1)
! 		| ... = A_3
! 		|    |
! 		+----+
! 
!    If the edge into A_2 is not executable, the first visit to A_3 will
!    yield the constant 4.  But the second visit to A_3 will be with A_2
!    in state UNKNOWN_VAL.  We can no longer conclude that A_3 is 4
!    because A_2 may have been set in another function.  If we had used
!    the lattice value UNDEFINED, we would have had wrongly concluded
!    that A_3 is 4.  */
!    
  
  static void
  ccp_lattice_meet (prop_value_t *val1, prop_value_t *val2)
--- 618,627 ----
     in VAL1.
  
     		any  M UNDEFINED   = any
  		any  M VARYING     = VARYING
  		Ci   M Cj	   = Ci		if (i == j)
  		Ci   M Cj	   = VARYING	if (i != j)
!    */
  
  static void
  ccp_lattice_meet (prop_value_t *val1, prop_value_t *val2)
*************** ccp_lattice_meet (prop_value_t *val1, pr
*** 663,679 ****
           Nothing to do.  VAL1 already contains the value we want.  */
        ;
      }
-   else if (val1->lattice_val == UNKNOWN_VAL
-            || val2->lattice_val == UNKNOWN_VAL)
-     {
-       /* UNKNOWN_VAL values are invalid if we are not doing STORE-CCP.  */
-       gcc_assert (do_store_ccp);
- 
-       /* any M UNKNOWN_VAL = UNKNOWN_VAL.  */
-       val1->lattice_val = UNKNOWN_VAL;
-       val1->value = NULL_TREE;
-       val1->mem_ref = NULL_TREE;
-     }
    else if (val1->lattice_val == VARYING
             || val2->lattice_val == VARYING)
      {
--- 637,642 ----
*************** ccp_visit_phi_node (tree phi)
*** 725,731 ****
        print_generic_expr (dump_file, phi, dump_flags);
      }
  
!   old_val = get_value (PHI_RESULT (phi), false);
    switch (old_val->lattice_val)
      {
      case VARYING:
--- 688,694 ----
        print_generic_expr (dump_file, phi, dump_flags);
      }
  
!   old_val = get_value (PHI_RESULT (phi));
    switch (old_val->lattice_val)
      {
      case VARYING:
*************** ccp_visit_phi_node (tree phi)
*** 735,753 ****
        new_val = *old_val;
        break;
  
-     case UNKNOWN_VAL:
-       /* To avoid the default value of UNKNOWN_VAL overriding
-          that of its possible constant arguments, temporarily
- 	 set the PHI node's default lattice value to be 
- 	 UNDEFINED.  If the PHI node's old value was UNKNOWN_VAL and
- 	 the new value is UNDEFINED, then we prevent the invalid
- 	 transition by not calling set_lattice_value.  */
-       gcc_assert (do_store_ccp);
- 
-       /* FALLTHRU  */
- 
      case UNDEFINED:
-     case UNINITIALIZED:
        new_val.lattice_val = UNDEFINED;
        new_val.value = NULL_TREE;
        new_val.mem_ref = NULL_TREE;
--- 698,704 ----
*************** ccp_visit_phi_node (tree phi)
*** 785,791 ****
  	      arg_val.mem_ref = NULL_TREE;
  	    }
  	  else
! 	    arg_val = *(get_value (arg, true));
  
  	  ccp_lattice_meet (&new_val, &arg_val);
  
--- 736,742 ----
  	      arg_val.mem_ref = NULL_TREE;
  	    }
  	  else
! 	    arg_val = *(get_value (arg));
  
  	  ccp_lattice_meet (&new_val, &arg_val);
  
*************** ccp_visit_phi_node (tree phi)
*** 808,820 ****
        fprintf (dump_file, "\n\n");
      }
  
!   /* Check for an invalid change from UNKNOWN_VAL to UNDEFINED.  */
!   if (do_store_ccp
!       && old_val->lattice_val == UNKNOWN_VAL
!       && new_val.lattice_val == UNDEFINED)
!     return SSA_PROP_NOT_INTERESTING;
! 
!   /* Otherwise, make the transition to the new value.  */
    if (set_lattice_value (PHI_RESULT (phi), new_val))
      {
        if (new_val.lattice_val == VARYING)
--- 759,765 ----
        fprintf (dump_file, "\n\n");
      }
  
!   /* Make the transition to the new value.  */
    if (set_lattice_value (PHI_RESULT (phi), new_val))
      {
        if (new_val.lattice_val == VARYING)
*************** ccp_fold (tree stmt)
*** 848,854 ****
      {
        /* If the RHS is an SSA_NAME, return its known constant value,
  	 if any.  */
!       return get_value (rhs, true)->value;
      }
    else if (do_store_ccp && stmt_makes_single_load (stmt))
      {
--- 793,799 ----
      {
        /* If the RHS is an SSA_NAME, return its known constant value,
  	 if any.  */
!       return get_value (rhs)->value;
      }
    else if (do_store_ccp && stmt_makes_single_load (stmt))
      {
*************** ccp_fold (tree stmt)
*** 881,889 ****
        /* Simplify the operand down to a constant.  */
        if (TREE_CODE (op0) == SSA_NAME)
  	{
! 	  prop_value_t *val = get_value (op0, true);
  	  if (val->lattice_val == CONSTANT)
! 	    op0 = get_value (op0, true)->value;
  	}
  
        if ((code == NOP_EXPR || code == CONVERT_EXPR)
--- 826,834 ----
        /* Simplify the operand down to a constant.  */
        if (TREE_CODE (op0) == SSA_NAME)
  	{
! 	  prop_value_t *val = get_value (op0);
  	  if (val->lattice_val == CONSTANT)
! 	    op0 = get_value (op0)->value;
  	}
  
        if ((code == NOP_EXPR || code == CONVERT_EXPR)
*************** ccp_fold (tree stmt)
*** 909,922 ****
        /* Simplify the operands down to constants when appropriate.  */
        if (TREE_CODE (op0) == SSA_NAME)
  	{
! 	  prop_value_t *val = get_value (op0, true);
  	  if (val->lattice_val == CONSTANT)
  	    op0 = val->value;
  	}
  
        if (TREE_CODE (op1) == SSA_NAME)
  	{
! 	  prop_value_t *val = get_value (op1, true);
  	  if (val->lattice_val == CONSTANT)
  	    op1 = val->value;
  	}
--- 854,867 ----
        /* Simplify the operands down to constants when appropriate.  */
        if (TREE_CODE (op0) == SSA_NAME)
  	{
! 	  prop_value_t *val = get_value (op0);
  	  if (val->lattice_val == CONSTANT)
  	    op0 = val->value;
  	}
  
        if (TREE_CODE (op1) == SSA_NAME)
  	{
! 	  prop_value_t *val = get_value (op1);
  	  if (val->lattice_val == CONSTANT)
  	    op1 = val->value;
  	}
*************** ccp_fold (tree stmt)
*** 969,975 ****
    return rhs;
  }
  
- 
  /* Return the tree representing the element referenced by T if T is an
     ARRAY_REF or COMPONENT_REF into constant aggregates.  Return
     NULL_TREE otherwise.  */
--- 914,919 ----
*************** fold_const_aggregate_ref (tree t)
*** 1022,1028 ****
        switch (TREE_CODE (idx))
  	{
  	case SSA_NAME:
! 	  if ((value = get_value (idx, true))
  	      && value->lattice_val == CONSTANT
  	      && TREE_CODE (value->value) == INTEGER_CST)
  	    idx = value->value;
--- 966,972 ----
        switch (TREE_CODE (idx))
  	{
  	case SSA_NAME:
! 	  if ((value = get_value (idx))
  	      && value->lattice_val == CONSTANT
  	      && TREE_CODE (value->value) == INTEGER_CST)
  	    idx = value->value;
*************** evaluate_stmt (tree stmt)
*** 1151,1157 ****
        /* The statement produced a nonconstant value.  If the statement
  	 had UNDEFINED operands, then the result of the statement
  	 should be UNDEFINED.  Otherwise, the statement is VARYING.  */
!       if (likelyvalue == UNDEFINED || likelyvalue == UNKNOWN_VAL)
  	val.lattice_val = likelyvalue;
        else
  	val.lattice_val = VARYING;
--- 1095,1101 ----
        /* The statement produced a nonconstant value.  If the statement
  	 had UNDEFINED operands, then the result of the statement
  	 should be UNDEFINED.  Otherwise, the statement is VARYING.  */
!       if (likelyvalue == UNDEFINED)
  	val.lattice_val = likelyvalue;
        else
  	val.lattice_val = VARYING;
*************** evaluate_stmt (tree stmt)
*** 1162,1168 ****
    return val;
  }
  
- 
  /* Visit the assignment statement STMT.  Set the value of its LHS to the
     value computed by the RHS and store LHS in *OUTPUT_P.  If STMT
     creates virtual definitions, set the value of each new name to that
--- 1106,1111 ----
*************** visit_assignment (tree stmt, tree *outpu
*** 1181,1198 ****
    if (TREE_CODE (rhs) == SSA_NAME)
      {
        /* For a simple copy operation, we copy the lattice values.  */
!       prop_value_t *nval = get_value (rhs, true);
        val = *nval;
      }
    else if (do_store_ccp && stmt_makes_single_load (stmt))
      {
        /* Same as above, but the RHS is not a gimple register and yet
!          has a known VUSE.  If STMT is loading from the same memory
  	 location that created the SSA_NAMEs for the virtual operands,
  	 we can propagate the value on the RHS.  */
        prop_value_t *nval = get_value_loaded_by (stmt, const_val);
  
!       if (nval && nval->mem_ref
  	  && operand_equal_p (nval->mem_ref, rhs, 0))
  	val = *nval;
        else
--- 1124,1142 ----
    if (TREE_CODE (rhs) == SSA_NAME)
      {
        /* For a simple copy operation, we copy the lattice values.  */
!       prop_value_t *nval = get_value (rhs);
        val = *nval;
      }
    else if (do_store_ccp && stmt_makes_single_load (stmt))
      {
        /* Same as above, but the RHS is not a gimple register and yet
! 	 has a known VUSE.  If STMT is loading from the same memory
  	 location that created the SSA_NAMEs for the virtual operands,
  	 we can propagate the value on the RHS.  */
        prop_value_t *nval = get_value_loaded_by (stmt, const_val);
  
!       if (nval
! 	  && nval->mem_ref
  	  && operand_equal_p (nval->mem_ref, rhs, 0))
  	val = *nval;
        else
*************** visit_assignment (tree stmt, tree *outpu
*** 1271,1282 ****
        tree vdef;
        bool changed;
  
-       /* Stores cannot take on an UNDEFINED value.  */
-       if (val.lattice_val == UNDEFINED)
- 	val.lattice_val = UNKNOWN_VAL;      
- 
        /* Mark VAL as stored in the LHS of this assignment.  */
!       val.mem_ref = lhs;
  
        /* Set the value of every VDEF to VAL.  */
        changed = false;
--- 1215,1223 ----
        tree vdef;
        bool changed;
  
        /* Mark VAL as stored in the LHS of this assignment.  */
!       if (val.lattice_val == CONSTANT)
! 	val.mem_ref = lhs;
  
        /* Set the value of every VDEF to VAL.  */
        changed = false;


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