From patchwork Fri Feb 3 20:12:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Segher Boessenkool X-Patchwork-Id: 723907 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vFShx3V1wz9rxm for ; Sat, 4 Feb 2017 07:12:49 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="e0YoF3qu"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; q=dns; s=default; b=xCDQEI4vSjta WERP3WU842/re+YfKJtRbivoTjg7xO1wcuBCZje2I6UVFBBkoX910Vm3Xa7dnJt5 hzJ2zKity/UDwuCYS6RKH4dHfMnYL+nR7YVvNpeWv+/H1SEEW1kUpJVlU1nXLcr3 vqPQjt4LGeDm6iPf5tKyJqyxb16EdJw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; s=default; bh=p7UTPD6yhbMnfK401T jJ9IuNgRM=; b=e0YoF3qukavRl78YvnGkaHyvwNsrcvRa0xEB9cQTSw4Vm1kVnJ NMX4YF6ndarwwU4Mn97nJfbevcRJ/cv3jsZ88VoxTneKTKJoteIgk1Iigo09wZPO e0ze5vIoFIKu11ftPG5ezzVS1rhJKAvaJLPW7UcfXRkP7fUjMAnbuDJuI= Received: (qmail 127563 invoked by alias); 3 Feb 2017 20:12:40 -0000 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 Received: (qmail 127554 invoked by uid 89); 3 Feb 2017 20:12:39 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=no version=3.3.2 spammy=speculated, trampoline, sk:hook_bo, PATTERN X-HELO: gcc1-power7.osuosl.org Received: from gcc1-power7.osuosl.org (HELO gcc1-power7.osuosl.org) (140.211.15.137) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 03 Feb 2017 20:12:29 +0000 Received: by gcc1-power7.osuosl.org (Postfix, from userid 10019) id 26F141C067A; Fri, 3 Feb 2017 20:12:26 +0000 (UTC) From: Segher Boessenkool To: gcc-patches@gcc.gnu.org Cc: dje.gcc@gmail.com, Segher Boessenkool Subject: [PATCH] sched: Do not move expensive insns speculatively (PR68664) Date: Fri, 3 Feb 2017 20:12:23 +0000 Message-Id: X-IsSubscribed: yes Scheduling should never move very expensive instructions to places they are executed more frequently. This patch fixes that, reducing the execution time of c-ray by over 40% (I tested on a BE Power7 system). This introduces a new target hook sched.can_speculate_insn which returns whether the scheduler is allowed to speculate a given instruction. The rs6000 implementation disallows all divide and square root instructions. Bootstrapped and tested on powerpc64-linux {-m32,-m64}. Is this okay for trunk? Segher 2017-02-03 Segher Boessenkool PR rtl-optimization/68664 * target.def (can_speculate_insn): New hook. * doc/tm.texi.in (TARGET_SCHED_CAN_SPECULATE_INSN): New hook. * doc/tm.texi: Regenerate. * sched-rgn.c (can_schedule_ready_p): Use the new hook. * config/rs6000/rs6000.c (TARGET_SCHED_CAN_SPECULATE_INSN): New macro. (rs6000_sched_can_speculate_insn): New function. --- gcc/config/rs6000/rs6000.c | 20 ++++++++++++++++++++ gcc/doc/tm.texi | 6 ++++++ gcc/doc/tm.texi.in | 2 ++ gcc/sched-rgn.c | 19 +++++++++++++------ gcc/target.def | 7 +++++++ 5 files changed, 48 insertions(+), 6 deletions(-) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 98e5f91..5e85858 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1608,6 +1608,9 @@ static const struct attribute_spec rs6000_attribute_table[] = #undef TARGET_SCHED_FREE_SCHED_CONTEXT #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context +#undef TARGET_SCHED_CAN_SPECULATE_INSN +#define TARGET_SCHED_CAN_SPECULATE_INSN rs6000_sched_can_speculate_insn + #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT @@ -34986,6 +34989,23 @@ rs6000_free_sched_context (void *_sc) free (_sc); } +static bool +rs6000_sched_can_speculate_insn (rtx_insn *insn) +{ + switch (get_attr_type (insn)) + { + case TYPE_DIV: + case TYPE_SDIV: + case TYPE_DDIV: + case TYPE_VECDIV: + case TYPE_SSQRT: + case TYPE_DSQRT: + return false; + + default: + return true; + } +} /* Length in units of the trampoline for entering a nested function. */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 909589c..1963402 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -7000,6 +7000,12 @@ The structure *@var{spec_info} should be filled in by the target. The structure describes speculation types that can be used in the scheduler. @end deftypefn +@deftypefn {Target Hook} bool TARGET_SCHED_CAN_SPECULATE_INSN (rtx_insn *@var{insn}) +Some instructions should never be speculated by the schedulers, usually + because the instruction is too expensive to get this wrong. This hook + should return @code{false} if @var{insn} should not be speculated. +@end deftypefn + @deftypefn {Target Hook} int TARGET_SCHED_SMS_RES_MII (struct ddg *@var{g}) This hook is called by the swing modulo scheduler to calculate a resource-based lower bound which is based on the resources available in diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index ea74d37..756c118 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -4882,6 +4882,8 @@ them: try the first ones in this list first. @hook TARGET_SCHED_SET_SCHED_FLAGS +@hook TARGET_SCHED_CAN_SPECULATE_INSN + @hook TARGET_SCHED_SMS_RES_MII @hook TARGET_SCHED_DISPATCH diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c index 2af3a03..a09fc5d 100644 --- a/gcc/sched-rgn.c +++ b/gcc/sched-rgn.c @@ -2147,12 +2147,19 @@ static int can_schedule_ready_p (rtx_insn *insn) { /* An interblock motion? */ - if (INSN_BB (insn) != target_bb - && IS_SPECULATIVE_INSN (insn) - && !check_live (insn, INSN_BB (insn))) - return 0; - else - return 1; + if (INSN_BB (insn) != target_bb && IS_SPECULATIVE_INSN (insn)) + { + /* Cannot schedule this insn unless all operands are live. */ + if (!check_live (insn, INSN_BB (insn))) + return 0; + + /* Should not move expensive instructions speculatively. */ + if (GET_CODE (PATTERN (insn)) != CLOBBER + && !targetm.sched.can_speculate_insn (insn)) + return 0; + } + + return 1; } /* Updates counter and other information. Split from can_schedule_ready_p () diff --git a/gcc/target.def b/gcc/target.def index 7308da1..dbb5d76 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -1480,6 +1480,13 @@ DEFHOOK_UNDOC "Return speculation types that are checked for instruction @var{insn}", unsigned int, (rtx_insn *insn), NULL) +DEFHOOK +(can_speculate_insn, + "Some instructions should never be speculated by the schedulers, usually\n\ + because the instruction is too expensive to get this wrong. This hook\n\ + should return @code{false} if @var{insn} should not be speculated.", + bool, (rtx_insn *insn), hook_bool_rtx_insn_true) + DEFHOOK_UNDOC (skip_rtx_p, "Return bool if rtx scanning should just skip current layer and\