aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-scopedtables.c
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2017-08-22 09:13:09 -0600
committerJeff Law <law@gcc.gnu.org>2017-08-22 09:13:09 -0600
commit0db8ddfcb660397bab428ce0d271967d24c23177 (patch)
tree4004740d0a74395c77ee7b55de8e23b4d1a201a6 /gcc/tree-ssa-scopedtables.c
parentd4c550fd0ecb17d577353074c58283e942d1f870 (diff)
downloadgcc-0db8ddfcb660397bab428ce0d271967d24c23177.zip
gcc-0db8ddfcb660397bab428ce0d271967d24c23177.tar.gz
gcc-0db8ddfcb660397bab428ce0d271967d24c23177.tar.bz2
re PR tree-optimization/81741 (Misoptimisation : replacing a constant field read access by a function call)
PR tree-optimization/81741 PR tree-optimization/71947 * tree-ssa-dom.c: Include tree-inline.h. (record_temporary_equivalences): Only record SSA_NAME = SSA_NAME equivalences if one is more expensive to compute than the other. * tree-ssa-scopedtables.h (class const_or_copies): Make record_const_or_copy_raw method private. (class avail_exprs_stack): New method simplify_binary_operation. * tree-ssa-scopedtables.c (avail_exprs_stack::lookup_avail_expr): Call avail_exprs_stack::simplify_binary_operation as needed. (avail_exprs_stack::simplify_binary_operation): New function. PR tree-optimization/81741 PR tree-optimization/71947 * gcc.dg/tree-ssa/pr81741.c: New test. * gcc.dg/tree-ssa/pr71947-7.c: New test. * gcc.dg/tree-ssa/pr71947-8.c: New test. * gcc.dg/tree-ssa/pr71947-9.c: New test. * gcc.dg/tree-ssa/pr71941-1.c: Tweak expected output. * gcc.dg/tree-ssa/pr71941-2.c: Tweak expected output. * gcc.dg/tree-ssa/pr71941-3.c: Tweak expected output. * gcc.dg/tree-ssa/20030922-2.c: xfail. From-SVN: r251279
Diffstat (limited to 'gcc/tree-ssa-scopedtables.c')
-rw-r--r--gcc/tree-ssa-scopedtables.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/gcc/tree-ssa-scopedtables.c b/gcc/tree-ssa-scopedtables.c
index 7b9ca78..6e1fd58 100644
--- a/gcc/tree-ssa-scopedtables.c
+++ b/gcc/tree-ssa-scopedtables.c
@@ -116,6 +116,102 @@ vuse_eq (ao_ref *, tree vuse1, unsigned int cnt, void *data)
return NULL;
}
+/* We looked for STMT in the hash table, but did not find it.
+
+ If STMT is an assignment from a binary operator, we may know something
+ about the operands relationship to each other which would allow
+ us to derive a constant value for the RHS of STMT. */
+
+tree
+avail_exprs_stack::simplify_binary_operation (gimple *stmt,
+ class expr_hash_elt element)
+{
+ if (is_gimple_assign (stmt))
+ {
+ struct hashable_expr *expr = element.expr ();
+ if (expr->kind == EXPR_BINARY)
+ {
+ enum tree_code code = expr->ops.binary.op;
+
+ switch (code)
+ {
+ /* For these cases, if we know the operands
+ are equal, then we know the result. */
+ case MIN_EXPR:
+ case MAX_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_XOR_EXPR:
+ case MINUS_EXPR:
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ {
+ /* Build a simple equality expr and query the hash table
+ for it. */
+ struct hashable_expr expr;
+ expr.type = boolean_type_node;
+ expr.kind = EXPR_BINARY;
+ expr.ops.binary.op = EQ_EXPR;
+ expr.ops.binary.opnd0 = gimple_assign_rhs1 (stmt);
+ expr.ops.binary.opnd1 = gimple_assign_rhs2 (stmt);
+ class expr_hash_elt element2 (&expr, NULL_TREE);
+ expr_hash_elt **slot
+ = m_avail_exprs->find_slot (&element2, NO_INSERT);
+ tree result_type = TREE_TYPE (gimple_assign_lhs (stmt));
+
+ /* If the query was successful and returned a nonzero
+ result, then we know that the operands of the binary
+ expression are the same. In many cases this allows
+ us to compute a constant result of the expression
+ at compile time, even if we do not know the exact
+ values of the operands. */
+ if (slot && *slot && integer_onep ((*slot)->lhs ()))
+ {
+ switch (code)
+ {
+ case MIN_EXPR:
+ case MAX_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_AND_EXPR:
+ return gimple_assign_rhs1 (stmt);
+
+ case BIT_XOR_EXPR:
+ case MINUS_EXPR:
+ case TRUNC_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ return build_zero_cst (result_type);
+
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ return build_one_cst (result_type);
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ }
+ return NULL_TREE;
+}
+
/* Search for an existing instance of STMT in the AVAIL_EXPRS_STACK table.
If found, return its LHS. Otherwise insert STMT in the table and
return NULL_TREE.
@@ -160,6 +256,12 @@ avail_exprs_stack::lookup_avail_expr (gimple *stmt, bool insert, bool tbaa_p)
}
else if (*slot == NULL)
{
+ /* If we did not find the expression in the hash table, we may still
+ be able to produce a result for some expressions. */
+ tree alt = avail_exprs_stack::simplify_binary_operation (stmt, element);
+ if (alt)
+ return alt;
+
class expr_hash_elt *element2 = new expr_hash_elt (element);
*slot = element2;