aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego Novillo <dnovillo@redhat.com>2005-01-27 04:45:20 +0000
committerDiego Novillo <dnovillo@gcc.gnu.org>2005-01-26 23:45:20 -0500
commit87637d21c0eab59ae9ba4ca7b3593fe847cc1bed (patch)
tree839beaf956bc6b73ae54db4610def572b171b9e0
parent9ff93eb01ce59be5d7b26428df5e5bf6671bce86 (diff)
downloadgcc-87637d21c0eab59ae9ba4ca7b3593fe847cc1bed.zip
gcc-87637d21c0eab59ae9ba4ca7b3593fe847cc1bed.tar.gz
gcc-87637d21c0eab59ae9ba4ca7b3593fe847cc1bed.tar.bz2
re PR tree-optimization/19633 (local address incorrectly thought to escape)
PR tree-optimization/19633 * tree-ssa-alias.c (ptr_is_dereferenced_by): Also handle CALL_EXPRs. (maybe_create_global_var): Do not create .GLOBAL_VAR if there are no call-clobbered variables. * tree-outof-ssa.c (check_replaceable): Return false for calls with side-effects. testsuite/ChangeLog PR tree-optimization/19633 * gcc.dg/pr19633.c: New test. * gcc.dg/tree-ssa/pr19633.c: New test. From-SVN: r94311
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/pr19633.c40
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr19633.c25
-rw-r--r--gcc/tree-outof-ssa.c10
-rw-r--r--gcc/tree-ssa-alias.c31
6 files changed, 102 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ca995cc..04ef357 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2005-01-26 Diego Novillo <dnovillo@redhat.com>
+
+ PR tree-optimization/19633
+ * tree-ssa-alias.c (ptr_is_dereferenced_by): Also handle
+ CALL_EXPRs.
+ (maybe_create_global_var): Do not create .GLOBAL_VAR if there
+ are no call-clobbered variables.
+ * tree-outof-ssa.c (check_replaceable): Return false for calls
+ with side-effects.
+
2005-01-26 Ulrich Weigand <uweigand@de.ibm.com>
* dbxout.c (dbxout_symbol_location): Resolve constant pool references
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0140e9a..deceb4a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2005-01-26 Diego Novillo <dnovillo@redhat.com>
+
+ PR tree-optimization/19633
+ * gcc.dg/pr19633.c: New test.
+ * gcc.dg/tree-ssa/pr19633.c: New test.
+
2005-01-26 Ulrich Weigand <uweigand@de.ibm.com>
* gcc.dg/20041216-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/pr19633.c b/gcc/testsuite/gcc.dg/pr19633.c
new file mode 100644
index 0000000..4e18375
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr19633.c
@@ -0,0 +1,40 @@
+/* { dg-do link } */
+/* { dg-options "-O2" } */
+
+struct S
+{
+ int w, x, y, z;
+};
+
+struct T
+{
+ int r;
+ struct S s;
+};
+
+void
+foo (int a, struct T b)
+{
+ struct S x;
+ struct S *c = &x;
+ if (a)
+ c = &b.s;
+ b.s.w = 3;
+ bar (*c, a);
+ if (b.s.w != 3)
+ link_error ();
+}
+
+int main ()
+{
+ struct T b;
+ foo (3, b);
+ return 0;
+}
+
+int X;
+
+int bar (struct S x, int i)
+{
+ X = 3;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr19633.c b/gcc/testsuite/gcc.dg/tree-ssa/pr19633.c
new file mode 100644
index 0000000..88cbfe2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr19633.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-ssa-vops" } */
+struct S
+{
+ int w, x, y, z;
+};
+struct T
+{
+ int r;
+ struct S s;
+};
+void bar (struct S, int);
+void
+foo (int a, struct T b)
+{
+ struct S x;
+ struct S *c = &x;
+ if (a)
+ c = &b.s;
+ bar (*c, a);
+}
+
+/* Make sure that .GLOBAL_VAR is not created when there are no
+ clobbering calls. */
+/* { dg-final { scan-tree-dump-times "GLOBAL_VAR" 0 "ssa"} } */
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index cfa1704..430e8ca 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -1460,6 +1460,7 @@ check_replaceable (temp_expr_table_p tab, tree stmt)
int num_use_ops, version;
var_map map = tab->map;
ssa_op_iter iter;
+ tree call_expr;
if (TREE_CODE (stmt) != MODIFY_EXPR)
return false;
@@ -1486,6 +1487,15 @@ check_replaceable (temp_expr_table_p tab, tree stmt)
if (flag_float_store && FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (stmt, 1))))
return false;
+ /* Calls to functions with side-effects cannot be replaced. */
+ if ((call_expr = get_call_expr_in (stmt)) != NULL_TREE)
+ {
+ int call_flags = call_expr_flags (call_expr);
+ if (TREE_SIDE_EFFECTS (call_expr)
+ && !(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN)))
+ return false;
+ }
+
uses = USE_OPS (ann);
num_use_ops = NUM_USES (uses);
vuseops = VUSE_OPS (ann);
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index a410217..da11fd0 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -621,6 +621,16 @@ ptr_is_dereferenced_by (tree ptr, tree stmt, bool *is_store)
return true;
}
}
+ else
+ {
+ /* CALL_EXPRs may also contain pointer dereferences for types
+ that are not GIMPLE register types. If the CALL_EXPR is on
+ the RHS of an assignment, it will be handled by the
+ MODIFY_EXPR handler above. */
+ tree call = get_call_expr_in (stmt);
+ if (call && walk_tree (&call, find_ptr_dereference, ptr, NULL))
+ return true;
+ }
return false;
}
@@ -1538,26 +1548,7 @@ maybe_create_global_var (struct alias_info *ai)
n_clobbered++;
}
- /* Create .GLOBAL_VAR if we have too many call-clobbered
- variables. We also create .GLOBAL_VAR when there no
- call-clobbered variables to prevent code motion
- transformations from re-arranging function calls that may
- have side effects. For instance,
-
- foo ()
- {
- int a = f ();
- g ();
- h (a);
- }
-
- There are no call-clobbered variables in foo(), so it would
- be entirely possible for a pass to want to move the call to
- f() after the call to g(). If f() has side effects, that
- would be wrong. Creating .GLOBAL_VAR in this case will
- insert VDEFs for it and prevent such transformations. */
- if (n_clobbered == 0
- || ai->num_calls_found * n_clobbered >= (size_t) GLOBAL_VAR_THRESHOLD)
+ if (ai->num_calls_found * n_clobbered >= (size_t) GLOBAL_VAR_THRESHOLD)
create_global_var ();
}