This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Fwd: Re: New problem compiling g-exctra.adb]
- From: Diego Novillo <dnovillo at redhat dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 30 Sep 2004 10:34:36 -0400
- Subject: [Fwd: Re: New problem compiling g-exctra.adb]
- Organization: Red Hat Canada
Moved from gcc@.
-----Forwarded Message-----
From: Diego Novillo <dnovillo@redhat.com>
To: Richard Henderson <rth@redhat.com>
Cc: Richard Kenner <kenner@vlsi1.ultra.nyu.edu>, gcc@gcc.gnu.org <gcc@gcc.gnu.org>
Subject: Re: New problem compiling g-exctra.adb
Date: Thu, 30 Sep 2004 10:32:21 -0400
On Tue, 2004-09-07 at 22:48, Richard Henderson wrote:
> Will you take care of fixing these routines up such that
> The Right Thing happens?
>
Done. This patch makes add_pointed_to_expr handle all kinds of
expressions, so that if DECL_INITIAL contains address arithmetic, it
parses it as if it was a regular assignment.
Bootstrapped and tested x86, x86-64 and ppc.
Diego.
* tree-ssa-alias.c (collect_points_to_info_r): Move analysis of
expressions...
(add_pointed_to_expr): ... here.
Call add_pointed_to_expr for variables with DECL_INITIAL set.
* tree-dfa.c (add_referenced_var): Scan DECL_INITIAL of any
pointer variable, if set.
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-dfa.c,v
retrieving revision 2.35
diff -d -c -p -u -r2.35 tree-dfa.c
--- tree-dfa.c 23 Sep 2004 21:00:54 -0000 2.35
+++ tree-dfa.c 30 Sep 2004 10:43:46 -0000
@@ -891,12 +891,11 @@ add_referenced_var (tree var, struct wal
if (is_global_var (var))
mark_call_clobbered (var);
- /* If an initialized global variable then register the
initializer
- as well. */
- if (POINTER_TYPE_P (TREE_TYPE (var))
- && TREE_READONLY (var)
- && DECL_INITIAL (var)
- && TREE_CODE (DECL_INITIAL (var)) == ADDR_EXPR)
+ /* Scan DECL_INITIAL for pointer variables as they may contain
+ address arithmetic referencing the address of other
+ variables. */
+ if (DECL_INITIAL (var)
+ && POINTER_TYPE_P (TREE_TYPE (var)))
walk_tree (&DECL_INITIAL (var), find_vars_r, walk_state, 0);
}
}
Index: tree-ssa-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-alias.c,v
retrieving revision 2.45
diff -d -c -p -u -r2.45 tree-ssa-alias.c
--- tree-ssa-alias.c 28 Sep 2004 13:45:05 -0000 2.45
+++ tree-ssa-alias.c 30 Sep 2004 10:43:47 -0000
@@ -147,7 +147,6 @@ static void setup_pointers_and_addressab
static bool collect_points_to_info_r (tree, tree, void *);
static bool is_escape_site (tree, size_t *);
static void add_pointed_to_var (struct alias_info *, tree, tree);
-static void add_pointed_to_expr (tree, tree);
static void create_global_var (void);
static void collect_points_to_info_for (struct alias_info *, tree);
static bool ptr_is_dereferenced_by (tree, tree, bool *);
@@ -1755,41 +1754,78 @@ merge_pointed_to_info (struct alias_info
}
-/* Add VALUE to the list of expressions pointed-to by PTR. */
+/* Add EXPR to the list of expressions pointed-to by PTR. */
static void
-add_pointed_to_expr (tree ptr, tree value)
+add_pointed_to_expr (struct alias_info *ai, tree ptr, tree expr)
{
- if (TREE_CODE (value) == WITH_SIZE_EXPR)
- value = TREE_OPERAND (value, 0);
-
- /* Pointer variables should have been handled by
merge_pointed_to_info. */
- gcc_assert (TREE_CODE (value) != SSA_NAME
- || !POINTER_TYPE_P (TREE_TYPE (value)));
+ if (TREE_CODE (expr) == WITH_SIZE_EXPR)
+ expr = TREE_OPERAND (expr, 0);
get_ptr_info (ptr);
- /* If VALUE is the result of a malloc-like call, then the area
pointed to
- PTR is guaranteed to not alias with anything else. */
- if (TREE_CODE (value) == CALL_EXPR
- && (call_expr_flags (value) & (ECF_MALLOC | ECF_MAY_BE_ALLOCA)))
- set_pt_malloc (ptr);
- else
- set_pt_anything (ptr);
-
- if (dump_file)
+ if (TREE_CODE (expr) == CALL_EXPR
+ && (call_expr_flags (expr) & (ECF_MALLOC | ECF_MAY_BE_ALLOCA)))
{
- struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
+ /* If EXPR is a malloc-like call, then the area pointed to PTR
+ is guaranteed to not alias with anything else. */
+ set_pt_malloc (ptr);
+ }
+ else if (TREE_CODE (expr) == ADDR_EXPR)
+ {
+ /* Found P_i = ADDR_EXPR */
+ add_pointed_to_var (ai, ptr, expr);
+ }
+ else if (TREE_CODE (expr) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE
(expr)))
+ {
+ /* Found P_i = Q_j. */
+ merge_pointed_to_info (ai, ptr, expr);
+ }
+ else if (TREE_CODE (expr) == PLUS_EXPR || TREE_CODE (expr) ==
MINUS_EXPR)
+ {
+ /* Found P_i = PLUS_EXPR or P_i = MINUS_EXPR */
+ tree op0 = TREE_OPERAND (expr, 0);
+ tree op1 = TREE_OPERAND (expr, 1);
- fprintf (dump_file, "Pointer ");
- print_generic_expr (dump_file, ptr, dump_flags);
- fprintf (dump_file, " points to ");
- if (pi->pt_malloc)
- fprintf (dump_file, "malloc space: ");
- else
- fprintf (dump_file, "an arbitrary address: ");
- print_generic_expr (dump_file, value, dump_flags);
- fprintf (dump_file, "\n");
+ /* Both operands may be of pointer type. FIXME: Shouldn't
+ we just expect PTR + OFFSET always? */
+ if (POINTER_TYPE_P (TREE_TYPE (op0))
+ && TREE_CODE (op0) != INTEGER_CST)
+ {
+ if (TREE_CODE (op0) == SSA_NAME)
+ merge_pointed_to_info (ai, ptr, op0);
+ else if (TREE_CODE (op0) == ADDR_EXPR)
+ add_pointed_to_var (ai, ptr, op0);
+ else
+ set_pt_anything (ptr);
+ }
+
+ if (POINTER_TYPE_P (TREE_TYPE (op1))
+ && TREE_CODE (op1) != INTEGER_CST)
+ {
+ if (TREE_CODE (op1) == SSA_NAME)
+ merge_pointed_to_info (ai, ptr, op1);
+ else if (TREE_CODE (op1) == ADDR_EXPR)
+ add_pointed_to_var (ai, ptr, op1);
+ else
+ set_pt_anything (ptr);
+ }
+
+ /* Neither operand is a pointer? VAR can be pointing anywhere.
+ FIXME: Shouldn't we abort here? If we get here, we found
+ PTR = INT_CST + INT_CST, which should not be a valid pointer
+ expression. */
+ if (!(POINTER_TYPE_P (TREE_TYPE (op0))
+ && TREE_CODE (op0) != INTEGER_CST)
+ && !(POINTER_TYPE_P (TREE_TYPE (op1))
+ && TREE_CODE (op1) != INTEGER_CST))
+ set_pt_anything (ptr);
+ }
+ else
+ {
+ /* If we can't recognize the expression, assume that PTR may
+ point anywhere. */
+ set_pt_anything (ptr);
}
}
@@ -1862,62 +1898,10 @@ collect_points_to_info_r (tree var, tree
{
tree rhs = TREE_OPERAND (stmt, 1);
STRIP_NOPS (rhs);
-
- /* Found P_i = ADDR_EXPR */
- if (TREE_CODE (rhs) == ADDR_EXPR)
- add_pointed_to_var (ai, var, rhs);
-
- /* Found P_i = Q_j. */
- else if (TREE_CODE (rhs) == SSA_NAME
- && POINTER_TYPE_P (TREE_TYPE (rhs)))
- merge_pointed_to_info (ai, var, rhs);
-
- /* Found P_i = PLUS_EXPR or P_i = MINUS_EXPR */
- else if (TREE_CODE (rhs) == PLUS_EXPR
- || TREE_CODE (rhs) == MINUS_EXPR)
- {
- tree op0 = TREE_OPERAND (rhs, 0);
- tree op1 = TREE_OPERAND (rhs, 1);
-
- /* Both operands may be of pointer type. FIXME: Shouldn't
- we just expect PTR + OFFSET always? */
- if (POINTER_TYPE_P (TREE_TYPE (op0))
- && TREE_CODE (op0) != INTEGER_CST)
- {
- if (TREE_CODE (op0) == SSA_NAME)
- merge_pointed_to_info (ai, var, op0);
- else if (TREE_CODE (op0) == ADDR_EXPR)
- add_pointed_to_var (ai, var, op0);
- else
- add_pointed_to_expr (var, op0);
- }
-
- if (POINTER_TYPE_P (TREE_TYPE (op1))
- && TREE_CODE (op1) != INTEGER_CST)
- {
- if (TREE_CODE (op1) == SSA_NAME)
- merge_pointed_to_info (ai, var, op1);
- else if (TREE_CODE (op1) == ADDR_EXPR)
- add_pointed_to_var (ai, var, op1);
- else
- add_pointed_to_expr (var, op1);
- }
-
- /* Neither operand is a pointer? VAR can be pointing
- anywhere. FIXME: Is this right? If we get here, we
- found PTR = INT_CST + INT_CST. */
- if (!(POINTER_TYPE_P (TREE_TYPE (op0))
- && TREE_CODE (op0) != INTEGER_CST)
- && !(POINTER_TYPE_P (TREE_TYPE (op1))
- && TREE_CODE (op1) != INTEGER_CST))
- add_pointed_to_expr (var, rhs);
- }
-
- /* Something else. */
- else
- add_pointed_to_expr (var, rhs);
+ add_pointed_to_expr (ai, var, rhs);
break;
}
+
case ASM_EXPR:
/* Pointers defined by __asm__ statements can point anywhere. */
set_pt_anything (var);
@@ -1929,13 +1913,14 @@ collect_points_to_info_r (tree var, tree
tree decl = SSA_NAME_VAR (var);
if (TREE_CODE (decl) == PARM_DECL)
- add_pointed_to_expr (var, decl);
+ add_pointed_to_expr (ai, var, decl);
else if (DECL_INITIAL (decl))
- add_pointed_to_var (ai, var, DECL_INITIAL (decl));
+ add_pointed_to_expr (ai, var, DECL_INITIAL (decl));
else
- add_pointed_to_expr (var, decl);
+ add_pointed_to_expr (ai, var, decl);
}
break;
+
case PHI_NODE:
{
/* It STMT is a PHI node, then VAR is one of its arguments.
The
@@ -1954,11 +1939,12 @@ collect_points_to_info_r (tree var, tree
default:
gcc_assert (is_gimple_min_invariant (var));
- add_pointed_to_expr (lhs, var);
+ add_pointed_to_expr (ai, lhs, var);
break;
}
break;
}
+
default:
gcc_unreachable ();
}