Commit 3c0b6c43 by Daniel Berlin Committed by Daniel Berlin

tree.c (init_ttree): Add STRUCT_FIELD_TAG handling.

2006-02-15 Daniel Berlin  <dberlin@dberlin.org>

	* tree.c (init_ttree): Add STRUCT_FIELD_TAG handling.
	(tree_code_size): Ditto.
	* tree.h (struct tree_memory_tag): Remove parent_var.
	(struct tree_struct_field_tag): New.
	(SFT_OFFSET): New.
	(SFT_SIZE): New.
	(union tree_node): Add sft member.
	* tree-ssa-alias.c (get_tmt_for): Don't handle TYPE_READONLY
	specially here.
	(create_sft): Add size and offset argument, set SFT_OFFSET and
	SFT_SIZE.
	(create_overlap_variables_for): Update for SFT_OFFSET/SFT_SIZE.
	* treestruct.def: Add TS_STRUCT_FIELD_TAG.
	* tree-flow-inline.h (get_subvar_at): Update for
	SFT_OFFSET/SFT_SIZE.
	(var_can_have_subvars): Ditto.
	(overlap_subvar): Ditto.
	* print-tree.c (print_node): Print out interesting things for
	SFT's.
	* tree-flow.h (struct subvar): Remove offset and size members.
	* tree-ssa-operands.c (get_expr_operands): Update for
	get_indirect_ref_operands changes.
	(get_indirect_ref_operands): Call add_virtual_operand instead of
	add_stmt_operand.  Only recurse on base var if requested.
	(access_can_touch_variable): New function.
	(add_stmt_operand): Split virtual operand handling into ...
	(add_virtual_operand): Here.  Add offset, size, and for_clobber
	arguments.  Prune alias sets.
	(add_call_clobber_ops): Call add_virtual_operand.

