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
+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
+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
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;
}
/* 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;
/* 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. */
/* 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;
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);
{
unsigned ix;
bitmap_iterator bi;
+ bool any = false;
EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, ix, bi)
{
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));
}
}
}
/* 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);
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);
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;
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);
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. */
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)
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");
/* 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;
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;
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;
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
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
|| stmt_escape_type == ESCAPE_STORED_IN_GLOBAL)
{
pointer_set_insert (ai->dereferenced_ptrs_store, var);
- pi->is_dereferenced = 1;
+ pi->memory_tag_needed = 1;
}
}
}
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));
}
}
/* 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;
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
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);
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;