This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Repair TYPE_REF_CAN_ALIAS_ALL machinery
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 22 May 2006 12:50:57 +0200
- Subject: [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;