This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Repair TYPE_REF_CAN_ALIAS_ALL machinery (take 2)
> Referenced variables in foo: 6
>
> Variable: i, UID 1520, int *, symbol memory tag: SMT.4, default def: i_1
>
> Variable: f, UID 1521, float *, symbol memory tag: SMT.5, default def: f_2
>
> Variable: <retval>, UID 1523, int
>
> Variable: D.1524, UID 1524, int
>
> Variable: SMT.4, UID 1531, int, is addressable, is global, call clobbered
>
> Variable: SMT.5, UID 1532, float, is addressable, is global, call clobbered
Well, then the SMT of the ref-all pointers needs to alias the call-clobbered
SMTs of pointers. Revised patch and Ada testcase at -O2 -fno-inline attached.
--
Eric Botcazou
with Unchecked_Conversion;
procedure P4 is
type int1 is new integer;
type int2 is new integer;
type a1 is access int1;
type a2 is access int2;
function to_a2 is new Unchecked_Conversion (a1, a2);
v1 : a1 := new int1;
v2 : a2 := to_a2 (v1);
procedure q (p1 : a1; p2 : a2) is
begin
p1.all := 1;
p2.all := 0;
if p1.all /= 0 then
raise Program_Error;
end if;
end;
begin
q (v1, v2);
end;
Index: tree-ssa-structalias.h
===================================================================
--- tree-ssa-structalias.h (revision 113948)
+++ tree-ssa-structalias.h (working copy)
@@ -22,6 +22,9 @@ Foundation, Inc., 51 Franklin Street, Fi
#ifndef TREE_SSA_STRUCTALIAS_H
#define TREE_SSA_STRUCTALIAS_H
+/* True if the data pointed to by PTR can alias anything. */
+#define PTR_IS_REF_ALL(PTR) TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (PTR))
+
struct constraint;
typedef struct constraint *constraint_t;
@@ -64,6 +67,9 @@ struct alias_info
/* Pointers that have been used in an indirect load operation. */
bitmap dereferenced_ptrs_load;
+
+ /* Memory tag for all the PTR_IS_REF_ALL pointers. */
+ tree ref_all_symbol_mem_tag;
};
/* Keep track of how many times each pointer has been dereferenced in
Index: tree-ssa-alias.c
===================================================================
--- tree-ssa-alias.c (revision 113948)
+++ tree-ssa-alias.c (working copy)
@@ -98,6 +98,7 @@ static struct alias_stats_d alias_stats;
/* Local functions. */
static void compute_flow_insensitive_aliasing (struct alias_info *);
+static void finalize_ref_all_pointers (struct alias_info *);
static void dump_alias_stats (FILE *);
static bool may_alias_p (tree, HOST_WIDE_INT, tree, HOST_WIDE_INT, bool);
static tree create_memory_tag (tree type, bool is_type_tag);
@@ -692,6 +693,12 @@ compute_may_aliases (void)
aliasing precision. */
maybe_create_global_var (ai);
+ /* If the program contains ref-all pointers, finalize may-alias information
+ for them. This pass needs to be run after call-clobbering information
+ has been computed. */
+ if (ai->ref_all_symbol_mem_tag)
+ finalize_ref_all_pointers (ai);
+
/* Debugging dumps. */
if (dump_file)
{
@@ -1156,6 +1163,10 @@ compute_flow_insensitive_aliasing (struc
tree tag = var_ann (p_map->var)->symbol_mem_tag;
var_ann_t tag_ann = var_ann (tag);
+ /* Call-clobbering information is not finalized yet at this point. */
+ if (PTR_IS_REF_ALL (p_map->var))
+ continue;
+
p_map->total_alias_vops = 0;
p_map->may_aliases = BITMAP_ALLOC (&alias_obstack);
@@ -1289,6 +1300,47 @@ compute_flow_insensitive_aliasing (struc
}
+/* Finalize may-alias information for ref-all pointers. Traverse all
+ the addressable variables found in setup_pointers_and_addressables.
+
+ If flow-sensitive alias analysis has attached a name memory tag to
+ a ref-all pointer, we will use it for the dereferences because that
+ will have more precise aliasing information. But if there is no
+ name tag, we will use a special symbol tag that aliases all the
+ call-clobbered addressable variables. */
+
+static void
+finalize_ref_all_pointers (struct alias_info *ai)
+{
+ size_t i;
+
+ if (global_var)
+ add_may_alias (ai->ref_all_symbol_mem_tag, global_var);
+ else
+ {
+ /* First add the real call-clobbered variables. */
+ for (i = 0; i < ai->num_addressable_vars; i++)
+ {
+ tree var = ai->addressable_vars[i]->var;
+ if (is_call_clobbered (var))
+ add_may_alias (ai->ref_all_symbol_mem_tag, var);
+ }
+
+ /* Then add the call-clobbered pointer memory tags. See
+ compute_flow_insensitive_aliasing for the rationale. */
+ for (i = 0; i < ai->num_pointers; i++)
+ {
+ tree ptr = ai->pointers[i]->var, tag;
+ if (PTR_IS_REF_ALL (ptr))
+ continue;
+ tag = var_ann (ptr)->symbol_mem_tag;
+ if (is_call_clobbered (tag))
+ add_may_alias (ai->ref_all_symbol_mem_tag, tag);
+ }
+ }
+}
+
+
/* Comparison function for qsort used in group_aliases. */
static int
@@ -2060,15 +2112,24 @@ is_escape_site (tree stmt, struct alias_
if (lhs == NULL_TREE)
return ESCAPE_UNKNOWN;
- /* If the RHS is a conversion between a pointer and an integer, the
- pointer escapes since we can't track the integer. */
- if ((TREE_CODE (TREE_OPERAND (stmt, 1)) == NOP_EXPR
- || TREE_CODE (TREE_OPERAND (stmt, 1)) == CONVERT_EXPR
- || TREE_CODE (TREE_OPERAND (stmt, 1)) == VIEW_CONVERT_EXPR)
- && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND
- (TREE_OPERAND (stmt, 1), 0)))
- && !POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (stmt, 1))))
- return ESCAPE_BAD_CAST;
+ if (TREE_CODE (TREE_OPERAND (stmt, 1)) == NOP_EXPR
+ || TREE_CODE (TREE_OPERAND (stmt, 1)) == CONVERT_EXPR
+ || TREE_CODE (TREE_OPERAND (stmt, 1)) == VIEW_CONVERT_EXPR)
+ {
+ tree from = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (stmt, 1), 0));
+ tree to = TREE_TYPE (TREE_OPERAND (stmt, 1));
+
+ /* If the RHS is a conversion between a pointer and an integer, the
+ pointer escapes since we can't track the integer. */
+ if (POINTER_TYPE_P (from) && !POINTER_TYPE_P (to))
+ return ESCAPE_BAD_CAST;
+
+ /* Same if the RHS is a conversion between a regular pointer and a
+ ref-all pointer since we can't track the SMT of the former. */
+ if (POINTER_TYPE_P (from) && !TYPE_REF_CAN_ALIAS_ALL (from)
+ && POINTER_TYPE_P (to) && TYPE_REF_CAN_ALIAS_ALL (to))
+ return ESCAPE_BAD_CAST;
+ }
/* If the LHS is an SSA name, it can't possibly represent a non-local
memory store. */
@@ -2180,6 +2241,14 @@ get_tmt_for (tree ptr, struct alias_info
tree tag_type = TREE_TYPE (TREE_TYPE (ptr));
HOST_WIDE_INT tag_set = get_alias_set (tag_type);
+ /* We use a unique memory tag for all the ref-all pointers. */
+ if (PTR_IS_REF_ALL (ptr))
+ {
+ if (!ai->ref_all_symbol_mem_tag)
+ ai->ref_all_symbol_mem_tag = create_memory_tag (void_type_node, true);
+ return ai->ref_all_symbol_mem_tag;
+ }
+
/* To avoid creating unnecessary memory tags, only create one memory tag
per alias set class. Note that it may be tempting to group
memory tags based on conflicting alias sets instead of