aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-structalias.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2009-06-13 22:58:13 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2009-06-13 22:58:13 +0000
commit1d24fdd92a0189c05fedccebfdfb696fee999a4d (patch)
tree8ff0bc85b42906f5dd2e481e0620be0c340e16de /gcc/tree-ssa-structalias.c
parent4b29c5e5434f7aaaabd4b6f314139fde5803b513 (diff)
downloadgcc-1d24fdd92a0189c05fedccebfdfb696fee999a4d.zip
gcc-1d24fdd92a0189c05fedccebfdfb696fee999a4d.tar.gz
gcc-1d24fdd92a0189c05fedccebfdfb696fee999a4d.tar.bz2
re PR c++/40389 (optimizer bug (possibly))
2009-06-14 Richard Guenther <rguenther@suse.de> PR middle-end/40389 * gimple.c (walk_stmt_load_store_addr_ops): The LHS of a call has its address taken if NRV was applied and it is addressable. * tree-ssa-structalias.c (get_constraint_for_address_of): New function split out from ... (get_constraint_for_1): ... here. (handle_rhs_call): Use it to mark the return slot escaped if it is addressable and NRV was applied. * g++.dg/torture/pr40389.C: New testcase. From-SVN: r148462
Diffstat (limited to 'gcc/tree-ssa-structalias.c')
-rw-r--r--gcc/tree-ssa-structalias.c57
1 files changed, 40 insertions, 17 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 827a916..7c95de4 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -3080,6 +3080,28 @@ do_deref (VEC (ce_s, heap) **constraints)
}
}
+static void get_constraint_for_1 (tree, VEC (ce_s, heap) **, bool);
+
+/* Given a tree T, return the constraint expression for taking the
+ address of it. */
+
+static void
+get_constraint_for_address_of (tree t, VEC (ce_s, heap) **results)
+{
+ struct constraint_expr *c;
+ unsigned int i;
+
+ get_constraint_for_1 (t, results, true);
+
+ for (i = 0; VEC_iterate (ce_s, *results, i, c); i++)
+ {
+ if (c->type == DEREF)
+ c->type = SCALAR;
+ else
+ c->type = ADDRESSOF;
+ }
+}
+
/* Given a tree T, return the constraint expression for it. */
static void
@@ -3131,23 +3153,8 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
switch (TREE_CODE (t))
{
case ADDR_EXPR:
- {
- struct constraint_expr *c;
- unsigned int i;
- tree exp = TREE_OPERAND (t, 0);
-
- get_constraint_for_1 (exp, results, true);
-
- for (i = 0; VEC_iterate (ce_s, *results, i, c); i++)
- {
- if (c->type == DEREF)
- c->type = SCALAR;
- else
- c->type = ADDRESSOF;
- }
- return;
- }
- break;
+ get_constraint_for_address_of (TREE_OPERAND (t, 0), results);
+ return;
default:;
}
break;
@@ -3333,6 +3340,22 @@ handle_rhs_call (gimple stmt, VEC(ce_s, heap) **results)
if (gimple_call_chain (stmt))
make_escape_constraint (gimple_call_chain (stmt));
+ /* And if we applied NRV the address of the return slot escapes as well. */
+ if (gimple_call_return_slot_opt_p (stmt)
+ && gimple_call_lhs (stmt) != NULL_TREE
+ && TREE_ADDRESSABLE (gimple_call_lhs (stmt)))
+ {
+ VEC(ce_s, heap) *tmpc = NULL;
+ struct constraint_expr lhsc, *c;
+ get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
+ lhsc.var = escaped_id;
+ lhsc.offset = 0;
+ lhsc.type = SCALAR;
+ for (i = 0; VEC_iterate (ce_s, tmpc, i, c); ++i)
+ process_constraint (new_constraint (lhsc, *c));
+ VEC_free(ce_s, heap, tmpc);
+ }
+
/* Regular functions return nonlocal memory. */
rhsc.var = nonlocal_id;
rhsc.offset = 0;