diff options
author | Richard Guenther <rguenther@suse.de> | 2009-06-13 22:58:13 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2009-06-13 22:58:13 +0000 |
commit | 1d24fdd92a0189c05fedccebfdfb696fee999a4d (patch) | |
tree | 8ff0bc85b42906f5dd2e481e0620be0c340e16de /gcc/tree-ssa-structalias.c | |
parent | 4b29c5e5434f7aaaabd4b6f314139fde5803b513 (diff) | |
download | gcc-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.c | 57 |
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; |