From patchwork Fri Dec 2 20:10:50 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bill Schmidt X-Patchwork-Id: 128953 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id F3244B6EE8 for ; Sat, 3 Dec 2011 07:11:33 +1100 (EST) Received: (qmail 11024 invoked by alias); 2 Dec 2011 20:11:29 -0000 Received: (qmail 11008 invoked by uid 22791); 2 Dec 2011 20:11:19 -0000 X-SWARE-Spam-Status: No, hits=-2.6 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, TW_TM X-Spam-Check-By: sourceware.org Received: from e39.co.us.ibm.com (HELO e39.co.us.ibm.com) (32.97.110.160) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 02 Dec 2011 20:11:04 +0000 Received: from /spool/local by e39.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 2 Dec 2011 13:11:01 -0700 Received: from d03relay02.boulder.ibm.com (9.17.195.227) by e39.co.us.ibm.com (192.168.1.139) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 2 Dec 2011 13:10:58 -0700 Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by d03relay02.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id pB2KAt7f087616 for ; Fri, 2 Dec 2011 13:10:57 -0700 Received: from d03av02.boulder.ibm.com (loopback [127.0.0.1]) by d03av02.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id pB2KAr9g001926 for ; Fri, 2 Dec 2011 13:10:53 -0700 Received: from [9.65.228.61] (sig-9-65-228-61.mts.ibm.com [9.65.228.61]) by d03av02.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id pB2KAo3M001758; Fri, 2 Dec 2011 13:10:51 -0700 Message-ID: <1322856650.29073.31.camel@gnopaine> Subject: Re: [PATCH] Fix PR middle-end/39976, 200.sixtrack degradation From: "William J. Schmidt" To: Michael Matz Cc: Richard Guenther , gcc-patches@gcc.gnu.org, bergner@vnet.ibm.com Date: Fri, 02 Dec 2011 14:10:50 -0600 In-Reply-To: References: <1322777636.19158.1.camel@gnopaine> <1322832917.2548.12.camel@gnopaine> <1322845466.2548.23.camel@gnopaine> Mime-Version: 1.0 x-cbid: 11120220-4242-0000-0000-000000428529 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org OK, one more version. This removes the basic block test and instead implements Michael's suggestion: On Fri, 2011-12-02 at 18:40 +0100, Michael Matz wrote: > But I wonder why it's not enough to just do a push/pop sequence on > avail_exprs_stack around your new PHI processing in dom_opt_enter_block, > ala > > + VEC_safe_push (expr_hash_elt_t, heap, avail_exprs_stack, NULL); > /* Create equivalences from redundant PHIs. */ > for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) > eliminate_redundant_computations (&gsi); > + remove_local_expressions_from_table (); > > on top of your current version. That ought to remove the added PHI > expressions (and only them) from the hash table but retain the information > of equality in the const_or_copies_stack. Checking the BB wouldn't be > required then. Bootstrapped and regression tested on powerpc64-linux. Thanks, Bill 2011-12-02 Bill Schmidt PR middle-end/39976 * tree-ssa-dom.c (enum expr_kind): Add EXPR_PHI. (struct hashable_expr): Add struct phi field. (initialize_hash_element): Handle phis. (hashable_expr_equal_p): Likewise. (iterative_hash_hashable_expr): Likewise. (print_expr_hash_elt): Likewise. (dom_opt_enter_block): Create equivalences from redundant phis. (eliminate_redundant_computations): Handle redundant phis. (lookup_avail_expr): Handle phis. Index: gcc/tree-ssa-dom.c =================================================================== --- gcc/tree-ssa-dom.c (revision 181929) +++ gcc/tree-ssa-dom.c (working copy) @@ -52,7 +52,8 @@ enum expr_kind EXPR_UNARY, EXPR_BINARY, EXPR_TERNARY, - EXPR_CALL + EXPR_CALL, + EXPR_PHI }; struct hashable_expr @@ -65,6 +66,7 @@ struct hashable_expr struct { enum tree_code op; tree opnd0, opnd1; } binary; struct { enum tree_code op; tree opnd0, opnd1, opnd2; } ternary; struct { gimple fn_from; bool pure; size_t nargs; tree *args; } call; + struct { size_t nargs; tree *args; } phi; } ops; }; @@ -281,6 +283,19 @@ initialize_hash_element (gimple stmt, tree lhs, expr->kind = EXPR_SINGLE; expr->ops.single.rhs = gimple_goto_dest (stmt); } + else if (code == GIMPLE_PHI) + { + size_t nargs = gimple_phi_num_args (stmt); + size_t i; + + expr->type = TREE_TYPE (gimple_phi_result (stmt)); + expr->kind = EXPR_PHI; + expr->ops.phi.nargs = nargs; + expr->ops.phi.args = (tree *) xcalloc (nargs, sizeof (tree)); + + for (i = 0; i < nargs; i++) + expr->ops.phi.args[i] = gimple_phi_arg_def (stmt, i); + } else gcc_unreachable (); @@ -439,6 +454,21 @@ hashable_expr_equal_p (const struct hashable_expr return true; } + case EXPR_PHI: + { + size_t i; + + if (expr0->ops.phi.nargs != expr1->ops.phi.nargs) + return false; + + for (i = 0; i < expr0->ops.phi.nargs; i++) + if (! operand_equal_p (expr0->ops.phi.args[i], + expr1->ops.phi.args[i], 0)) + return false; + + return true; + } + default: gcc_unreachable (); } @@ -516,6 +546,15 @@ iterative_hash_hashable_expr (const struct hashabl } break; + case EXPR_PHI: + { + size_t i; + + for (i = 0; i < expr->ops.phi.nargs; i++) + val = iterative_hash_expr (expr->ops.phi.args[i], val); + } + break; + default: gcc_unreachable (); } @@ -588,6 +627,22 @@ print_expr_hash_elt (FILE * stream, const struct e fprintf (stream, ")"); } break; + + case EXPR_PHI: + { + size_t i; + size_t nargs = element->expr.ops.phi.nargs; + + fprintf (stream, "PHI <"); + for (i = 0; i < nargs; i++) + { + print_generic_expr (stream, element->expr.ops.phi.args[i], 0); + if (i + 1 < nargs) + fprintf (stream, ", "); + } + fprintf (stream, ">"); + } + break; } fprintf (stream, "\n"); @@ -1688,6 +1743,14 @@ dom_opt_enter_block (struct dom_walk_data *walk_da /* PHI nodes can create equivalences too. */ record_equivalences_from_phis (bb); + /* Create equivalences from redundant PHIs. PHIs are only truly + redundant when they exist in the same block, so push another + marker and unwind right afterwards. */ + VEC_safe_push (expr_hash_elt_t, heap, avail_exprs_stack, NULL); + for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + eliminate_redundant_computations (&gsi); + remove_local_expressions_from_table (); + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) optimize_stmt (bb, gsi); @@ -1818,12 +1881,16 @@ eliminate_redundant_computations (gimple_stmt_iter { tree expr_type; tree cached_lhs; + tree def; bool insert = true; bool assigns_var_p = false; gimple stmt = gsi_stmt (*gsi); - tree def = gimple_get_lhs (stmt); + if (gimple_code (stmt) == GIMPLE_PHI) + def = gimple_phi_result (stmt); + else + def = gimple_get_lhs (stmt); /* Certain expressions on the RHS can be optimized away, but can not themselves be entered into the hash tables. */ @@ -1857,6 +1924,16 @@ eliminate_redundant_computations (gimple_stmt_iter } else if (gimple_code (stmt) == GIMPLE_SWITCH) expr_type = TREE_TYPE (gimple_switch_index (stmt)); + else if (gimple_code (stmt) == GIMPLE_PHI) + /* We can't propagate into a phi, so the logic below doesn't apply. + Instead record an equivalence between the cached LHS and the + PHI result of this statement, provided they are in the same block. + This should be sufficient to kill the redundant phi. */ + { + if (def && cached_lhs) + record_const_or_copy (def, cached_lhs); + return; + } else gcc_unreachable (); @@ -2299,8 +2376,11 @@ lookup_avail_expr (gimple stmt, bool insert) tree temp; struct expr_hash_elt element; - /* Get LHS of assignment or call, else NULL_TREE. */ - lhs = gimple_get_lhs (stmt); + /* Get LHS of phi, assignment, or call; else NULL_TREE. */ + if (gimple_code (stmt) == GIMPLE_PHI) + lhs = gimple_phi_result (stmt); + else + lhs = gimple_get_lhs (stmt); initialize_hash_element (stmt, lhs, &element);