From patchwork Wed Aug 29 02:21:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Wilson X-Patchwork-Id: 963218 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-484647-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sifive.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="p+RAkgYZ"; dkim=pass (2048-bit key; unprotected) header.d=sifive.com header.i=@sifive.com header.b="JPHZDKei"; dkim-atps=neutral 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 420Ts51NvRz9s1x for ; Wed, 29 Aug 2018 12:21:42 +1000 (AEST) 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=WbYFWY/YdOIG LS5om4xbhG8tAPF0mS21y+5Y6Q27mJMUW2Bu8d64pg8WJ/9LGmvWOBRPQbc35YHb B8P2molqqPL6xYNaFayPfoUTcHtvQDC2mhzL4gv0PNUO6koPOG79b/XA/feizz5+ Z5z0W/pyKLdzhO29d1lg4zJren5K4OM= 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=6o1txYmnp973FRqhgs amt8jQT8U=; b=p+RAkgYZdoJkjejOxP9XAkzIlut2MVt6BqhPlIzFbUNJ8K21Y8 iGscSW9+mtYZbnvPYZaEqZM5Y4SfqIpi3yGdvhZwfPcOkiHsAacJUSKOPhmuDiRx c3y3AqPt2Uz8NM8qUBZvOWagIw78Wn88Nn4hQu1jYuToSVLu3FoYuhpuA= Received: (qmail 38851 invoked by alias); 29 Aug 2018 02:21:34 -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 38834 invoked by uid 89); 29 Aug 2018 02:21:33 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, MEDICAL_SUBJECT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=boot, Mode, newlib X-HELO: mail-pg1-f196.google.com Received: from mail-pg1-f196.google.com (HELO mail-pg1-f196.google.com) (209.85.215.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 29 Aug 2018 02:21:31 +0000 Received: by mail-pg1-f196.google.com with SMTP id y3-v6so396049pgv.0 for ; Tue, 28 Aug 2018 19:21:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=from:to:cc:subject:date:message-id; bh=VGJ2ymOXDxz/Ae62Ozv5CNffPnCHHvy9rZCuuCuMr+c=; b=JPHZDKeiUXg6qF/MjQVyiUnzwXcsUUJN9iQoPBrLt1HZwj8HJJsjpvOqrloRoMOagl oE3Z6x7OZL8CwPbupRs82tF0xyTaR9PcTlr+TmTVx8qGtGILooGyzWpa6n+6wsSPOtnT KWhWVVlHGlyI0PGJxXq1APohK2Mn/+pPkoh9zJkOlSjc0Vpz6FgKomTmS/keTLZOpnC/ bETTBbCRnlMoe2XRF87qLR7hhkq7+jTz6T4uguyH1l0cVQc0cHdb7O69rsqS5Ojq2oIs /R+ybNUlJ6gMYfgn0mwRxwuIHZ5xVlBiZAV99HstHCZ3iC5y4Mthd+mHd+VrhGYBfhPG ue9g== Received: from rohan.internal.sifive.com ([12.206.222.5]) by smtp.gmail.com with ESMTPSA id z17-v6sm4776216pfl.146.2018.08.28.19.21.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Aug 2018 19:21:28 -0700 (PDT) From: Jim Wilson To: gcc-patches@gcc.gnu.org Cc: Jim Wilson Subject: [PATCH] Rewrite pic.md to improve medany and pic code size. Date: Tue, 28 Aug 2018 19:21:23 -0700 Message-Id: <20180829022123.25863-1-jimw@sifive.com> The pic.md file has patterns used only for the medany code model and for pic code. They match an unsplit 2-instruction address load pattern followed by a load or store instruction, and emit an assembler macro that expands to two instructions. This replaces 3 instructions with 2. Unfortunately, there are a lot of broken patterns in the file. It has things like (sign_extend:ANYI (mem:ANYI ...) which can't work, as the sign_extend needs to be a larger mode than the mem. There are also a lot of missing patterns. It has patterns for sign and zero extending loads, but not regular loads for instance. Fixing these problems required a major rewrite of the file. While doing this, I noticed a case that results in worse code, and had to change address costs to fix that. I also ended up adding a number of new mode attributes and mode iterators to support the new pic.md file. This was tested with cross rv{32,64}-{elf,linux} builds and checks using the medany code model. There were no regressions. I'm seeing about a 0.3% to 0.4% code size reduction for newlib/glibc libc.a/libc.so. This was also tested with a cross kernel build and boot on qemu to verify that I didn't break kernel builds. Committed. Jim gcc/ * config/riscv/pic.md: Rewrite. * config/riscv/riscv.c (riscv_address_insns): Return cost of 3 for invalid address. * config/riscv/riscv.md (ZERO_EXTEND_LOAD): Delete. (SOFTF, default_load, softload, softstore): New. --- gcc/config/riscv/pic.md | 113 ++++++++++++++++++++++++-------------- gcc/config/riscv/riscv.c | 8 ++- gcc/config/riscv/riscv.md | 16 +++++- 3 files changed, 91 insertions(+), 46 deletions(-) diff --git a/gcc/config/riscv/pic.md b/gcc/config/riscv/pic.md index a4a9732656c..942502058e0 100644 --- a/gcc/config/riscv/pic.md +++ b/gcc/config/riscv/pic.md @@ -22,71 +22,100 @@ ;; Simplify PIC loads to static variables. ;; These should go away once we figure out how to emit auipc discretely. -(define_insn "*local_pic_load_s" +(define_insn "*local_pic_load" [(set (match_operand:ANYI 0 "register_operand" "=r") - (sign_extend:ANYI (mem:ANYI (match_operand 1 "absolute_symbolic_operand" ""))))] + (mem:ANYI (match_operand 1 "absolute_symbolic_operand" "")))] + "USE_LOAD_ADDRESS_MACRO (operands[1])" + "\t%0,%1" + [(set (attr "length") (const_int 8))]) + +(define_insn "*local_pic_load_s" + [(set (match_operand:SUPERQI 0 "register_operand" "=r") + (sign_extend:SUPERQI (mem:SUBX (match_operand 1 "absolute_symbolic_operand" ""))))] "USE_LOAD_ADDRESS_MACRO (operands[1])" - "\t%0,%1" + "\t%0,%1" [(set (attr "length") (const_int 8))]) (define_insn "*local_pic_load_u" - [(set (match_operand:ZERO_EXTEND_LOAD 0 "register_operand" "=r") - (zero_extend:ZERO_EXTEND_LOAD (mem:ZERO_EXTEND_LOAD (match_operand 1 "absolute_symbolic_operand" ""))))] + [(set (match_operand:SUPERQI 0 "register_operand" "=r") + (zero_extend:SUPERQI (mem:SUBX (match_operand 1 "absolute_symbolic_operand" ""))))] "USE_LOAD_ADDRESS_MACRO (operands[1])" - "u\t%0,%1" + "u\t%0,%1" [(set (attr "length") (const_int 8))]) -(define_insn "*local_pic_load" - [(set (match_operand:ANYF 0 "register_operand" "=f") +;; We can support ANYF loads into X register if there is no double support +;; or if the target is 64-bit. + +(define_insn "*local_pic_load" + [(set (match_operand:ANYF 0 "register_operand" "=f,*r") (mem:ANYF (match_operand 1 "absolute_symbolic_operand" ""))) - (clobber (match_scratch:DI 2 "=r"))] - "TARGET_HARD_FLOAT && TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[1])" - "\t%0,%1,%2" + (clobber (match_scratch:P 2 "=r,X"))] + "TARGET_HARD_FLOAT && USE_LOAD_ADDRESS_MACRO (operands[1]) + && (!TARGET_DOUBLE_FLOAT || TARGET_64BIT)" + "@ + \t%0,%1,%2 + \t%0,%1" [(set (attr "length") (const_int 8))]) -(define_insn "*local_pic_load" +;; ??? For a 32-bit target with double float, a DF load into a X reg isn't +;; supported. ld is not valid in that case. Punt for now. Maybe add a split +;; for this later. + +(define_insn "*local_pic_load_32d" [(set (match_operand:ANYF 0 "register_operand" "=f") (mem:ANYF (match_operand 1 "absolute_symbolic_operand" ""))) - (clobber (match_scratch:SI 2 "=r"))] - "TARGET_HARD_FLOAT && !TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[1])" - "\t%0,%1,%2" + (clobber (match_scratch:P 2 "=r"))] + "TARGET_HARD_FLOAT && USE_LOAD_ADDRESS_MACRO (operands[1]) + && (TARGET_DOUBLE_FLOAT && !TARGET_64BIT)" + "\t%0,%1,%2" [(set (attr "length") (const_int 8))]) -(define_insn "*local_pic_loadu" - [(set (match_operand:SUPERQI 0 "register_operand" "=r") - (zero_extend:SUPERQI (mem:SUBX (match_operand 1 "absolute_symbolic_operand" ""))))] - "USE_LOAD_ADDRESS_MACRO (operands[1])" - "u\t%0,%1" +(define_insn "*local_pic_load_sf" + [(set (match_operand:SOFTF 0 "register_operand" "=r") + (mem:SOFTF (match_operand 1 "absolute_symbolic_operand" "")))] + "!TARGET_HARD_FLOAT && USE_LOAD_ADDRESS_MACRO (operands[1])" + "\t%0,%1" [(set (attr "length") (const_int 8))]) -(define_insn "*local_pic_storedi" - [(set (mem:ANYI (match_operand 0 "absolute_symbolic_operand" "")) - (match_operand:ANYI 1 "reg_or_0_operand" "rJ")) - (clobber (match_scratch:DI 2 "=&r"))] - "TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])" - "\t%z1,%0,%2" - [(set (attr "length") (const_int 8))]) +;; Simplify PIC stores to static variables. +;; These should go away once we figure out how to emit auipc discretely. -(define_insn "*local_pic_storesi" +(define_insn "*local_pic_store" [(set (mem:ANYI (match_operand 0 "absolute_symbolic_operand" "")) (match_operand:ANYI 1 "reg_or_0_operand" "rJ")) - (clobber (match_scratch:SI 2 "=&r"))] - "!TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])" - "\t%z1,%0,%2" + (clobber (match_scratch:P 2 "=&r"))] + "USE_LOAD_ADDRESS_MACRO (operands[0])" + "\t%z1,%0,%2" [(set (attr "length") (const_int 8))]) -(define_insn "*local_pic_storedi" +(define_insn "*local_pic_store" [(set (mem:ANYF (match_operand 0 "absolute_symbolic_operand" "")) - (match_operand:ANYF 1 "register_operand" "f")) - (clobber (match_scratch:DI 2 "=r"))] - "TARGET_HARD_FLOAT && TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])" - "\t%1,%0,%2" + (match_operand:ANYF 1 "register_operand" "f,*r")) + (clobber (match_scratch:P 2 "=r,&r"))] + "TARGET_HARD_FLOAT && USE_LOAD_ADDRESS_MACRO (operands[0]) + && (!TARGET_DOUBLE_FLOAT || TARGET_64BIT)" + "@ + \t%1,%0,%2 + \t%1,%0,%2" [(set (attr "length") (const_int 8))]) -(define_insn "*local_pic_storesi" - [(set (mem:ANYF (match_operand 0 "absolute_symbolic_operand" "")) - (match_operand:ANYF 1 "register_operand" "f")) - (clobber (match_scratch:SI 2 "=r"))] - "TARGET_HARD_FLOAT && !TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])" - "\t%1,%0,%2" +;; ??? For a 32-bit target with double float, a DF store from a X reg isn't +;; supported. sd is not valid in that case. Punt for now. Maybe add a split +;; for this later. + +(define_insn "*local_pic_store_32d" + [(set (match_operand:ANYF 0 "register_operand" "=f") + (mem:ANYF (match_operand 1 "absolute_symbolic_operand" ""))) + (clobber (match_scratch:P 2 "=r"))] + "TARGET_HARD_FLOAT && USE_LOAD_ADDRESS_MACRO (operands[1]) + && (TARGET_DOUBLE_FLOAT && !TARGET_64BIT)" + "\t%1,%0,%2" + [(set (attr "length") (const_int 8))]) + +(define_insn "*local_pic_store_sf" + [(set (mem:SOFTF (match_operand 0 "absolute_symbolic_operand" "")) + (match_operand:SOFTF 1 "register_operand" "r")) + (clobber (match_scratch:P 2 "=&r"))] + "!TARGET_HARD_FLOAT && USE_LOAD_ADDRESS_MACRO (operands[0])" + "\t%1,%0,%2" [(set (attr "length") (const_int 8))]) diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 69e70feaf33..9d6d981a42a 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -802,7 +802,13 @@ riscv_address_insns (rtx x, machine_mode mode, bool might_split_p) int n = 1; if (!riscv_classify_address (&addr, x, mode, false)) - return 0; + { + /* This could be a pattern from the pic.md file. In which case we want + this address to always have a cost of 3 to make it as expensive as the + most expensive symbol. This prevents constant propagation from + preferring symbols over register plus offset. */ + return 3; + } /* BLKmode is used for single unaligned loads and stores and should not count as a multiword mode. */ diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 613af9d79e4..95fbb282c7c 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -269,9 +269,6 @@ ;; Iterator for QImode extension patterns. (define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")]) -;; Iterator for extending loads. -(define_mode_iterator ZERO_EXTEND_LOAD [QI HI (SI "TARGET_64BIT")]) - ;; Iterator for hardware integer modes narrower than XLEN. (define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")]) @@ -282,6 +279,9 @@ (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT") (DF "TARGET_DOUBLE_FLOAT")]) +;; Iterator for floating-point modes that can be loaded into X registers. +(define_mode_iterator SOFTF [SF (DF "TARGET_64BIT")]) + ;; This attribute gives the length suffix for a sign- or zero-extension ;; instruction. (define_mode_attr size [(QI "b") (HI "h")]) @@ -289,9 +289,19 @@ ;; Mode attributes for loads. (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")]) +;; Instruction names for integer loads that aren't explicitly sign or zero +;; extended. See riscv_output_move and LOAD_EXTEND_OP. +(define_mode_attr default_load [(QI "lbu") (HI "lhu") (SI "lw") (DI "ld")]) + +;; Mode attribute for FP loads into integer registers. +(define_mode_attr softload [(SF "lw") (DF "ld")]) + ;; Instruction names for stores. (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")]) +;; Instruction names for FP stores from integer registers. +(define_mode_attr softstore [(SF "sw") (DF "sd")]) + ;; This attribute gives the best constraint to use for registers of ;; a given mode. (define_mode_attr reg [(SI "d") (DI "d") (CC "d")])