diff options
author | Jeff Law <law@redhat.com> | 2017-08-22 09:13:09 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2017-08-22 09:13:09 -0600 |
commit | 0db8ddfcb660397bab428ce0d271967d24c23177 (patch) | |
tree | 4004740d0a74395c77ee7b55de8e23b4d1a201a6 /gcc/tree-ssa-scopedtables.c | |
parent | d4c550fd0ecb17d577353074c58283e942d1f870 (diff) | |
download | gcc-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.c | 102 |
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; |