This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Repair TYPE_REF_CAN_ALIAS_ALL machinery


Hi,

As you may know, the TYPE_REF_CAN_ALIAS_ALL machinery is used by the Ada 
compiler to bypass strict aliasing on a pointer type basis.  This makes it 
possible to use Unchecked_Conversion between pointers without the need to 
specify -fno-strict-aliasing, for example:

with Unchecked_Conversion;

procedure P 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);

begin
   v1.all := 1;
   v2.all := 0;

   if v1.all /= 0 then
      raise Program_Error;
   end if;
end;

The front-end detects that a2 is the target of an Unchecked_Conversion and 
automatically sets TYPE_REF_CAN_ALIAS_ALL on it.  The program should compile 
and execute silently at -O2.

While this works with a 3.4.x compiler, this doesn't with a 4.x compiler as 
the tree aliasing machinery currently overlooks TYPE_REF_CAN_ALIAS_ALL.
The attached patch is a first attempt at repairing that and implements a 
two-pronged approach:

1. Treat a conversion from a pointer type to a ref-all pointer type like a 
conversion from a pointer type to a non-pointer type, i.e as an escape site 
for alias analysis purposes.

2. Treat a dereference of a pointer of ref-all type like a call or an asm, 
i.e. as clobbering all the call-clobbered variables.


Bootstrapped/regtested on i586-suse-linux.  OK for mainline and 4.1 branch 
once it reopens?


2006-05-22  Eric Botcazou  <ebotcazou@adacore.com>

	* tree-ssa-alias.c (is_escape_site): Return ESCAPE_BAD_CAST for
	conversion from a regular pointer type to a ref-all pointer type.
	* tree-ssa-operands.c (get_indirect_ref_operands): Add V_MAY_DEF
	or V_USE operands for call-clobbered variables if the pointer is
	of a ref-all type.


-- 
Eric Botcazou
Index: tree-ssa-alias.c
===================================================================
--- tree-ssa-alias.c	(revision 113948)
+++ tree-ssa-alias.c	(working copy)
@@ -2060,15 +2060,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.  */
Index: tree-ssa-operands.c
===================================================================
--- tree-ssa-operands.c	(revision 113948)
+++ tree-ssa-operands.c	(working copy)
@@ -1404,6 +1404,28 @@ get_indirect_ref_operands (tree stmt, tr
     {
       struct ptr_info_def *pi = NULL;
 
+      /* If aliases have been computed already and the dereferenced
+	 pointer is ref-all, add V_MAY_DEF or V_USE operands for all
+	 the symbols that have been found to be call-clobbered.  */
+      if (aliases_computed_p
+	  && !bitmap_empty_p (call_clobbered_vars)
+	  && !(flags & opf_no_vops)
+	  && POINTER_TYPE_P (TREE_TYPE (ptr))
+	  && TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (ptr)))
+	{
+	  unsigned int i;
+	  bitmap_iterator bi;
+
+	  if (global_var)
+	    add_stmt_operand (&global_var, s_ann, flags);
+	  else
+	    EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
+	      {
+	        tree var = referenced_var (i);
+	        add_stmt_operand (&var, s_ann, flags);
+	      }
+	}
+
       /* If PTR has flow-sensitive points-to information, use it.  */
       if (TREE_CODE (ptr) == SSA_NAME
 	  && (pi = SSA_NAME_PTR_INFO (ptr)) != NULL
with Unchecked_Conversion;

procedure P 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);

begin
   v1.all := 1;
   v2.all := 0;

   if v1.all /= 0 then
      raise Program_Error;
   end if;
end;
with System.Address_To_Access_Conversions;

procedure P2 is

   type Integer_type1 is new Integer;
   type Integer_type2 is new Integer;

   package AA is new System.Address_To_Access_Conversions (Integer_type1);

   K1 : Integer_type1;
   K2 : Integer_type2;

begin
   K1 := 1;
   K2 := 2;

   AA.To_Pointer(K2'Address).all := K1;
   if K2 /= 1 then
      raise Program_Error;
   end if;
end;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]