diff options
author | Richard Guenther <rguenther@suse.de> | 2009-04-04 09:34:32 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2009-04-04 09:34:32 +0000 |
commit | aa7069aa9faf250b01c10bb7c2c442d329c0bab8 (patch) | |
tree | 9008d47a69f8bfcbddab1535dfb7516d4a030aff /gcc/tree-ssa-pre.c | |
parent | cd15ad3e604aaa74991b72dcbf74ab61fe2fc9c4 (diff) | |
download | gcc-aa7069aa9faf250b01c10bb7c2c442d329c0bab8.zip gcc-aa7069aa9faf250b01c10bb7c2c442d329c0bab8.tar.gz gcc-aa7069aa9faf250b01c10bb7c2c442d329c0bab8.tar.bz2 |
re PR c++/8781 (Pessimization of C++ (functional) code)
2009-04-04 Richard Guenther <rguenther@suse.de>
PR tree-optimization/8781
PR tree-optimization/37892
* tree-ssa-sccvn.h (vn_reference_fold_indirect): Declare.
* tree-ssa-sccvn.c (vn_reference_fold_indirect): New function.
(valueize_refs): Call it for *& valueizations.
(shared_reference_ops_from_ref): Rename to ...
(valueize_shared_reference_ops_from_ref): ... this and valueize.
(shared_reference_ops_from_call): Rename to ...
(valueize_shared_reference_ops_from_call): ... this and valueize.
(vn_reference_lookup): Update.
(visit_reference_op_call): Likewise.
* tree-ssa-pre.c (phi_translate_1): Fold *&.
(eliminate): Value-replace the call address in call statements.
* g++.dg/tree-ssa/pr8781.C: New testcase.
* gcc.dg/tree-ssa/ssa-pre-25.c: Likewise.
From-SVN: r145533
Diffstat (limited to 'gcc/tree-ssa-pre.c')
-rw-r--r-- | gcc/tree-ssa-pre.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index c1cbe0c..ed326e4 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -1563,11 +1563,12 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, tree newvuse = vuse; VEC (vn_reference_op_s, heap) *newoperands = NULL; bool changed = false; - unsigned int i; + unsigned int i, j; vn_reference_op_t operand; vn_reference_t newref; - for (i = 0; VEC_iterate (vn_reference_op_s, operands, i, operand); i++) + for (i = 0, j = 0; + VEC_iterate (vn_reference_op_s, operands, i, operand); i++, j++) { pre_expr opresult; pre_expr leader; @@ -1642,7 +1643,13 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, newop.op0 = op0; newop.op1 = op1; newop.op2 = op2; - VEC_replace (vn_reference_op_s, newoperands, i, &newop); + VEC_replace (vn_reference_op_s, newoperands, j, &newop); + /* If it transforms from an SSA_NAME to an address, fold with + a preceding indirect reference. */ + if (j > 0 && op0 && TREE_CODE (op0) == ADDR_EXPR + && VEC_index (vn_reference_op_s, + newoperands, j - 1)->opcode == INDIRECT_REF) + vn_reference_fold_indirect (&newoperands, &j); } if (i != VEC_length (vn_reference_op_s, operands)) { @@ -4098,6 +4105,29 @@ eliminate (void) todo = TODO_cleanup_cfg; } } + /* Visit indirect calls and turn them into direct calls if + possible. */ + if (gimple_code (stmt) == GIMPLE_CALL + && TREE_CODE (gimple_call_fn (stmt)) == SSA_NAME) + { + tree fn = VN_INFO (gimple_call_fn (stmt))->valnum; + if (TREE_CODE (fn) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Replacing call target with "); + print_generic_expr (dump_file, fn, 0); + fprintf (dump_file, " in "); + print_gimple_stmt (dump_file, stmt, 0, 0); + } + + gimple_call_set_fn (stmt, fn); + update_stmt (stmt); + if (maybe_clean_or_replace_eh_stmt (stmt, stmt)) + gimple_purge_dead_eh_edges (b); + } + } } } |