aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2008-06-12 10:21:45 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2008-06-12 10:21:45 +0000
commitb377855627f22cdef5712621e89e68048a94a164 (patch)
treee7f6dd778d69424ba44e89344260ba54c29fac8c /gcc
parent3fd29fa912911b3db52046ef0d44144dd0e043ee (diff)
downloadgcc-b377855627f22cdef5712621e89e68048a94a164.zip
gcc-b377855627f22cdef5712621e89e68048a94a164.tar.gz
gcc-b377855627f22cdef5712621e89e68048a94a164.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog25
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20020619-1.c12
-rw-r--r--gcc/tree-flow.h13
-rw-r--r--gcc/tree-ssa-alias-warnings.c10
-rw-r--r--gcc/tree-ssa-alias.c14
-rw-r--r--gcc/tree-ssa-structalias.c40
-rw-r--r--gcc/tree-ssa.c2
8 files changed, 79 insertions, 43 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e1c11b1..eb6c434e6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,28 @@
+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>
* config/i386/i386.c (ix86_compute_frame_layout): Disable red zone for
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index dfbe10d..7155d91 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+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>
PR target/36425
diff --git a/gcc/testsuite/gcc.c-torture/execute/20020619-1.c b/gcc/testsuite/gcc.c-torture/execute/20020619-1.c
index 5ed4d00..6db1546 100644
--- a/gcc/testsuite/gcc.c-torture/execute/20020619-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/20020619-1.c
@@ -14,19 +14,11 @@ static int ref(void)
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 a = test();
int b = ref();
- if (a != b)
+ if (b != 0x01020304
+ && b != 0x04030201)
abort ();
return 0;
}
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 45711ae..855f080 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -227,6 +227,9 @@ typedef struct
/* Aliasing information for SSA_NAMEs representing pointer variables. */
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
is pointing to. */
unsigned int pt_anything : 1;
@@ -234,7 +237,11 @@ struct ptr_info_def GTY(())
/* Nonzero if the value of this pointer escapes the current function. */
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;
/* Nonzero if this pointer points to a global variable. */
@@ -243,9 +250,6 @@ struct ptr_info_def GTY(())
/* Nonzero if this pointer points to NULL. */
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. */
bitmap pt_vars;
@@ -852,6 +856,7 @@ extern void debug_points_to_info (void);
extern void dump_points_to_info_for (FILE *, tree);
extern void debug_points_to_info_for (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 bool may_point_to_global_var (tree);
extern void new_type_alias (tree, tree, tree);
diff --git a/gcc/tree-ssa-alias-warnings.c b/gcc/tree-ssa-alias-warnings.c
index bf95258..be26cb3 100644
--- a/gcc/tree-ssa-alias-warnings.c
+++ b/gcc/tree-ssa-alias-warnings.c
@@ -914,6 +914,7 @@ dsa_named_for (tree ptr)
{
unsigned ix;
bitmap_iterator bi;
+ bool any = false;
EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, ix, bi)
{
@@ -922,7 +923,16 @@ dsa_named_for (tree ptr)
if (nonstandard_alias_p (ptr, alias, false))
strict_aliasing_warn (SSA_NAME_DEF_STMT (ptr),
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));
}
}
}
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index e89e73b..0e50719 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -197,7 +197,6 @@ static bitmap_obstack alias_bitmap_obstack;
/* Local functions. */
static void compute_flow_insensitive_aliasing (struct alias_info *);
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 get_smt_for (tree, struct alias_info *);
static tree get_nmt_for (tree);
@@ -588,14 +587,14 @@ set_initial_properties (struct alias_info *ai)
So removing this code and fixing all the bugs would be nice.
It is the cause of a bunch of clobbering. */
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);
MTAG_GLOBAL (pi->name_mem_tag) = true;
}
if ((pi->pt_global_mem || pi->pt_anything)
- && pi->is_dereferenced
+ && pi->memory_tag_needed
&& tag)
{
mark_call_clobbered (tag, ESCAPE_IS_GLOBAL);
@@ -1278,7 +1277,7 @@ update_reference_counts (struct mem_ref_stats_d *mem_ref_stats)
if (ptr
&& POINTER_TYPE_P (TREE_TYPE (ptr))
&& (pi = SSA_NAME_PTR_INFO (ptr)) != NULL
- && pi->is_dereferenced)
+ && pi->memory_tag_needed)
{
unsigned j;
bitmap_iterator bj;
@@ -2027,6 +2026,7 @@ reset_alias_info (void)
pi->pt_anything = 0;
pi->pt_null = 0;
pi->value_escapes_p = 0;
+ pi->memory_tag_needed = 0;
pi->is_dereferenced = 0;
if (pi->pt_vars)
bitmap_clear (pi->pt_vars);
@@ -2170,7 +2170,7 @@ create_name_tags (void)
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
dereferenced or point to an arbitrary location. */
@@ -2649,7 +2649,7 @@ maybe_create_global_var (void)
VAR_ALIAS_SET is the alias set for VAR. */
-static bool
+bool
may_alias_p (tree ptr, alias_set_type mem_alias_set,
tree var, alias_set_type var_alias_set,
bool alias_set_only)
@@ -3231,6 +3231,8 @@ dump_points_to_info_for (FILE *file, tree ptr)
if (pi->is_dereferenced)
fprintf (file, ", is dereferenced");
+ else if (pi->memory_tag_needed)
+ fprintf (file, ", is dereferenced in call");
if (pi->value_escapes_p)
fprintf (file, ", its value escapes");
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index d66a4a8..338e190 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -227,11 +227,6 @@ struct variable_info
/* A link to the variable for the next field in this structure. */
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
heap variables and constraints we had to break up. */
unsigned int is_artificial_var:1;
@@ -364,7 +359,6 @@ new_var_info (tree t, unsigned int id, const char *name)
ret->id = id;
ret->name = name;
ret->decl = t;
- ret->directly_dereferenced = false;
ret->is_artificial_var = false;
ret->is_heap_var = false;
ret->is_special_var = false;
@@ -2520,14 +2514,6 @@ process_constraint_1 (constraint_t t, bool from_call)
gcc_assert (rhs.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)
{
t->rhs.offset = 0;
@@ -3369,6 +3355,12 @@ update_alias_info (tree stmt, struct alias_info *ai)
is an escape point, whether OP escapes. */
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
form '&PTR->FLD'. The problem with these expressions is that
they do not represent a dereference of PTR. However, if some
@@ -3409,7 +3401,10 @@ update_alias_info (tree stmt, struct alias_info *ai)
dereferenced pointers that point to a set of
variables will be assigned a name tag to alias
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
dereferenced to store, otherwise mark it as being
@@ -3443,7 +3438,7 @@ update_alias_info (tree stmt, struct alias_info *ai)
|| stmt_escape_type == ESCAPE_STORED_IN_GLOBAL)
{
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,
bitmap_set_bit (into, DECL_UID (vi->decl));
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);
- ptr_alias_set = get_alias_set (TREE_TYPE (TREE_TYPE (ptr)));
- if (alias_sets_conflict_p (ptr_alias_set, var_alias_set))
+ mem_alias_set = get_alias_set (TREE_TYPE (TREE_TYPE (ptr)));
+ 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));
}
}
@@ -4703,7 +4699,7 @@ set_used_smts (void)
/* Skip the special variables and those that can't be aliased. */
if (vi->is_special_var
|| !SSA_VAR_P (var)
- || (pi && !pi->is_dereferenced)
+ || (pi && !pi->memory_tag_needed)
|| (TREE_CODE (var) == VAR_DECL && !may_be_aliased (var))
|| !POINTER_TYPE_P (TREE_TYPE (var)))
continue;
@@ -4771,7 +4767,7 @@ find_what_p_points_to (tree p)
bitmap finished_solution;
bitmap result;
- if (!pi->is_dereferenced)
+ if (!pi->memory_tag_needed)
return false;
/* This variable may have been collapsed, let's get the real
@@ -4815,7 +4811,7 @@ find_what_p_points_to (tree p)
stats.points_to_sets_created++;
set_uids_in_ptset (p, finished_solution, vi->solution,
- vi->directly_dereferenced,
+ pi->is_dereferenced,
vi->no_tbaa_pruning);
result = shared_bitmap_lookup (finished_solution);
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 8e6ea4c..52b17d4 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -559,7 +559,7 @@ verify_flow_sensitive_alias_info (void)
continue;
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");
goto err;