From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21688 invoked by alias); 9 Sep 2015 04:41:20 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 20837 invoked by uid 89); 9 Sep 2015 04:41:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.3 required=5.0 tests=AWL,BAYES_50,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 X-HELO: shards.monkeyblade.net Received: from shards.monkeyblade.net (HELO shards.monkeyblade.net) (149.20.54.216) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 09 Sep 2015 04:41:18 +0000 Received: from localhost (74-93-104-98-Washington.hfc.comcastbusiness.net [74.93.104.98]) (Authenticated sender: davem-davemloft) by shards.monkeyblade.net (Postfix) with ESMTPSA id 310CE592D41; Tue, 8 Sep 2015 21:41:16 -0700 (PDT) Date: Wed, 09 Sep 2015 07:25:00 -0000 Message-Id: <20150908.214115.1585933992134500164.davem@davemloft.net> To: gcc-patches@gcc.gnu.org CC: rth@redhat.com, ebotcazou@libertysurf.fr, vmakarov@redhat.com Subject: [PATCH] Convert SPARC to LRA From: David Miller Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2015-09/txt/msg00563.txt.bz2 The following patch converts the sparc backend over to LRA. The three major obstacles to overcome were: 1) The funky "U" constraint. It was a register constraint, but did not evaluate to a register class, and was used to help handling unaligned integer register pairs. It turns out to be unnecessary, since GENERAL_REGS plus HARD_REGNO_MODE_OK() do the job just fine now. 2) Sparc generates unreasonable amounts of subregging because it did not define PROMOTE_MODE(). All of the subreg LRA problems I was running into went away once I simply added the define. 3) The sethi/or patterns accepting direct symbol references and similar should not be available when flag_pic. The testsuite runs really well, there are no regressions and in fact the LRA conversion fixes some failures. I'm therefore reasonably confident in these changes, but I will not apply them just yet to give the other sparc maintainers some time to review and give feedback. 2015-09-08 David S. Miller * config/sparc/constraints.md: Make "U" constraint a real register constraint. * config/sparc/sparc.c (TARGET_LRA_P): Define. (D_MODES, DF_MODES): Add missing cast. (TF_MODES, TF_MODES_NO_S): Include T_MODE. (OF_MODES, OF_MODES_NO_S): Include O_MODE. (sparc_register_move_cost): Decrease Niagara/UltrsSPARC memory cost to 8. * config/sparc/sparc.h (PROMOTE_MODE): Define. * config/sparc/sparc.md (*movsi_lo_sum, *movsi_high): Do not provide these insn when flag_pic. diff --git a/gcc/config/sparc/constraints.md b/gcc/config/sparc/constraints.md index e12efa1..7a18879 100644 --- a/gcc/config/sparc/constraints.md +++ b/gcc/config/sparc/constraints.md @@ -44,6 +44,8 @@ (define_register_constraint "h" "(TARGET_V9 && TARGET_V8PLUS ? I64_REGS : NO_REGS)" "64-bit global or out register in V8+ mode") +(define_register_constraint "U" "(TARGET_ARCH32 ? GENERAL_REGS : NO_REGS)") + ;; Floating-point constant constraints (define_constraint "G" @@ -135,51 +137,6 @@ (match_code "mem") (match_test "memory_ok_for_ldd (op)"))) -;; This awkward register constraint is necessary because it is not -;; possible to express the "must be even numbered register" condition -;; using register classes. The problem is that membership in a -;; register class requires that all registers of a multi-regno -;; register be included in the set. It is add_to_hard_reg_set -;; and in_hard_reg_set_p which populate and test regsets with these -;; semantics. -;; -;; So this means that we would have to put both the even and odd -;; register into the register class, which would not restrict things -;; at all. -;; -;; Using a combination of GENERAL_REGS and HARD_REGNO_MODE_OK is not a -;; full solution either. In fact, even though IRA uses the macro -;; HARD_REGNO_MODE_OK to calculate which registers are prohibited from -;; use in certain modes, it still can allocate an odd hard register -;; for DImode values. This is due to how IRA populates the table -;; ira_useful_class_mode_regs[][]. It suffers from the same problem -;; as using a register class to describe this restriction. Namely, it -;; sets both the odd and even part of an even register pair in the -;; regset. Therefore IRA can and will allocate odd registers for -;; DImode values on 32-bit. -;; -;; There are legitimate cases where DImode values can end up in odd -;; hard registers, the most notable example is argument passing. -;; -;; What saves us is reload and the DImode splitters. Both are -;; necessary. The odd register splitters cannot match if, for -;; example, we have a non-offsetable MEM. Reload will notice this -;; case and reload the address into a single hard register. -;; -;; The real downfall of this awkward register constraint is that it does -;; not evaluate to a true register class like a bonafide use of -;; define_register_constraint would. This currently means that we cannot -;; use LRA on Sparc, since the constraint processing of LRA really depends -;; upon whether an extra constraint is for registers or not. It uses -;; reg_class_for_constraint, and checks it against NO_REGS. -(define_constraint "U" - "Pseudo-register or hard even-numbered integer register" - (and (match_test "TARGET_ARCH32") - (match_code "reg") - (ior (match_test "REGNO (op) < FIRST_PSEUDO_REGISTER") - (not (match_test "reload_in_progress && reg_renumber [REGNO (op)] < 0"))) - (match_test "register_ok_for_ldd (op)"))) - ;; Equivalent to 'T' but available in 64-bit mode (define_memory_constraint "W" "Memory reference for 'e' constraint floating-point register" diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index ed8a166..b41800c 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -808,6 +808,9 @@ char sparc_hard_reg_printed[8]; #undef TARGET_CAN_ELIMINATE #define TARGET_CAN_ELIMINATE sparc_can_eliminate +#undef TARGET_LRA_P +#define TARGET_LRA_P hook_bool_void_true + #undef TARGET_PREFERRED_RELOAD_CLASS #define TARGET_PREFERRED_RELOAD_CLASS sparc_preferred_reload_class @@ -4691,7 +4694,7 @@ enum sparc_mode_class { ((1 << (int) H_MODE) | (1 << (int) S_MODE) | (1 << (int) SF_MODE)) /* Modes for double-word and smaller quantities. */ -#define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE)) +#define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << (int) DF_MODE)) /* Modes for quad-word and smaller quantities. */ #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE)) @@ -4703,22 +4706,24 @@ enum sparc_mode_class { #define SF_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE)) /* Modes for double-float and smaller quantities. */ -#define DF_MODES (SF_MODES | (1 << (int) D_MODE) | (1 << DF_MODE)) +#define DF_MODES (SF_MODES | (1 << (int) D_MODE) | (1 << (int) DF_MODE)) /* Modes for quad-float and smaller quantities. */ -#define TF_MODES (DF_MODES | (1 << (int) TF_MODE)) +#define TF_MODES (DF_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE)) /* Modes for quad-float pairs and smaller quantities. */ -#define OF_MODES (TF_MODES | (1 << (int) OF_MODE)) +#define OF_MODES (TF_MODES | (1 << (int) O_MODE) | (1 << (int) OF_MODE)) /* Modes for double-float only quantities. */ #define DF_MODES_NO_S ((1 << (int) D_MODE) | (1 << (int) DF_MODE)) /* Modes for quad-float and double-float only quantities. */ -#define TF_MODES_NO_S (DF_MODES_NO_S | (1 << (int) TF_MODE)) +#define TF_MODES_NO_S \ + (DF_MODES_NO_S | (1 << (int) T_MODE) | (1 << (int) TF_MODE)) /* Modes for quad-float pairs and double-float only quantities. */ -#define OF_MODES_NO_S (TF_MODES_NO_S | (1 << (int) OF_MODE)) +#define OF_MODES_NO_S \ + (TF_MODES_NO_S | (1 << (int) O_MODE) | (1 << (int) OF_MODE)) /* Modes for condition codes. */ #define CC_MODES (1 << (int) CC_MODE) @@ -11188,7 +11193,7 @@ sparc_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED, || sparc_cpu == PROCESSOR_NIAGARA2 || sparc_cpu == PROCESSOR_NIAGARA3 || sparc_cpu == PROCESSOR_NIAGARA4) - return 12; + return 8; return 6; } diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 2cbe0d9..8343671 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -452,6 +452,17 @@ extern enum cmodel sparc_cmodel; /* target machine storage layout */ +/* Define this macro if it is advisable to hold scalars in registers + in a wider mode than that declared by the program. In such cases, + the value is constrained to be within the bounds of the declared + type, but kept valid in the wider mode. The signedness of the + extension may differ from that of the type. */ + +#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \ + if (GET_MODE_CLASS (MODE) == MODE_INT \ + && GET_MODE_SIZE (MODE) < (TARGET_ARCH64 ? 8 : 4)) \ + (MODE) = TARGET_ARCH64 ? DImode : SImode; + /* Define this if most significant bit is lowest numbered in instructions that operate on numbered bit-fields. */ #define BITS_BIG_ENDIAN 1 diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 5b9f051..f514d9f 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -1467,13 +1467,13 @@ [(set (match_operand:SI 0 "register_operand" "=r") (lo_sum:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "immediate_operand" "in")))] - "" + "! flag_pic" "or\t%1, %%lo(%a2), %0") (define_insn "*movsi_high" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (match_operand:SI 1 "immediate_operand" "in")))] - "" + "! flag_pic" "sethi\t%%hi(%a1), %0") ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC