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: [PATCH] PR14841 and PR15838


On Tuesday 31 August 2004 18:20, Diego Novillo wrote:
> On Tue, 2004-08-31 at 12:10, Steven Bosscher wrote:
> > !       else if (((TREE_CODE (rhs) == ARRAY_REF
> > ! 	         && TREE_CODE (var = TREE_OPERAND (rhs, 0)) == VAR_DECL
> > ! 		 && TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
> > ! 	        || (TREE_CODE (rhs) == COMPONENT_REF
> > ! 		    && TREE_CODE (var = TREE_OPERAND (rhs, 0)) == VAR_DECL
> > ! 		    && TREE_CODE (TREE_TYPE (var)) == RECORD_TYPE
> > ! 		    && TREE_CODE (TREE_OPERAND (rhs, 1)) == FIELD_DECL))
> > ! 	       && TREE_READONLY (var)
> > ! 	       && DECL_INITIAL (var)
> > ! 	       && TREE_CODE (DECL_INITIAL (var)) == CONSTRUCTOR
> > ! 	       && ! TREE_SIDE_EFFECTS (DECL_INITIAL (var)))
>
> Put all this inside a static bool predicate, please.

Like attached.

> OK with that change.

Thanks.
>  Also, could you add both PRs to the testsuite?  A
> link_test() should be fine.

Of course.  Tree dump scans in the ccp dump also OK?

I'll also investigate if the corresponding expr.c parts
can go away now.

Gr.
Steven


        PR tree-optimization/14841
        PR tree-optimization/15838
	* tree-ssa-ccp.c (is_load_from_const_array,
	is_load_from_const_struct): New predicates.
	(try_extract_const_array_ref): New function to extract
	a constant from a constant array initializer.
	(try_extract_const_component_ref): Likewise for const
	struct initializers.
	(evaluate_stmt): Use all of them.

Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-ccp.c,v
retrieving revision 2.35
diff -c -3 -p -r2.35 tree-ssa-ccp.c
*** tree-ssa-ccp.c	29 Aug 2004 15:42:42 -0000	2.35
--- tree-ssa-ccp.c	31 Aug 2004 17:12:18 -0000
*************** ccp_finalize (void)
*** 622,628 ****
  }
  
  
