Commit 3d9b47dc by Adam Nemet Committed by Adam Nemet

re PR tree-optimization/25737 (ACATS c974001 c974013 hang with struct aliasing)

	PR tree-optimization/25737
	* tree.h (struct tree_struct_field_tag): Add new field alias_set.
	(SFT_NONADDRESSABLE_P, SFT_ALIAS_SET): New macros.
	* tree-flow.h (struct fieldoff): Add new field alias_set.
	* tree-ssa-structalias.c (push_fields_onto_fieldstack): Add new
	argument addressable_type.  Set alias_set of fieldoff.
	* tree-ssa-alias.c (create_sft): Add new argument alias_set.
	(create_overlap_variables_for): Pass alias_set from fieldoff to
	create_sft.
	* alias.c (get_alias_set): Use alias_set from SFT if set.

From-SVN: r125890
parent 034bfe7a
2007-06-20 Adam Nemet <anemet@caviumnetworks.com>
PR tree-optimization/25737
* tree.h (struct tree_struct_field_tag): Add new field alias_set.
(SFT_NONADDRESSABLE_P, SFT_ALIAS_SET): New macros.
* tree-flow.h (struct fieldoff): Add new field alias_set.
* tree-ssa-structalias.c (push_fields_onto_fieldstack): Add new
argument addressable_type. Set alias_set of fieldoff.
* tree-ssa-alias.c (create_sft): Add new argument alias_set.
(create_overlap_variables_for): Pass alias_set from fieldoff to
create_sft.
* alias.c (get_alias_set): Use alias_set from SFT if set.
2007-06-20 Hui-May Chang <hm.chang@apple.com> 2007-06-20 Hui-May Chang <hm.chang@apple.com>
* config/i386/darwin.h (ASM_OUTPUT_COMMON): Print the size * config/i386/darwin.h (ASM_OUTPUT_COMMON): Print the size
......
...@@ -586,6 +586,13 @@ get_alias_set (tree t) ...@@ -586,6 +586,13 @@ get_alias_set (tree t)
return 0; return 0;
} }
/* For non-addressable fields we return the alias set of the
outermost object that could have its address taken. If this
is an SFT use the precomputed value. */
if (TREE_CODE (t) == STRUCT_FIELD_TAG
&& SFT_NONADDRESSABLE_P (t))
return SFT_ALIAS_SET (t);
/* Otherwise, pick up the outermost object that we could have a pointer /* Otherwise, pick up the outermost object that we could have a pointer
to, processing conversions as above. */ to, processing conversions as above. */
while (component_uses_parent_alias_set (t)) while (component_uses_parent_alias_set (t))
......
...@@ -1158,13 +1158,14 @@ struct fieldoff ...@@ -1158,13 +1158,14 @@ struct fieldoff
tree size; tree size;
tree decl; tree decl;
HOST_WIDE_INT offset; HOST_WIDE_INT offset;
HOST_WIDE_INT alias_set;
}; };
typedef struct fieldoff fieldoff_s; typedef struct fieldoff fieldoff_s;
DEF_VEC_O(fieldoff_s); DEF_VEC_O(fieldoff_s);
DEF_VEC_ALLOC_O(fieldoff_s,heap); DEF_VEC_ALLOC_O(fieldoff_s,heap);
int push_fields_onto_fieldstack (tree, VEC(fieldoff_s,heap) **, int push_fields_onto_fieldstack (tree, VEC(fieldoff_s,heap) **,
HOST_WIDE_INT, bool *); HOST_WIDE_INT, bool *, tree);
void sort_fieldstack (VEC(fieldoff_s,heap) *); void sort_fieldstack (VEC(fieldoff_s,heap) *);
void init_alias_heapvars (void); void init_alias_heapvars (void);
......
...@@ -3646,11 +3646,13 @@ get_or_create_used_part_for (size_t uid) ...@@ -3646,11 +3646,13 @@ get_or_create_used_part_for (size_t uid)
/* Create and return a structure sub-variable for field type FIELD at /* Create and return a structure sub-variable for field type FIELD at
offset OFFSET, with size SIZE, of variable VAR. */ offset OFFSET, with size SIZE, of variable VAR. If ALIAS_SET not
-1 this field is non-addressable and we should use this alias set
with this field. */
static tree static tree
create_sft (tree var, tree field, unsigned HOST_WIDE_INT offset, create_sft (tree var, tree field, unsigned HOST_WIDE_INT offset,
unsigned HOST_WIDE_INT size) unsigned HOST_WIDE_INT size, HOST_WIDE_INT alias_set)
{ {
tree subvar = create_tag_raw (STRUCT_FIELD_TAG, field, "SFT"); tree subvar = create_tag_raw (STRUCT_FIELD_TAG, field, "SFT");
...@@ -3669,6 +3671,7 @@ create_sft (tree var, tree field, unsigned HOST_WIDE_INT offset, ...@@ -3669,6 +3671,7 @@ create_sft (tree var, tree field, unsigned HOST_WIDE_INT offset,
SFT_PARENT_VAR (subvar) = var; SFT_PARENT_VAR (subvar) = var;
SFT_OFFSET (subvar) = offset; SFT_OFFSET (subvar) = offset;
SFT_SIZE (subvar) = size; SFT_SIZE (subvar) = size;
SFT_ALIAS_SET (subvar) = alias_set;
return subvar; return subvar;
} }
...@@ -3688,7 +3691,8 @@ create_overlap_variables_for (tree var) ...@@ -3688,7 +3691,8 @@ create_overlap_variables_for (tree var)
|| up->write_only) || up->write_only)
return; return;
push_fields_onto_fieldstack (TREE_TYPE (var), &fieldstack, 0, NULL); push_fields_onto_fieldstack (TREE_TYPE (var), &fieldstack, 0, NULL,
TREE_TYPE (var));
if (VEC_length (fieldoff_s, fieldstack) != 0) if (VEC_length (fieldoff_s, fieldstack) != 0)
{ {
subvar_t *subvars; subvar_t *subvars;
...@@ -3780,7 +3784,8 @@ create_overlap_variables_for (tree var) ...@@ -3780,7 +3784,8 @@ create_overlap_variables_for (tree var)
continue; continue;
sv = GGC_NEW (struct subvar); sv = GGC_NEW (struct subvar);
sv->next = *subvars; sv->next = *subvars;
sv->var = create_sft (var, fo->type, fo->offset, fosize); sv->var =
create_sft (var, fo->type, fo->offset, fosize, fo->alias_set);
if (dump_file) if (dump_file)
{ {
......
...@@ -3695,11 +3695,13 @@ sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack) ...@@ -3695,11 +3695,13 @@ sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack)
than just the immediately containing structure. Returns the number than just the immediately containing structure. Returns the number
of fields pushed. of fields pushed.
HAS_UNION is set to true if we find a union type as a field of HAS_UNION is set to true if we find a union type as a field of
TYPE. */ TYPE. ADDRESSABLE_TYPE is the type of the outermost object that could have
its address taken. */
int int
push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
HOST_WIDE_INT offset, bool *has_union) HOST_WIDE_INT offset, bool *has_union,
tree addressable_type)
{ {
tree field; tree field;
int count = 0; int count = 0;
...@@ -3712,12 +3714,14 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, ...@@ -3712,12 +3714,14 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
real_part->size = TYPE_SIZE (TREE_TYPE (type)); real_part->size = TYPE_SIZE (TREE_TYPE (type));
real_part->offset = offset; real_part->offset = offset;
real_part->decl = NULL_TREE; real_part->decl = NULL_TREE;
real_part->alias_set = -1;
img_part = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL); img_part = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
img_part->type = TREE_TYPE (type); img_part->type = TREE_TYPE (type);
img_part->size = TYPE_SIZE (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->offset = offset + TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (type)));
img_part->decl = NULL_TREE; img_part->decl = NULL_TREE;
img_part->alias_set = -1;
return 2; return 2;
} }
...@@ -3755,7 +3759,8 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, ...@@ -3755,7 +3759,8 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
push = true; push = true;
else if (!(pushed = push_fields_onto_fieldstack else if (!(pushed = push_fields_onto_fieldstack
(TREE_TYPE (type), fieldstack, (TREE_TYPE (type), fieldstack,
offset + i * TREE_INT_CST_LOW (elsz), has_union))) offset + i * TREE_INT_CST_LOW (elsz), has_union,
TREE_TYPE (type))))
/* Empty structures may have actual size, like in C++. So /* Empty structures may have actual size, like in C++. So
see if we didn't push any subfields and the size is see if we didn't push any subfields and the size is
nonzero, push the field onto the stack */ nonzero, push the field onto the stack */
...@@ -3770,6 +3775,7 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, ...@@ -3770,6 +3775,7 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
pair->size = elsz; pair->size = elsz;
pair->decl = NULL_TREE; pair->decl = NULL_TREE;
pair->offset = offset + i * TREE_INT_CST_LOW (elsz); pair->offset = offset + i * TREE_INT_CST_LOW (elsz);
pair->alias_set = -1;
count++; count++;
} }
else else
...@@ -3794,7 +3800,10 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, ...@@ -3794,7 +3800,10 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
push = true; push = true;
else if (!(pushed = push_fields_onto_fieldstack else if (!(pushed = push_fields_onto_fieldstack
(TREE_TYPE (field), fieldstack, (TREE_TYPE (field), fieldstack,
offset + bitpos_of_field (field), has_union)) offset + bitpos_of_field (field), has_union,
(DECL_NONADDRESSABLE_P (field)
? addressable_type
: TREE_TYPE (field))))
&& DECL_SIZE (field) && DECL_SIZE (field)
&& !integer_zerop (DECL_SIZE (field))) && !integer_zerop (DECL_SIZE (field)))
/* Empty structures may have actual size, like in C++. So /* Empty structures may have actual size, like in C++. So
...@@ -3811,6 +3820,10 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, ...@@ -3811,6 +3820,10 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
pair->size = DECL_SIZE (field); pair->size = DECL_SIZE (field);
pair->decl = field; pair->decl = field;
pair->offset = offset + bitpos_of_field (field); pair->offset = offset + bitpos_of_field (field);
if (DECL_NONADDRESSABLE_P (field))
pair->alias_set = get_alias_set (addressable_type);
else
pair->alias_set = -1;
count++; count++;
} }
else else
...@@ -4009,7 +4022,8 @@ create_variable_info_for (tree decl, const char *name) ...@@ -4009,7 +4022,8 @@ create_variable_info_for (tree decl, const char *name)
|| TREE_CODE (decltype) == QUAL_UNION_TYPE; || TREE_CODE (decltype) == QUAL_UNION_TYPE;
if (var_can_have_subvars (decl) && use_field_sensitive && !hasunion) if (var_can_have_subvars (decl) && use_field_sensitive && !hasunion)
{ {
push_fields_onto_fieldstack (decltype, &fieldstack, 0, &hasunion); push_fields_onto_fieldstack (decltype, &fieldstack, 0, &hasunion,
decltype);
if (hasunion) if (hasunion)
{ {
VEC_free (fieldoff_s, heap, fieldstack); VEC_free (fieldoff_s, heap, fieldstack);
......
...@@ -2516,10 +2516,15 @@ struct tree_struct_field_tag GTY(()) ...@@ -2516,10 +2516,15 @@ struct tree_struct_field_tag GTY(())
/* Size of the field. */ /* Size of the field. */
unsigned HOST_WIDE_INT size; unsigned HOST_WIDE_INT size;
/* Alias set for a DECL_NONADDRESSABLE_P field. Otherwise -1. */
HOST_WIDE_INT alias_set;
}; };
#define SFT_PARENT_VAR(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.parent_var) #define SFT_PARENT_VAR(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.parent_var)
#define SFT_OFFSET(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.offset) #define SFT_OFFSET(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.offset)
#define SFT_SIZE(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.size) #define SFT_SIZE(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.size)
#define SFT_NONADDRESSABLE_P(NODE) \
(STRUCT_FIELD_TAG_CHECK (NODE)->sft.alias_set != -1)
#define SFT_ALIAS_SET(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.alias_set)
/* Memory Partition Tags (MPTs) group memory symbols under one /* Memory Partition Tags (MPTs) group memory symbols under one
common name for the purposes of placing memory PHI nodes. */ common name for the purposes of placing memory PHI nodes. */
......
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