From patchwork Wed Apr 11 14:08:04 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 151800 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 BA4B0B7061 for ; Thu, 12 Apr 2012 00:10:55 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1334758256; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC: Subject:References:In-Reply-To:Content-Type:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=7ckVMrdXHannqnp8ogp1oZ+V8qA=; b=FBmRocM7X4W3z9uMvz3wkk8ugOa/MyjNSt2A69myj3PAetWkppCpbtZ3OXdNsm CeOsTn5OUX7pOf6Ypr6+N8bcURYnzpz9BrxiCblcHazqEYkgEtb1gFpIWHYfFXkm FIBVCgHNW7L3/F1npaXevJAzw9gfUNu8a0JQtz34YY5XU= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=mZF5x5pm0VVFe5p7f6OkFhZo9Rw33cPv1iPaltzSOL6WfWCwRFOGf0Hxh/kNjM p8knBFosXCSwwpbVpvupwJuznKKlzV/P69zlH/5ZZfRnwG3x2RqyPX7ZbE9lzoWw kr9QW0QXPqz3zhBTnc8voiK/O+u3uXzVdl17anDb9I5QA=; Received: (qmail 11886 invoked by alias); 11 Apr 2012 14:10:47 -0000 Received: (qmail 11868 invoked by uid 22791); 11 Apr 2012 14:10:44 -0000 X-SWARE-Spam-Status: No, hits=-4.2 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL, TW_CP X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 11 Apr 2012 14:10:29 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1SHyFg-0001IT-QC from Bernd_Schmidt@mentor.com ; Wed, 11 Apr 2012 07:10:28 -0700 Received: from SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Wed, 11 Apr 2012 07:10:28 -0700 Received: from [127.0.0.1] (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.1.289.1; Wed, 11 Apr 2012 15:10:26 +0100 Message-ID: <4F859044.3070907@codesourcery.com> Date: Wed, 11 Apr 2012 16:08:04 +0200 From: Bernd Schmidt User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.20) Gecko/20110920 Lightning/1.0b3pre Thunderbird/3.1.12 MIME-Version: 1.0 To: Vladimir Makarov CC: GCC Patches Subject: Re: haifa-sched: Fix problems with cc0 in prune_ready_list References: <4F328E64.3060601@codesourcery.com> <4F35698D.60208@redhat.com> In-Reply-To: <4F35698D.60208@redhat.com> 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 02/10/2012 08:01 PM, Vladimir Makarov wrote: > On 02/08/2012 10:01 AM, Bernd Schmidt wrote: >> We found a scheduler problem while testing Coldfire targets. The >> prune_ready_list function I introduced doesn't take SCHED_GROUPs into >> account, which can lead to a random insn being scheduled between a cc0 >> setter and user. The patch below fixes it, OK? (Bootstrapped& tested >> i686-linux). >> >> > Ok. Thanks, Bernd. It turns out that the previous fix was insufficient. If a cc0 user and another insn are on the ready list, it can happen that the cc0 user is delayed for longer than the other insn, and we will reenter prune_ready_list with a new ready insn but with the cc0 user still queued for later. In that case we'll do the wrong thing. The following patch reworks the function to take care of this problem. Bootstrapped and tested on i686-linux, and also tested with a m68k multilib on our internal compiler (4.6 based but with scheduler patches from 4.7). Ok? I assume this should also go into 4.7 eventually. Bernd * haifa-sched.c (prune_ready_list): Rework handling of SHCED_GROUP_P insns so that no other insn is queued for a time before them. Index: gcc/haifa-sched.c =================================================================== --- gcc/haifa-sched.c (revision 186270) +++ gcc/haifa-sched.c (working copy) @@ -3946,88 +3946,106 @@ static void prune_ready_list (state_t temp_state, bool first_cycle_insn_p, bool shadows_only_p, bool modulo_epilogue_p) { - int i; + int i, pass; bool sched_group_found = false; + int min_cost_group = 1; - restart: for (i = 0; i < ready.n_ready; i++) { rtx insn = ready_element (&ready, i); - int cost = 0; - const char *reason = "resource conflict"; - - if (DEBUG_INSN_P (insn)) - continue; - - if (SCHED_GROUP_P (insn) && !sched_group_found) + if (SCHED_GROUP_P (insn)) { sched_group_found = true; - if (i > 0) - goto restart; + break; } + } - if (sched_group_found && !SCHED_GROUP_P (insn)) - { - cost = 1; - reason = "not in sched group"; - } - else if (modulo_epilogue_p && INSN_EXACT_TICK (insn) == INVALID_TICK) - { - cost = max_insn_queue_index; - reason = "not an epilogue insn"; - } - else if (shadows_only_p && !SHADOW_P (insn)) - { - cost = 1; - reason = "not a shadow"; - } - else if (recog_memoized (insn) < 0) - { - if (!first_cycle_insn_p - && (GET_CODE (PATTERN (insn)) == ASM_INPUT - || asm_noperands (PATTERN (insn)) >= 0)) - cost = 1; - reason = "asm"; - } - else if (sched_pressure_p) - cost = 0; - else + /* Make two passes if there's a SCHED_GROUP_P insn; make sure to handle + such an insn first and note its cost, then schedule all other insns + for one cycle later. */ + for (pass = sched_group_found ? 0 : 1; pass < 2; ) + { + int n = ready.n_ready; + for (i = 0; i < n; i++) { - int delay_cost = 0; + rtx insn = ready_element (&ready, i); + int cost = 0; + const char *reason = "resource conflict"; - if (delay_htab) + if (DEBUG_INSN_P (insn)) + continue; + + if (sched_group_found && !SCHED_GROUP_P (insn)) { - struct delay_pair *delay_entry; - delay_entry - = (struct delay_pair *)htab_find_with_hash (delay_htab, insn, - htab_hash_pointer (insn)); - while (delay_entry && delay_cost == 0) + if (pass == 0) + continue; + cost = min_cost_group; + reason = "not in sched group"; + } + else if (modulo_epilogue_p + && INSN_EXACT_TICK (insn) == INVALID_TICK) + { + cost = max_insn_queue_index; + reason = "not an epilogue insn"; + } + else if (shadows_only_p && !SHADOW_P (insn)) + { + cost = 1; + reason = "not a shadow"; + } + else if (recog_memoized (insn) < 0) + { + if (!first_cycle_insn_p + && (GET_CODE (PATTERN (insn)) == ASM_INPUT + || asm_noperands (PATTERN (insn)) >= 0)) + cost = 1; + reason = "asm"; + } + else if (sched_pressure_p) + cost = 0; + else + { + int delay_cost = 0; + + if (delay_htab) { - delay_cost = estimate_shadow_tick (delay_entry); - if (delay_cost > max_insn_queue_index) - delay_cost = max_insn_queue_index; - delay_entry = delay_entry->next_same_i1; + struct delay_pair *delay_entry; + delay_entry + = (struct delay_pair *)htab_find_with_hash (delay_htab, insn, + htab_hash_pointer (insn)); + while (delay_entry && delay_cost == 0) + { + delay_cost = estimate_shadow_tick (delay_entry); + if (delay_cost > max_insn_queue_index) + delay_cost = max_insn_queue_index; + delay_entry = delay_entry->next_same_i1; + } } - } - memcpy (temp_state, curr_state, dfa_state_size); - cost = state_transition (temp_state, insn); - if (cost < 0) - cost = 0; - else if (cost == 0) - cost = 1; - if (cost < delay_cost) + memcpy (temp_state, curr_state, dfa_state_size); + cost = state_transition (temp_state, insn); + if (cost < 0) + cost = 0; + else if (cost == 0) + cost = 1; + if (cost < delay_cost) + { + cost = delay_cost; + reason = "shadow tick"; + } + } + if (cost >= 1) { - cost = delay_cost; - reason = "shadow tick"; + if (SCHED_GROUP_P (insn) && cost > min_cost_group) + min_cost_group = cost; + ready_remove (&ready, i); + queue_insn (insn, cost, reason); + if (i + 1 < n) + break; } } - if (cost >= 1) - { - ready_remove (&ready, i); - queue_insn (insn, cost, reason); - goto restart; - } + if (i == n) + pass++; } }