tree.def (SYMBOL_MEMORY_TAG): Rename from TYPE_MEMORY_TAG.
* tree.def (SYMBOL_MEMORY_TAG): Rename from TYPE_MEMORY_TAG. Update all users. * tree-pass.h (PROP_smt_usage): Rename from PROP_tmt_usage. Update all users. (TODO_update_smt_usage): Rename from TODO_update_tmt_usage. Update all users. * tree.h (SMT_USED_ALONE): Rename from TMT_USED_ALONE. Update all users. * tree-flow.h (struct var_ann_d): Rename field 'type_mem_tag' to 'symbol_mem_tag'. Update all users. * doc/tree-ssa.texi: Update documentation to reflect TMT->SMT rename. From-SVN: r111617
This commit is contained in:
parent
61321991ff
commit
18cd8a03f8
@ -1,3 +1,19 @@
|
||||
2006-03-01 Diego Novillo <dnovillo@redhat.com>
|
||||
|
||||
* tree.def (SYMBOL_MEMORY_TAG): Rename from TYPE_MEMORY_TAG.
|
||||
Update all users.
|
||||
* tree-pass.h (PROP_smt_usage): Rename from PROP_tmt_usage.
|
||||
Update all users.
|
||||
(TODO_update_smt_usage): Rename from TODO_update_tmt_usage.
|
||||
Update all users.
|
||||
* tree.h (SMT_USED_ALONE): Rename from TMT_USED_ALONE.
|
||||
Update all users.
|
||||
* tree-flow.h (struct var_ann_d): Rename field 'type_mem_tag'
|
||||
to 'symbol_mem_tag'.
|
||||
Update all users.
|
||||
* doc/tree-ssa.texi: Update documentation to reflect TMT->SMT
|
||||
rename.
|
||||
|
||||
2006-03-01 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* builtins.c (fold_builtin_copysign): Delete unreachable code.
|
||||
@ -25,7 +41,7 @@
|
||||
* config/darwin.h (TARGET_ASM_OUTPUT_ANCHOR): Define.
|
||||
|
||||
2006-03-01 Daniel Berlin <dberlin@dberlin.org>
|
||||
|
||||
|
||||
Fix PR tree-optimization/26443
|
||||
* tree-vrp.c (pass_vrp): Add TODO_update_tmt_usage
|
||||
to todo and PROP_tmt_usage to properties_destroyed.
|
||||
|
@ -1506,7 +1506,7 @@ int bar (void)
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
If you copy the type tag for a variable for some reason, you probably
|
||||
If you copy the symbol tag for a variable for some reason, you probably
|
||||
also want to copy the subvariables for that variable.
|
||||
|
||||
@item Points-to and escape analysis.
|
||||
@ -1540,12 +1540,12 @@ the variables pointed-to by P_i (and its memory tag) also escape.
|
||||
|
||||
We have two classes of memory tags. Memory tags associated with
|
||||
the pointed-to data type of the pointers in the program. These
|
||||
tags are called ``type memory tag'' (TMT)@. The other class are
|
||||
tags are called ``symbol memory tag'' (SMT)@. The other class are
|
||||
those associated with SSA_NAMEs, called ``name memory tag'' (NMT)@.
|
||||
The basic idea is that when adding operands for an INDIRECT_REF
|
||||
*P_i, we will first check whether P_i has a name tag, if it does
|
||||
we use it, because that will have more precise aliasing
|
||||
information. Otherwise, we use the standard type tag.
|
||||
information. Otherwise, we use the standard symbol tag.
|
||||
|
||||
In this phase, we go through all the pointers we found in
|
||||
points-to analysis and create alias sets for the name memory tags
|
||||
@ -1555,11 +1555,11 @@ call-clobbered the variables it points to and its tag.
|
||||
|
||||
@item Compute flow-insensitive aliases
|
||||
|
||||
This pass will compare the alias set of every type memory tag and
|
||||
every addressable variable found in the program. Given a type
|
||||
memory tag TMT and an addressable variable V@. If the alias sets
|
||||
of TMT and V conflict (as computed by may_alias_p), then V is
|
||||
marked as an alias tag and added to the alias set of TMT@.
|
||||
This pass will compare the alias set of every symbol memory tag and
|
||||
every addressable variable found in the program. Given a symbol
|
||||
memory tag SMT and an addressable variable V@. If the alias sets
|
||||
of SMT and V conflict (as computed by may_alias_p), then V is
|
||||
marked as an alias tag and added to the alias set of SMT@.
|
||||
@end enumerate
|
||||
|
||||
For instance, consider the following function:
|
||||
@ -1581,7 +1581,7 @@ foo (int i)
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
After aliasing analysis has finished, the type memory tag for
|
||||
After aliasing analysis has finished, the symbol memory tag for
|
||||
pointer @code{p} will have two aliases, namely variables @code{a} and
|
||||
@code{b}.
|
||||
Every time pointer @code{p} is dereferenced, we want to mark the
|
||||
|
@ -718,8 +718,8 @@ execute_todo (unsigned int flags)
|
||||
if (!flags)
|
||||
return;
|
||||
|
||||
/* Always recalculate TMT usage before doing anything else. */
|
||||
if (flags & TODO_update_tmt_usage)
|
||||
/* Always recalculate SMT usage before doing anything else. */
|
||||
if (flags & TODO_update_smt_usage)
|
||||
recalculate_used_alone ();
|
||||
|
||||
/* Always cleanup the CFG before trying to update SSA . */
|
||||
@ -825,7 +825,7 @@ execute_one_pass (struct tree_opt_pass *pass)
|
||||
gcc_assert ((curr_properties & pass->properties_required)
|
||||
== pass->properties_required);
|
||||
|
||||
if (pass->properties_destroyed & PROP_tmt_usage)
|
||||
if (pass->properties_destroyed & PROP_smt_usage)
|
||||
updating_used_alone = true;
|
||||
|
||||
/* If a dump file name is present, open it if enabled. */
|
||||
@ -894,7 +894,7 @@ execute_one_pass (struct tree_opt_pass *pass)
|
||||
dump_file = NULL;
|
||||
}
|
||||
|
||||
if (pass->properties_destroyed & PROP_tmt_usage)
|
||||
if (pass->properties_destroyed & PROP_smt_usage)
|
||||
updating_used_alone = false;
|
||||
|
||||
return true;
|
||||
|
@ -129,9 +129,10 @@ static struct data_reference * init_data_ref (tree, tree, tree, tree, bool,
|
||||
struct ptr_info_def *,
|
||||
enum data_ref_type);
|
||||
|
||||
|
||||
/* Determine if PTR and DECL may alias, the result is put in ALIASED.
|
||||
Return FALSE if there is no type memory tag for PTR.
|
||||
*/
|
||||
Return FALSE if there is no symbol memory tag for PTR. */
|
||||
|
||||
static bool
|
||||
ptr_decl_may_alias_p (tree ptr, tree decl,
|
||||
struct data_reference *ptr_dr,
|
||||
@ -141,7 +142,7 @@ ptr_decl_may_alias_p (tree ptr, tree decl,
|
||||
|
||||
gcc_assert (TREE_CODE (ptr) == SSA_NAME && DECL_P (decl));
|
||||
|
||||
tag = get_var_ann (SSA_NAME_VAR (ptr))->type_mem_tag;
|
||||
tag = get_var_ann (SSA_NAME_VAR (ptr))->symbol_mem_tag;
|
||||
if (!tag)
|
||||
tag = DR_MEMTAG (ptr_dr);
|
||||
if (!tag)
|
||||
@ -153,8 +154,8 @@ ptr_decl_may_alias_p (tree ptr, tree decl,
|
||||
|
||||
|
||||
/* Determine if two pointers may alias, the result is put in ALIASED.
|
||||
Return FALSE if there is no type memory tag for one of the pointers.
|
||||
*/
|
||||
Return FALSE if there is no symbol memory tag for one of the pointers. */
|
||||
|
||||
static bool
|
||||
ptr_ptr_may_alias_p (tree ptr_a, tree ptr_b,
|
||||
struct data_reference *dra,
|
||||
@ -163,12 +164,12 @@ ptr_ptr_may_alias_p (tree ptr_a, tree ptr_b,
|
||||
{
|
||||
tree tag_a, tag_b;
|
||||
|
||||
tag_a = get_var_ann (SSA_NAME_VAR (ptr_a))->type_mem_tag;
|
||||
tag_a = get_var_ann (SSA_NAME_VAR (ptr_a))->symbol_mem_tag;
|
||||
if (!tag_a)
|
||||
tag_a = DR_MEMTAG (dra);
|
||||
if (!tag_a)
|
||||
return false;
|
||||
tag_b = get_var_ann (SSA_NAME_VAR (ptr_b))->type_mem_tag;
|
||||
tag_b = get_var_ann (SSA_NAME_VAR (ptr_b))->symbol_mem_tag;
|
||||
if (!tag_b)
|
||||
tag_b = DR_MEMTAG (drb);
|
||||
if (!tag_b)
|
||||
@ -179,8 +180,8 @@ ptr_ptr_may_alias_p (tree ptr_a, tree ptr_b,
|
||||
|
||||
|
||||
/* Determine if BASE_A and BASE_B may alias, the result is put in ALIASED.
|
||||
Return FALSE if there is no type memory tag for one of the symbols.
|
||||
*/
|
||||
Return FALSE if there is no symbol memory tag for one of the symbols. */
|
||||
|
||||
static bool
|
||||
may_alias_p (tree base_a, tree base_b,
|
||||
struct data_reference *dra,
|
||||
@ -1712,10 +1713,10 @@ object_analysis (tree memref, tree stmt, bool is_read,
|
||||
switch (TREE_CODE (base_address))
|
||||
{
|
||||
case SSA_NAME:
|
||||
*memtag = get_var_ann (SSA_NAME_VAR (base_address))->type_mem_tag;
|
||||
*memtag = get_var_ann (SSA_NAME_VAR (base_address))->symbol_mem_tag;
|
||||
if (!(*memtag) && TREE_CODE (TREE_OPERAND (memref, 0)) == SSA_NAME)
|
||||
*memtag = get_var_ann (
|
||||
SSA_NAME_VAR (TREE_OPERAND (memref, 0)))->type_mem_tag;
|
||||
SSA_NAME_VAR (TREE_OPERAND (memref, 0)))->symbol_mem_tag;
|
||||
break;
|
||||
case ADDR_EXPR:
|
||||
*memtag = TREE_OPERAND (base_address, 0);
|
||||
|
@ -344,10 +344,10 @@ dump_variable (FILE *file, tree var)
|
||||
fprintf (file, ", ");
|
||||
print_generic_expr (file, TREE_TYPE (var), dump_flags);
|
||||
|
||||
if (ann && ann->type_mem_tag)
|
||||
if (ann && ann->symbol_mem_tag)
|
||||
{
|
||||
fprintf (file, ", type memory tag: ");
|
||||
print_generic_expr (file, ann->type_mem_tag, dump_flags);
|
||||
fprintf (file, ", symbol memory tag: ");
|
||||
print_generic_expr (file, ann->symbol_mem_tag, dump_flags);
|
||||
}
|
||||
|
||||
if (ann && ann->is_aliased)
|
||||
|
@ -478,7 +478,7 @@ dequeue_and_dump (dump_info_p di)
|
||||
dump_child ("cnst", DECL_INITIAL (t));
|
||||
break;
|
||||
|
||||
case TYPE_MEMORY_TAG:
|
||||
case SYMBOL_MEMORY_TAG:
|
||||
case NAME_MEMORY_TAG:
|
||||
case STRUCT_FIELD_TAG:
|
||||
break;
|
||||
|
@ -185,10 +185,10 @@ struct var_ann_d GTY(())
|
||||
unsigned in_v_may_def_list : 1;
|
||||
|
||||
/* An artificial variable representing the memory location pointed-to by
|
||||
all the pointers that TBAA (type-based alias analysis) considers
|
||||
to be aliased. If the variable is not a pointer or if it is never
|
||||
dereferenced, this must be NULL. */
|
||||
tree type_mem_tag;
|
||||
all the pointer symbols that flow-insensitive alias analysis
|
||||
(mostly type-based) considers to be aliased. If the variable is
|
||||
not a pointer or if it is never dereferenced, this must be NULL. */
|
||||
tree symbol_mem_tag;
|
||||
|
||||
/* Variables that may alias this variable. */
|
||||
VEC(tree, gc) *may_aliases;
|
||||
|
@ -175,7 +175,7 @@ create_temp (tree t)
|
||||
/* add_referenced_tmp_var will create the annotation and set up some
|
||||
of the flags in the annotation. However, some flags we need to
|
||||
inherit from our original variable. */
|
||||
var_ann (tmp)->type_mem_tag = var_ann (t)->type_mem_tag;
|
||||
var_ann (tmp)->symbol_mem_tag = var_ann (t)->symbol_mem_tag;
|
||||
if (is_call_clobbered (t))
|
||||
mark_call_clobbered (tmp, var_ann (t)->escape_mask);
|
||||
|
||||
|
@ -150,7 +150,7 @@ struct dump_file_info
|
||||
#define PROP_rtl (1 << 8)
|
||||
#define PROP_alias (1 << 9)
|
||||
#define PROP_gimple_lomp (1 << 10) /* lowered OpenMP directives */
|
||||
#define PROP_tmt_usage (1 << 11) /* which TMT's are
|
||||
#define PROP_smt_usage (1 << 11) /* which SMT's are
|
||||
used alone. */
|
||||
|
||||
#define PROP_trees \
|
||||
@ -212,9 +212,9 @@ struct dump_file_info
|
||||
for the passes that are handed to register_dump_files. */
|
||||
#define TODO_set_props (1 << 12)
|
||||
|
||||
/* Set by passes that may make TMT's that were previously never used
|
||||
/* Set by passes that may make SMT's that were previously never used
|
||||
in statements, used. */
|
||||
#define TODO_update_tmt_usage (1 << 13)
|
||||
#define TODO_update_smt_usage (1 << 13)
|
||||
|
||||
#define TODO_update_ssa_any \
|
||||
(TODO_update_ssa \
|
||||
|
@ -847,7 +847,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_MEMORY_TAG:
|
||||
case SYMBOL_MEMORY_TAG:
|
||||
case NAME_MEMORY_TAG:
|
||||
case STRUCT_FIELD_TAG:
|
||||
case VAR_DECL:
|
||||
|
@ -2223,9 +2223,9 @@ struct tree_opt_pass pass_sra =
|
||||
TV_TREE_SRA, /* tv_id */
|
||||
PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
PROP_tmt_usage, /* properties_destroyed */
|
||||
PROP_smt_usage, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_update_tmt_usage | TODO_dump_func /* todo_flags_finish */
|
||||
TODO_update_smt_usage | TODO_dump_func /* todo_flags_finish */
|
||||
| TODO_update_ssa
|
||||
| TODO_ggc_collect | TODO_verify_ssa,
|
||||
0 /* letter */
|
||||
|
@ -349,8 +349,8 @@ set_initial_properties (struct alias_info *ai)
|
||||
if (pi->name_mem_tag)
|
||||
mark_call_clobbered (pi->name_mem_tag, pi->escape_mask);
|
||||
|
||||
if (v_ann->type_mem_tag)
|
||||
mark_call_clobbered (v_ann->type_mem_tag, pi->escape_mask);
|
||||
if (v_ann->symbol_mem_tag)
|
||||
mark_call_clobbered (v_ann->symbol_mem_tag, pi->escape_mask);
|
||||
|
||||
if (pi->pt_vars)
|
||||
{
|
||||
@ -361,14 +361,15 @@ set_initial_properties (struct alias_info *ai)
|
||||
mark_call_clobbered (referenced_var (j), pi->escape_mask);
|
||||
}
|
||||
}
|
||||
/* If the name tag is call clobbered, so is the type tag
|
||||
|
||||
/* If the name tag is call clobbered, so is the symbol tag
|
||||
associated with the base VAR_DECL. */
|
||||
if (pi->name_mem_tag
|
||||
&& v_ann->type_mem_tag
|
||||
&& v_ann->symbol_mem_tag
|
||||
&& is_call_clobbered (pi->name_mem_tag))
|
||||
mark_call_clobbered (v_ann->type_mem_tag, pi->escape_mask);
|
||||
mark_call_clobbered (v_ann->symbol_mem_tag, pi->escape_mask);
|
||||
|
||||
/* Name tags and type tags that we don't know where they point
|
||||
/* Name tags and symbol tags that we don't know where they point
|
||||
to, might point to global memory, and thus, are clobbered.
|
||||
|
||||
FIXME: This is not quite right. They should only be
|
||||
@ -384,18 +385,19 @@ set_initial_properties (struct alias_info *ai)
|
||||
}
|
||||
|
||||
if ((pi->pt_global_mem || pi->pt_anything)
|
||||
&& pi->is_dereferenced && v_ann->type_mem_tag)
|
||||
&& pi->is_dereferenced
|
||||
&& v_ann->symbol_mem_tag)
|
||||
{
|
||||
mark_call_clobbered (v_ann->type_mem_tag, ESCAPE_IS_GLOBAL);
|
||||
MTAG_GLOBAL (v_ann->type_mem_tag) = true;
|
||||
mark_call_clobbered (v_ann->symbol_mem_tag, ESCAPE_IS_GLOBAL);
|
||||
MTAG_GLOBAL (v_ann->symbol_mem_tag) = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This variable is set to true if we are updating the used alone
|
||||
information for TMT's, or are in a pass that is going to break it
|
||||
temporarily. */
|
||||
|
||||
/* This variable is set to true if we are updating the used alone
|
||||
information for SMTs, or are in a pass that is going to break it
|
||||
temporarily. */
|
||||
bool updating_used_alone;
|
||||
|
||||
/* Compute which variables need to be marked call clobbered because
|
||||
@ -424,7 +426,8 @@ compute_call_clobbered (struct alias_info *ai)
|
||||
}
|
||||
|
||||
|
||||
/* Recalculate the used_alone information for TMT's . */
|
||||
/* Recalculate the used_alone information for SMTs . */
|
||||
|
||||
void
|
||||
recalculate_used_alone (void)
|
||||
{
|
||||
@ -436,19 +439,17 @@ recalculate_used_alone (void)
|
||||
referenced_var_iterator rvi;
|
||||
tree var;
|
||||
|
||||
/* First, reset all the TMT used alone bits to zero. */
|
||||
/* First, reset all the SMT used alone bits to zero. */
|
||||
updating_used_alone = true;
|
||||
FOR_EACH_REFERENCED_VAR (var, rvi)
|
||||
if (TREE_CODE (var) == TYPE_MEMORY_TAG)
|
||||
TMT_USED_ALONE (var) = 0;
|
||||
if (TREE_CODE (var) == SYMBOL_MEMORY_TAG)
|
||||
SMT_USED_ALONE (var) = 0;
|
||||
|
||||
/* Walk all the statements.
|
||||
Calls get put into a list of statements to update, since we will
|
||||
need to update operands on them if we make any changes.
|
||||
If we see a bare use of a TMT anywhere in a real virtual use or virtual
|
||||
def, mark the TMT as used alone, and for renaming. */
|
||||
|
||||
|
||||
If we see a bare use of a SMT anywhere in a real virtual use or virtual
|
||||
def, mark the SMT as used alone, and for renaming. */
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
@ -470,11 +471,11 @@ recalculate_used_alone (void)
|
||||
if(TREE_CODE (var) == SSA_NAME)
|
||||
svar = SSA_NAME_VAR (var);
|
||||
|
||||
if (TREE_CODE (svar) == TYPE_MEMORY_TAG)
|
||||
if (TREE_CODE (svar) == SYMBOL_MEMORY_TAG)
|
||||
{
|
||||
if (!TMT_USED_ALONE (svar))
|
||||
if (!SMT_USED_ALONE (svar))
|
||||
{
|
||||
TMT_USED_ALONE (svar) = true;
|
||||
SMT_USED_ALONE (svar) = true;
|
||||
mark_sym_for_renaming (svar);
|
||||
}
|
||||
}
|
||||
@ -527,11 +528,11 @@ recalculate_used_alone (void)
|
||||
|
||||
We have two classes of memory tags. Memory tags associated with the
|
||||
pointed-to data type of the pointers in the program. These tags are
|
||||
called "type memory tag" (TMT). The other class are those associated
|
||||
called "symbol memory tag" (SMT). The other class are those associated
|
||||
with SSA_NAMEs, called "name memory tag" (NMT). The basic idea is that
|
||||
when adding operands for an INDIRECT_REF *P_i, we will first check
|
||||
whether P_i has a name tag, if it does we use it, because that will have
|
||||
more precise aliasing information. Otherwise, we use the standard type
|
||||
more precise aliasing information. Otherwise, we use the standard symbol
|
||||
tag.
|
||||
|
||||
In this phase, we go through all the pointers we found in points-to
|
||||
@ -542,11 +543,11 @@ recalculate_used_alone (void)
|
||||
|
||||
3- Compute flow-insensitive aliases
|
||||
|
||||
This pass will compare the alias set of every type memory tag and every
|
||||
addressable variable found in the program. Given a type memory tag TMT
|
||||
and an addressable variable V. If the alias sets of TMT and V conflict
|
||||
(as computed by may_alias_p), then V is marked as an alias tag and added
|
||||
to the alias set of TMT.
|
||||
This pass will compare the alias set of every symbol memory tag and
|
||||
every addressable variable found in the program. Given a symbol
|
||||
memory tag SMT and an addressable variable V. If the alias sets of
|
||||
SMT and V conflict (as computed by may_alias_p), then V is marked
|
||||
as an alias tag and added to the alias set of SMT.
|
||||
|
||||
For instance, consider the following function:
|
||||
|
||||
@ -564,7 +565,7 @@ recalculate_used_alone (void)
|
||||
return *p;
|
||||
}
|
||||
|
||||
After aliasing analysis has finished, the type memory tag for pointer
|
||||
After aliasing analysis has finished, the symbol memory tag for pointer
|
||||
'p' will have two aliases, namely variables 'a' and 'b'. Every time
|
||||
pointer 'p' is dereferenced, we want to mark the operation as a
|
||||
potential reference to 'a' and 'b'.
|
||||
@ -627,7 +628,7 @@ compute_may_aliases (void)
|
||||
/* Compute flow-sensitive, points-to based aliasing for all the name
|
||||
memory tags. Note that this pass needs to be done before flow
|
||||
insensitive analysis because it uses the points-to information
|
||||
gathered before to mark call-clobbered type tags. */
|
||||
gathered before to mark call-clobbered symbol tags. */
|
||||
compute_flow_sensitive_aliasing (ai);
|
||||
|
||||
/* Compute type-based flow-insensitive aliasing for all the type
|
||||
@ -860,7 +861,7 @@ init_alias_info (void)
|
||||
just because they are tags, though we will clear it if they
|
||||
aren't for global variables. */
|
||||
if (TREE_CODE (var) == NAME_MEMORY_TAG
|
||||
|| TREE_CODE (var) == TYPE_MEMORY_TAG
|
||||
|| TREE_CODE (var) == SYMBOL_MEMORY_TAG
|
||||
|| !is_global_var (var))
|
||||
clear_call_clobbered (var);
|
||||
}
|
||||
@ -973,8 +974,7 @@ create_name_tags (void)
|
||||
}
|
||||
|
||||
/* Set pt_anything on the pointers without pt_vars filled in so
|
||||
that they are assigned a type tag. */
|
||||
|
||||
that they are assigned a symbol tag. */
|
||||
if (pi->pt_vars && !bitmap_empty_p (pi->pt_vars))
|
||||
VEC_safe_push (tree, heap, with_ptvars, ptr);
|
||||
else
|
||||
@ -1078,7 +1078,7 @@ compute_flow_sensitive_aliasing (struct alias_info *ai)
|
||||
EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j, bi)
|
||||
{
|
||||
add_may_alias (pi->name_mem_tag, referenced_var (j));
|
||||
add_may_alias (v_ann->type_mem_tag, referenced_var (j));
|
||||
add_may_alias (v_ann->symbol_mem_tag, referenced_var (j));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1088,8 +1088,8 @@ compute_flow_sensitive_aliasing (struct alias_info *ai)
|
||||
addressable variables found in setup_pointers_and_addressables.
|
||||
|
||||
For every pointer P in AI->POINTERS and addressable variable V in
|
||||
AI->ADDRESSABLE_VARS, add V to the may-alias sets of P's type
|
||||
memory tag (TMT) if their alias sets conflict. V is then marked as
|
||||
AI->ADDRESSABLE_VARS, add V to the may-alias sets of P's symbol
|
||||
memory tag (SMT) if their alias sets conflict. V is then marked as
|
||||
an alias tag so that the operand scanner knows that statements
|
||||
containing V have aliased operands. */
|
||||
|
||||
@ -1105,12 +1105,12 @@ compute_flow_insensitive_aliasing (struct alias_info *ai)
|
||||
ai->total_alias_vops = 0;
|
||||
|
||||
/* For every pointer P, determine which addressable variables may alias
|
||||
with P's type memory tag. */
|
||||
with P's symbol memory tag. */
|
||||
for (i = 0; i < ai->num_pointers; i++)
|
||||
{
|
||||
size_t j;
|
||||
struct alias_map_d *p_map = ai->pointers[i];
|
||||
tree tag = var_ann (p_map->var)->type_mem_tag;
|
||||
tree tag = var_ann (p_map->var)->symbol_mem_tag;
|
||||
var_ann_t tag_ann = var_ann (tag);
|
||||
|
||||
p_map->total_alias_vops = 0;
|
||||
@ -1181,15 +1181,15 @@ compute_flow_insensitive_aliasing (struct alias_info *ai)
|
||||
tags with conflicting alias set numbers but no aliased symbols in
|
||||
common.
|
||||
|
||||
For example, suppose that we have two memory tags TMT.1 and TMT.2
|
||||
For example, suppose that we have two memory tags SMT.1 and SMT.2
|
||||
such that
|
||||
|
||||
may-aliases (TMT.1) = { a }
|
||||
may-aliases (TMT.2) = { b }
|
||||
may-aliases (SMT.1) = { a }
|
||||
may-aliases (SMT.2) = { b }
|
||||
|
||||
and the alias set number of TMT.1 conflicts with that of TMT.2.
|
||||
and the alias set number of SMT.1 conflicts with that of SMT.2.
|
||||
Since they don't have symbols in common, loads and stores from
|
||||
TMT.1 and TMT.2 will seem independent of each other, which will
|
||||
SMT.1 and SMT.2 will seem independent of each other, which will
|
||||
lead to the optimizers making invalid transformations (see
|
||||
testsuite/gcc.c-torture/execute/pr15262-[12].c).
|
||||
|
||||
@ -1200,13 +1200,13 @@ compute_flow_insensitive_aliasing (struct alias_info *ai)
|
||||
{
|
||||
size_t j;
|
||||
struct alias_map_d *p_map1 = ai->pointers[i];
|
||||
tree tag1 = var_ann (p_map1->var)->type_mem_tag;
|
||||
tree tag1 = var_ann (p_map1->var)->symbol_mem_tag;
|
||||
bitmap may_aliases1 = p_map1->may_aliases;
|
||||
|
||||
for (j = i + 1; j < ai->num_pointers; j++)
|
||||
{
|
||||
struct alias_map_d *p_map2 = ai->pointers[j];
|
||||
tree tag2 = var_ann (p_map2->var)->type_mem_tag;
|
||||
tree tag2 = var_ann (p_map2->var)->symbol_mem_tag;
|
||||
bitmap may_aliases2 = p_map2->may_aliases;
|
||||
|
||||
/* If the pointers may not point to each other, do nothing. */
|
||||
@ -1389,14 +1389,14 @@ group_aliases (struct alias_info *ai)
|
||||
for (i = 0; i < ai->num_pointers; i++)
|
||||
{
|
||||
size_t j;
|
||||
tree tag1 = var_ann (ai->pointers[i]->var)->type_mem_tag;
|
||||
tree tag1 = var_ann (ai->pointers[i]->var)->symbol_mem_tag;
|
||||
bitmap tag1_aliases = ai->pointers[i]->may_aliases;
|
||||
|
||||
/* Skip tags that have been grouped already. */
|
||||
if (ai->pointers[i]->grouped_p)
|
||||
continue;
|
||||
|
||||
/* See if TAG1 had any aliases in common with other type tags.
|
||||
/* See if TAG1 had any aliases in common with other symbol tags.
|
||||
If we find a TAG2 with common aliases with TAG1, add TAG2's
|
||||
aliases into TAG1. */
|
||||
for (j = i + 1; j < ai->num_pointers; j++)
|
||||
@ -1405,7 +1405,7 @@ group_aliases (struct alias_info *ai)
|
||||
|
||||
if (bitmap_intersect_p (tag1_aliases, tag2_aliases))
|
||||
{
|
||||
tree tag2 = var_ann (ai->pointers[j]->var)->type_mem_tag;
|
||||
tree tag2 = var_ann (ai->pointers[j]->var)->symbol_mem_tag;
|
||||
|
||||
bitmap_ior_into (tag1_aliases, tag2_aliases);
|
||||
|
||||
@ -1431,20 +1431,20 @@ group_aliases (struct alias_info *ai)
|
||||
|
||||
/* Finally, all the variables that have been grouped cannot be in
|
||||
the may-alias set of name memory tags. Suppose that we have
|
||||
grouped the aliases in this code so that may-aliases(a) = TMT.20
|
||||
grouped the aliases in this code so that may-aliases(a) = SMT.20
|
||||
|
||||
p_5 = &a;
|
||||
...
|
||||
# a_9 = V_MAY_DEF <a_8>
|
||||
p_5->field = 0
|
||||
... Several modifications to TMT.20 ...
|
||||
... Several modifications to SMT.20 ...
|
||||
# VUSE <a_9>
|
||||
x_30 = p_5->field
|
||||
|
||||
Since p_5 points to 'a', the optimizers will try to propagate 0
|
||||
into p_5->field, but that is wrong because there have been
|
||||
modifications to 'TMT.20' in between. To prevent this we have to
|
||||
replace 'a' with 'TMT.20' in the name tag of p_5. */
|
||||
modifications to 'SMT.20' in between. To prevent this we have to
|
||||
replace 'a' with 'SMT.20' in the name tag of p_5. */
|
||||
for (i = 0; i < VARRAY_ACTIVE_SIZE (ai->processed_ptrs); i++)
|
||||
{
|
||||
size_t j;
|
||||
@ -1534,16 +1534,16 @@ setup_pointers_and_addressables (struct alias_info *ai)
|
||||
/* Create ADDRESSABLE_VARS and POINTERS. Note that these arrays are
|
||||
always going to be slightly bigger than we actually need them
|
||||
because some TREE_ADDRESSABLE variables will be marked
|
||||
non-addressable below and only pointers with unique type tags are
|
||||
non-addressable below and only pointers with unique symbol tags are
|
||||
going to be added to POINTERS. */
|
||||
ai->addressable_vars = XCNEWVEC (struct alias_map_d *, num_addressable_vars);
|
||||
ai->pointers = XCNEWVEC (struct alias_map_d *, num_pointers);
|
||||
ai->num_addressable_vars = 0;
|
||||
ai->num_pointers = 0;
|
||||
|
||||
/* Since we will be creating type memory tags within this loop, cache the
|
||||
value of NUM_REFERENCED_VARS to avoid processing the additional tags
|
||||
unnecessarily. */
|
||||
/* Since we will be creating symbol memory tags within this loop,
|
||||
cache the value of NUM_REFERENCED_VARS to avoid processing the
|
||||
additional tags unnecessarily. */
|
||||
n_vars = num_referenced_vars;
|
||||
|
||||
FOR_EACH_REFERENCED_VAR_SAFE (var, varvec, srvi)
|
||||
@ -1553,7 +1553,7 @@ setup_pointers_and_addressables (struct alias_info *ai)
|
||||
|
||||
/* Name memory tags already have flow-sensitive aliasing
|
||||
information, so they need not be processed by
|
||||
compute_flow_insensitive_aliasing. Similarly, type memory
|
||||
compute_flow_insensitive_aliasing. Similarly, symbol memory
|
||||
tags are already accounted for when we process their
|
||||
associated pointer.
|
||||
|
||||
@ -1615,7 +1615,7 @@ setup_pointers_and_addressables (struct alias_info *ai)
|
||||
}
|
||||
|
||||
/* Add pointer variables that have been dereferenced to the POINTERS
|
||||
array and create a type memory tag for them. */
|
||||
array and create a symbol memory tag for them. */
|
||||
if (POINTER_TYPE_P (TREE_TYPE (var)))
|
||||
{
|
||||
if ((bitmap_bit_p (ai->dereferenced_ptrs_store, DECL_UID (var))
|
||||
@ -1630,20 +1630,20 @@ setup_pointers_and_addressables (struct alias_info *ai)
|
||||
tag = get_tmt_for (var, ai);
|
||||
t_ann = var_ann (tag);
|
||||
|
||||
/* The type tag will need to be renamed into SSA
|
||||
/* The symbol tag will need to be renamed into SSA
|
||||
afterwards. Note that we cannot do this inside
|
||||
get_tmt_for because aliasing may run multiple times
|
||||
and we only create type tags the first time. */
|
||||
and we only create symbol tags the first time. */
|
||||
mark_sym_for_renaming (tag);
|
||||
|
||||
/* Similarly, if pointer VAR used to have another type
|
||||
tag, we will need to process it in the renamer to
|
||||
remove the stale virtual operands. */
|
||||
if (v_ann->type_mem_tag)
|
||||
mark_sym_for_renaming (v_ann->type_mem_tag);
|
||||
if (v_ann->symbol_mem_tag)
|
||||
mark_sym_for_renaming (v_ann->symbol_mem_tag);
|
||||
|
||||
/* Associate the tag with pointer VAR. */
|
||||
v_ann->type_mem_tag = tag;
|
||||
v_ann->symbol_mem_tag = tag;
|
||||
|
||||
/* If pointer VAR has been used in a store operation,
|
||||
then its memory tag must be marked as written-to. */
|
||||
@ -1661,14 +1661,14 @@ setup_pointers_and_addressables (struct alias_info *ai)
|
||||
else
|
||||
{
|
||||
/* The pointer has not been dereferenced. If it had a
|
||||
type memory tag, remove it and mark the old tag for
|
||||
symbol memory tag, remove it and mark the old tag for
|
||||
renaming to remove it out of the IL. */
|
||||
var_ann_t ann = var_ann (var);
|
||||
tree tag = ann->type_mem_tag;
|
||||
tree tag = ann->symbol_mem_tag;
|
||||
if (tag)
|
||||
{
|
||||
mark_sym_for_renaming (tag);
|
||||
ann->type_mem_tag = NULL_TREE;
|
||||
ann->symbol_mem_tag = NULL_TREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1796,7 +1796,7 @@ may_alias_p (tree ptr, HOST_WIDE_INT mem_alias_set,
|
||||
alias_stats.simple_queries++;
|
||||
|
||||
/* By convention, a variable cannot alias itself. */
|
||||
mem = var_ann (ptr)->type_mem_tag;
|
||||
mem = var_ann (ptr)->symbol_mem_tag;
|
||||
if (mem == var)
|
||||
{
|
||||
alias_stats.alias_noalias++;
|
||||
@ -1824,7 +1824,7 @@ may_alias_p (tree ptr, HOST_WIDE_INT mem_alias_set,
|
||||
return false;
|
||||
}
|
||||
|
||||
gcc_assert (TREE_CODE (mem) == TYPE_MEMORY_TAG);
|
||||
gcc_assert (TREE_CODE (mem) == SYMBOL_MEMORY_TAG);
|
||||
|
||||
alias_stats.tbaa_queries++;
|
||||
|
||||
@ -2075,8 +2075,8 @@ static tree
|
||||
create_memory_tag (tree type, bool is_type_tag)
|
||||
{
|
||||
var_ann_t ann;
|
||||
tree tag = create_tag_raw (is_type_tag ? TYPE_MEMORY_TAG : NAME_MEMORY_TAG,
|
||||
type, (is_type_tag) ? "TMT" : "NMT");
|
||||
tree tag = create_tag_raw (is_type_tag ? SYMBOL_MEMORY_TAG : NAME_MEMORY_TAG,
|
||||
type, (is_type_tag) ? "SMT" : "NMT");
|
||||
|
||||
/* By default, memory tags are local variables. Alias analysis will
|
||||
determine whether they should be considered globals. */
|
||||
@ -2086,7 +2086,7 @@ create_memory_tag (tree type, bool is_type_tag)
|
||||
TREE_ADDRESSABLE (tag) = 1;
|
||||
|
||||
ann = get_var_ann (tag);
|
||||
ann->type_mem_tag = NULL_TREE;
|
||||
ann->symbol_mem_tag = NULL_TREE;
|
||||
|
||||
/* Add the tag to the symbol table. */
|
||||
add_referenced_tmp_var (tag);
|
||||
@ -2112,13 +2112,13 @@ get_nmt_for (tree ptr)
|
||||
}
|
||||
|
||||
|
||||
/* Return the type memory tag associated to pointer PTR. A memory tag is an
|
||||
artificial variable that represents the memory location pointed-to by
|
||||
PTR. It is used to model the effects of pointer de-references on
|
||||
addressable variables.
|
||||
/* Return the symbol memory tag associated to pointer PTR. A memory
|
||||
tag is an artificial variable that represents the memory location
|
||||
pointed-to by PTR. It is used to model the effects of pointer
|
||||
de-references on addressable variables.
|
||||
|
||||
AI points to the data gathered during alias analysis. This function
|
||||
populates the array AI->POINTERS. */
|
||||
AI points to the data gathered during alias analysis. This
|
||||
function populates the array AI->POINTERS. */
|
||||
|
||||
static tree
|
||||
get_tmt_for (tree ptr, struct alias_info *ai)
|
||||
@ -2139,7 +2139,7 @@ get_tmt_for (tree ptr, struct alias_info *ai)
|
||||
for (i = 0, tag = NULL_TREE; i < ai->num_pointers; i++)
|
||||
{
|
||||
struct alias_map_d *curr = ai->pointers[i];
|
||||
tree curr_tag = var_ann (curr->var)->type_mem_tag;
|
||||
tree curr_tag = var_ann (curr->var)->symbol_mem_tag;
|
||||
if (tag_set == curr->set)
|
||||
{
|
||||
tag = curr_tag;
|
||||
@ -2153,13 +2153,13 @@ get_tmt_for (tree ptr, struct alias_info *ai)
|
||||
{
|
||||
struct alias_map_d *alias_map;
|
||||
|
||||
/* If PTR did not have a type tag already, create a new TMT.*
|
||||
/* If PTR did not have a symbol tag already, create a new SMT.*
|
||||
artificial variable representing the memory location
|
||||
pointed-to by PTR. */
|
||||
if (var_ann (ptr)->type_mem_tag == NULL_TREE)
|
||||
if (var_ann (ptr)->symbol_mem_tag == NULL_TREE)
|
||||
tag = create_memory_tag (tag_type, true);
|
||||
else
|
||||
tag = var_ann (ptr)->type_mem_tag;
|
||||
tag = var_ann (ptr)->symbol_mem_tag;
|
||||
|
||||
/* Add PTR to the POINTERS array. Note that we are not interested in
|
||||
PTR's alias set. Instead, we cache the alias set for the memory that
|
||||
@ -2173,7 +2173,7 @@ get_tmt_for (tree ptr, struct alias_info *ai)
|
||||
/* If the pointed-to type is volatile, so is the tag. */
|
||||
TREE_THIS_VOLATILE (tag) |= TREE_THIS_VOLATILE (tag_type);
|
||||
|
||||
/* Make sure that the type tag has the same alias set as the
|
||||
/* Make sure that the symbol tag has the same alias set as the
|
||||
pointed-to type. */
|
||||
gcc_assert (tag_set == get_alias_set (tag));
|
||||
|
||||
@ -2260,15 +2260,15 @@ dump_alias_info (FILE *file)
|
||||
FOR_EACH_REFERENCED_VAR (var, rvi)
|
||||
{
|
||||
var_ann_t ann = var_ann (var);
|
||||
if (ann->type_mem_tag)
|
||||
if (ann->symbol_mem_tag)
|
||||
dump_variable (file, var);
|
||||
}
|
||||
|
||||
fprintf (file, "\nType memory tags\n\n");
|
||||
fprintf (file, "\nSymbol memory tags\n\n");
|
||||
|
||||
FOR_EACH_REFERENCED_VAR (var, rvi)
|
||||
{
|
||||
if (TREE_CODE (var) == TYPE_MEMORY_TAG)
|
||||
if (TREE_CODE (var) == SYMBOL_MEMORY_TAG)
|
||||
dump_variable (file, var);
|
||||
}
|
||||
|
||||
@ -2560,8 +2560,8 @@ is_aliased_with (tree tag, tree sym)
|
||||
}
|
||||
|
||||
|
||||
/* Add VAR to the list of may-aliases of PTR's type tag. If PTR
|
||||
doesn't already have a type tag, create one. */
|
||||
/* Add VAR to the list of may-aliases of PTR's symbol tag. If PTR
|
||||
doesn't already have a symbol tag, create one. */
|
||||
|
||||
void
|
||||
add_type_alias (tree ptr, tree var)
|
||||
@ -2573,19 +2573,19 @@ add_type_alias (tree ptr, tree var)
|
||||
VEC (tree, heap) *varvec = NULL;
|
||||
unsigned i;
|
||||
|
||||
if (ann->type_mem_tag == NULL_TREE)
|
||||
if (ann->symbol_mem_tag == NULL_TREE)
|
||||
{
|
||||
tree q = NULL_TREE;
|
||||
tree tag_type = TREE_TYPE (TREE_TYPE (ptr));
|
||||
HOST_WIDE_INT tag_set = get_alias_set (tag_type);
|
||||
safe_referenced_var_iterator rvi;
|
||||
|
||||
/* PTR doesn't have a type tag, create a new one and add VAR to
|
||||
/* PTR doesn't have a symbol tag, create a new one and add VAR to
|
||||
the new tag's alias set.
|
||||
|
||||
FIXME, This is slower than necessary. We need to determine
|
||||
whether there is another pointer Q with the same alias set as
|
||||
PTR. This could be sped up by having type tags associated
|
||||
PTR. This could be sped up by having symbol tags associated
|
||||
with types. */
|
||||
FOR_EACH_REFERENCED_VAR_SAFE (q, varvec, rvi)
|
||||
{
|
||||
@ -2593,27 +2593,27 @@ add_type_alias (tree ptr, tree var)
|
||||
&& tag_set == get_alias_set (TREE_TYPE (TREE_TYPE (q))))
|
||||
{
|
||||
/* Found another pointer Q with the same alias set as
|
||||
the PTR's pointed-to type. If Q has a type tag, use
|
||||
the PTR's pointed-to type. If Q has a symbol tag, use
|
||||
it. Otherwise, create a new memory tag for PTR. */
|
||||
var_ann_t ann1 = var_ann (q);
|
||||
if (ann1->type_mem_tag)
|
||||
ann->type_mem_tag = ann1->type_mem_tag;
|
||||
if (ann1->symbol_mem_tag)
|
||||
ann->symbol_mem_tag = ann1->symbol_mem_tag;
|
||||
else
|
||||
ann->type_mem_tag = create_memory_tag (tag_type, true);
|
||||
ann->symbol_mem_tag = create_memory_tag (tag_type, true);
|
||||
goto found_tag;
|
||||
}
|
||||
}
|
||||
|
||||
/* Couldn't find any other pointer with a type tag we could use.
|
||||
/* Couldn't find any other pointer with a symbol tag we could use.
|
||||
Create a new memory tag for PTR. */
|
||||
ann->type_mem_tag = create_memory_tag (tag_type, true);
|
||||
ann->symbol_mem_tag = create_memory_tag (tag_type, true);
|
||||
}
|
||||
|
||||
found_tag:
|
||||
/* If VAR is not already PTR's type tag, add it to the may-alias set
|
||||
for PTR's type tag. */
|
||||
/* If VAR is not already PTR's symbol tag, add it to the may-alias set
|
||||
for PTR's symbol tag. */
|
||||
gcc_assert (!MTAG_P (var));
|
||||
tag = ann->type_mem_tag;
|
||||
tag = ann->symbol_mem_tag;
|
||||
|
||||
/* If VAR has subvars, add the subvars to the tag instead of the
|
||||
actual var. */
|
||||
@ -2647,10 +2647,10 @@ found_tag:
|
||||
}
|
||||
|
||||
|
||||
/* Create a new type tag for PTR. Construct the may-alias list of this type
|
||||
/* Create a new symbol tag for PTR. Construct the may-alias list of this type
|
||||
tag so that it has the aliasing of VAR.
|
||||
|
||||
Note, the set of aliases represented by the new type tag are not marked
|
||||
Note, the set of aliases represented by the new symbol tag are not marked
|
||||
for renaming. */
|
||||
|
||||
void
|
||||
@ -2662,10 +2662,10 @@ new_type_alias (tree ptr, tree var)
|
||||
tree tag;
|
||||
subvar_t svars;
|
||||
|
||||
gcc_assert (p_ann->type_mem_tag == NULL_TREE);
|
||||
gcc_assert (p_ann->symbol_mem_tag == NULL_TREE);
|
||||
gcc_assert (!MTAG_P (var));
|
||||
|
||||
/* Add VAR to the may-alias set of PTR's new type tag. If VAR has
|
||||
/* Add VAR to the may-alias set of PTR's new symbol tag. If VAR has
|
||||
subvars, add the subvars to the tag instead of the actual var. */
|
||||
if (var_can_have_subvars (var)
|
||||
&& (svars = get_subvars_for_var (var)))
|
||||
@ -2673,7 +2673,7 @@ new_type_alias (tree ptr, tree var)
|
||||
subvar_t sv;
|
||||
|
||||
tag = create_memory_tag (tag_type, true);
|
||||
p_ann->type_mem_tag = tag;
|
||||
p_ann->symbol_mem_tag = tag;
|
||||
|
||||
for (sv = svars; sv; sv = sv->next)
|
||||
add_may_alias (tag, sv->var);
|
||||
@ -2691,15 +2691,15 @@ new_type_alias (tree ptr, tree var)
|
||||
{
|
||||
tree ali = VEC_index (tree, aliases, 0);
|
||||
|
||||
if (TREE_CODE (ali) == TYPE_MEMORY_TAG)
|
||||
if (TREE_CODE (ali) == SYMBOL_MEMORY_TAG)
|
||||
{
|
||||
p_ann->type_mem_tag = ali;
|
||||
p_ann->symbol_mem_tag = ali;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
tag = create_memory_tag (tag_type, true);
|
||||
p_ann->type_mem_tag = tag;
|
||||
p_ann->symbol_mem_tag = tag;
|
||||
|
||||
if (aliases == NULL)
|
||||
add_may_alias (tag, var);
|
||||
@ -2846,7 +2846,7 @@ create_sft (tree var, tree field, unsigned HOST_WIDE_INT offset,
|
||||
|
||||
/* Add the new variable to REFERENCED_VARS. */
|
||||
ann = get_var_ann (subvar);
|
||||
ann->type_mem_tag = NULL;
|
||||
ann->symbol_mem_tag = NULL;
|
||||
add_referenced_tmp_var (subvar);
|
||||
SFT_PARENT_VAR (subvar) = var;
|
||||
SFT_OFFSET (subvar) = offset;
|
||||
|
@ -1403,11 +1403,11 @@ struct tree_opt_pass pass_ccp =
|
||||
TV_TREE_CCP, /* tv_id */
|
||||
PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
PROP_tmt_usage, /* properties_destroyed */
|
||||
PROP_smt_usage, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_cleanup_cfg | TODO_dump_func | TODO_update_ssa
|
||||
| TODO_ggc_collect | TODO_verify_ssa
|
||||
| TODO_verify_stmts | TODO_update_tmt_usage, /* todo_flags_finish */
|
||||
| TODO_verify_stmts | TODO_update_smt_usage, /* todo_flags_finish */
|
||||
0 /* letter */
|
||||
};
|
||||
|
||||
@ -1440,12 +1440,12 @@ struct tree_opt_pass pass_store_ccp =
|
||||
TV_TREE_STORE_CCP, /* tv_id */
|
||||
PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
PROP_tmt_usage, /* properties_destroyed */
|
||||
PROP_smt_usage, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_dump_func | TODO_update_ssa
|
||||
| TODO_ggc_collect | TODO_verify_ssa
|
||||
| TODO_cleanup_cfg
|
||||
| TODO_verify_stmts | TODO_update_tmt_usage, /* todo_flags_finish */
|
||||
| TODO_verify_stmts | TODO_update_smt_usage, /* todo_flags_finish */
|
||||
0 /* letter */
|
||||
};
|
||||
|
||||
|
@ -108,8 +108,8 @@ may_propagate_copy (tree dest, tree orig)
|
||||
&& POINTER_TYPE_P (type_d)
|
||||
&& POINTER_TYPE_P (type_o))
|
||||
{
|
||||
tree mt_dest = var_ann (SSA_NAME_VAR (dest))->type_mem_tag;
|
||||
tree mt_orig = var_ann (SSA_NAME_VAR (orig))->type_mem_tag;
|
||||
tree mt_dest = var_ann (SSA_NAME_VAR (dest))->symbol_mem_tag;
|
||||
tree mt_orig = var_ann (SSA_NAME_VAR (orig))->symbol_mem_tag;
|
||||
if (mt_dest && mt_orig && mt_dest != mt_orig)
|
||||
return false;
|
||||
else if (!lang_hooks.types_compatible_p (type_d, type_o))
|
||||
@ -187,16 +187,16 @@ merge_alias_info (tree orig, tree new)
|
||||
== get_alias_set (TREE_TYPE (TREE_TYPE (orig_sym))));
|
||||
#endif
|
||||
|
||||
/* Synchronize the type tags. If both pointers had a tag and they
|
||||
are different, then something has gone wrong. Type tags can
|
||||
/* Synchronize the symbol tags. If both pointers had a tag and they
|
||||
are different, then something has gone wrong. Symbol tags can
|
||||
always be merged because they are flow insensitive, all the SSA
|
||||
names of the same base DECL share the same type tag. */
|
||||
if (new_ann->type_mem_tag == NULL_TREE)
|
||||
new_ann->type_mem_tag = orig_ann->type_mem_tag;
|
||||
else if (orig_ann->type_mem_tag == NULL_TREE)
|
||||
orig_ann->type_mem_tag = new_ann->type_mem_tag;
|
||||
names of the same base DECL share the same symbol tag. */
|
||||
if (new_ann->symbol_mem_tag == NULL_TREE)
|
||||
new_ann->symbol_mem_tag = orig_ann->symbol_mem_tag;
|
||||
else if (orig_ann->symbol_mem_tag == NULL_TREE)
|
||||
orig_ann->symbol_mem_tag = new_ann->symbol_mem_tag;
|
||||
else
|
||||
gcc_assert (new_ann->type_mem_tag == orig_ann->type_mem_tag);
|
||||
gcc_assert (new_ann->symbol_mem_tag == orig_ann->symbol_mem_tag);
|
||||
|
||||
/* Check that flow-sensitive information is compatible. Notice that
|
||||
we may not merge flow-sensitive information here. This function
|
||||
|
@ -208,8 +208,9 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
|
||||
}
|
||||
|
||||
/* Don't coalesce if there are two different memory tags. */
|
||||
if (ann1->type_mem_tag && ann2->type_mem_tag
|
||||
&& ann1->type_mem_tag != ann2->type_mem_tag)
|
||||
if (ann1->symbol_mem_tag
|
||||
&& ann2->symbol_mem_tag
|
||||
&& ann1->symbol_mem_tag != ann2->symbol_mem_tag)
|
||||
{
|
||||
if (debug)
|
||||
fprintf (debug, " : 2 memory tags. No coalesce.\n");
|
||||
@ -270,10 +271,10 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
|
||||
|
||||
/* Update the various flag widgitry of the current base representative. */
|
||||
ann3 = var_ann (SSA_NAME_VAR (partition_to_var (map, p3)));
|
||||
if (ann1->type_mem_tag)
|
||||
ann3->type_mem_tag = ann1->type_mem_tag;
|
||||
if (ann1->symbol_mem_tag)
|
||||
ann3->symbol_mem_tag = ann1->symbol_mem_tag;
|
||||
else
|
||||
ann3->type_mem_tag = ann2->type_mem_tag;
|
||||
ann3->symbol_mem_tag = ann2->symbol_mem_tag;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
|
@ -377,13 +377,13 @@ struct tree_opt_pass pass_dominator =
|
||||
TV_TREE_SSA_DOMINATOR_OPTS, /* tv_id */
|
||||
PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
PROP_tmt_usage, /* properties_destroyed */
|
||||
PROP_smt_usage, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_dump_func
|
||||
| TODO_update_ssa
|
||||
| TODO_cleanup_cfg
|
||||
| TODO_verify_ssa
|
||||
| TODO_update_tmt_usage, /* todo_flags_finish */
|
||||
| TODO_update_smt_usage, /* todo_flags_finish */
|
||||
0 /* letter */
|
||||
};
|
||||
|
||||
|
@ -1011,9 +1011,9 @@ struct tree_opt_pass pass_forwprop = {
|
||||
PROP_cfg | PROP_ssa
|
||||
| PROP_alias, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
PROP_tmt_usage, /* properties_destroyed */
|
||||
PROP_smt_usage, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_update_tmt_usage |TODO_dump_func /* todo_flags_finish */
|
||||
TODO_update_smt_usage |TODO_dump_func /* todo_flags_finish */
|
||||
| TODO_ggc_collect
|
||||
| TODO_update_ssa | TODO_verify_ssa,
|
||||
0 /* letter */
|
||||
|
@ -5342,8 +5342,8 @@ get_ref_tag (tree ref, tree orig)
|
||||
|
||||
if (TREE_CODE (var) == INDIRECT_REF)
|
||||
{
|
||||
/* In case the base is a dereference of a pointer, first check its name
|
||||
mem tag, and if it does not have one, use type mem tag. */
|
||||
/* If the base is a dereference of a pointer, first check its name memory
|
||||
tag. If it does not have one, use its symbol memory tag. */
|
||||
var = TREE_OPERAND (var, 0);
|
||||
if (TREE_CODE (var) != SSA_NAME)
|
||||
return NULL_TREE;
|
||||
@ -5356,7 +5356,7 @@ get_ref_tag (tree ref, tree orig)
|
||||
}
|
||||
|
||||
var = SSA_NAME_VAR (var);
|
||||
tag = var_ann (var)->type_mem_tag;
|
||||
tag = var_ann (var)->symbol_mem_tag;
|
||||
gcc_assert (tag != NULL_TREE);
|
||||
return tag;
|
||||
}
|
||||
@ -5365,7 +5365,7 @@ get_ref_tag (tree ref, tree orig)
|
||||
if (!DECL_P (var))
|
||||
return NULL_TREE;
|
||||
|
||||
tag = var_ann (var)->type_mem_tag;
|
||||
tag = var_ann (var)->symbol_mem_tag;
|
||||
if (tag)
|
||||
return tag;
|
||||
|
||||
|
@ -954,23 +954,24 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
|
||||
This fixes the bug in gcc.c-torture/execute/20020503-1.c.
|
||||
|
||||
It is also necessary to add bare defs on clobbers for
|
||||
TMT's, so that bare TMT uses caused by pruning all the
|
||||
SMT's, so that bare SMT uses caused by pruning all the
|
||||
aliases will link up properly with calls. In order to
|
||||
keep the number of these bare defs we add down to the
|
||||
minimum necessary, we keep track of which TMT's were used
|
||||
alone in statement defs or vuses. */
|
||||
minimum necessary, we keep track of which SMT's were used
|
||||
alone in statement vdefs or vuses. */
|
||||
if (v_ann->is_aliased
|
||||
|| none_added
|
||||
|| (TREE_CODE (var) == TYPE_MEMORY_TAG && for_clobber
|
||||
&& TMT_USED_ALONE (var)))
|
||||
|| (TREE_CODE (var) == SYMBOL_MEMORY_TAG
|
||||
&& for_clobber
|
||||
&& SMT_USED_ALONE (var)))
|
||||
{
|
||||
/* Every bare tmt def we add should have TMT_USED_ALONE
|
||||
/* Every bare SMT def we add should have SMT_USED_ALONE
|
||||
set on it, or else we will get the wrong answer on
|
||||
clobbers. */
|
||||
|
||||
if (none_added && !updating_used_alone && aliases_computed_p
|
||||
&& TREE_CODE (var) == TYPE_MEMORY_TAG)
|
||||
gcc_assert (TMT_USED_ALONE (var));
|
||||
if (none_added
|
||||
&& !updating_used_alone && aliases_computed_p
|
||||
&& TREE_CODE (var) == SYMBOL_MEMORY_TAG)
|
||||
gcc_assert (SMT_USED_ALONE (var));
|
||||
|
||||
append_v_may_def (var);
|
||||
}
|
||||
@ -1084,7 +1085,7 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags,
|
||||
else
|
||||
{
|
||||
/* If PTR is not an SSA_NAME or it doesn't have a name
|
||||
tag, use its type memory tag. */
|
||||
tag, use its symbol memory tag. */
|
||||
var_ann_t v_ann;
|
||||
|
||||
/* If we are emitting debugging dumps, display a warning if
|
||||
@ -1106,8 +1107,8 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags,
|
||||
ptr = SSA_NAME_VAR (ptr);
|
||||
v_ann = var_ann (ptr);
|
||||
|
||||
if (v_ann->type_mem_tag)
|
||||
add_virtual_operand (v_ann->type_mem_tag, s_ann, flags,
|
||||
if (v_ann->symbol_mem_tag)
|
||||
add_virtual_operand (v_ann->symbol_mem_tag, s_ann, flags,
|
||||
full_ref, offset, size, false);
|
||||
}
|
||||
}
|
||||
@ -1504,7 +1505,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
|
||||
|
||||
case SSA_NAME:
|
||||
case STRUCT_FIELD_TAG:
|
||||
case TYPE_MEMORY_TAG:
|
||||
case SYMBOL_MEMORY_TAG:
|
||||
case NAME_MEMORY_TAG:
|
||||
add_stmt_operand (expr_p, s_ann, flags);
|
||||
return;
|
||||
|
@ -168,7 +168,7 @@ is_hidden_global_store (tree stmt)
|
||||
variable.
|
||||
|
||||
Therefore, we check the base address of the LHS. If the
|
||||
address is a pointer, we check if its name tag or type tag is
|
||||
address is a pointer, we check if its name tag or symbol tag is
|
||||
a global variable. Otherwise, we check if the base variable
|
||||
is a global. */
|
||||
lhs = TREE_OPERAND (stmt, 0);
|
||||
@ -194,12 +194,12 @@ is_hidden_global_store (tree stmt)
|
||||
tree ptr = TREE_OPERAND (lhs, 0);
|
||||
struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
|
||||
tree nmt = (pi) ? pi->name_mem_tag : NULL_TREE;
|
||||
tree tmt = var_ann (SSA_NAME_VAR (ptr))->type_mem_tag;
|
||||
tree smt = var_ann (SSA_NAME_VAR (ptr))->symbol_mem_tag;
|
||||
|
||||
/* If either the name tag or the type tag for PTR is a
|
||||
/* If either the name tag or the symbol tag for PTR is a
|
||||
global variable, then the store is necessary. */
|
||||
if ((nmt && is_global_var (nmt))
|
||||
|| (tmt && is_global_var (tmt)))
|
||||
|| (smt && is_global_var (smt)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -459,9 +459,9 @@ verify_flow_sensitive_alias_info (void)
|
||||
continue;
|
||||
|
||||
ann = var_ann (var);
|
||||
if (pi->is_dereferenced && !pi->name_mem_tag && !ann->type_mem_tag)
|
||||
if (pi->is_dereferenced && !pi->name_mem_tag && !ann->symbol_mem_tag)
|
||||
{
|
||||
error ("dereferenced pointers should have a name or a type tag");
|
||||
error ("dereferenced pointers should have a name or a symbol tag");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -498,8 +498,8 @@ DEF_VEC_ALLOC_P (bitmap,heap);
|
||||
points-to set is different from every other points-to set for other name
|
||||
tags.
|
||||
|
||||
Additionally, given a pointer P_i with name tag NMT and type tag
|
||||
TMT, this function verified the alias set of TMT is a superset of
|
||||
Additionally, given a pointer P_i with name tag NMT and symbol tag
|
||||
SMT, this function verified the alias set of SMT is a superset of
|
||||
the alias set of NMT. */
|
||||
|
||||
static void
|
||||
@ -516,7 +516,7 @@ verify_name_tags (void)
|
||||
for (i = 0; i < num_ssa_names; i++)
|
||||
{
|
||||
struct ptr_info_def *pi;
|
||||
tree tmt, ptr = ssa_name (i);
|
||||
tree smt, ptr = ssa_name (i);
|
||||
|
||||
if (ptr == NULL_TREE)
|
||||
continue;
|
||||
@ -538,31 +538,31 @@ verify_name_tags (void)
|
||||
VEC_safe_push (tree, heap, name_tag_reps, ptr);
|
||||
VEC_safe_push (bitmap, heap, pt_vars_for_reps, pi->pt_vars);
|
||||
|
||||
/* Verify that alias set of PTR's type tag is a superset of the
|
||||
/* Verify that alias set of PTR's symbol tag is a superset of the
|
||||
alias set of PTR's name tag. */
|
||||
tmt = var_ann (SSA_NAME_VAR (ptr))->type_mem_tag;
|
||||
if (tmt)
|
||||
smt = var_ann (SSA_NAME_VAR (ptr))->symbol_mem_tag;
|
||||
if (smt)
|
||||
{
|
||||
size_t i;
|
||||
VEC(tree,gc) *aliases = var_ann (tmt)->may_aliases;
|
||||
VEC(tree,gc) *aliases = var_ann (smt)->may_aliases;
|
||||
tree alias;
|
||||
|
||||
bitmap_clear (type_aliases);
|
||||
for (i = 0; VEC_iterate (tree, aliases, i, alias); i++)
|
||||
bitmap_set_bit (type_aliases, DECL_UID (alias));
|
||||
|
||||
/* When grouping, we may have added PTR's type tag into the
|
||||
/* When grouping, we may have added PTR's symbol tag into the
|
||||
alias set of PTR's name tag. To prevent a false
|
||||
positive, pretend that TMT is in its own alias set. */
|
||||
bitmap_set_bit (type_aliases, DECL_UID (tmt));
|
||||
positive, pretend that SMT is in its own alias set. */
|
||||
bitmap_set_bit (type_aliases, DECL_UID (smt));
|
||||
|
||||
if (bitmap_equal_p (type_aliases, pi->pt_vars))
|
||||
continue;
|
||||
|
||||
if (!bitmap_intersect_compl_p (type_aliases, pi->pt_vars))
|
||||
{
|
||||
error ("alias set of a pointer's type tag should be a superset of the corresponding name tag");
|
||||
debug_variable (tmt);
|
||||
error ("alias set of a pointer's symbol tag should be a superset of the corresponding name tag");
|
||||
debug_variable (smt);
|
||||
debug_variable (pi->name_mem_tag);
|
||||
goto err;
|
||||
}
|
||||
|
@ -300,12 +300,12 @@ vect_create_data_ref_ptr (tree stmt,
|
||||
tag = DR_MEMTAG (dr);
|
||||
gcc_assert (tag);
|
||||
|
||||
/* If tag is a variable (and NOT_A_TAG) than a new type alias
|
||||
/* If tag is a variable (and NOT_A_TAG) than a new symbol memory
|
||||
tag must be created with tag added to its may alias list. */
|
||||
if (!MTAG_P (tag))
|
||||
new_type_alias (vect_ptr, tag);
|
||||
else
|
||||
var_ann (vect_ptr)->type_mem_tag = tag;
|
||||
var_ann (vect_ptr)->symbol_mem_tag = tag;
|
||||
|
||||
var_ann (vect_ptr)->subvars = DR_SUBVARS (dr);
|
||||
|
||||
|
@ -4571,13 +4571,13 @@ struct tree_opt_pass pass_vrp =
|
||||
TV_TREE_VRP, /* tv_id */
|
||||
PROP_ssa | PROP_alias, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
PROP_tmt_usage, /* properties_destroyed */
|
||||
PROP_smt_usage, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_cleanup_cfg
|
||||
| TODO_ggc_collect
|
||||
| TODO_verify_ssa
|
||||
| TODO_dump_func
|
||||
| TODO_update_ssa
|
||||
| TODO_update_tmt_usage, /* todo_flags_finish */
|
||||
| TODO_update_smt_usage, /* todo_flags_finish */
|
||||
0 /* letter */
|
||||
};
|
||||
|
@ -270,11 +270,11 @@ init_ttree (void)
|
||||
tree_contains_struct[FIELD_DECL][TS_DECL_MINIMAL] = 1;
|
||||
tree_contains_struct[STRUCT_FIELD_TAG][TS_DECL_MINIMAL] = 1;
|
||||
tree_contains_struct[NAME_MEMORY_TAG][TS_DECL_MINIMAL] = 1;
|
||||
tree_contains_struct[TYPE_MEMORY_TAG][TS_DECL_MINIMAL] = 1;
|
||||
tree_contains_struct[SYMBOL_MEMORY_TAG][TS_DECL_MINIMAL] = 1;
|
||||
|
||||
tree_contains_struct[STRUCT_FIELD_TAG][TS_MEMORY_TAG] = 1;
|
||||
tree_contains_struct[NAME_MEMORY_TAG][TS_MEMORY_TAG] = 1;
|
||||
tree_contains_struct[TYPE_MEMORY_TAG][TS_MEMORY_TAG] = 1;
|
||||
tree_contains_struct[SYMBOL_MEMORY_TAG][TS_MEMORY_TAG] = 1;
|
||||
|
||||
tree_contains_struct[STRUCT_FIELD_TAG][TS_STRUCT_FIELD_TAG] = 1;
|
||||
|
||||
@ -336,7 +336,7 @@ tree_code_size (enum tree_code code)
|
||||
case FUNCTION_DECL:
|
||||
return sizeof (struct tree_function_decl);
|
||||
case NAME_MEMORY_TAG:
|
||||
case TYPE_MEMORY_TAG:
|
||||
case SYMBOL_MEMORY_TAG:
|
||||
return sizeof (struct tree_memory_tag);
|
||||
case STRUCT_FIELD_TAG:
|
||||
return sizeof (struct tree_struct_field_tag);
|
||||
@ -2042,7 +2042,7 @@ tree_node_structure (tree t)
|
||||
return TS_TYPE_DECL;
|
||||
case FUNCTION_DECL:
|
||||
return TS_FUNCTION_DECL;
|
||||
case TYPE_MEMORY_TAG:
|
||||
case SYMBOL_MEMORY_TAG:
|
||||
case NAME_MEMORY_TAG:
|
||||
case STRUCT_FIELD_TAG:
|
||||
return TS_MEMORY_TAG;
|
||||
|
@ -358,7 +358,7 @@ DEFTREECODE (RESULT_DECL, "result_decl", tcc_declaration, 0)
|
||||
virtual SSA. */
|
||||
DEFTREECODE (STRUCT_FIELD_TAG, "struct_field_tag", tcc_declaration, 0)
|
||||
DEFTREECODE (NAME_MEMORY_TAG, "name_memory_tag", tcc_declaration, 0)
|
||||
DEFTREECODE (TYPE_MEMORY_TAG, "type_memory_tag", tcc_declaration, 0)
|
||||
DEFTREECODE (SYMBOL_MEMORY_TAG, "symbol_memory_tag", tcc_declaration, 0)
|
||||
|
||||
/* A namespace declaration. Namespaces appear in DECL_CONTEXT of other
|
||||
_DECLs, providing a hierarchy of names. */
|
||||
|
28
gcc/tree.h
28
gcc/tree.h
@ -105,7 +105,7 @@ extern const enum tree_code_class tree_code_type[];
|
||||
#define MTAG_P(CODE) \
|
||||
(TREE_CODE (CODE) == STRUCT_FIELD_TAG \
|
||||
|| TREE_CODE (CODE) == NAME_MEMORY_TAG \
|
||||
|| TREE_CODE (CODE) == TYPE_MEMORY_TAG)
|
||||
|| TREE_CODE (CODE) == SYMBOL_MEMORY_TAG)
|
||||
|
||||
|
||||
/* Nonzero if DECL represents a VAR_DECL or FUNCTION_DECL. */
|
||||
@ -2298,12 +2298,21 @@ struct tree_decl_minimal GTY(())
|
||||
|
||||
/* When computing aliasing information, we represent the memory pointed-to
|
||||
by pointers with artificial variables called "memory tags" (MT). There
|
||||
are two kinds of tags: type and name. Type tags (TMT) are used in
|
||||
type-based alias analysis, they represent all the pointed-to locations
|
||||
and variables of the same alias set class. Name tags (NMT) are used in
|
||||
flow-sensitive points-to alias analysis, they represent the variables
|
||||
and memory locations pointed-to by a specific SSA_NAME pointer. */
|
||||
are two kinds of tags, namely symbol and name:
|
||||
|
||||
Symbol tags (SMT) are used in flow-insensitive alias analysis, they
|
||||
represent all the pointed-to locations and variables pointed-to by
|
||||
the same pointer symbol. Usually, this set is computed using
|
||||
type-based analysis (i.e., alias set classes), but this may not
|
||||
always be the case.
|
||||
|
||||
Name tags (NMT) are used in flow-sensitive points-to alias
|
||||
analysis, they represent the variables and memory locations
|
||||
pointed-to by a specific SSA_NAME pointer.
|
||||
|
||||
In general, given a pointer P with a symbol tag SMT, the alias set
|
||||
of SMT should be the union of all the alias sets of the NMTs of
|
||||
every SSA_NAME for P. */
|
||||
struct tree_memory_tag GTY(())
|
||||
{
|
||||
struct tree_decl_minimal common;
|
||||
@ -2313,9 +2322,10 @@ struct tree_memory_tag GTY(())
|
||||
|
||||
#define MTAG_GLOBAL(NODE) (TREE_MEMORY_TAG_CHECK (NODE)->mtag.is_global)
|
||||
|
||||
/* This flag is true if a TMT is used as the vdef or vuse operand directly,
|
||||
because the access had all of the TMT's aliases pruned from it. */
|
||||
#define TMT_USED_ALONE(NODE) (TYPE_MEMORY_TAG_CHECK (NODE)->mtag.is_used_alone)
|
||||
/* This flag is true if a SMT is used as the V_MAY_DEF or VUSE operand
|
||||
directly, because the access had all of the SMT's aliases pruned
|
||||
from it. */
|
||||
#define SMT_USED_ALONE(NODE) (SYMBOL_MEMORY_TAG_CHECK (NODE)->mtag.is_used_alone)
|
||||
|
||||
struct tree_struct_field_tag GTY(())
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user