summaryrefslogtreecommitdiffstats
path: root/gcc/tree-sra.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-11 17:41:52 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-11 17:41:52 +0000
commit504d3463155888e30ae12775390b578c7723a827 (patch)
tree2934106e3d3e6eaac5aa3e9c20bb96aa1aaada5f /gcc/tree-sra.c
parenteece3694d24497188aef662b7e87a5733ed1a79c (diff)
downloadppe42-gcc-504d3463155888e30ae12775390b578c7723a827.tar.gz
ppe42-gcc-504d3463155888e30ae12775390b578c7723a827.zip
PR tree-opt/16383
* tree-ssa-ccp.c (fold_stmt_r): Split out... * tree.c (fields_compatible_p, find_compatible_field): ... new. * tree.h (fields_compatible_p, find_compatible_field): Declare. * tree-sra.c (sra_hash_tree): Hash fields by offset. (sra_elt_eq): Use fields_compatible_p. (generate_one_element_ref): Use find_compatible_field. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@84524 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r--gcc/tree-sra.c67
1 files changed, 55 insertions, 12 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 1a4e5586c4f..423ee3ca498 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -357,18 +357,32 @@ can_completely_scalarize_p (struct sra_elt *elt)
static hashval_t
sra_hash_tree (tree t)
{
+ hashval_t h;
+
switch (TREE_CODE (t))
{
case VAR_DECL:
case PARM_DECL:
case RESULT_DECL:
- case FIELD_DECL:
- return DECL_UID (t);
+ h = DECL_UID (t);
+ break;
+
case INTEGER_CST:
- return TREE_INT_CST_LOW (t) ^ TREE_INT_CST_HIGH (t);
+ h = TREE_INT_CST_LOW (t) ^ TREE_INT_CST_HIGH (t);
+ break;
+
+ case FIELD_DECL:
+ /* We can have types that are compatible, but have different member
+ lists, so we can't hash fields by ID. Use offsets instead. */
+ h = iterative_hash_expr (DECL_FIELD_OFFSET (t), 0);
+ h = iterative_hash_expr (DECL_FIELD_BIT_OFFSET (t), h);
+ break;
+
default:
abort ();
}
+
+ return h;
}
/* Hash function for type SRA_PAIR. */
@@ -399,20 +413,41 @@ sra_elt_eq (const void *x, const void *y)
{
const struct sra_elt *a = x;
const struct sra_elt *b = y;
+ tree ae, be;
if (a->parent != b->parent)
return false;
- /* All the field/decl stuff is unique. */
- if (a->element == b->element)
- return true;
+ ae = a->element;
+ be = b->element;
- /* The only thing left is integer equality. */
- if (TREE_CODE (a->element) == INTEGER_CST
- && TREE_CODE (b->element) == INTEGER_CST)
- return tree_int_cst_equal (a->element, b->element);
- else
+ if (ae == be)
+ return true;
+ if (TREE_CODE (ae) != TREE_CODE (be))
return false;
+
+ switch (TREE_CODE (ae))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ /* These are all pointer unique. */
+ return false;
+
+ case INTEGER_CST:
+ /* Integers are not pointer unique, so compare their values. */
+ return tree_int_cst_equal (ae, be);
+
+ case FIELD_DECL:
+ /* Fields are unique within a record, but not between
+ compatible records. */
+ if (DECL_FIELD_CONTEXT (ae) == DECL_FIELD_CONTEXT (be))
+ return false;
+ return fields_compatible_p (ae, be);
+
+ default:
+ abort ();
+ }
}
/* Create or return the SRA_ELT structure for CHILD in PARENT. PARENT
@@ -1392,7 +1427,15 @@ generate_one_element_ref (struct sra_elt *elt, tree base)
switch (TREE_CODE (TREE_TYPE (base)))
{
case RECORD_TYPE:
- return build (COMPONENT_REF, elt->type, base, elt->element, NULL);
+ {
+ tree field = elt->element;
+
+ /* Watch out for compatible records with differing field lists. */
+ if (DECL_FIELD_CONTEXT (field) != TYPE_MAIN_VARIANT (TREE_TYPE (base)))
+ field = find_compatible_field (TREE_TYPE (base), field);
+
+ return build (COMPONENT_REF, elt->type, base, field, NULL);
+ }
case ARRAY_TYPE:
return build (ARRAY_REF, elt->type, base, elt->element, NULL, NULL);
OpenPOWER on IntegriCloud