From patchwork Wed Jul 21 19:38:30 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 59491 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 30EAAB70B1 for ; Thu, 22 Jul 2010 05:38:44 +1000 (EST) Received: (qmail 3227 invoked by alias); 21 Jul 2010 19:38:42 -0000 Received: (qmail 3207 invoked by uid 22791); 21 Jul 2010 19:38:39 -0000 X-SWARE-Spam-Status: No, hits=-5.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_TM, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 21 Jul 2010 19:38:33 +0000 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o6LJcVEi025044 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 21 Jul 2010 15:38:31 -0400 Received: from anchor.twiddle.home (vpn-230-204.phx2.redhat.com [10.3.230.204]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o6LJcUCH020380; Wed, 21 Jul 2010 15:38:31 -0400 Message-ID: <4C474CB6.9080303@redhat.com> Date: Wed, 21 Jul 2010 12:38:30 -0700 From: Richard Henderson User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.10) Gecko/20100621 Fedora/3.0.5-1.fc13 Thunderbird/3.0.5 MIME-Version: 1.0 To: Richard Guenther CC: IainS , GCC Patches , Jakub Jelinek , jh@suse.cz Subject: [CFT, try 9] Emulated tls rewrite References: <4C3E4D3C.1030205@redhat.com> <4C44AA95.9000505@redhat.com> <4C45CBEC.7020400@redhat.com> <4C47212E.70005@redhat.com> In-Reply-To: <4C47212E.70005@redhat.com> X-IsSubscribed: yes 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 On 07/21/2010 09:32 AM, Richard Henderson wrote: > On 07/21/2010 01:23 AM, Richard Guenther wrote: >> Couldn't you do gsi_insert_on_edge_immediate? > > I could. It doesn't really help though, since the location at which > the call statement and the call edge are created is shared between > the normal statements and the phi statements. It gets ugly either way. As discussed on IRC, what do you think of this incremental patch? I've tested it on tls.exp and see no failures. I'll start a proper bootstrap and test in a moment to see that there are no other unexpected consequences. r~ diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c index 1402c0d..291e4d9 100644 --- a/gcc/gimple-iterator.c +++ b/gcc/gimple-iterator.c @@ -65,6 +65,25 @@ update_bb_for_stmts (gimple_seq_node first, basic_block bb) gimple_set_bb (n->stmt, bb); } +/* Set the frequencies for the cgraph_edges for each of the calls + starting at FIRST for their new position within BB. */ + +static void +update_call_edge_frequencies (gimple_seq_node first, basic_block bb) +{ + int bb_freq = compute_call_stmt_bb_frequency (current_function_decl, bb); + struct cgraph_node *cfun_node = cgraph_node (current_function_decl); + gimple_seq_node n; + + for (n = first; n ; n = n->next) + if (is_gimple_call (n->stmt)) + { + struct cgraph_edge *e = cgraph_edge (cfun_node, n->stmt); + if (e != NULL) + e->frequency = bb_freq; + } +} + /* Insert the sequence delimited by nodes FIRST and LAST before iterator I. M specifies how to update iterator I after insertion @@ -696,11 +715,19 @@ basic_block gsi_insert_on_edge_immediate (edge e, gimple stmt) { gimple_stmt_iterator gsi; + struct gimple_seq_node_d node; basic_block new_bb = NULL; + bool ins_after; gcc_assert (!PENDING_STMT (e)); - if (gimple_find_edge_insert_loc (e, &gsi, &new_bb)) + ins_after = gimple_find_edge_insert_loc (e, &gsi, &new_bb); + + node.stmt = stmt; + node.prev = node.next = NULL; + update_call_edge_frequencies (&node, gsi.bb); + + if (ins_after) gsi_insert_after (&gsi, stmt, GSI_NEW_STMT); else gsi_insert_before (&gsi, stmt, GSI_NEW_STMT); @@ -716,10 +743,14 @@ gsi_insert_seq_on_edge_immediate (edge e, gimple_seq stmts) { gimple_stmt_iterator gsi; basic_block new_bb = NULL; + bool ins_after; gcc_assert (!PENDING_STMT (e)); - if (gimple_find_edge_insert_loc (e, &gsi, &new_bb)) + ins_after = gimple_find_edge_insert_loc (e, &gsi, &new_bb); + update_call_edge_frequencies (gimple_seq_first (stmts), gsi.bb); + + if (ins_after) gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT); else gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT); @@ -744,7 +775,6 @@ gsi_commit_edge_inserts (void) gsi_commit_one_edge_insert (e, NULL); } - /* Commit insertions pending at edge E. If a new block is created, set NEW_BB to this block, otherwise set it to NULL. */ @@ -758,10 +788,14 @@ gsi_commit_one_edge_insert (edge e, basic_block *new_bb) { gimple_stmt_iterator gsi; gimple_seq seq = PENDING_STMT (e); + bool ins_after; PENDING_STMT (e) = NULL; - if (gimple_find_edge_insert_loc (e, &gsi, new_bb)) + ins_after = gimple_find_edge_insert_loc (e, &gsi, new_bb); + update_call_edge_frequencies (gimple_seq_first (seq), gsi.bb); + + if (ins_after) gsi_insert_seq_after (&gsi, seq, GSI_NEW_STMT); else gsi_insert_seq_before (&gsi, seq, GSI_NEW_STMT); diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c index 8b7c7d8..17f97be 100644 --- a/gcc/tree-emutls.c +++ b/gcc/tree-emutls.c @@ -596,61 +596,6 @@ clear_access_vars (void) VEC_length (tree, access_vars) * sizeof(tree)); } -/* Compute the frequency of instructions to be insertted on an edge E. - - Mirror a portion of the logic from gimple_find_edge_insert_loc to - do this. Determine if statements inserted on E will be insertted - into the predecessor block. We must choose the correct block, - and thus frequency, in order to pass verify_cgraph. */ - -static int -compute_edge_bb_frequency (edge e) -{ - basic_block src = e->src; - - /* If the destination has one predecessor and no PHI nodes, insert - there... Except that we *know* it has PHI nodes or else there's - nothing for us to do. Skip this step. */ - - /* If the source has one successor, the edge is not abnormal and the - last statement does not end a basic block, insert there. */ - if ((e->flags & EDGE_ABNORMAL) == 0 - && src != ENTRY_BLOCK_PTR - && single_succ_p (src)) - { - gimple_stmt_iterator gsi; - gimple last; - - /* If the block is empty, of course we use it. */ - gsi = gsi_last_bb (src); - if (gsi_end_p (gsi)) - goto return_pred; - - /* If the last stmt does not end the block, we insert after. */ - last = gsi_stmt (gsi); - if (!stmt_ends_bb_p (last)) - goto return_pred; - - /* If the last stmt is a trivial control, we insert before. */ - switch (gimple_code (last)) - { - case GIMPLE_RETURN: - case GIMPLE_RESX: - goto return_pred; - default: - break; - } - } - - /* We will be splitting the edge and insertting there. */ - return EDGE_FREQUENCY (e); - - /* If we get here, we will not be splitting the edge and instead - insertting any code into the predecessor block. */ - return_pred: - return compute_call_stmt_bb_frequency (current_function_decl, e->src); -} - /* Lower the entire function NODE. */ static void @@ -677,13 +622,15 @@ lower_emutls_function_body (struct cgraph_node *node) PHI argument for that edge. */ if (!gimple_seq_empty_p (phi_nodes (d.bb))) { + /* The calls will be inserted on the edges, and the frequencies + will be computed during the commit process. */ + d.bb_freq = 0; + nedge = EDGE_COUNT (d.bb->preds); for (i = 0; i < nedge; ++i) { edge e = EDGE_PRED (d.bb, i); - d.bb_freq = compute_edge_bb_frequency (e); - /* We can re-use any SSA_NAME created on this edge. */ clear_access_vars (); d.seq = NULL;