This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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))
{