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] Make non-store CCP stronger


I wondered why early CCP does not recognize 

static const int x;

int foo(void)
{
  return "hello"[x];
}

but in fact it does notice that "hello"[x] is likely constant.  
It just fails to try folding constant aggregate refs in ccp_fold
which then returns not NULL as advertised, but the original tree.
So we do not fall back to the !simplified case, but simply fail.

Duh.  This part of evaluate_stmt was "interesting" everytime
I looked at it, so I just simplified it and moved the foldings
that should be done for likely constant values into ccp_fold
itself.  Of course it had some shortcomings which were thus
fixed.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.


2008-03-15  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-ccp.c (ccp_fold): Also read from constant values
	and fold constant aggregate refs.
	(fold_const_aggregate_ref): Handle string constants
	and constructors in ARRAY_REFs.  Handle INDIRECT_REF.
	(evaluate_stmt): Simplify now that ccp_fold folds constant
	aggregate refs.

	* gcc.dg/tree-ssa/ssa-ccp-16.c: New testcase.

Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-16.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-16.c	2008-03-15 16:46:24.000000000 +0100
***************
*** 0 ****
--- 1,22 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-ccp1" } */
+ 
+ static const int x;
+ 
+ int test1 (void)
+ {
+   char *p = "hello";
+   int i = x;
+   i = i + 5;
+   return p[i];
+ }
+ 
+ int test2 (void)
+ {
+   int i = x;
+   i = i + 5;
+   return "hello"[i];
+ }
+ 
+ /* { dg-final { scan-tree-dump-times "return 0;" 2 "ccp1" } } */
+ /* { dg-final { cleanup-tree-dump "ccp1" } } */
Index: trunk/gcc/tree-ssa-ccp.c
===================================================================
*** trunk.orig/gcc/tree-ssa-ccp.c	2008-03-15 15:35:15.000000000 +0100
--- trunk/gcc/tree-ssa-ccp.c	2008-03-15 16:39:52.000000000 +0100
*************** ccp_fold (tree stmt)
*** 984,989 ****
--- 984,995 ----
        return fold_binary (code, TREE_TYPE (rhs), op0, op1);
      }
  
+   else if (kind == tcc_declaration)
+     return get_symbol_constant_value (rhs);
+ 
+   else if (kind == tcc_reference)
+     return fold_const_aggregate_ref (rhs);
+ 
    /* We may be able to fold away calls to builtin functions if their
       arguments are constants.  */
    else if (code == CALL_EXPR
*************** fold_const_aggregate_ref (tree t)
*** 1062,1067 ****
--- 1068,1078 ----
  	  ctor = fold_const_aggregate_ref (base);
  	  break;
  
+ 	case STRING_CST:
+ 	case CONSTRUCTOR:
+ 	  ctor = base;
+ 	  break;
+ 
  	default:
  	  return NULL_TREE;
  	}
*************** fold_const_aggregate_ref (tree t)
*** 1162,1168 ****
  	  return fold_build1 (TREE_CODE (t), TREE_TYPE (t), c);
  	break;
        }
!     
      default:
        break;
      }
--- 1173,1190 ----
  	  return fold_build1 (TREE_CODE (t), TREE_TYPE (t), c);
  	break;
        }
! 
!     case INDIRECT_REF:
!       {
! 	tree base = TREE_OPERAND (t, 0);
! 	if (TREE_CODE (base) == SSA_NAME
! 	    && (value = get_value (base))
! 	    && value->lattice_val == CONSTANT
! 	    && TREE_CODE (value->value) == ADDR_EXPR)
! 	  return fold_const_aggregate_ref (TREE_OPERAND (value->value, 0));
! 	break;
!       }
! 
      default:
        break;
      }
*************** evaluate_stmt (tree stmt)
*** 1190,1204 ****
      simplified = ccp_fold (stmt);
    /* If the statement is likely to have a VARYING result, then do not
       bother folding the statement.  */
!   if (likelyvalue == VARYING)
      simplified = get_rhs (stmt);
-   /* If the statement is an ARRAY_REF or COMPONENT_REF into constant
-      aggregates, extract the referenced constant.  Otherwise the
-      statement is likely to have an UNDEFINED value, and there will be
-      nothing to do.  Note that fold_const_aggregate_ref returns
-      NULL_TREE if the first case does not match.  */
-   else if (!simplified)
-     simplified = fold_const_aggregate_ref (get_rhs (stmt));
  
    is_constant = simplified && is_gimple_min_invariant (simplified);
  
--- 1212,1219 ----
      simplified = ccp_fold (stmt);
    /* If the statement is likely to have a VARYING result, then do not
       bother folding the statement.  */
!   else if (likelyvalue == VARYING)
      simplified = get_rhs (stmt);
  
    is_constant = simplified && is_gimple_min_invariant (simplified);
  
*************** visit_assignment (tree stmt, tree *outpu
*** 1265,1271 ****
      }
    else
      /* Evaluate the statement.  */
!       val = evaluate_stmt (stmt);
  
    /* If the original LHS was a VIEW_CONVERT_EXPR, modify the constant
       value to be a VIEW_CONVERT_EXPR of the old constant value.
--- 1280,1286 ----
      }
    else
      /* Evaluate the statement.  */
!     val = evaluate_stmt (stmt);
  
    /* If the original LHS was a VIEW_CONVERT_EXPR, modify the constant
       value to be a VIEW_CONVERT_EXPR of the old constant value.


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