- 
  /* Compute the meet operator between VAL1 and VAL2:
  
     		any  M UNDEFINED     = any
--- 622,627 ----
*************** ccp_fold (tree stmt)
*** 957,962 ****
--- 956,1062 ----
  }
  
  
+ /* Return true iff T is a const array with an initializer.  */
+ 
+ static bool
+ is_load_from_const_array (tree t)
+ {
+   tree var;
+ 
+   if (TREE_CODE (t) != ARRAY_REF)
+     return false;
+ 
+   var = TREE_OPERAND (t, 0);
+   return (TREE_CODE (var) == VAR_DECL
+ 	  && TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
+ 	  && TREE_READONLY (var)
+ 	  && DECL_INITIAL (var)
+ 	  && TREE_CODE (DECL_INITIAL (var)) == CONSTRUCTOR
+ 	  && ! TREE_SIDE_EFFECTS (DECL_INITIAL (var)));
+ }
+ 
+ 
+ /* Return the tree representing the element referenced by T.
+    T must be an ARRAY_REF to a constant array with a constant index.  */
+ 
+ static tree
+ try_extract_const_array_ref (tree t)
+ {
+   value *value;
+   tree var = TREE_OPERAND (t, 0);
+   tree idx = TREE_OPERAND (t, 1);
+   tree array = DECL_INITIAL (var);
+ 
+   if (TREE_CODE (idx) == SSA_NAME
+       && (value = get_value (idx))
+       && value->lattice_val == CONSTANT
+       && TREE_CODE (value->const_val) == INTEGER_CST)
+     idx = value->const_val;
+ 
+   if (TREE_CODE (idx) == INTEGER_CST
+       && compare_tree_int (idx, list_length (CONSTRUCTOR_ELTS (array))) < 0)
+     {
+       /* Try to extract the referenced element.  */
+       tree elt;
+       HOST_WIDE_INT i;
+ 
+       for (elt = CONSTRUCTOR_ELTS (array), i = TREE_INT_CST_LOW (idx);
+ 	   elt != 0 && i != 0;
+ 	   i--, elt = TREE_CHAIN (elt))
+ 	/* Find that element.  */ ;
+ 
+       if (elt)
+ 	return TREE_VALUE (elt);
+     }
+ 
+   return NULL_TREE;
+ }
+ 
+ 
+ /* Return true iff T is a const struct with an initializer.  */
+ 
+ static bool
+ is_load_from_const_struct (tree t)
+ {
+   tree var;
+   if (TREE_CODE (t) != COMPONENT_REF)
+     return false;
+ 
+   var = TREE_OPERAND (t, 0);
+   return (TREE_CODE (var) == VAR_DECL
+ 	  && TREE_CODE (TREE_TYPE (var)) == RECORD_TYPE
+ 	  && TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL
+ 	  && TREE_READONLY (var)
+ 	  && DECL_INITIAL (var)
+ 	  && TREE_CODE (DECL_INITIAL (var)) == CONSTRUCTOR
+ 	  && ! TREE_SIDE_EFFECTS (DECL_INITIAL (var)));
+ }
+ 
+ 
+ /* Return the tree representing the element referenced by T.
+    T must be a COMPONENT_REF to a constant struct.  */
+ 
+ static tree
+ try_extract_const_component_ref (tree t)
+ {
+   tree var = TREE_OPERAND (t, 0);
+   tree field = TREE_OPERAND (t, 1);
+   tree constructor = DECL_INITIAL (var);
+   tree elt;
+ 
+   for (elt = CONSTRUCTOR_ELTS (constructor);
+        elt;
+        elt = TREE_CHAIN (elt))
+     {
+       if (TREE_CODE (TREE_PURPOSE (elt)) == FIELD_DECL
+ 	  && fields_compatible_p (TREE_PURPOSE (elt), field))
+ 	return TREE_VALUE (elt);
+     }
+ 
+   return NULL_TREE;
+ }
+ 
+ 
  /* Evaluate statement STMT.  */
  
  static value
*************** evaluate_stmt (tree stmt)
*** 970,983 ****
       to fold the statement to determine the constant value.  */
    if (likelyvalue == CONSTANT)
      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);
-   /* Otherwise the statement is likely to have an UNDEFINED value and
-      there will be nothing to do.  */
    else
!     simplified = NULL_TREE;
  
    if (simplified && is_gimple_min_invariant (simplified))
      {
--- 1070,1097 ----
       to fold the statement to determine the constant value.  */
    if (likelyvalue == CONSTANT)
      simplified = ccp_fold (stmt);
    else
!     {
!       tree rhs = get_rhs (stmt);
! 
!       /* If the statement is likely to have a VARYING result, then do not
! 	 bother folding the statement.  */
!       if (likelyvalue == VARYING)
! 	simplified = rhs;
! 
!       /* If the statement is a load from a const struct or a constant array
! 	 with a constant index, try to extract the referenced constant.
! 	 Note that try_extract_const_{array,component}_ref return NULL_TREE
! 	 if a constant could not be extacted.  */
!       else if (is_load_from_const_array (rhs))
! 	simplified = try_extract_const_array_ref (rhs);
!       else if (is_load_from_const_struct (rhs))
! 	simplified = try_extract_const_component_ref (rhs);
!       else
!       /* Otherwise the statement is likely to have an UNDEFINED value and
! 	 there will be nothing to do.  */
! 	simplified = NULL_TREE;
!     }
  
    if (simplified && is_gimple_min_invariant (simplified))
      {



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