aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2005-12-19 21:08:01 -0700
committerJeff Law <law@gcc.gnu.org>2005-12-19 21:08:01 -0700
commitea65cd378bf9c6457a2a400e2f2fef92514d06bb (patch)
tree8d2ebf3b6d782aec9f3bf036565cf93ba43dd849
parent4322a86f3281d7a9d17e8316a25789c6f378321a (diff)
downloadgcc-ea65cd378bf9c6457a2a400e2f2fef92514d06bb.zip
gcc-ea65cd378bf9c6457a2a400e2f2fef92514d06bb.tar.gz
gcc-ea65cd378bf9c6457a2a400e2f2fef92514d06bb.tar.bz2
tree-ssa-dom.c (thread_across_edge): Do not use local_fold.
* tree-ssa-dom.c (thread_across_edge): Do not use local_fold. Strip away all type conversions after simplifying the condition. * tree-cfgcleanup.c (merge_phi_nodes): Allow merging in some cases the forwarder block dominates the destination. From-SVN: r108833
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/tree-cfgcleanup.c33
-rw-r--r--gcc/tree-ssa-dom.c11
3 files changed, 50 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2bd2e7c..69bfe7a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2005-12-19 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (thread_across_edge): Do not use local_fold.
+ Strip away all type conversions after simplifying the
+ condition.
+
+ * tree-cfgcleanup.c (merge_phi_nodes): Allow merging in some
+ cases the forwarder block dominates the destination.
+
2005-12-19 DJ Delorie <dj@redhat.com>
* reload1.c (spill_failure): Dump reload data to dump file.
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index 7e719c1..6f8b1c0 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -743,6 +743,39 @@ merge_phi_nodes (void)
nodes at BB. */
*current++ = bb;
}
+ else
+ {
+ tree phi;
+
+ /* BB dominates DEST. There may be many users of the PHI
+ nodes in BB. However, there is still a trivial case we
+ can handle. If the result of every PHI in BB is used
+ only by a PHI in DEST, then we can trivially merge the
+ PHI nodes from BB into DEST. */
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ {
+ tree result = PHI_RESULT (phi);
+ int num_uses = num_imm_uses (result);
+ use_operand_p imm_use;
+ tree use_stmt;
+
+ /* If the PHI's result is never used, then we can just
+ ignore it. */
+ if (num_uses == 0)
+ continue;
+
+ /* Get the single use of the result of this PHI node. */
+ if (!single_imm_use (result, &imm_use, &use_stmt)
+ || TREE_CODE (use_stmt) != PHI_NODE
+ || bb_for_stmt (use_stmt) != dest)
+ break;
+ }
+
+ /* If the loop above iterated thorugh all the PHI nodes
+ in BB, then we can merge the PHIs from BB into DEST. */
+ if (!phi)
+ *current++ = bb;
+ }
}
/* Now let's drain WORKLIST. */
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index b6257d3..45a5b7d 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -892,9 +892,14 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
TREE_OPERAND (COND_EXPR_COND (dummy_cond), 1) = op1;
}
- /* If the conditional folds to an invariant, then we are done,
- otherwise look it up in the hash tables. */
- cached_lhs = local_fold (COND_EXPR_COND (dummy_cond));
+ /* We absolutely do not care about any type conversions
+ we only care about a zero/nonzero value. */
+ cached_lhs = fold (COND_EXPR_COND (dummy_cond));
+ while (TREE_CODE (cached_lhs) == NOP_EXPR
+ || TREE_CODE (cached_lhs) == CONVERT_EXPR
+ || TREE_CODE (cached_lhs) == NON_LVALUE_EXPR)
+ cached_lhs = TREE_OPERAND (cached_lhs, 0);
+
if (! is_gimple_min_invariant (cached_lhs))
{
cached_lhs = lookup_avail_expr (dummy_cond, false);