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] Fix PR22303, CCP not handling reads from constant strings


This fixes the PR by teaching fold_const_aggregate_ref about STRING_CSTs
and falling back to that if ccp_fold did not simplify the stmt.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Thanks,
Richard.

:ADDPATCH middle-end:

2006-05-08  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/22303
	* tree-ssa-ccp.c (fold_const_aggregate_ref): Handle reads
	from STRING_CSTs.
	(evaluate_stmt): Fall back to fold_const_aggregate_ref, if
	ccp_fold did not simplify the statement.

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

Index: tree-ssa-ccp.c
===================================================================
*** tree-ssa-ccp.c	(revision 113628)
--- tree-ssa-ccp.c	(working copy)
*************** fold_const_aggregate_ref (tree t)
*** 1011,1017 ****
  	}
  
        if (ctor == NULL_TREE
! 	  || TREE_CODE (ctor) != CONSTRUCTOR
  	  || !TREE_STATIC (ctor))
  	return NULL_TREE;
  
--- 1011,1018 ----
  	}
  
        if (ctor == NULL_TREE
! 	  || (TREE_CODE (ctor) != CONSTRUCTOR
! 	      && TREE_CODE (ctor) != STRING_CST)
  	  || !TREE_STATIC (ctor))
  	return NULL_TREE;
  
*************** fold_const_aggregate_ref (tree t)
*** 1036,1041 ****
--- 1037,1056 ----
  	  return NULL_TREE;
  	}
  
+       /* Fold read from constant string.  */
+       if (TREE_CODE (ctor) == STRING_CST)
+ 	{
+ 	  if ((TYPE_MODE (TREE_TYPE (t))
+ 	       == TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor))))
+ 	      && (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor))))
+ 	          == MODE_INT)
+ 	      && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor)))) == 1
+ 	      && compare_tree_int (idx, TREE_STRING_LENGTH (ctor)) < 0)
+ 	    return build_int_cst (TREE_TYPE (t), (TREE_STRING_POINTER (ctor)
+ 					          [TREE_INT_CST_LOW (idx)]));
+ 	  return NULL_TREE;
+ 	}
+ 
        /* Whoo-hoo!  I'll fold ya baby.  Yeah!  */
        FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
  	if (tree_int_cst_equal (cfield, idx))
*************** static prop_value_t
*** 1104,1110 ****
  evaluate_stmt (tree stmt)
  {
    prop_value_t val;
!   tree simplified;
    ccp_lattice_t likelyvalue = likely_value (stmt);
  
    val.mem_ref = NULL_TREE;
--- 1119,1125 ----
  evaluate_stmt (tree stmt)
  {
    prop_value_t val;
!   tree simplified = NULL_TREE;
    ccp_lattice_t likelyvalue = likely_value (stmt);
  
    val.mem_ref = NULL_TREE;
*************** evaluate_stmt (tree stmt)
*** 1115,1128 ****
      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);
    /* 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
      simplified = fold_const_aggregate_ref (get_rhs (stmt));
  
    if (simplified && is_gimple_min_invariant (simplified))
--- 1130,1143 ----
      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));
  
    if (simplified && is_gimple_min_invariant (simplified))
Index: testsuite/gcc.dg/tree-ssa/ssa-ccp-13.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/ssa-ccp-13.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/ssa-ccp-13.c	(revision 0)
***************
*** 0 ****
--- 1,14 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-optimized" } */
+ 
+ static const char f[3] = "?";
+ 
+ int foo()
+ {
+   int i = 0;
+   return f[i] != '?';
+ }
+ 
+ /* { dg-final { scan-tree-dump "return 0;" "optimized" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */
+ 


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