Commit ae3df618 by Steven Bosscher Committed by Kazu Hirata

PR tree-optimization/14841, tree-optimization/15838

gcc/
	PR tree-optimization/14841, tree-optimization/15838
	* tree-ssa-ccp.c (fold_const_aggregate_ref): New.
	(evaluate_stmt): Call it.

testsuite/
	PR tree-optimization/14841, tree-optimization/15838
	* gcc.dg/tree-ssa/pr14841.c: New.

Co-Authored-By: Kazu Hirata <kazu@cs.umass.edu>

From-SVN: r99410
parent 0f666d6e
2005-05-08 Steven Bosscher <stevenb@suse.de>
Kazu Hirata <kazu@cs.umass.edu>
PR tree-optimization/14841, tree-optimization/15838
* tree-ssa-ccp.c (fold_const_aggregate_ref): New.
(evaluate_stmt): Call it.
2005-05-08 Jakub Jelinek <jakub@redhat.com>
* config/ia64/ia64.c (ia64_override_options): Don't set
......
......@@ -2078,7 +2078,7 @@ tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \
$(DIAGNOSTIC_H) errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) $(BASIC_BLOCK_H) tree-pass.h langhooks.h \
tree-ssa-propagate.h $(FLAGS_H)
tree-ssa-propagate.h $(FLAGS_H) $(TARGET_H)
tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) errors.h $(TREE_H) $(RTL_H) \
$(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) tree-inline.h \
$(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_GIMPLE_H) \
......
/* PR tree-optimization/14841
Make sure that we can fold a possible nested reference into a
constant aggregate. */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-store_ccp-details" } */
struct car {
int speed;
int tire_pressure[4];
};
const struct car cars[] = {
{ 75, { 10, 20, 30, 40 } },
{ 35, { 12, 34, 56, 78 } },
{ 40, { 19, 28, 37, 46 } }
};
extern void link_error (void);
void
foo (void)
{
if (cars[1].tire_pressure[2] != 56)
link_error ();
}
/* { dg-final { scan-tree-dump-times "with if \\(0\\)" 1 "store_ccp"} } */
/* { dg-final { cleanup-tree-dump "store_ccp" } } */
......@@ -209,6 +209,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tree-pass.h"
#include "tree-ssa-propagate.h"
#include "langhooks.h"
#include "target.h"
/* Possible lattice values. */
......@@ -970,6 +971,127 @@ ccp_fold (tree stmt)
}
/* 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. */
static tree
fold_const_aggregate_ref (tree t)
{
prop_value_t *value;
tree base, ctor, idx, field, elt;
switch (TREE_CODE (t))
{
case ARRAY_REF:
/* Get a CONSTRUCTOR. If BASE is a VAR_DECL, get its
DECL_INITIAL. If BASE is a nested reference into another
ARRAY_REF or COMPONENT_REF, make a recursive call to resolve
the inner reference. */
base = TREE_OPERAND (t, 0);
switch (TREE_CODE (base))
{
case VAR_DECL:
if (!TREE_READONLY (base)
|| TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE
|| !targetm.binds_local_p (base))
return NULL_TREE;
ctor = DECL_INITIAL (base);
break;
case ARRAY_REF:
case COMPONENT_REF:
ctor = fold_const_aggregate_ref (base);
break;
default:
return NULL_TREE;
}
if (ctor == NULL_TREE
|| TREE_CODE (ctor) != CONSTRUCTOR
|| !TREE_STATIC (ctor))
return NULL_TREE;
/* Get the index. If we have an SSA_NAME, try to resolve it
with the current lattice value for the SSA_NAME. */
idx = TREE_OPERAND (t, 1);
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;
else
return NULL_TREE;
break;
case INTEGER_CST:
break;
default:
return NULL_TREE;
}
/* Whoo-hoo! I'll fold ya baby. Yeah! */
for (elt = CONSTRUCTOR_ELTS (ctor);
(elt && !tree_int_cst_equal (TREE_PURPOSE (elt), idx));
elt = TREE_CHAIN (elt))
;
if (elt)
return TREE_VALUE (elt);
break;
case COMPONENT_REF:
/* Get a CONSTRUCTOR. If BASE is a VAR_DECL, get its
DECL_INITIAL. If BASE is a nested reference into another
ARRAY_REF or COMPONENT_REF, make a recursive call to resolve
the inner reference. */
base = TREE_OPERAND (t, 0);
switch (TREE_CODE (base))
{
case VAR_DECL:
if (!TREE_READONLY (base)
|| TREE_CODE (TREE_TYPE (base)) != RECORD_TYPE
|| !targetm.binds_local_p (base))
return NULL_TREE;
ctor = DECL_INITIAL (base);
break;
case ARRAY_REF:
case COMPONENT_REF:
ctor = fold_const_aggregate_ref (base);
break;
default:
return NULL_TREE;
}
if (ctor == NULL_TREE
|| TREE_CODE (ctor) != CONSTRUCTOR
|| !TREE_STATIC (ctor))
return NULL_TREE;
field = TREE_OPERAND (t, 1);
for (elt = CONSTRUCTOR_ELTS (ctor); elt; elt = TREE_CHAIN (elt))
if (TREE_PURPOSE (elt) == field
/* FIXME: Handle bit-fields. */
&& ! DECL_BIT_FIELD (TREE_PURPOSE (elt)))
return TREE_VALUE (elt);
break;
default:
break;
}
return NULL_TREE;
}
/* Evaluate statement STMT. */
static prop_value_t
......@@ -989,10 +1111,13 @@ evaluate_stmt (tree stmt)
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. */
/* 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 = NULL_TREE;
simplified = fold_const_aggregate_ref (get_rhs (stmt));
if (simplified && is_gimple_min_invariant (simplified))
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment