Commit b3778556 by Richard Guenther Committed by Richard Biener

re PR tree-optimization/36345 (TBAA-pruning of points-to sets ineffective)

2008-06-12  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/36345
	* tree-flow.h (struct ptr_info_def): Align escape_mask,
	add memory_tag_needed flag.
	(may_alias_p): Declare.
	* tree-ssa-alias.c (may_alias_p): Export.
	(set_initial_properties): Use memory_tag_needed flag.
	(update_reference_counts): Likewise.
	(reset_alias_info): Reset memory_tag_needed flag.
	(create_name_tags): Check memory_tag_needed flag.
	(dump_points_to_info_for): Dump it.
	* tree-ssa-structalias.c (struct variable_info): Remove
	directly_dereferenced flag.
	(new_var_info): Do not initialize it.
	(process_constraint_1): Do not set it.
	(update_alias_info): Set is_dereferenced flag.
	(set_uids_in_ptset): Use may_alias_p.
	(set_used_smts): Check memory_tag_needed flag.
	(find_what_p_points_to): Likewise.  Pass is_dereferenced flag.
	* tree-ssa-alias.c (verify_flow_sensitive_alias_info): Check
	memory_tag_needed flag.
	* tree-ssa-alias-warnings.c (dsa_named_for): Try to recover
	from broken design.

	* gcc.c-torture/execute/20020619-1.c: Remove broken part of
	the testcase.

