diff options
author | Richard Guenther <rguenther@suse.de> | 2008-03-14 14:52:07 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2008-03-14 14:52:07 +0000 |
commit | 3d45dd59c7fcad07ddec7a45d91eb3b7d31897a8 (patch) | |
tree | 0508ac0fafc550eb92cb66bcb48ef0d5a3af1d88 /gcc/tree-ssa-sccvn.c | |
parent | c539732f969e784725ca51dd9ff66b32a2c198cd (diff) | |
download | gcc-3d45dd59c7fcad07ddec7a45d91eb3b7d31897a8.zip gcc-3d45dd59c7fcad07ddec7a45d91eb3b7d31897a8.tar.gz gcc-3d45dd59c7fcad07ddec7a45d91eb3b7d31897a8.tar.bz2 |
re PR tree-optimization/34043 (Missed optimization causing extra loads and stores when using x86_64 builtin function together with aggregate types.)
2008-03-14 Richard Guenther <rguenther@suse.de>
PR tree-optimization/34043
PR tree-optimization/33989
* tree-ssa-pre.c (execute_pre): Allow SCCVN to do insertion
when doing FRE.
(bitmap_find_leader): Use extra argument to verify dominance
relationship inside a basic-block.
(can_PRE_operation): Add VIEW_CONVERT_EXPR.
(find_leader_in_sets): Adjust.
(create_component_ref_by_pieces): Take extra argument for
dominance check, handle lookup failures.
(find_or_generate_expression): Likewise.
(create_expression_by_pieces): Likewise.
(insert_into_preds_of_block): Adjust.
(create_value_expr_from): If asked for, verify all operands
are in the blocks AVAIL_OUT set.
(make_values_for_stmt): Check for SSA_NAMEs that are life
over an abnormal edge.
(compute_avail): Remove such check.
(do_SCCVN_insertion): New function.
(eliminate): If we do not find a leader suitable for replacement
insert a replacement expression from SCCVN if available.
* tree-ssa-sccvn.h (run_scc_vn): Update prototype.
(struct vn_ssa_aux): Add needs_insertion flag.
* tree-ssa-sccvn.c (may_insert): New global flag.
(copy_reference_ops_from_ref): Value-number union member access
based on its size, not type and member if insertion is allowed.
(visit_reference_op_load): For a weak match from union type
punning lookup a view-converted value and insert a SSA_NAME
for that value if that is not found.
(visit_use): Make dumps shorter. Do not disallow value numbering
SSA_NAMEs that are life over an abnormal edge to constants.
(free_scc_vn): Release inserted SSA_NAMEs.
(run_scc_vn): New flag to specify whether insertion is allowed.
Process SSA_NAMEs in forward order.
* tree-ssa-loop-im.c (for_each_index): Handle invariant
ADDR_EXPRs inside VIEW_CONVERT_EXPR.
* fold-const.c (fold_unary): Fold VIEW_CONVERT_EXPRs from/to
pointer type to/from integral types that do not change the
precision to regular conversions.
* gcc.dg/tree-ssa/ssa-fre-7.c: New testcase.
* gcc.dg/tree-ssa/ssa-fre-8.c: Likewise.
* gcc.dg/tree-ssa/ssa-fre-9.c: Likewise.
* gcc.dg/tree-ssa/ssa-fre-10.c: Likewise.
* gcc.dg/tree-ssa/ssa-pre-17.c: Likewise.
From-SVN: r133218
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 98 |
1 files changed, 93 insertions, 5 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 044be45..20d1498 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -221,6 +221,9 @@ tree VN_TOP; static unsigned int next_dfs_num; static VEC (tree, heap) *sccstack; +static bool may_insert; + + DEF_VEC_P(vn_ssa_aux_t); DEF_VEC_ALLOC_P(vn_ssa_aux_t, heap); @@ -525,8 +528,21 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result) temp.op1 = TREE_OPERAND (ref, 2); break; case COMPONENT_REF: - /* Record field as operand. */ - temp.op0 = TREE_OPERAND (ref, 1); + /* If this is a reference to a union member, record the union + member size as operand. Do so only if we are doing + expression insertion (during FRE), as PRE currently gets + confused with this. */ + if (may_insert + && TREE_CODE (DECL_CONTEXT (TREE_OPERAND (ref, 1))) == UNION_TYPE + && integer_zerop (DECL_FIELD_OFFSET (TREE_OPERAND (ref, 1))) + && integer_zerop (DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1)))) + { + temp.type = NULL_TREE; + temp.op0 = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (ref, 1))); + } + else + /* Record field as operand. */ + temp.op0 = TREE_OPERAND (ref, 1); break; case ARRAY_RANGE_REF: case ARRAY_REF: @@ -1017,6 +1033,9 @@ defs_to_varying (tree stmt) return changed; } +static tree +try_to_simplify (tree stmt, tree rhs); + /* Visit a copy between LHS and RHS, return true if the value number changed. */ @@ -1089,6 +1108,64 @@ visit_reference_op_load (tree lhs, tree op, tree stmt) bool changed = false; tree result = vn_reference_lookup (op, shared_vuses_from_stmt (stmt)); + /* We handle type-punning through unions by value-numbering based + on offset and size of the access. Be prepared to handle a + type-mismatch here via creating a VIEW_CONVERT_EXPR. */ + if (result + && !useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (op))) + { + /* We will be setting the value number of lhs to the value number + of VIEW_CONVERT_EXPR <TREE_TYPE (result)> (result). + So first simplify and lookup this expression to see if it + is already available. */ + tree val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (op), result); + if (stmt + && !is_gimple_min_invariant (val) + && TREE_CODE (val) != SSA_NAME) + { + tree tem = try_to_simplify (stmt, val); + if (tem) + val = tem; + } + result = val; + if (!is_gimple_min_invariant (val) + && TREE_CODE (val) != SSA_NAME) + result = vn_nary_op_lookup (val); + /* If the expression is not yet available, value-number lhs to + a new SSA_NAME we create. */ + if (!result && may_insert) + { + result = make_ssa_name (SSA_NAME_VAR (lhs), NULL_TREE); + /* Initialize value-number information properly. */ + VN_INFO_GET (result)->valnum = result; + VN_INFO (result)->expr = val; + VN_INFO (result)->needs_insertion = true; + /* As all "inserted" statements are singleton SCCs, insert + to the valid table. This is strictly needed to + avoid re-generating new value SSA_NAMEs for the same + expression during SCC iteration over and over (the + optimistic table gets cleared after each iteration). + We do not need to insert into the optimistic table, as + lookups there will fall back to the valid table. */ + if (current_info == optimistic_info) + { + current_info = valid_info; + vn_nary_op_insert (val, result); + current_info = optimistic_info; + } + else + vn_nary_op_insert (val, result); + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Inserting name "); + print_generic_expr (dump_file, result, 0); + fprintf (dump_file, " for expression "); + print_generic_expr (dump_file, val, 0); + fprintf (dump_file, "\n"); + } + } + } + if (result) { changed = set_ssa_val_to (lhs, result); @@ -1496,7 +1573,8 @@ visit_use (tree use) VN_INFO (use)->use_processed = true; gcc_assert (!SSA_NAME_IN_FREE_LIST (use)); - if (dump_file && (dump_flags & TDF_DETAILS)) + if (dump_file && (dump_flags & TDF_DETAILS) + && !IS_EMPTY_STMT (stmt)) { fprintf (dump_file, "Value numbering "); print_generic_expr (dump_file, use, 0); @@ -1607,6 +1685,9 @@ visit_use (tree use) } if (TREE_CODE (lhs) == SSA_NAME + /* We can substitute SSA_NAMEs that are live over + abnormal edges with their constant value. */ + && !is_gimple_min_invariant (rhs) && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)) changed = defs_to_varying (stmt); else if (REFERENCE_CLASS_P (lhs) || DECL_P (lhs)) @@ -1985,6 +2066,9 @@ free_scc_vn (void) && SSA_NAME_VALUE (name) && TREE_CODE (SSA_NAME_VALUE (name)) == VALUE_HANDLE) SSA_NAME_VALUE (name) = NULL; + if (name + && VN_INFO (name)->needs_insertion) + release_ssa_name (name); } obstack_free (&vn_ssa_aux_obstack, NULL); VEC_free (vn_ssa_aux_t, heap, vn_ssa_aux_table); @@ -2005,11 +2089,13 @@ free_scc_vn (void) due to ressource constraints. */ bool -run_scc_vn (void) +run_scc_vn (bool may_insert_arg) { size_t i; tree param; + may_insert = may_insert_arg; + init_scc_vn (); current_info = valid_info; @@ -2024,7 +2110,7 @@ run_scc_vn (void) } } - for (i = num_ssa_names - 1; i > 0; i--) + for (i = 1; i < num_ssa_names; ++i) { tree name = ssa_name (i); if (name @@ -2033,6 +2119,7 @@ run_scc_vn (void) if (!DFS (name)) { free_scc_vn (); + may_insert = false; return false; } } @@ -2058,5 +2145,6 @@ run_scc_vn (void) } } + may_insert = false; return true; } |