* [PATCH][match-and-simplify] Enable simplifying of GIMPLE_CONDs
@ 2014-09-15 11:38 Richard Biener
0 siblings, 0 replies; only message in thread
From: Richard Biener @ 2014-09-15 11:38 UTC (permalink / raw)
To: gcc-patches
To get desired transforms from tree-ssa-forwprop.c which uses
fold_stmt.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard.
2014-09-15 Richard Biener <rguenther@suse.de>
* gimple-fold.c: Include tree-eh.c.
(fold_stmt_1): Handle GIMPLE_CONDs for gimple_simplify.
* gimple-match-head.c (gimple_simplify): Likewise.
* match-comparison.pd (bool != 0): Avoid some churn on
GIMPLE and amend comment.
Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c (revision 215212)
+++ gcc/gimple-fold.c (working copy)
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.
#include "dbgcnt.h"
#include "builtins.h"
#include "output.h"
+#include "tree-eh.h"
#include "gimple-match.h"
@@ -2881,15 +2882,67 @@ fold_stmt_1 (gimple_stmt_iterator *gsi,
no further stmts need to be inserted (basically disallow
creating of new SSA names). */
if (!inplace
- || is_gimple_assign (stmt))
+ || is_gimple_assign (stmt)
+ || gimple_code (stmt) == GIMPLE_COND)
{
gimple_seq seq = NULL;
code_helper rcode;
tree ops[3] = {};
if (gimple_simplify (stmt, &rcode, ops, inplace ? NULL : &seq, valueize))
{
- if (is_gimple_assign (stmt)
- && rcode.is_tree_code ())
+ 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))
Index: gcc/gimple-match-head.c
===================================================================
--- gcc/gimple-match-head.c (revision 215212)
+++ gcc/gimple-match-head.c (working copy)
@@ -573,213 +573,244 @@ gimple_simplify (gimple stmt,
code_helper *rcode, tree *ops,
gimple_seq *seq, tree (*valueize)(tree))
{
- if (is_gimple_assign (stmt))
+ switch (gimple_code (stmt))
{
- enum tree_code code = gimple_assign_rhs_code (stmt);
- tree type = TREE_TYPE (gimple_assign_lhs (stmt));
- switch (gimple_assign_rhs_class (stmt))
- {
- case GIMPLE_SINGLE_RHS:
- if (code == REALPART_EXPR
- || code == IMAGPART_EXPR
- || code == VIEW_CONVERT_EXPR)
+ case GIMPLE_ASSIGN:
+ {
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+ tree type = TREE_TYPE (gimple_assign_lhs (stmt));
+ switch (gimple_assign_rhs_class (stmt))
+ {
+ case GIMPLE_SINGLE_RHS:
+ if (code == REALPART_EXPR
+ || code == IMAGPART_EXPR
+ || code == VIEW_CONVERT_EXPR)
+ {
+ tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
+ if (valueize && TREE_CODE (op0) == SSA_NAME)
+ {
+ op0 = valueize (op0);
+ if (!op0)
+ return false;
+ }
+ *rcode = code;
+ ops[0] = op0;
+ return gimple_resimplify1 (seq, rcode, type, ops, valueize);
+ }
+ else if (code == BIT_FIELD_REF)
+ {
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ tree op0 = TREE_OPERAND (rhs1, 0);
+ if (valueize && TREE_CODE (op0) == SSA_NAME)
+ {
+ op0 = valueize (op0);
+ if (!op0)
+ return false;
+ }
+ *rcode = code;
+ ops[0] = op0;
+ ops[1] = TREE_OPERAND (rhs1, 1);
+ ops[2] = TREE_OPERAND (rhs1, 2);
+ return gimple_resimplify3 (seq, rcode, type, ops, valueize);
+ }
+ else if (code == SSA_NAME
+ && valueize)
+ {
+ tree op0 = gimple_assign_rhs1 (stmt);
+ tree valueized = valueize (op0);
+ if (!valueized || op0 == valueized)
+ return false;
+ ops[0] = valueized;
+ *rcode = TREE_CODE (op0);
+ return true;
+ }
+ break;
+ case GIMPLE_UNARY_RHS:
{
- tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
- if (valueize && TREE_CODE (op0) == SSA_NAME)
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ if (valueize && TREE_CODE (rhs1) == SSA_NAME)
{
- op0 = valueize (op0);
- if (!op0)
+ rhs1 = valueize (rhs1);
+ if (!rhs1)
return false;
}
*rcode = code;
- ops[0] = op0;
+ ops[0] = rhs1;
return gimple_resimplify1 (seq, rcode, type, ops, valueize);
}
- else if (code == BIT_FIELD_REF)
+ case GIMPLE_BINARY_RHS:
{
tree rhs1 = gimple_assign_rhs1 (stmt);
- tree op0 = TREE_OPERAND (rhs1, 0);
- if (valueize && TREE_CODE (op0) == SSA_NAME)
+ if (valueize && TREE_CODE (rhs1) == SSA_NAME)
{
- op0 = valueize (op0);
- if (!op0)
+ rhs1 = valueize (rhs1);
+ if (!rhs1)
+ return false;
+ }
+ tree rhs2 = gimple_assign_rhs2 (stmt);
+ if (valueize && TREE_CODE (rhs2) == SSA_NAME)
+ {
+ rhs2 = valueize (rhs2);
+ if (!rhs2)
return false;
}
*rcode = code;
- ops[0] = op0;
- ops[1] = TREE_OPERAND (rhs1, 1);
- ops[2] = TREE_OPERAND (rhs1, 2);
- return gimple_resimplify3 (seq, rcode, type, ops, valueize);
+ ops[0] = rhs1;
+ ops[1] = rhs2;
+ return gimple_resimplify2 (seq, rcode, type, ops, valueize);
}
- else if (code == SSA_NAME
- && valueize)
+ case GIMPLE_TERNARY_RHS:
{
- tree op0 = gimple_assign_rhs1 (stmt);
- tree valueized = valueize (op0);
- if (!valueized || op0 == valueized)
- return false;
- ops[0] = valueized;
- *rcode = TREE_CODE (op0);
- return true;
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ if (valueize && TREE_CODE (rhs1) == SSA_NAME)
+ {
+ rhs1 = valueize (rhs1);
+ if (!rhs1)
+ return false;
+ }
+ tree rhs2 = gimple_assign_rhs2 (stmt);
+ if (valueize && TREE_CODE (rhs2) == SSA_NAME)
+ {
+ rhs2 = valueize (rhs2);
+ if (!rhs2)
+ return false;
+ }
+ tree rhs3 = gimple_assign_rhs3 (stmt);
+ if (valueize && TREE_CODE (rhs3) == SSA_NAME)
+ {
+ rhs3 = valueize (rhs3);
+ if (!rhs3)
+ return false;
+ }
+ *rcode = code;
+ ops[0] = rhs1;
+ ops[1] = rhs2;
+ ops[2] = rhs3;
+ return gimple_resimplify3 (seq, rcode, type, ops, valueize);
}
- break;
- case GIMPLE_UNARY_RHS:
- {
- tree rhs1 = gimple_assign_rhs1 (stmt);
- if (valueize && TREE_CODE (rhs1) == SSA_NAME)
- {
- rhs1 = valueize (rhs1);
- if (!rhs1)
- return false;
- }
- *rcode = code;
- ops[0] = rhs1;
- return gimple_resimplify1 (seq, rcode, type, ops, valueize);
- }
- case GIMPLE_BINARY_RHS:
- {
- tree rhs1 = gimple_assign_rhs1 (stmt);
- if (valueize && TREE_CODE (rhs1) == SSA_NAME)
- {
- rhs1 = valueize (rhs1);
- if (!rhs1)
- return false;
- }
- tree rhs2 = gimple_assign_rhs2 (stmt);
- if (valueize && TREE_CODE (rhs2) == SSA_NAME)
- {
- rhs2 = valueize (rhs2);
- if (!rhs2)
- return false;
- }
- *rcode = code;
- ops[0] = rhs1;
- ops[1] = rhs2;
- return gimple_resimplify2 (seq, rcode, type, ops, valueize);
- }
- case GIMPLE_TERNARY_RHS:
- {
- tree rhs1 = gimple_assign_rhs1 (stmt);
- if (valueize && TREE_CODE (rhs1) == SSA_NAME)
- {
- rhs1 = valueize (rhs1);
- if (!rhs1)
- return false;
- }
- tree rhs2 = gimple_assign_rhs2 (stmt);
- if (valueize && TREE_CODE (rhs2) == SSA_NAME)
- {
- rhs2 = valueize (rhs2);
- if (!rhs2)
- return false;
- }
- tree rhs3 = gimple_assign_rhs3 (stmt);
- if (valueize && TREE_CODE (rhs3) == SSA_NAME)
- {
- rhs3 = valueize (rhs3);
- if (!rhs3)
- return false;
- }
- *rcode = code;
- ops[0] = rhs1;
- ops[1] = rhs2;
- ops[2] = rhs3;
- return gimple_resimplify3 (seq, rcode, type, ops, valueize);
+ default:
+ gcc_unreachable ();
}
- default:
- gcc_unreachable ();
- }
- }
- else if (is_gimple_call (stmt)
- /* ??? This way we can't simplify calls with side-effects. */
- && gimple_call_lhs (stmt) != NULL_TREE)
- {
- tree fn = gimple_call_fn (stmt);
- /* ??? Internal function support missing. */
- if (!fn)
- return false;
- if (TREE_CODE (fn) == SSA_NAME
- && valueize)
- fn = valueize (fn);
- if (!fn
- || TREE_CODE (fn) != ADDR_EXPR
- || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL
- || DECL_BUILT_IN_CLASS (TREE_OPERAND (fn, 0)) != BUILT_IN_NORMAL
- || !builtin_decl_implicit (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0)))
- || !gimple_builtin_call_types_compatible_p (stmt,
- TREE_OPERAND (fn, 0)))
- return false;
+ break;
+ }
- tree decl = TREE_OPERAND (fn, 0);
- tree type = TREE_TYPE (gimple_call_lhs (stmt));
- switch (gimple_call_num_args (stmt))
+ case GIMPLE_CALL:
+ /* ??? This way we can't simplify calls with side-effects. */
+ if (gimple_call_lhs (stmt) != NULL_TREE)
{
- case 1:
- {
- tree arg1 = gimple_call_arg (stmt, 0);
- if (valueize && TREE_CODE (arg1) == SSA_NAME)
- {
- arg1 = valueize (arg1);
- if (!arg1)
- return false;
- }
- *rcode = DECL_FUNCTION_CODE (decl);
- ops[0] = arg1;
- return gimple_resimplify1 (seq, rcode, type, ops, valueize);
- }
- case 2:
- {
- tree arg1 = gimple_call_arg (stmt, 0);
- if (valueize && TREE_CODE (arg1) == SSA_NAME)
- {
- arg1 = valueize (arg1);
- if (!arg1)
- return false;
- }
- tree arg2 = gimple_call_arg (stmt, 1);
- if (valueize && TREE_CODE (arg2) == SSA_NAME)
- {
- arg2 = valueize (arg2);
- if (!arg2)
- return false;
- }
- *rcode = DECL_FUNCTION_CODE (decl);
- ops[0] = arg1;
- ops[1] = arg2;
- return gimple_resimplify2 (seq, rcode, type, ops, valueize);
- }
- case 3:
- {
- tree arg1 = gimple_call_arg (stmt, 0);
- if (valueize && TREE_CODE (arg1) == SSA_NAME)
- {
- arg1 = valueize (arg1);
- if (!arg1)
- return false;
- }
- tree arg2 = gimple_call_arg (stmt, 1);
- if (valueize && TREE_CODE (arg2) == SSA_NAME)
- {
- arg2 = valueize (arg2);
- if (!arg2)
- return false;
- }
- tree arg3 = gimple_call_arg (stmt, 2);
- if (valueize && TREE_CODE (arg3) == SSA_NAME)
+ tree fn = gimple_call_fn (stmt);
+ /* ??? Internal function support missing. */
+ if (!fn)
+ return false;
+ if (TREE_CODE (fn) == SSA_NAME
+ && valueize)
+ fn = valueize (fn);
+ if (!fn
+ || TREE_CODE (fn) != ADDR_EXPR
+ || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL
+ || DECL_BUILT_IN_CLASS (TREE_OPERAND (fn, 0)) != BUILT_IN_NORMAL
+ || !builtin_decl_implicit (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0)))
+ || !gimple_builtin_call_types_compatible_p (stmt,
+ TREE_OPERAND (fn, 0)))
+ return false;
+
+ tree decl = TREE_OPERAND (fn, 0);
+ tree type = TREE_TYPE (gimple_call_lhs (stmt));
+ switch (gimple_call_num_args (stmt))
+ {
+ case 1:
{
- arg3 = valueize (arg3);
- if (!arg3)
- return false;
+ tree arg1 = gimple_call_arg (stmt, 0);
+ if (valueize && TREE_CODE (arg1) == SSA_NAME)
+ {
+ arg1 = valueize (arg1);
+ if (!arg1)
+ return false;
+ }
+ *rcode = DECL_FUNCTION_CODE (decl);
+ ops[0] = arg1;
+ return gimple_resimplify1 (seq, rcode, type, ops, valueize);
+ }
+ case 2:
+ {
+ tree arg1 = gimple_call_arg (stmt, 0);
+ if (valueize && TREE_CODE (arg1) == SSA_NAME)
+ {
+ arg1 = valueize (arg1);
+ if (!arg1)
+ return false;
+ }
+ tree arg2 = gimple_call_arg (stmt, 1);
+ if (valueize && TREE_CODE (arg2) == SSA_NAME)
+ {
+ arg2 = valueize (arg2);
+ if (!arg2)
+ return false;
+ }
+ *rcode = DECL_FUNCTION_CODE (decl);
+ ops[0] = arg1;
+ ops[1] = arg2;
+ return gimple_resimplify2 (seq, rcode, type, ops, valueize);
+ }
+ case 3:
+ {
+ tree arg1 = gimple_call_arg (stmt, 0);
+ if (valueize && TREE_CODE (arg1) == SSA_NAME)
+ {
+ arg1 = valueize (arg1);
+ if (!arg1)
+ return false;
+ }
+ tree arg2 = gimple_call_arg (stmt, 1);
+ if (valueize && TREE_CODE (arg2) == SSA_NAME)
+ {
+ arg2 = valueize (arg2);
+ if (!arg2)
+ return false;
+ }
+ tree arg3 = gimple_call_arg (stmt, 2);
+ if (valueize && TREE_CODE (arg3) == SSA_NAME)
+ {
+ arg3 = valueize (arg3);
+ if (!arg3)
+ return false;
+ }
+ *rcode = DECL_FUNCTION_CODE (decl);
+ ops[0] = arg1;
+ ops[1] = arg2;
+ ops[2] = arg3;
+ return gimple_resimplify3 (seq, rcode, type, ops, valueize);
}
- *rcode = DECL_FUNCTION_CODE (decl);
- ops[0] = arg1;
- ops[1] = arg2;
- ops[2] = arg3;
- return gimple_resimplify3 (seq, rcode, type, ops, valueize);
- }
- default:
- return false;
+ default:
+ return false;
+ }
}
+ break;
+
+ case GIMPLE_COND:
+ {
+ tree lhs = gimple_cond_lhs (stmt);
+ if (valueize && TREE_CODE (lhs) == SSA_NAME)
+ {
+ lhs = valueize (lhs);
+ if (!lhs)
+ return false;
+ }
+ tree rhs = gimple_cond_rhs (stmt);
+ if (valueize && TREE_CODE (rhs) == SSA_NAME)
+ {
+ rhs = valueize (rhs);
+ if (!rhs)
+ return false;
+ }
+ *rcode = gimple_cond_code (stmt);
+ ops[0] = lhs;
+ ops[1] = rhs;
+ return gimple_resimplify2 (seq, rcode, boolean_type_node, ops, valueize);
+ }
+
+ default:
+ break;
}
return false;
Index: gcc/match-comparison.pd
===================================================================
--- gcc/match-comparison.pd (revision 215212)
+++ gcc/match-comparison.pd (working copy)
@@ -1,10 +1,18 @@
/* From fold_binary. */
+/* On GIMPLE bool != 0 is simply the canonical way to express a
+ condition in COND_EXPRs and GIMPLE_CONDs.
+ ??? Of course for assignments we still may want to strip those... */
(simplify
(ne @0 integer_zerop@1)
(if (TREE_CODE (TREE_TYPE (@0)) == BOOLEAN_TYPE)
- /* ??? In GENERIC the type of the comparison may be 'int'. */
- (convert @0)))
+ /* On GENERIC comparisons can have arbitrary integer types. */
+ (if (GENERIC)
+ (convert @0))
+ /* On GIMPLE boolean types may have a precision != 1 thus the
+ comparison serves as a more canonical required conversion. */
+ (if (GIMPLE && useless_type_conversion_p (type, TREE_TYPE (@0)))
+ @0)))
/* Distribute operations in equality compares. */
(for op (eq ne)
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2014-09-15 11:38 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-15 11:38 [PATCH][match-and-simplify] Enable simplifying of GIMPLE_CONDs Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).