From-SVN: r111120
parent cce283c7
2006-02-15 Daniel Berlin <dberlin@dberlin.org>
* tree.c (init_ttree): Add STRUCT_FIELD_TAG handling.
(tree_code_size): Ditto.
* tree.h (struct tree_memory_tag): Remove parent_var.
(struct tree_struct_field_tag): New.
(SFT_OFFSET): New.
(SFT_SIZE): New.
(union tree_node): Add sft member.
* tree-ssa-alias.c (get_tmt_for): Don't handle TYPE_READONLY
specially here.
(create_sft): Add size and offset argument, set SFT_OFFSET and
SFT_SIZE.
(create_overlap_variables_for): Update for SFT_OFFSET/SFT_SIZE.
* treestruct.def: Add TS_STRUCT_FIELD_TAG.
* tree-flow-inline.h (get_subvar_at): Update for
SFT_OFFSET/SFT_SIZE.
(var_can_have_subvars): Ditto.
(overlap_subvar): Ditto.
* print-tree.c (print_node): Print out interesting things for
SFT's.
* tree-flow.h (struct subvar): Remove offset and size members.
* tree-ssa-operands.c (get_expr_operands): Update for
get_indirect_ref_operands changes.
(get_indirect_ref_operands): Call add_virtual_operand instead of
add_stmt_operand. Only recurse on base var if requested.
(access_can_touch_variable): New function.
(add_stmt_operand): Split virtual operand handling into ...
(add_virtual_operand): Here. Add offset, size, and for_clobber
arguments. Prune alias sets.
(add_call_clobber_ops): Call add_virtual_operand.
2006-02-15 Jakub Jelinek <jakub@redhat.com>
PR middle-end/26300
......
......@@ -510,6 +510,15 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
&& DECL_HAS_VALUE_EXPR_P (node))
print_node (file, "value-expr", DECL_VALUE_EXPR (node), indent + 4);
if (TREE_CODE (node) == STRUCT_FIELD_TAG)
{
fprintf (file, " sft size " HOST_WIDE_INT_PRINT_DEC,
SFT_SIZE (node));
fprintf (file, " sft offset " HOST_WIDE_INT_PRINT_DEC,
SFT_OFFSET (node));
print_node_brief (file, "parent var", SFT_PARENT_VAR (node),
indent + 4);
}
/* Print the decl chain only if decl is at second level. */
if (indent == 4)
print_node (file, "chain", TREE_CHAIN (node), indent + 4);
......
......@@ -1450,7 +1450,7 @@ get_subvar_at (tree var, unsigned HOST_WIDE_INT offset)
subvar_t sv;
for (sv = get_subvars_for_var (var); sv; sv = sv->next)
if (sv->offset == offset)
if (SFT_OFFSET (sv->var) == offset)
return sv->var;
return NULL_TREE;
......@@ -1491,7 +1491,7 @@ var_can_have_subvars (tree v)
static inline bool
overlap_subvar (unsigned HOST_WIDE_INT offset, unsigned HOST_WIDE_INT size,
subvar_t sv, bool *exact)
tree sv, bool *exact)
{
/* There are three possible cases of overlap.
1. We can have an exact overlap, like so:
......@@ -1511,17 +1511,19 @@ overlap_subvar (unsigned HOST_WIDE_INT offset, unsigned HOST_WIDE_INT size,
if (exact)
*exact = false;
if (offset == sv->offset && size == sv->size)
if (offset == SFT_OFFSET (sv) && size == SFT_SIZE (sv))
{
if (exact)
*exact = true;
return true;
}
else if (offset >= sv->offset && offset < (sv->offset + sv->size))
else if (offset >= SFT_OFFSET (sv)
&& offset < (SFT_OFFSET (sv) + SFT_SIZE (sv)))
{
return true;
}
else if (offset < sv->offset && (size > sv->offset - offset))
else if (offset < SFT_OFFSET (sv)
&& (size > SFT_OFFSET (sv) - offset))
{
return true;
}
......
......@@ -149,12 +149,6 @@ struct subvar GTY(())
/* Fake variable. */
tree var;
/* Offset inside structure. */
unsigned HOST_WIDE_INT offset;
/* Size of the field. */
unsigned HOST_WIDE_INT size;
/* Next subvar for this structure. */
subvar_t next;
};
......@@ -610,7 +604,7 @@ extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *,
static inline bool var_can_have_subvars (tree);
static inline bool overlap_subvar (unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT,
subvar_t, bool *);
tree, bool *);
/* Call-back function for walk_use_def_chains(). At each reaching
definition, a function with this prototype is called. */
......
......@@ -2061,8 +2061,7 @@ get_tmt_for (tree ptr, struct alias_info *ai)
{
struct alias_map_d *curr = ai->pointers[i];
tree curr_tag = var_ann (curr->var)->type_mem_tag;
if (tag_set == curr->set
&& TYPE_READONLY (tag_type) == TYPE_READONLY (TREE_TYPE (curr_tag)))
if (tag_set == curr->set)
{
tag = curr_tag;
break;
......@@ -2099,10 +2098,6 @@ get_tmt_for (tree ptr, struct alias_info *ai)
pointed-to type. */
gcc_assert (tag_set == get_alias_set (tag));
/* If PTR's pointed-to type is read-only, then TAG's type must also
be read-only. */
gcc_assert (TYPE_READONLY (tag_type) == TYPE_READONLY (TREE_TYPE (tag)));
return tag;
}
......@@ -2749,11 +2744,12 @@ get_or_create_used_part_for (size_t uid)
}
/* Create and return a structure sub-variable for field type FIELD of
variable VAR. */
/* Create and return a structure sub-variable for field type FIELD at
offset OFFSET, with size SIZE, of variable VAR. */
static tree
create_sft (tree var, tree field)
create_sft (tree var, tree field, unsigned HOST_WIDE_INT offset,
unsigned HOST_WIDE_INT size)
{
var_ann_t ann;
tree subvar = create_tag_raw (STRUCT_FIELD_TAG, field, "SFT");
......@@ -2771,7 +2767,8 @@ create_sft (tree var, tree field)
ann->type_mem_tag = NULL;
add_referenced_tmp_var (subvar);
SFT_PARENT_VAR (subvar) = var;
SFT_OFFSET (subvar) = offset;
SFT_SIZE (subvar) = size;
return subvar;
}
......@@ -2882,19 +2879,17 @@ create_overlap_variables_for (tree var)
&& currfotype == lastfotype))
continue;
sv = GGC_NEW (struct subvar);
sv->offset = fo->offset;
sv->size = fosize;
sv->next = *subvars;
sv->var = create_sft (var, fo->type);
sv->var = create_sft (var, fo->type, fo->offset, fosize);
if (dump_file)
{
fprintf (dump_file, "structure field tag %s created for var %s",
get_name (sv->var), get_name (var));
fprintf (dump_file, " offset " HOST_WIDE_INT_PRINT_DEC,
sv->offset);
SFT_OFFSET (sv->var));
fprintf (dump_file, " size " HOST_WIDE_INT_PRINT_DEC,
sv->size);
SFT_SIZE (sv->var));
fprintf (dump_file, "\n");
}
......
......@@ -276,6 +276,8 @@ init_ttree (void)
tree_contains_struct[NAME_MEMORY_TAG][TS_MEMORY_TAG] = 1;
tree_contains_struct[TYPE_MEMORY_TAG][TS_MEMORY_TAG] = 1;
tree_contains_struct[STRUCT_FIELD_TAG][TS_STRUCT_FIELD_TAG] = 1;
tree_contains_struct[VAR_DECL][TS_DECL_WITH_VIS] = 1;
tree_contains_struct[FUNCTION_DECL][TS_DECL_WITH_VIS] = 1;
tree_contains_struct[TYPE_DECL][TS_DECL_WITH_VIS] = 1;
......@@ -335,8 +337,9 @@ tree_code_size (enum tree_code code)
return sizeof (struct tree_function_decl);
case NAME_MEMORY_TAG:
case TYPE_MEMORY_TAG:
case STRUCT_FIELD_TAG:
return sizeof (struct tree_memory_tag);
case STRUCT_FIELD_TAG:
return sizeof (struct tree_struct_field_tag);
default:
return sizeof (struct tree_decl_non_common);
}
......
......@@ -2309,12 +2309,28 @@ struct tree_decl_minimal GTY(())
struct tree_memory_tag GTY(())
{
struct tree_decl_minimal common;
tree parent_var;
unsigned int is_global:1;
};
#define MTAG_GLOBAL(NODE) (TREE_MEMORY_TAG_CHECK (NODE)->mtag.is_global)
#define SFT_PARENT_VAR(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->mtag.parent_var)
struct tree_struct_field_tag GTY(())
{
struct tree_memory_tag common;
/* Parent variable. */
tree parent_var;
/* Offset inside structure. */
unsigned HOST_WIDE_INT offset;
/* Size of the field. */
unsigned HOST_WIDE_INT size;
};
#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_SIZE(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.size)
/* For any sort of a ..._DECL node, this points to the original (abstract)
decl node which this decl is an instance of, or else it is NULL indicating
......@@ -3124,6 +3140,7 @@ union tree_node GTY ((ptr_alias (union lang_tree_node),
struct tree_value_handle GTY ((tag ("TS_VALUE_HANDLE"))) value_handle;
struct tree_constructor GTY ((tag ("TS_CONSTRUCTOR"))) constructor;
struct tree_memory_tag GTY ((tag ("TS_MEMORY_TAG"))) mtag;
struct tree_struct_field_tag GTY ((tag ("TS_STRUCT_FIELD_TAG"))) sft;
struct tree_omp_clause GTY ((tag ("TS_OMP_CLAUSE"))) omp_clause;
};
......
......@@ -60,4 +60,5 @@ DEFTREESTRUCT(TS_STATEMENT_LIST, "statement list")
DEFTREESTRUCT(TS_VALUE_HANDLE, "value handle")
DEFTREESTRUCT(TS_CONSTRUCTOR, "constructor")
DEFTREESTRUCT(TS_MEMORY_TAG, "memory tag")
DEFTREESTRUCT(TS_STRUCT_FIELD_TAG, "struct field tag")
DEFTREESTRUCT(TS_OMP_CLAUSE, "omp clause")
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