aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-10-01 07:54:26 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-10-01 07:54:26 +0000
commit34050b6bee181a12099a9bc31a4d25469573bc6d (patch)
tree84b464b97cc715dd2e30f73f4fc420d296b60500 /gcc
parente01c66ca3083cf998d7e2f568ff6227f86727499 (diff)
downloadgcc-34050b6bee181a12099a9bc31a4d25469573bc6d.zip
gcc-34050b6bee181a12099a9bc31a4d25469573bc6d.tar.gz
gcc-34050b6bee181a12099a9bc31a4d25469573bc6d.tar.bz2
gimple-match.h (mprts_hook): Declare.
2015-10-01 Richard Biener <rguenther@suse.de> * gimple-match.h (mprts_hook): Declare. * gimple-match.head.c (mprts_hook): Define. (maybe_push_res_to_seq): Use new hook. * gimple-fold.c (gimple_fold_stmt_to_constant_1): Likewise. * tree-ssa-sccvn.h (vn_ssa_aux::expr): Change to a gimple_seq. (vn_ssa_aux::has_constants): Remove. * tree-ssa-sccvn.c: Include gimple-match.h. (VN_INFO_GET): Assert we don't re-use SSA names. (vn_get_expr_for): Remove. (expr_has_constants): Likewise. (stmt_has_constants): Likewise. (simplify_binary_expression): Likewise. (simplify_unary_expression): Likewise. (vn_lookup_simplify_result): New hook. (visit_copy): Adjust. (visit_reference_op_call): Likewise. (visit_phi): Likewise. (visit_use): Likewise. (process_scc): Likewise. (init_scc_vn): Likewise. (visit_reference_op_load): Likewise. Use match-and-simplify and a gimple seq for inserted expressions. (try_to_simplify): Remove GENERIC stmt combining code. (sccvn_dom_walker::before_dom_children): Use match-and-simplify. * tree-ssa-pre.c (eliminate_insert): Adjust. (eliminate_dom_walker::before_dom_children): Likewise. * gcc.dg/tree-ssa/ssa-fre-7.c: Adjust. * gcc.dg/tree-ssa/ssa-fre-8.c: Likewise. From-SVN: r228320
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog29
-rw-r--r--gcc/gimple-fold.c34
-rw-r--r--gcc/gimple-match-head.c8
-rw-r--r--gcc/gimple-match.h2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c4
-rw-r--r--gcc/tree-ssa-pre.c24
-rw-r--r--gcc/tree-ssa-sccvn.c483
-rw-r--r--gcc/tree-ssa-sccvn.h6
10 files changed, 148 insertions, 451 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d50f991..122f3b4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,32 @@
+2015-10-01 Richard Biener <rguenther@suse.de>
+
+ * gimple-match.h (mprts_hook): Declare.
+ * gimple-match.head.c (mprts_hook): Define.
+ (maybe_push_res_to_seq): Use new hook.
+ * gimple-fold.c (gimple_fold_stmt_to_constant_1): Likewise.
+ * tree-ssa-sccvn.h (vn_ssa_aux::expr): Change to a gimple_seq.
+ (vn_ssa_aux::has_constants): Remove.
+ * tree-ssa-sccvn.c: Include gimple-match.h.
+ (VN_INFO_GET): Assert we don't re-use SSA names.
+ (vn_get_expr_for): Remove.
+ (expr_has_constants): Likewise.
+ (stmt_has_constants): Likewise.
+ (simplify_binary_expression): Likewise.
+ (simplify_unary_expression): Likewise.
+ (vn_lookup_simplify_result): New hook.
+ (visit_copy): Adjust.
+ (visit_reference_op_call): Likewise.
+ (visit_phi): Likewise.
+ (visit_use): Likewise.
+ (process_scc): Likewise.
+ (init_scc_vn): Likewise.
+ (visit_reference_op_load): Likewise. Use match-and-simplify and
+ a gimple seq for inserted expressions.
+ (try_to_simplify): Remove GENERIC stmt combining code.
+ (sccvn_dom_walker::before_dom_children): Use match-and-simplify.
+ * tree-ssa-pre.c (eliminate_insert): Adjust.
+ (eliminate_dom_walker::before_dom_children): Likewise.
+
2015-10-01 Segher Boessenkool <segher@kernel.crashing.org>
* doc/invoke.texi (Optimization Options): Add
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 51309f2..9f5e4e9 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -4877,22 +4877,28 @@ gimple_fold_stmt_to_constant_1 (gimple *stmt, tree (*valueize) (tree),
edges if there are intermediate VARYING defs. For this reason
do not follow SSA edges here even though SCCVN can technically
just deal fine with that. */
- if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize, valueize)
- && rcode.is_tree_code ()
- && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
- || ((tree_code) rcode) == ADDR_EXPR)
- && is_gimple_val (ops[0]))
- {
- tree res = ops[0];
- if (dump_file && dump_flags & TDF_DETAILS)
+ if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize, valueize))
+ {
+ tree res = NULL_TREE;
+ if (rcode.is_tree_code ()
+ && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
+ || ((tree_code) rcode) == ADDR_EXPR)
+ && is_gimple_val (ops[0]))
+ res = ops[0];
+ else if (mprts_hook)
+ res = mprts_hook (rcode, gimple_expr_type (stmt), ops);
+ if (res)
{
- fprintf (dump_file, "Match-and-simplified ");
- print_gimple_expr (dump_file, stmt, 0, TDF_SLIM);
- fprintf (dump_file, " to ");
- print_generic_expr (dump_file, res, 0);
- fprintf (dump_file, "\n");
+ if (dump_file && dump_flags & TDF_DETAILS)
+ {
+ fprintf (dump_file, "Match-and-simplified ");
+ print_gimple_expr (dump_file, stmt, 0, TDF_SLIM);
+ fprintf (dump_file, " to ");
+ print_generic_expr (dump_file, res, 0);
+ fprintf (dump_file, "\n");
+ }
+ return res;
}
- return res;
}
location_t loc = gimple_location (stmt);
diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c
index 0587ce1..cab77a4 100644
--- a/gcc/gimple-match-head.c
+++ b/gcc/gimple-match-head.c
@@ -293,6 +293,8 @@ maybe_build_generic_op (enum tree_code code, tree type,
}
}
+tree (*mprts_hook) (code_helper, tree, tree *);
+
/* Push the exploded expression described by RCODE, TYPE and OPS
as a statement to SEQ if necessary and return a gimple value
denoting the value of the expression. If RES is not NULL
@@ -310,6 +312,12 @@ maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops,
|| ((tree_code) rcode) == ADDR_EXPR)
&& is_gimple_val (ops[0]))
return ops[0];
+ if (mprts_hook)
+ {
+ tree tem = mprts_hook (rcode, type, ops);
+ if (tem)
+ return tem;
+ }
if (!seq)
return NULL_TREE;
/* Play safe and do not allow abnormals to be mentioned in
diff --git a/gcc/gimple-match.h b/gcc/gimple-match.h
index 9e58755..4663a34 100644
--- a/gcc/gimple-match.h
+++ b/gcc/gimple-match.h
@@ -40,6 +40,8 @@ private:
int rep;
};
+extern tree (*mprts_hook) (code_helper, tree, tree *);
+
bool gimple_simplify (gimple *, code_helper *, tree *, gimple_seq *,
tree (*)(tree), tree (*)(tree));
tree maybe_push_res_to_seq (code_helper, tree, tree *,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 46f355a..a8a3481 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-10-01 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/ssa-fre-7.c: Adjust.
+ * gcc.dg/tree-ssa/ssa-fre-8.c: Likewise.
+
2015-09-30 Jeff Law <law@redhat.com>
* gcc.dg/tree-ssa/ssa-dom-branch-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c
index 9a555f1..2b23531 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c
@@ -29,8 +29,8 @@ intflt foo(intflt j)
return a.u.k;
}
-/* { dg-final { scan-tree-dump-times "Inserted pretmp" 1 "fre1" } } */
-/* { dg-final { scan-tree-dump-times "Replaced a.u.f with pretmp" 3 "fre1" } } */
+/* { dg-final { scan-tree-dump-times "Inserted" 1 "fre1" } } */
+/* { dg-final { scan-tree-dump-times "Replaced a.u.f with" 3 "fre1" } } */
/* { dg-final { scan-tree-dump-times "Replaced a.u.k with j" 1 "fre1" } } */
/* { dg-final { scan-tree-dump "= VIEW_CONVERT_EXPR<float>\\\(j_" "fre1" } } */
/* { dg-final { scan-tree-dump "return j" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c
index c04f699..1a537d8 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c
@@ -28,5 +28,5 @@ intflt foo(int i, int b)
}
}
-/* { dg-final { scan-tree-dump-times "Replaced u.f with pretmp" 2 "fre1" } } */
-/* { dg-final { scan-tree-dump-times "Inserted pretmp" 2 "fre1" } } */
+/* { dg-final { scan-tree-dump-times "Replaced u.f with" 2 "fre1" } } */
+/* { dg-final { scan-tree-dump-times "Inserted" 2 "fre1" } } */
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index ac298d3..f8feaa1 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -3945,21 +3945,23 @@ eliminate_push_avail (tree op)
static tree
eliminate_insert (gimple_stmt_iterator *gsi, tree val)
{
- tree expr = vn_get_expr_for (val);
- if (!CONVERT_EXPR_P (expr)
- && TREE_CODE (expr) != VIEW_CONVERT_EXPR)
+ gimple *stmt = gimple_seq_first_stmt (VN_INFO (val)->expr);
+ if (!is_gimple_assign (stmt)
+ || (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
+ && gimple_assign_rhs_code (stmt) != VIEW_CONVERT_EXPR))
return NULL_TREE;
- tree op = TREE_OPERAND (expr, 0);
+ tree op = gimple_assign_rhs1 (stmt);
+ if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)
+ op = TREE_OPERAND (op, 0);
tree leader = TREE_CODE (op) == SSA_NAME ? eliminate_avail (op) : op;
if (!leader)
return NULL_TREE;
- tree res = make_temp_ssa_name (TREE_TYPE (val), NULL, "pretmp");
- gassign *tem = gimple_build_assign (res,
- fold_build1 (TREE_CODE (expr),
- TREE_TYPE (expr), leader));
- gsi_insert_before (gsi, tem, GSI_SAME_STMT);
+ gimple_seq stmts = NULL;
+ tree res = gimple_build (&stmts, gimple_assign_rhs_code (stmt),
+ TREE_TYPE (val), leader);
+ gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
VN_INFO_GET (res)->valnum = val;
if (TREE_CODE (leader) == SSA_NAME)
@@ -3969,7 +3971,7 @@ eliminate_insert (gimple_stmt_iterator *gsi, tree val)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Inserted ");
- print_gimple_stmt (dump_file, tem, 0, 0);
+ print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (res), 0, 0);
}
return res;
@@ -4093,7 +4095,7 @@ eliminate_dom_walker::before_dom_children (basic_block b)
if (val != VN_TOP
&& TREE_CODE (val) == SSA_NAME
&& VN_INFO (val)->needs_insertion
- && VN_INFO (val)->expr != NULL_TREE
+ && VN_INFO (val)->expr != NULL
&& (sprime = eliminate_insert (&gsi, val)) != NULL_TREE)
eliminate_push_avail (sprime);
}
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 5b06d29..9db5a7f 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see
#include "domwalk.h"
#include "cgraph.h"
#include "gimple-iterator.h"
+#include "gimple-match.h"
/* This algorithm is based on the SCC algorithm presented by Keith
Cooper and L. Taylor Simpson in "SCC-Based Value numbering"
@@ -391,6 +392,8 @@ VN_INFO_GET (tree name)
{
vn_ssa_aux_t newinfo;
+ gcc_assert (SSA_NAME_VERSION (name) >= vn_ssa_aux_table.length ()
+ || vn_ssa_aux_table[SSA_NAME_VERSION (name)] == NULL);
newinfo = XOBNEW (&vn_ssa_aux_obstack, struct vn_ssa_aux);
memset (newinfo, 0, sizeof (struct vn_ssa_aux));
if (SSA_NAME_VERSION (name) >= vn_ssa_aux_table.length ())
@@ -400,92 +403,6 @@ VN_INFO_GET (tree name)
}
-/* Get the representative expression for the SSA_NAME NAME. Returns
- the representative SSA_NAME if there is no expression associated with it. */
-
-tree
-vn_get_expr_for (tree name)
-{
- vn_ssa_aux_t vn = VN_INFO (name);
- gimple *def_stmt;
- tree expr = NULL_TREE;
- enum tree_code code;
-
- if (vn->valnum == VN_TOP)
- return name;
-
- /* If the value-number is a constant it is the representative
- expression. */
- if (TREE_CODE (vn->valnum) != SSA_NAME)
- return vn->valnum;
-
- /* Get to the information of the value of this SSA_NAME. */
- vn = VN_INFO (vn->valnum);
-
- /* If the value-number is a constant it is the representative
- expression. */
- if (TREE_CODE (vn->valnum) != SSA_NAME)
- return vn->valnum;
-
- /* Else if we have an expression, return it. */
- if (vn->expr != NULL_TREE)
- return vn->expr;
-
- /* Otherwise use the defining statement to build the expression. */
- def_stmt = SSA_NAME_DEF_STMT (vn->valnum);
-
- /* If the value number is not an assignment use it directly. */
- if (!is_gimple_assign (def_stmt))
- return vn->valnum;
-
- /* Note that we can valueize here because we clear the cached
- simplified expressions after each optimistic iteration. */
- code = gimple_assign_rhs_code (def_stmt);
- switch (TREE_CODE_CLASS (code))
- {
- case tcc_reference:
- if ((code == REALPART_EXPR
- || code == IMAGPART_EXPR
- || code == VIEW_CONVERT_EXPR)
- && TREE_CODE (TREE_OPERAND (gimple_assign_rhs1 (def_stmt),
- 0)) == SSA_NAME)
- expr = fold_build1 (code,
- gimple_expr_type (def_stmt),
- vn_valueize (TREE_OPERAND
- (gimple_assign_rhs1 (def_stmt), 0)));
- break;
-
- case tcc_unary:
- expr = fold_build1 (code,
- gimple_expr_type (def_stmt),
- vn_valueize (gimple_assign_rhs1 (def_stmt)));
- break;
-
- case tcc_binary:
- expr = fold_build2 (code,
- gimple_expr_type (def_stmt),
- vn_valueize (gimple_assign_rhs1 (def_stmt)),
- vn_valueize (gimple_assign_rhs2 (def_stmt)));
- break;
-
- case tcc_exceptional:
- if (code == CONSTRUCTOR
- && TREE_CODE
- (TREE_TYPE (gimple_assign_rhs1 (def_stmt))) == VECTOR_TYPE)
- expr = gimple_assign_rhs1 (def_stmt);
- break;
-
- default:;
- }
- if (expr == NULL_TREE)
- return vn->valnum;
-
- /* Cache the expression. */
- vn->expr = expr;
-
- return expr;
-}
-
/* Return the vn_kind the expression computed by the stmt should be
associated with. */
@@ -2629,6 +2546,18 @@ vn_nary_op_lookup_stmt (gimple *stmt, vn_nary_op_t *vnresult)
return vn_nary_op_lookup_1 (vno1, vnresult);
}
+/* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables. */
+
+static tree
+vn_lookup_simplify_result (code_helper rcode, tree type, tree *ops)
+{
+ if (!rcode.is_tree_code ())
+ return NULL_TREE;
+ vn_nary_op_t vnresult = NULL;
+ return vn_nary_op_lookup_pieces (TREE_CODE_LENGTH ((tree_code) rcode),
+ (tree_code) rcode, type, ops, &vnresult);
+}
+
/* Allocate a vn_nary_op_t with LENGTH operands on STACK. */
static vn_nary_op_t
@@ -2991,20 +2920,13 @@ defs_to_varying (gimple *stmt)
return changed;
}
-static bool expr_has_constants (tree expr);
-
/* Visit a copy between LHS and RHS, return true if the value number
changed. */
static bool
visit_copy (tree lhs, tree rhs)
{
- /* The copy may have a more interesting constant filled expression
- (we don't, since we know our RHS is just an SSA name). */
- VN_INFO (lhs)->has_constants = VN_INFO (rhs)->has_constants;
- VN_INFO (lhs)->expr = VN_INFO (rhs)->expr;
-
- /* And finally valueize. */
+ /* Valueize. */
rhs = SSA_VAL (rhs);
return set_ssa_val_to (lhs, rhs);
@@ -3055,12 +2977,7 @@ visit_reference_op_call (tree lhs, gcall *stmt)
vnresult->result = lhs;
if (vnresult->result && lhs)
- {
- changed |= set_ssa_val_to (lhs, vnresult->result);
-
- if (VN_INFO (vnresult->result)->has_constants)
- VN_INFO (lhs)->has_constants = true;
- }
+ changed |= set_ssa_val_to (lhs, vnresult->result);
}
else
{
@@ -3116,33 +3033,38 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt)
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 ((CONVERT_EXPR_P (val)
- || TREE_CODE (val) == VIEW_CONVERT_EXPR)
- && TREE_CODE (TREE_OPERAND (val, 0)) == SSA_NAME)
- {
- tree tem = vn_get_expr_for (TREE_OPERAND (val, 0));
- if ((CONVERT_EXPR_P (tem)
- || TREE_CODE (tem) == VIEW_CONVERT_EXPR)
- && (tem = fold_unary_ignore_overflow (TREE_CODE (val),
- TREE_TYPE (val), tem)))
- val = tem;
+ gimple_seq stmts = NULL;
+ mprts_hook = vn_lookup_simplify_result;
+ tree val = gimple_simplify (VIEW_CONVERT_EXPR, TREE_TYPE (op),
+ result, &stmts, vn_valueize);
+ mprts_hook = NULL;
+ if (!val)
+ {
+ val = vn_nary_op_lookup_pieces (1, VIEW_CONVERT_EXPR,
+ TREE_TYPE (op), &result, NULL);
+ if (!val)
+ {
+ val = make_ssa_name (TREE_TYPE (op));
+ gimple *new_stmt = gimple_build_assign (val, VIEW_CONVERT_EXPR,
+ build1 (VIEW_CONVERT_EXPR,
+ TREE_TYPE (op),
+ result));
+ gimple_seq_add_stmt_without_update (&stmts, new_stmt);
+ }
}
- result = val;
- if (!is_gimple_min_invariant (val)
- && TREE_CODE (val) != SSA_NAME)
- result = vn_nary_op_lookup (val, NULL);
- /* If the expression is not yet available, value-number lhs to
- a new SSA_NAME we create. */
- if (!result)
- {
- result = make_temp_ssa_name (TREE_TYPE (lhs), gimple_build_nop (),
- "vntemp");
+ if (gimple_seq_empty_p (stmts))
+ /* The expression is already available. */
+ result = val;
+ else
+ {
+ gcc_assert (gimple_seq_singleton_p (stmts));
+ /* The expression is not yet available, value-number lhs to
+ the new SSA_NAME we created. */
+ result = val;
/* Initialize value-number information properly. */
VN_INFO_GET (result)->valnum = result;
VN_INFO (result)->value_id = get_next_value_id ();
- VN_INFO (result)->expr = val;
- VN_INFO (result)->has_constants = expr_has_constants (val);
+ VN_INFO (result)->expr = stmts;
VN_INFO (result)->needs_insertion = true;
/* As all "inserted" statements are singleton SCCs, insert
to the valid table. This is strictly needed to
@@ -3154,32 +3076,25 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt)
if (current_info == optimistic_info)
{
current_info = valid_info;
- vn_nary_op_insert (val, result);
+ vn_nary_op_insert_stmt (gimple_seq_first_stmt (stmts), result);
current_info = optimistic_info;
}
else
- vn_nary_op_insert (val, result);
+ vn_nary_op_insert_stmt (gimple_seq_first_stmt (stmts), 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);
+ print_gimple_expr (dump_file, gimple_seq_first_stmt (stmts),
+ 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
}
}
if (result)
- {
- changed = set_ssa_val_to (lhs, result);
- if (TREE_CODE (result) == SSA_NAME
- && VN_INFO (result)->has_constants)
- {
- VN_INFO (lhs)->expr = VN_INFO (result)->expr;
- VN_INFO (lhs)->has_constants = true;
- }
- }
+ changed = set_ssa_val_to (lhs, result);
else
{
changed = set_ssa_val_to (lhs, lhs);
@@ -3346,208 +3261,12 @@ visit_phi (gimple *phi)
else
{
vn_phi_insert (phi, PHI_RESULT (phi));
- VN_INFO (PHI_RESULT (phi))->has_constants = false;
- VN_INFO (PHI_RESULT (phi))->expr = PHI_RESULT (phi);
changed = set_ssa_val_to (PHI_RESULT (phi), PHI_RESULT (phi));
}
return changed;
}
-/* Return true if EXPR contains constants. */
-
-static bool
-expr_has_constants (tree expr)
-{
- switch (TREE_CODE_CLASS (TREE_CODE (expr)))
- {
- case tcc_unary:
- return is_gimple_min_invariant (TREE_OPERAND (expr, 0));
-
- case tcc_binary:
- return is_gimple_min_invariant (TREE_OPERAND (expr, 0))
- || is_gimple_min_invariant (TREE_OPERAND (expr, 1));
- /* Constants inside reference ops are rarely interesting, but
- it can take a lot of looking to find them. */
- case tcc_reference:
- case tcc_declaration:
- return false;
- default:
- return is_gimple_min_invariant (expr);
- }
- return false;
-}
-
-/* Return true if STMT contains constants. */
-
-static bool
-stmt_has_constants (gimple *stmt)
-{
- tree tem;
-
- if (gimple_code (stmt) != GIMPLE_ASSIGN)
- return false;
-
- switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
- {
- case GIMPLE_TERNARY_RHS:
- tem = gimple_assign_rhs3 (stmt);
- if (TREE_CODE (tem) == SSA_NAME)
- tem = SSA_VAL (tem);
- if (is_gimple_min_invariant (tem))
- return true;
- /* Fallthru. */
-
- case GIMPLE_BINARY_RHS:
- tem = gimple_assign_rhs2 (stmt);
- if (TREE_CODE (tem) == SSA_NAME)
- tem = SSA_VAL (tem);
- if (is_gimple_min_invariant (tem))
- return true;
- /* Fallthru. */
-
- case GIMPLE_SINGLE_RHS:
- /* Constants inside reference ops are rarely interesting, but
- it can take a lot of looking to find them. */
- case GIMPLE_UNARY_RHS:
- tem = gimple_assign_rhs1 (stmt);
- if (TREE_CODE (tem) == SSA_NAME)
- tem = SSA_VAL (tem);
- return is_gimple_min_invariant (tem);
-
- default:
- gcc_unreachable ();
- }
- return false;
-}
-
-/* Simplify the binary expression RHS, and return the result if
- simplified. */
-
-static tree
-simplify_binary_expression (gimple *stmt)
-{
- tree result = NULL_TREE;
- tree op0 = gimple_assign_rhs1 (stmt);
- tree op1 = gimple_assign_rhs2 (stmt);
- enum tree_code code = gimple_assign_rhs_code (stmt);
-
- /* This will not catch every single case we could combine, but will
- catch those with constants. The goal here is to simultaneously
- combine constants between expressions, but avoid infinite
- expansion of expressions during simplification. */
- op0 = vn_valueize (op0);
- if (TREE_CODE (op0) == SSA_NAME
- && (VN_INFO (op0)->has_constants
- || TREE_CODE_CLASS (code) == tcc_comparison
- || code == COMPLEX_EXPR))
- op0 = vn_get_expr_for (op0);
-
- op1 = vn_valueize (op1);
- if (TREE_CODE (op1) == SSA_NAME
- && (VN_INFO (op1)->has_constants
- || code == COMPLEX_EXPR))
- op1 = vn_get_expr_for (op1);
-
- /* Pointer plus constant can be represented as invariant address.
- Do so to allow further propatation, see also tree forwprop. */
- if (code == POINTER_PLUS_EXPR
- && tree_fits_uhwi_p (op1)
- && TREE_CODE (op0) == ADDR_EXPR
- && is_gimple_min_invariant (op0))
- return build_invariant_address (TREE_TYPE (op0),
- TREE_OPERAND (op0, 0),
- tree_to_uhwi (op1));
-
- /* Avoid folding if nothing changed. */
- if (op0 == gimple_assign_rhs1 (stmt)
- && op1 == gimple_assign_rhs2 (stmt))
- return NULL_TREE;
-
- fold_defer_overflow_warnings ();
-
- result = fold_binary (code, gimple_expr_type (stmt), op0, op1);
- if (result)
- STRIP_USELESS_TYPE_CONVERSION (result);
-
- fold_undefer_overflow_warnings (result && valid_gimple_rhs_p (result),
- stmt, 0);
-
- /* Make sure result is not a complex expression consisting
- of operators of operators (IE (a + b) + (a + c))
- Otherwise, we will end up with unbounded expressions if
- fold does anything at all. */
- if (result && valid_gimple_rhs_p (result))
- return result;
-
- return NULL_TREE;
-}
-
-/* Simplify the unary expression RHS, and return the result if
- simplified. */
-
-static tree
-simplify_unary_expression (gassign *stmt)
-{
- tree result = NULL_TREE;
- tree orig_op0, op0 = gimple_assign_rhs1 (stmt);
- enum tree_code code = gimple_assign_rhs_code (stmt);
-
- /* We handle some tcc_reference codes here that are all
- GIMPLE_ASSIGN_SINGLE codes. */
- if (code == REALPART_EXPR
- || code == IMAGPART_EXPR
- || code == VIEW_CONVERT_EXPR
- || code == BIT_FIELD_REF)
- op0 = TREE_OPERAND (op0, 0);
-
- orig_op0 = op0;
- op0 = vn_valueize (op0);
- if (TREE_CODE (op0) == SSA_NAME)
- {
- if (VN_INFO (op0)->has_constants)
- op0 = vn_get_expr_for (op0);
- else if (CONVERT_EXPR_CODE_P (code)
- || code == REALPART_EXPR
- || code == IMAGPART_EXPR
- || code == VIEW_CONVERT_EXPR
- || code == BIT_FIELD_REF)
- {
- /* We want to do tree-combining on conversion-like expressions.
- Make sure we feed only SSA_NAMEs or constants to fold though. */
- tree tem = vn_get_expr_for (op0);
- if (UNARY_CLASS_P (tem)
- || BINARY_CLASS_P (tem)
- || TREE_CODE (tem) == VIEW_CONVERT_EXPR
- || TREE_CODE (tem) == SSA_NAME
- || TREE_CODE (tem) == CONSTRUCTOR
- || is_gimple_min_invariant (tem))
- op0 = tem;
- }
- }
-
- /* Avoid folding if nothing changed, but remember the expression. */
- if (op0 == orig_op0)
- return NULL_TREE;
-
- if (code == BIT_FIELD_REF)
- {
- tree rhs = gimple_assign_rhs1 (stmt);
- result = fold_ternary (BIT_FIELD_REF, TREE_TYPE (rhs),
- op0, TREE_OPERAND (rhs, 1), TREE_OPERAND (rhs, 2));
- }
- else
- result = fold_unary_ignore_overflow (code, gimple_expr_type (stmt), op0);
- if (result)
- {
- STRIP_USELESS_TYPE_CONVERSION (result);
- if (valid_gimple_rhs_p (result))
- return result;
- }
-
- return NULL_TREE;
-}
-
/* Try to simplify RHS using equivalences and constant folding. */
static tree
@@ -3562,35 +3281,14 @@ try_to_simplify (gassign *stmt)
return NULL_TREE;
/* First try constant folding based on our current lattice. */
+ mprts_hook = vn_lookup_simplify_result;
tem = gimple_fold_stmt_to_constant_1 (stmt, vn_valueize, vn_valueize);
+ mprts_hook = NULL;
if (tem
&& (TREE_CODE (tem) == SSA_NAME
|| is_gimple_min_invariant (tem)))
return tem;
- /* If that didn't work try combining multiple statements. */
- switch (TREE_CODE_CLASS (code))
- {
- case tcc_reference:
- /* Fallthrough for some unary codes that can operate on registers. */
- if (!(code == REALPART_EXPR
- || code == IMAGPART_EXPR
- || code == VIEW_CONVERT_EXPR
- || code == BIT_FIELD_REF))
- break;
- /* We could do a little more with unary ops, if they expand
- into binary ops, but it's debatable whether it is worth it. */
- case tcc_unary:
- return simplify_unary_expression (stmt);
-
- case tcc_comparison:
- case tcc_binary:
- return simplify_binary_expression (stmt);
-
- default:
- break;
- }
-
return NULL_TREE;
}
@@ -3648,11 +3346,7 @@ visit_use (tree use)
print_gimple_expr (dump_file, stmt, 0, 0);
fprintf (dump_file, " simplified to ");
print_generic_expr (dump_file, simplified, 0);
- if (TREE_CODE (lhs) == SSA_NAME)
- fprintf (dump_file, " has constants %d\n",
- expr_has_constants (simplified));
- else
- fprintf (dump_file, "\n");
+ fprintf (dump_file, "\n");
}
}
/* Setting value numbers to constants will occasionally
@@ -3663,8 +3357,6 @@ visit_use (tree use)
&& is_gimple_min_invariant (simplified)
&& TREE_CODE (lhs) == SSA_NAME)
{
- VN_INFO (lhs)->expr = simplified;
- VN_INFO (lhs)->has_constants = true;
changed = set_ssa_val_to (lhs, simplified);
goto done;
}
@@ -3675,29 +3367,6 @@ visit_use (tree use)
changed = visit_copy (lhs, simplified);
goto done;
}
- else if (simplified)
- {
- if (TREE_CODE (lhs) == SSA_NAME)
- {
- VN_INFO (lhs)->has_constants = expr_has_constants (simplified);
- /* We have to unshare the expression or else
- valuizing may change the IL stream. */
- VN_INFO (lhs)->expr = unshare_expr (simplified);
- }
- }
- else if (stmt_has_constants (stmt)
- && TREE_CODE (lhs) == SSA_NAME)
- VN_INFO (lhs)->has_constants = true;
- else if (TREE_CODE (lhs) == SSA_NAME)
- {
- /* We reset expr and constantness here because we may
- have been value numbering optimistically, and
- iterating. They may become non-constant in this case,
- even if they were optimistically constant. */
-
- VN_INFO (lhs)->has_constants = false;
- VN_INFO (lhs)->expr = NULL_TREE;
- }
if ((TREE_CODE (lhs) == SSA_NAME
/* We can substitute SSA_NAMEs that are live over
@@ -3722,7 +3391,6 @@ visit_use (tree use)
|| (simplified
&& is_gimple_min_invariant (simplified)))
{
- VN_INFO (lhs)->has_constants = true;
if (simplified)
changed = set_ssa_val_to (lhs, simplified);
else
@@ -3785,11 +3453,7 @@ visit_use (tree use)
print_gimple_expr (dump_file, stmt, 0, 0);
fprintf (dump_file, " simplified to ");
print_generic_expr (dump_file, simplified, 0);
- if (TREE_CODE (lhs) == SSA_NAME)
- fprintf (dump_file, " has constants %d\n",
- expr_has_constants (simplified));
- else
- fprintf (dump_file, "\n");
+ fprintf (dump_file, "\n");
}
}
/* Setting value numbers to constants will occasionally
@@ -3799,8 +3463,6 @@ visit_use (tree use)
if (simplified
&& is_gimple_min_invariant (simplified))
{
- VN_INFO (lhs)->expr = simplified;
- VN_INFO (lhs)->has_constants = true;
changed = set_ssa_val_to (lhs, simplified);
if (gimple_vdef (stmt))
changed |= set_ssa_val_to (gimple_vdef (stmt),
@@ -3818,18 +3480,6 @@ visit_use (tree use)
}
else
{
- if (stmt_has_constants (stmt))
- VN_INFO (lhs)->has_constants = true;
- else
- {
- /* We reset expr and constantness here because we may
- have been value numbering optimistically, and
- iterating. They may become non-constant in this case,
- even if they were optimistically constant. */
- VN_INFO (lhs)->has_constants = false;
- VN_INFO (lhs)->expr = NULL_TREE;
- }
-
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
{
changed = defs_to_varying (stmt);
@@ -4028,7 +3678,8 @@ process_scc (vec<tree> scc)
optimistic_info->phis_pool->release ();
optimistic_info->references_pool->release ();
FOR_EACH_VEC_ELT (scc, i, var)
- VN_INFO (var)->expr = NULL_TREE;
+ gcc_assert (!VN_INFO (var)->needs_insertion
+ && VN_INFO (var)->expr == NULL);
FOR_EACH_VEC_ELT (scc, i, var)
changed |= visit_use (var);
}
@@ -4283,7 +3934,8 @@ init_scc_vn (void)
continue;
VN_INFO_GET (name)->valnum = VN_TOP;
- VN_INFO (name)->expr = NULL_TREE;
+ VN_INFO (name)->needs_insertion = false;
+ VN_INFO (name)->expr = NULL;
VN_INFO (name)->value_id = 0;
if (!SSA_NAME_IS_DEFAULT_DEF (name))
@@ -4638,23 +4290,18 @@ sccvn_dom_walker::before_dom_children (basic_block bb)
{
case GIMPLE_COND:
{
- tree lhs = gimple_cond_lhs (stmt);
- tree rhs = gimple_cond_rhs (stmt);
- /* Work hard in computing the condition and take into account
- the valueization of the defining stmt. */
- if (TREE_CODE (lhs) == SSA_NAME)
- lhs = vn_get_expr_for (lhs);
- if (TREE_CODE (rhs) == SSA_NAME)
- rhs = vn_get_expr_for (rhs);
- val = fold_binary (gimple_cond_code (stmt),
- boolean_type_node, lhs, rhs);
+ tree lhs = vn_valueize (gimple_cond_lhs (stmt));
+ tree rhs = vn_valueize (gimple_cond_rhs (stmt));
+ val = gimple_simplify (gimple_cond_code (stmt),
+ boolean_type_node, lhs, rhs,
+ NULL, vn_valueize);
/* If that didn't simplify to a constant see if we have recorded
temporary expressions from taken edges. */
if (!val || TREE_CODE (val) != INTEGER_CST)
{
tree ops[2];
- ops[0] = gimple_cond_lhs (stmt);
- ops[1] = gimple_cond_rhs (stmt);
+ ops[0] = lhs;
+ ops[1] = rhs;
val = vn_nary_op_lookup_pieces (2, gimple_cond_code (stmt),
boolean_type_node, ops, NULL);
}
diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h
index d0a911f..c8b918a 100644
--- a/gcc/tree-ssa-sccvn.h
+++ b/gcc/tree-ssa-sccvn.h
@@ -165,8 +165,8 @@ typedef struct vn_ssa_aux
{
/* Value number. This may be an SSA name or a constant. */
tree valnum;
- /* Representative expression, if not a direct constant. */
- tree expr;
+ /* Statements to insert if needs_insertion is true. */
+ gimple_seq expr;
/* Unique identifier that all expressions with the same value have. */
unsigned int value_id;
@@ -177,8 +177,6 @@ typedef struct vn_ssa_aux
unsigned visited : 1;
unsigned on_sccstack : 1;
- /* Whether the representative expression contains constants. */
- unsigned has_constants : 1;
/* Whether the SSA_NAME has been value numbered already. This is
only saying whether visit_use has been called on it at least
once. It cannot be used to avoid visitation for SSA_NAME's