From patchwork Fri May 5 07:23:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 98604 Delivered-To: patch@linaro.org Received: by 10.140.96.100 with SMTP id j91csp55767qge; Fri, 5 May 2017 00:23:42 -0700 (PDT) X-Received: by 10.84.174.197 with SMTP id r63mr62522711plb.67.1493969022759; Fri, 05 May 2017 00:23:42 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id 36si1056561pgx.243.2017.05.05.00.23.42 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 May 2017 00:23:42 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-452856-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-452856-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-452856-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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:subject:date:message-id:mime-version:content-type; q=dns; s= default; b=Ge+GjoI0ElTiUYDPI4iHsjxM/YOTYq+TSIarBANeZ0Y89ZYjcX11H aHVbWXNxld4tvgKT7o08Id9y7pyE2YHy6mHpysV436c3w9NqqLGp+HpaMj3cXJc8 iRCNFZqCf95a9fZ1W9yDuVGWhTRCByaYRcLpcFqnVAeEtrJ29q91qg= 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:subject:date:message-id:mime-version:content-type; s= default; bh=yaMGiyQoNjWwmIQiSpLqtUcITLY=; b=goBt7IKLgGt7JOGBetAq AKXvDwTqUHKRlvMopF7A6eUyjxReqPGjdNpVgSRdJamk3FY2VxOfybfu1v1v1U6V c5Ya7FYidZEmnaLjlVQaQPI+6hakdInBPotin9YS0pFRcKV3lSzdhtunvS6Riexy Uppr25Z7B9SMBMub7yUfEJ8= Received: (qmail 12633 invoked by alias); 5 May 2017 07:23:27 -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 12594 invoked by uid 89); 5 May 2017 07:23:26 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=ebb X-HELO: mail-wm0-f50.google.com Received: from mail-wm0-f50.google.com (HELO mail-wm0-f50.google.com) (74.125.82.50) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 05 May 2017 07:23:24 +0000 Received: by mail-wm0-f50.google.com with SMTP id 142so14740981wma.1 for ; Fri, 05 May 2017 00:23:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:mail-followup-to:subject:date:message-id :user-agent:mime-version; bh=unwru9PZjYNksNcHBLYzD4a19qqMQZaSLZ3OopNw2eM=; b=jud3BSu1ezHYsBKQ+7fN+ai47U4Cs9k3uYMf1zJndeVL3iKMtmyrIbpvLnHyMrDBGU 0b/m+rDo7HSHhrsbL7Ro7alCxQqmUfI4jwb8Yzm854t0TCweRqI+uBf/7cbelnxag2CS E+zj1Xs5RQBG10mrIvOXpZHI2NlETL1BBYlpxZLv1gXQ33kLG/0QyKEQ0WhT2+a9+y7A FtxUZ8KoJWQpXeK/h9/zrVL91TN3ND8fhoqeTjIKuADTapyHNE2hChsIuOUKgyObuWwt Bm9RGcVDkBeHB2O6Ed8h4WDMvOgdQl9P4+pyR2HUiedUceA3U8Pxa6yV7YMbRvXtENSC 1sMQ== X-Gm-Message-State: AN3rC/5GOBdl49zofGNvsTJadIBnNHGcMMsPc1qdZJBVTD6v1DrMVSz6 zYo46GZx5M/94qqycq/MPw== X-Received: by 10.28.15.14 with SMTP id 14mr4537339wmp.106.1493969004690; Fri, 05 May 2017 00:23:24 -0700 (PDT) Received: from localhost (92.40.249.76.threembb.co.uk. [92.40.249.76]) by smtp.gmail.com with ESMTPSA id g25sm5326622wra.1.2017.05.05.00.23.23 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 05 May 2017 00:23:24 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: Record equivalences for spill registers Date: Fri, 05 May 2017 08:23:21 +0100 Message-ID: <87inlfsr6e.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux) MIME-Version: 1.0 If we decide to allocate a call-clobbered register R to a value that is live across a call, LRA will create a new spill register TMPR, insert: TMPR <- R before the call and R <- TMPR after it. But if we then failed to allocate a register to TMPR, we would always spill it to the stack, even if R was known to be equivalent to a constant or to some existing memory location. And on AArch64, we'd always fail to allocate such a register for 128-bit Advanced SIMD modes, since no registers of those modes are call-preserved. This patch avoids the problem by copying the equivalence information from the original pseudo to the spill register. It means that the code for the testcase is as good with -O2 as it is with -O, whereas previously the -O code was better. Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? Thanks, Richard [Based on commit branches/ARM/sve-branch@247248] 2017-05-05 Richard Sandiford gcc/ * lra-constraints.c (lra_copy_reg_equiv): New function. (split_reg): Use it to copy equivalence information from the original register to the spill register. gcc/testsuite/ * gcc.target/aarch64/spill_1.c: New test. Index: gcc/lra-constraints.c =================================================================== --- gcc/lra-constraints.c 2017-04-18 19:52:35.062175087 +0100 +++ gcc/lra-constraints.c 2017-05-05 08:19:18.243479648 +0100 @@ -5394,6 +5394,29 @@ choose_split_class (enum reg_class alloc #endif } +/* Copy any equivalence information from ORIGINAL_REGNO to NEW_REGNO. + It only makes sense to call this function if NEW_REGNO is always + equal to ORIGINAL_REGNO. */ + +static void +lra_copy_reg_equiv (unsigned int new_regno, unsigned int original_regno) +{ + if (!ira_reg_equiv[original_regno].defined_p) + return; + + ira_expand_reg_equiv (); + ira_reg_equiv[new_regno].defined_p = true; + if (ira_reg_equiv[original_regno].memory) + ira_reg_equiv[new_regno].memory + = copy_rtx (ira_reg_equiv[original_regno].memory); + if (ira_reg_equiv[original_regno].constant) + ira_reg_equiv[new_regno].constant + = copy_rtx (ira_reg_equiv[original_regno].constant); + if (ira_reg_equiv[original_regno].invariant) + ira_reg_equiv[new_regno].invariant + = copy_rtx (ira_reg_equiv[original_regno].invariant); +} + /* Do split transformations for insn INSN, which defines or uses ORIGINAL_REGNO. NEXT_USAGE_INSNS specifies which instruction in the EBB next uses ORIGINAL_REGNO; it has the same form as the @@ -5515,6 +5538,7 @@ split_reg (bool before_p, int original_r new_reg = lra_create_new_reg (mode, original_reg, rclass, "split"); reg_renumber[REGNO (new_reg)] = hard_regno; } + int new_regno = REGNO (new_reg); save = emit_spill_move (true, new_reg, original_reg); if (NEXT_INSN (save) != NULL_RTX && !call_save_p) { @@ -5523,7 +5547,7 @@ split_reg (bool before_p, int original_r fprintf (lra_dump_file, " Rejecting split %d->%d resulting in > 2 save insns:\n", - original_regno, REGNO (new_reg)); + original_regno, new_regno); dump_rtl_slim (lra_dump_file, save, NULL, -1, 0); fprintf (lra_dump_file, " ))))))))))))))))))))))))))))))))))))))))))))))))\n"); @@ -5538,18 +5562,24 @@ split_reg (bool before_p, int original_r fprintf (lra_dump_file, " Rejecting split %d->%d " "resulting in > 2 restore insns:\n", - original_regno, REGNO (new_reg)); + original_regno, new_regno); dump_rtl_slim (lra_dump_file, restore, NULL, -1, 0); fprintf (lra_dump_file, " ))))))))))))))))))))))))))))))))))))))))))))))))\n"); } return false; } + /* Transfer equivalence information to the spill register, so that + if we fail to allocate the spill register, we have the option of + rematerializing the original value instead of spilling to the stack. */ + if (!HARD_REGISTER_NUM_P (original_regno) + && mode == PSEUDO_REGNO_MODE (original_regno)) + lra_copy_reg_equiv (new_regno, original_regno); after_p = usage_insns[original_regno].after_p; - lra_reg_info[REGNO (new_reg)].restore_rtx = regno_reg_rtx[original_regno]; - bitmap_set_bit (&check_only_regs, REGNO (new_reg)); + lra_reg_info[new_regno].restore_rtx = regno_reg_rtx[original_regno]; + bitmap_set_bit (&check_only_regs, new_regno); bitmap_set_bit (&check_only_regs, original_regno); - bitmap_set_bit (&lra_split_regs, REGNO (new_reg)); + bitmap_set_bit (&lra_split_regs, new_regno); for (;;) { if (GET_CODE (next_usage_insns) != INSN_LIST) @@ -5565,7 +5595,7 @@ split_reg (bool before_p, int original_r if (lra_dump_file != NULL) { fprintf (lra_dump_file, " Split reuse change %d->%d:\n", - original_regno, REGNO (new_reg)); + original_regno, new_regno); dump_insn_slim (lra_dump_file, as_a (usage_insn)); } } Index: gcc/testsuite/gcc.target/aarch64/spill_1.c =================================================================== --- /dev/null 2017-05-05 07:30:08.141451281 +0100 +++ gcc/testsuite/gcc.target/aarch64/spill_1.c 2017-05-05 08:19:18.244456716 +0100 @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef int v4si __attribute__ ((vector_size (16))); + +void bar (void); +void +foo (void) +{ + v4si x = { 1, 1, 1, 1 }; + asm ("# %0" :: "w" (x)); + bar (); + asm ("# %0" :: "w" (x)); +} + +/* { dg-final { scan-assembler-times {\tmovi\tv[0-9]+\.4s,} 2 } } */ +/* { dg-final { scan-assembler-not {\tldr\t} } } */ +/* { dg-final { scan-assembler-not {\tstr\t} } } */