aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/tree-flow-inline.h21
-rw-r--r--gcc/tree-ssa-alias.c2
-rw-r--r--gcc/tree-ssa-operands.c8
-rw-r--r--gcc/tree-ssa-structalias.c18
5 files changed, 58 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 93bd4e1..65aba5c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2006-01-06 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR tree-opt/25528
+ * tree-ssa-alias.c (find_used_portions): Handle REALPART_EXPR
+ and IMAGPART_EXPR.
+ * tree-flow-inline.h (var_can_have_subvars): Handle complex types
+ on non gimple variables. Also add checks at the top for decls and
+ mtags.
+ * tree-ssa-structalias.c (push_fields_onto_fieldstack): Handle
+ complex types.
+ * tree-ssa-operands.c (parse_ssa_operands): Handle REALPART_EXPR
+ and IMAGPART_EXPR for creating MUST_DEFs.
+ (get_expr_operands): Handle SSA_NAME, STRUCT_FIELD_TAG, TYPE_MEMORY_TAG,
+ and NAME_MEMORY_TAG separately from the DECLs.
+
2006-01-06 Richard Guenther <rguenther@suse.de>
* tree-dfa.c (mark_new_vars_to_rename): Create stmt
diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h
index 94e1972..3f8e89d 100644
--- a/gcc/tree-flow-inline.h
+++ b/gcc/tree-flow-inline.h
@@ -1490,13 +1490,28 @@ get_subvar_at (tree var, unsigned HOST_WIDE_INT offset)
/* Return true if V is a tree that we can have subvars for.
Normally, this is any aggregate type, however, due to implementation
- limitations ATM, we exclude array types as well. */
+ limitations ATM, we exclude array types as well. Also complex
+ types which are not gimple registers can have subvars. */
static inline bool
var_can_have_subvars (tree v)
{
- return (AGGREGATE_TYPE_P (TREE_TYPE (v)) &&
- TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE);
+ /* Non decls or memory tags can never have subvars. */
+ if (!DECL_P (v) || MTAG_P (v))
+ return false;
+
+ /* Aggregates besides arrays can have subvars. */
+ if (AGGREGATE_TYPE_P (TREE_TYPE (v))
+ && TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE)
+ return true;
+
+ /* Complex types variables which are not also a gimple register can
+ have subvars. */
+ if (TREE_CODE (TREE_TYPE (v)) == COMPLEX_TYPE
+ && !DECL_COMPLEX_GIMPLE_REG_P (v))
+ return true;
+
+ return false;
}
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index ee6a6e6..cb5dead 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -2694,6 +2694,8 @@ find_used_portions (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
{
switch (TREE_CODE (*tp))
{
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
case COMPONENT_REF:
{
HOST_WIDE_INT bitsize;
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index b7319de..60973ce 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -734,9 +734,7 @@ parse_ssa_operands (tree stmt)
if (TREE_CODE (lhs) != ARRAY_REF
&& TREE_CODE (lhs) != ARRAY_RANGE_REF
- && TREE_CODE (lhs) != BIT_FIELD_REF
- && TREE_CODE (lhs) != REALPART_EXPR
- && TREE_CODE (lhs) != IMAGPART_EXPR)
+ && TREE_CODE (lhs) != BIT_FIELD_REF)
lhs_flags |= opf_kill_def;
get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), lhs_flags);
@@ -1065,6 +1063,10 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
case STRUCT_FIELD_TAG:
case TYPE_MEMORY_TAG:
case NAME_MEMORY_TAG:
+
+ add_stmt_operand (expr_p, s_ann, flags);
+ return;
+
case VAR_DECL:
case PARM_DECL:
case RESULT_DECL:
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index bae21a0..0e2032c 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -3568,6 +3568,24 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
{
tree field;
int count = 0;
+
+ if (TREE_CODE (type) == COMPLEX_TYPE)
+ {
+ fieldoff_s *real_part, *img_part;
+ real_part = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
+ real_part->type = TREE_TYPE (type);
+ real_part->size = TYPE_SIZE (TREE_TYPE (type));
+ real_part->offset = offset;
+ real_part->decl = NULL_TREE;
+
+ img_part = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
+ img_part->type = TREE_TYPE (type);
+ img_part->size = TYPE_SIZE (TREE_TYPE (type));
+ img_part->offset = offset + TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (type)));
+ img_part->decl = NULL_TREE;
+
+ return 2;
+ }
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
if (TREE_CODE (field) == FIELD_DECL)