From-SVN: r136695
parent 3fd29fa9
2008-06-12 Richard Guenther <rguenther@suse.de>
PR tree-optimization/36345
* tree-flow.h (struct ptr_info_def): Align escape_mask,
add memory_tag_needed flag.
(may_alias_p): Declare.
* tree-ssa-alias.c (may_alias_p): Export.
(set_initial_properties): Use memory_tag_needed flag.
(update_reference_counts): Likewise.
(reset_alias_info): Reset memory_tag_needed flag.
(create_name_tags): Check memory_tag_needed flag.
(dump_points_to_info_for): Dump it.
* tree-ssa-structalias.c (struct variable_info): Remove
directly_dereferenced flag.
(new_var_info): Do not initialize it.
(process_constraint_1): Do not set it.
(update_alias_info): Set is_dereferenced flag.
(set_uids_in_ptset): Use may_alias_p.
(set_used_smts): Check memory_tag_needed flag.
(find_what_p_points_to): Likewise. Pass is_dereferenced flag.
* tree-ssa-alias.c (verify_flow_sensitive_alias_info): Check
memory_tag_needed flag.
* tree-ssa-alias-warnings.c (dsa_named_for): Try to recover
from broken design.
2008-06-12 Kai Tietz <kai.tietz@onevision.com> 2008-06-12 Kai Tietz <kai.tietz@onevision.com>
* config/i386/i386.c (ix86_compute_frame_layout): Disable red zone for * config/i386/i386.c (ix86_compute_frame_layout): Disable red zone for
......
2008-06-12 Richard Guenther <rguenther@suse.de>
PR tree-optimization/36345
* gcc.c-torture/execute/20020619-1.c: Remove broken part of
the testcase.
2008-06-11 Edmar Wienskoski <edmar@freescale.com> 2008-06-11 Edmar Wienskoski <edmar@freescale.com>
PR target/36425 PR target/36425
......
...@@ -14,19 +14,11 @@ static int ref(void) ...@@ -14,19 +14,11 @@ static int ref(void)
return u.i; return u.i;
} }
#define MAX(a,b) (a < b ? b : a)
static int test(void)
{
char c[MAX(5, sizeof(int))] __attribute__((aligned)) = { 1, 2, 3, 4 };
return *(int *)c;
}
int main() int main()
{ {
int a = test();
int b = ref(); int b = ref();
if (a != b) if (b != 0x01020304
&& b != 0x04030201)
abort (); abort ();
return 0; return 0;
} }
...@@ -227,6 +227,9 @@ typedef struct ...@@ -227,6 +227,9 @@ typedef struct
/* Aliasing information for SSA_NAMEs representing pointer variables. */ /* Aliasing information for SSA_NAMEs representing pointer variables. */
struct ptr_info_def GTY(()) struct ptr_info_def GTY(())
{ {
/* Mask of reasons this pointer's value escapes the function. */
ENUM_BITFIELD (escape_type) escape_mask : 9;
/* Nonzero if points-to analysis couldn't determine where this pointer /* Nonzero if points-to analysis couldn't determine where this pointer
is pointing to. */ is pointing to. */
unsigned int pt_anything : 1; unsigned int pt_anything : 1;
...@@ -234,7 +237,11 @@ struct ptr_info_def GTY(()) ...@@ -234,7 +237,11 @@ struct ptr_info_def GTY(())
/* Nonzero if the value of this pointer escapes the current function. */ /* Nonzero if the value of this pointer escapes the current function. */
unsigned int value_escapes_p : 1; unsigned int value_escapes_p : 1;
/* Nonzero if this pointer is dereferenced. */ /* Nonzero if a memory tag is needed for this pointer. This is
true if this pointer is eventually dereferenced. */
unsigned int memory_tag_needed : 1;
/* Nonzero if this pointer is really dereferenced. */
unsigned int is_dereferenced : 1; unsigned int is_dereferenced : 1;
/* Nonzero if this pointer points to a global variable. */ /* Nonzero if this pointer points to a global variable. */
...@@ -243,9 +250,6 @@ struct ptr_info_def GTY(()) ...@@ -243,9 +250,6 @@ struct ptr_info_def GTY(())
/* Nonzero if this pointer points to NULL. */ /* Nonzero if this pointer points to NULL. */
unsigned int pt_null : 1; unsigned int pt_null : 1;
/* Mask of reasons this pointer's value escapes the function */
ENUM_BITFIELD (escape_type) escape_mask : 9;
/* Set of variables that this pointer may point to. */ /* Set of variables that this pointer may point to. */
bitmap pt_vars; bitmap pt_vars;
...@@ -852,6 +856,7 @@ extern void debug_points_to_info (void); ...@@ -852,6 +856,7 @@ extern void debug_points_to_info (void);
extern void dump_points_to_info_for (FILE *, tree); extern void dump_points_to_info_for (FILE *, tree);
extern void debug_points_to_info_for (tree); extern void debug_points_to_info_for (tree);
extern bool may_be_aliased (tree); extern bool may_be_aliased (tree);
extern bool may_alias_p (tree, alias_set_type, tree, alias_set_type, bool);
extern struct ptr_info_def *get_ptr_info (tree); extern struct ptr_info_def *get_ptr_info (tree);
extern bool may_point_to_global_var (tree); extern bool may_point_to_global_var (tree);
extern void new_type_alias (tree, tree, tree); extern void new_type_alias (tree, tree, tree);
......
...@@ -914,6 +914,7 @@ dsa_named_for (tree ptr) ...@@ -914,6 +914,7 @@ dsa_named_for (tree ptr)
{ {
unsigned ix; unsigned ix;
bitmap_iterator bi; bitmap_iterator bi;
bool any = false;
EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, ix, bi) EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, ix, bi)
{ {
...@@ -922,7 +923,16 @@ dsa_named_for (tree ptr) ...@@ -922,7 +923,16 @@ dsa_named_for (tree ptr)
if (nonstandard_alias_p (ptr, alias, false)) if (nonstandard_alias_p (ptr, alias, false))
strict_aliasing_warn (SSA_NAME_DEF_STMT (ptr), strict_aliasing_warn (SSA_NAME_DEF_STMT (ptr),
ptr, true, alias, false, true); ptr, true, alias, false, true);
else
any = true;
} }
/* If there was no object in the points-to set that the pointer
may alias, unconditionally warn. */
if (!any)
warning (OPT_Wstrict_aliasing,
"dereferencing type-punned pointer %D will "
"break strict-aliasing rules", SSA_NAME_VAR (ptr));
} }
} }
} }
......
...@@ -197,7 +197,6 @@ static bitmap_obstack alias_bitmap_obstack; ...@@ -197,7 +197,6 @@ static bitmap_obstack alias_bitmap_obstack;
/* Local functions. */ /* Local functions. */
static void compute_flow_insensitive_aliasing (struct alias_info *); static void compute_flow_insensitive_aliasing (struct alias_info *);
static void dump_alias_stats (FILE *); static void dump_alias_stats (FILE *);
static bool may_alias_p (tree, alias_set_type, tree, alias_set_type, bool);
static tree create_memory_tag (tree type, bool is_type_tag); static tree create_memory_tag (tree type, bool is_type_tag);
static tree get_smt_for (tree, struct alias_info *); static tree get_smt_for (tree, struct alias_info *);
static tree get_nmt_for (tree); static tree get_nmt_for (tree);
...@@ -588,14 +587,14 @@ set_initial_properties (struct alias_info *ai) ...@@ -588,14 +587,14 @@ set_initial_properties (struct alias_info *ai)
So removing this code and fixing all the bugs would be nice. So removing this code and fixing all the bugs would be nice.
It is the cause of a bunch of clobbering. */ It is the cause of a bunch of clobbering. */
if ((pi->pt_global_mem || pi->pt_anything) if ((pi->pt_global_mem || pi->pt_anything)
&& pi->is_dereferenced && pi->name_mem_tag) && pi->memory_tag_needed && pi->name_mem_tag)
{ {
mark_call_clobbered (pi->name_mem_tag, ESCAPE_IS_GLOBAL); mark_call_clobbered (pi->name_mem_tag, ESCAPE_IS_GLOBAL);
MTAG_GLOBAL (pi->name_mem_tag) = true; MTAG_GLOBAL (pi->name_mem_tag) = true;
} }
if ((pi->pt_global_mem || pi->pt_anything) if ((pi->pt_global_mem || pi->pt_anything)
&& pi->is_dereferenced && pi->memory_tag_needed
&& tag) && tag)
{ {
mark_call_clobbered (tag, ESCAPE_IS_GLOBAL); mark_call_clobbered (tag, ESCAPE_IS_GLOBAL);
...@@ -1278,7 +1277,7 @@ update_reference_counts (struct mem_ref_stats_d *mem_ref_stats) ...@@ -1278,7 +1277,7 @@ update_reference_counts (struct mem_ref_stats_d *mem_ref_stats)
if (ptr if (ptr
&& POINTER_TYPE_P (TREE_TYPE (ptr)) && POINTER_TYPE_P (TREE_TYPE (ptr))
&& (pi = SSA_NAME_PTR_INFO (ptr)) != NULL && (pi = SSA_NAME_PTR_INFO (ptr)) != NULL
&& pi->is_dereferenced) && pi->memory_tag_needed)
{ {
unsigned j; unsigned j;
bitmap_iterator bj; bitmap_iterator bj;
...@@ -2027,6 +2026,7 @@ reset_alias_info (void) ...@@ -2027,6 +2026,7 @@ reset_alias_info (void)
pi->pt_anything = 0; pi->pt_anything = 0;
pi->pt_null = 0; pi->pt_null = 0;
pi->value_escapes_p = 0; pi->value_escapes_p = 0;
pi->memory_tag_needed = 0;
pi->is_dereferenced = 0; pi->is_dereferenced = 0;
if (pi->pt_vars) if (pi->pt_vars)
bitmap_clear (pi->pt_vars); bitmap_clear (pi->pt_vars);
...@@ -2170,7 +2170,7 @@ create_name_tags (void) ...@@ -2170,7 +2170,7 @@ create_name_tags (void)
pi = SSA_NAME_PTR_INFO (ptr); pi = SSA_NAME_PTR_INFO (ptr);
if (pi->pt_anything || !pi->is_dereferenced) if (pi->pt_anything || !pi->memory_tag_needed)
{ {
/* No name tags for pointers that have not been /* No name tags for pointers that have not been
dereferenced or point to an arbitrary location. */ dereferenced or point to an arbitrary location. */
...@@ -2649,7 +2649,7 @@ maybe_create_global_var (void) ...@@ -2649,7 +2649,7 @@ maybe_create_global_var (void)
VAR_ALIAS_SET is the alias set for VAR. */ VAR_ALIAS_SET is the alias set for VAR. */
static bool bool
may_alias_p (tree ptr, alias_set_type mem_alias_set, may_alias_p (tree ptr, alias_set_type mem_alias_set,
tree var, alias_set_type var_alias_set, tree var, alias_set_type var_alias_set,
bool alias_set_only) bool alias_set_only)
...@@ -3231,6 +3231,8 @@ dump_points_to_info_for (FILE *file, tree ptr) ...@@ -3231,6 +3231,8 @@ dump_points_to_info_for (FILE *file, tree ptr)
if (pi->is_dereferenced) if (pi->is_dereferenced)
fprintf (file, ", is dereferenced"); fprintf (file, ", is dereferenced");
else if (pi->memory_tag_needed)
fprintf (file, ", is dereferenced in call");
if (pi->value_escapes_p) if (pi->value_escapes_p)
fprintf (file, ", its value escapes"); fprintf (file, ", its value escapes");
......
...@@ -227,11 +227,6 @@ struct variable_info ...@@ -227,11 +227,6 @@ struct variable_info
/* A link to the variable for the next field in this structure. */ /* A link to the variable for the next field in this structure. */
struct variable_info *next; struct variable_info *next;
/* True if the variable is directly the target of a dereference.
This is used to track which variables are *actually* dereferenced
so we can prune their points to listed. */
unsigned int directly_dereferenced:1;
/* True if this is a variable created by the constraint analysis, such as /* True if this is a variable created by the constraint analysis, such as
heap variables and constraints we had to break up. */ heap variables and constraints we had to break up. */
unsigned int is_artificial_var:1; unsigned int is_artificial_var:1;
...@@ -364,7 +359,6 @@ new_var_info (tree t, unsigned int id, const char *name) ...@@ -364,7 +359,6 @@ new_var_info (tree t, unsigned int id, const char *name)
ret->id = id; ret->id = id;
ret->name = name; ret->name = name;
ret->decl = t; ret->decl = t;
ret->directly_dereferenced = false;
ret->is_artificial_var = false; ret->is_artificial_var = false;
ret->is_heap_var = false; ret->is_heap_var = false;
ret->is_special_var = false; ret->is_special_var = false;
...@@ -2520,14 +2514,6 @@ process_constraint_1 (constraint_t t, bool from_call) ...@@ -2520,14 +2514,6 @@ process_constraint_1 (constraint_t t, bool from_call)
gcc_assert (rhs.var < VEC_length (varinfo_t, varmap)); gcc_assert (rhs.var < VEC_length (varinfo_t, varmap));
gcc_assert (lhs.var < VEC_length (varinfo_t, varmap)); gcc_assert (lhs.var < VEC_length (varinfo_t, varmap));
if (!from_call)
{
if (lhs.type == DEREF)
get_varinfo (lhs.var)->directly_dereferenced = true;
if (rhs.type == DEREF)
get_varinfo (rhs.var)->directly_dereferenced = true;
}
if (!use_field_sensitive) if (!use_field_sensitive)
{ {
t->rhs.offset = 0; t->rhs.offset = 0;
...@@ -3369,6 +3355,12 @@ update_alias_info (tree stmt, struct alias_info *ai) ...@@ -3369,6 +3355,12 @@ update_alias_info (tree stmt, struct alias_info *ai)
is an escape point, whether OP escapes. */ is an escape point, whether OP escapes. */
count_uses_and_derefs (op, stmt, &num_uses, &num_loads, &num_stores); count_uses_and_derefs (op, stmt, &num_uses, &num_loads, &num_stores);
/* For directly dereferenced pointers we can apply
TBAA-pruning to their points-to set. We may not count the
implicit dereferences &PTR->FLD here. */
if (num_loads + num_stores > 0)
pi->is_dereferenced = 1;
/* Handle a corner case involving address expressions of the /* Handle a corner case involving address expressions of the
form '&PTR->FLD'. The problem with these expressions is that form '&PTR->FLD'. The problem with these expressions is that
they do not represent a dereference of PTR. However, if some they do not represent a dereference of PTR. However, if some
...@@ -3409,7 +3401,10 @@ update_alias_info (tree stmt, struct alias_info *ai) ...@@ -3409,7 +3401,10 @@ update_alias_info (tree stmt, struct alias_info *ai)
dereferenced pointers that point to a set of dereferenced pointers that point to a set of
variables will be assigned a name tag to alias variables will be assigned a name tag to alias
all the variables OP points to. */ all the variables OP points to. */
pi->is_dereferenced = 1; pi->memory_tag_needed = 1;
/* ??? For always executed direct dereferences we can
apply TBAA-pruning to their escape set. */
/* If this is a store operation, mark OP as being /* If this is a store operation, mark OP as being
dereferenced to store, otherwise mark it as being dereferenced to store, otherwise mark it as being
...@@ -3443,7 +3438,7 @@ update_alias_info (tree stmt, struct alias_info *ai) ...@@ -3443,7 +3438,7 @@ update_alias_info (tree stmt, struct alias_info *ai)
|| stmt_escape_type == ESCAPE_STORED_IN_GLOBAL) || stmt_escape_type == ESCAPE_STORED_IN_GLOBAL)
{ {
pointer_set_insert (ai->dereferenced_ptrs_store, var); pointer_set_insert (ai->dereferenced_ptrs_store, var);
pi->is_dereferenced = 1; pi->memory_tag_needed = 1;
} }
} }
} }
...@@ -4653,10 +4648,11 @@ set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed, ...@@ -4653,10 +4648,11 @@ set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed,
bitmap_set_bit (into, DECL_UID (vi->decl)); bitmap_set_bit (into, DECL_UID (vi->decl));
else else
{ {
alias_set_type var_alias_set, ptr_alias_set; alias_set_type var_alias_set, mem_alias_set;
var_alias_set = get_alias_set (vi->decl); var_alias_set = get_alias_set (vi->decl);
ptr_alias_set = get_alias_set (TREE_TYPE (TREE_TYPE (ptr))); mem_alias_set = get_alias_set (TREE_TYPE (TREE_TYPE (ptr)));
if (alias_sets_conflict_p (ptr_alias_set, var_alias_set)) if (may_alias_p (SSA_NAME_VAR (ptr), mem_alias_set,
vi->decl, var_alias_set, true))
bitmap_set_bit (into, DECL_UID (vi->decl)); bitmap_set_bit (into, DECL_UID (vi->decl));
} }
} }
...@@ -4703,7 +4699,7 @@ set_used_smts (void) ...@@ -4703,7 +4699,7 @@ set_used_smts (void)
/* Skip the special variables and those that can't be aliased. */ /* Skip the special variables and those that can't be aliased. */
if (vi->is_special_var if (vi->is_special_var
|| !SSA_VAR_P (var) || !SSA_VAR_P (var)
|| (pi && !pi->is_dereferenced) || (pi && !pi->memory_tag_needed)
|| (TREE_CODE (var) == VAR_DECL && !may_be_aliased (var)) || (TREE_CODE (var) == VAR_DECL && !may_be_aliased (var))
|| !POINTER_TYPE_P (TREE_TYPE (var))) || !POINTER_TYPE_P (TREE_TYPE (var)))
continue; continue;
...@@ -4771,7 +4767,7 @@ find_what_p_points_to (tree p) ...@@ -4771,7 +4767,7 @@ find_what_p_points_to (tree p)
bitmap finished_solution; bitmap finished_solution;
bitmap result; bitmap result;
if (!pi->is_dereferenced) if (!pi->memory_tag_needed)
return false; return false;
/* This variable may have been collapsed, let's get the real /* This variable may have been collapsed, let's get the real
...@@ -4815,7 +4811,7 @@ find_what_p_points_to (tree p) ...@@ -4815,7 +4811,7 @@ find_what_p_points_to (tree p)
stats.points_to_sets_created++; stats.points_to_sets_created++;
set_uids_in_ptset (p, finished_solution, vi->solution, set_uids_in_ptset (p, finished_solution, vi->solution,
vi->directly_dereferenced, pi->is_dereferenced,
vi->no_tbaa_pruning); vi->no_tbaa_pruning);
result = shared_bitmap_lookup (finished_solution); result = shared_bitmap_lookup (finished_solution);
......
...@@ -559,7 +559,7 @@ verify_flow_sensitive_alias_info (void) ...@@ -559,7 +559,7 @@ verify_flow_sensitive_alias_info (void)
continue; continue;
ann = var_ann (var); ann = var_ann (var);
if (pi->is_dereferenced && !pi->name_mem_tag && !ann->symbol_mem_tag) if (pi->memory_tag_needed && !pi->name_mem_tag && !ann->symbol_mem_tag)
{ {
error ("dereferenced pointers should have a name or a symbol tag"); error ("dereferenced pointers should have a name or a symbol tag");
goto err; goto err;
......
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