[PATCH][match-and-simplify] Re-factor code in fold_stmt_1
Richard Biener
rguenther@suse.de
Tue Oct 21 14:01:00 GMT 2014
This refactors the code I added to fold_stmt to dispatch to
pattern-based folding to avoid long lines and make error
handling easier (no goto). It also uses the newly introduced
gimple_seq_discard to properly discard an unused simplification
result.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
This piece will land in trunk with the next merge piece.
Richard.
2014-10-21 Richard Biener <rguenther@suse.de>
* gimple-fold.c (replace_stmt_with_simplification): New helper
split out from ...
(fold_stmt_1): ... here. Discard the simplified sequence if
replacement failed.
Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c (revision 216505)
+++ gcc/gimple-fold.c (working copy)
@@ -2794,6 +2794,121 @@ gimple_fold_call (gimple_stmt_iterator *
return changed;
}
+
+/* Worker for fold_stmt_1 dispatch to pattern based folding with
+ gimple_simplify.
+
+ Replaces *GSI with the simplification result in RCODE and OPS
+ and the associated statements in *SEQ. Does the replacement
+ according to INPLACE and returns true if the operation succeeded. */
+
+static bool
+replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
+ code_helper rcode, tree *ops,
+ gimple_seq *seq, bool inplace)
+{
+ gimple stmt = gsi_stmt (*gsi);
+
+ /* Play safe and do not allow abnormals to be mentioned in
+ newly created statements. See also maybe_push_res_to_seq. */
+ if ((TREE_CODE (ops[0]) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
+ || (ops[1]
+ && TREE_CODE (ops[1]) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
+ || (ops[2]
+ && TREE_CODE (ops[2]) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
+ return false;
+
+ if (gimple_code (stmt) == GIMPLE_COND)
+ {
+ gcc_assert (rcode.is_tree_code ());
+ if (TREE_CODE_CLASS ((enum tree_code)rcode) == tcc_comparison
+ /* GIMPLE_CONDs condition may not throw. */
+ && (!flag_exceptions
+ || !cfun->can_throw_non_call_exceptions
+ || !operation_could_trap_p (rcode,
+ FLOAT_TYPE_P (TREE_TYPE (ops[0])),
+ false, NULL_TREE)))
+ gimple_cond_set_condition (stmt, rcode, ops[0], ops[1]);
+ else if (rcode == SSA_NAME)
+ gimple_cond_set_condition (stmt, NE_EXPR, ops[0],
+ build_zero_cst (TREE_TYPE (ops[0])));
+ else if (rcode == INTEGER_CST)
+ {
+ if (integer_zerop (ops[0]))
+ gimple_cond_make_false (stmt);
+ else
+ gimple_cond_make_true (stmt);
+ }
+ else if (!inplace)
+ {
+ tree res = maybe_push_res_to_seq (rcode, boolean_type_node,
+ ops, seq);
+ if (!res)
+ return false;
+ gimple_cond_set_condition (stmt, NE_EXPR, res,
+ build_zero_cst (TREE_TYPE (res)));
+ }
+ else
+ return false;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "gimple_simplified to ");
+ if (!gimple_seq_empty_p (*seq))
+ print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
+ print_gimple_stmt (dump_file, gsi_stmt (*gsi),
+ 0, TDF_SLIM);
+ }
+ gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
+ return true;
+ }
+ else if (is_gimple_assign (stmt)
+ && rcode.is_tree_code ())
+ {
+ if (!inplace
+ || gimple_num_ops (stmt) <= get_gimple_rhs_num_ops (rcode))
+ {
+ maybe_build_generic_op (rcode,
+ TREE_TYPE (gimple_assign_lhs (stmt)),
+ &ops[0], ops[1], ops[2]);
+ gimple_assign_set_rhs_with_ops_1 (gsi, rcode,
+ ops[0], ops[1], ops[2]);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "gimple_simplified to ");
+ if (!gimple_seq_empty_p (*seq))
+ print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
+ print_gimple_stmt (dump_file, gsi_stmt (*gsi),
+ 0, TDF_SLIM);
+ }
+ gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
+ return true;
+ }
+ }
+ else if (!inplace)
+ {
+ if (gimple_has_lhs (stmt))
+ {
+ tree lhs = gimple_get_lhs (stmt);
+ maybe_push_res_to_seq (rcode, TREE_TYPE (lhs),
+ ops, seq, lhs);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "gimple_simplified to ");
+ print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
+ }
+ gsi_replace_with_seq_vops (gsi, *seq);
+ return true;
+ }
+ else
+ gcc_unreachable ();
+ }
+
+ return false;
+}
+
/* Canonicalize MEM_REFs invariant address operand after propagation. */
static bool
@@ -2959,9 +3074,6 @@ fold_stmt_1 (gimple_stmt_iterator *gsi,
}
/* Dispatch to pattern-based folding. */
- /* ??? Change "inplace" semantics to allow replacing a stmt if
- no further stmts need to be inserted (basically disallow
- creating of new SSA names). */
if (!inplace
|| is_gimple_assign (stmt)
|| gimple_code (stmt) == GIMPLE_COND)
@@ -2971,108 +3083,10 @@ fold_stmt_1 (gimple_stmt_iterator *gsi,
tree ops[3] = {};
if (gimple_simplify (stmt, &rcode, ops, inplace ? NULL : &seq, valueize))
{
- if (gimple_code (stmt) == GIMPLE_COND)
- {
- gcc_assert (rcode.is_tree_code ());
- if (TREE_CODE_CLASS ((enum tree_code)rcode) == tcc_comparison
- /* GIMPLE_CONDs condition may not throw. */
- /* ??? Not sure how we want to deal with combining
- from possibly throwing statements. Trivial
- simplifications may lead to DCEing an internal
- throw. But we probably still want to simplify
- things to a constant for example? Similar to
- abnormals we could discard the simplification
- result if we ever push a could-throw stmt to
- the sequence. */
- && (!flag_exceptions
- || !cfun->can_throw_non_call_exceptions
- || !operation_could_trap_p (rcode, FLOAT_TYPE_P (TREE_TYPE (ops[0])), false, NULL_TREE)))
- gimple_cond_set_condition (stmt, rcode, ops[0], ops[1]);
- else if (rcode == SSA_NAME)
- gimple_cond_set_condition (stmt, NE_EXPR, ops[0],
- build_zero_cst (TREE_TYPE (ops[0])));
- else if (rcode == INTEGER_CST)
- {
- if (integer_zerop (ops[0]))
- gimple_cond_make_false (stmt);
- else
- gimple_cond_make_true (stmt);
- }
- else if (!inplace)
- {
- tree res = maybe_push_res_to_seq (rcode, boolean_type_node,
- ops, &seq);
- if (!res)
- goto fail;
- gimple_cond_set_condition (stmt, NE_EXPR, res,
- build_zero_cst (TREE_TYPE (res)));
- }
- else
- goto fail;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "gimple_simplified to ");
- if (!gimple_seq_empty_p (seq))
- print_gimple_seq (dump_file, seq, 0, TDF_SLIM);
- print_gimple_stmt (dump_file, gsi_stmt (*gsi),
- 0, TDF_SLIM);
- }
- gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
- changed = true;
-fail:
- ;
- }
- else if (is_gimple_assign (stmt)
- && rcode.is_tree_code ())
- {
- if ((!inplace
- || gimple_num_ops (stmt) <= get_gimple_rhs_num_ops (rcode))
- /* Play safe and do not allow abnormals to be mentioned in
- newly created statements. */
- && !((TREE_CODE (ops[0]) == SSA_NAME
- && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
- || (ops[1]
- && TREE_CODE (ops[1]) == SSA_NAME
- && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
- || (ops[2]
- && TREE_CODE (ops[2]) == SSA_NAME
- && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2]))))
- {
- maybe_build_generic_op (rcode,
- TREE_TYPE (gimple_assign_lhs (stmt)),
- &ops[0], ops[1], ops[2]);
- gimple_assign_set_rhs_with_ops_1 (gsi, rcode,
- ops[0], ops[1], ops[2]);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "gimple_simplified to ");
- if (!gimple_seq_empty_p (seq))
- print_gimple_seq (dump_file, seq, 0, TDF_SLIM);
- print_gimple_stmt (dump_file, gsi_stmt (*gsi),
- 0, TDF_SLIM);
- }
- gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
- changed = true;
- }
- }
- else if (!inplace)
- {
- if (gimple_has_lhs (stmt))
- {
- tree lhs = gimple_get_lhs (stmt);
- maybe_push_res_to_seq (rcode, TREE_TYPE (lhs),
- ops, &seq, lhs);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "gimple_simplified to ");
- print_gimple_seq (dump_file, seq, 0, TDF_SLIM);
- }
- gsi_replace_with_seq_vops (gsi, seq);
- changed = true;
- }
- else
- gcc_unreachable ();
- }
+ if (replace_stmt_with_simplification (gsi, rcode, ops, &seq, inplace))
+ changed = true;
+ else
+ gimple_seq_discard (seq);
}
}
More information about the Gcc-patches
mailing list