public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Convert SPARC to LRA
@ 2015-09-09  7:25 David Miller
  2015-09-09 14:48 ` Mike Stump
                   ` (2 more replies)
  0 siblings, 3 replies; 35+ messages in thread
From: David Miller @ 2015-09-09  7:25 UTC (permalink / raw)
  To: gcc-patches; +Cc: rth, ebotcazou, vmakarov


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  <davem@davemloft.net>

	* 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;
 \f
 /* 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

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2016-11-04 11:56 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-09  7:25 [PATCH] Convert SPARC to LRA David Miller
2015-09-09 14:48 ` Mike Stump
2015-09-28  4:29   ` Hans-Peter Nilsson
2015-09-28  5:27     ` Jeff Law
2015-09-28 12:36       ` Oleg Endo
2015-09-28 19:23         ` David Miller
2015-09-28 18:49       ` Mike Stump
2015-09-28 19:39       ` Vladimir Makarov
2015-09-28 22:48         ` Segher Boessenkool
2015-09-29 13:43           ` Oleg Endo
2015-09-29 13:50             ` Jeff Law
2015-09-29 14:31               ` Richard Biener
2015-09-30  3:33                 ` Jeff Law
2015-09-30  7:29                   ` Sebastian Huber
2015-09-29 13:53           ` Jeff Law
2015-09-30  6:06             ` Vladimir Makarov
2015-09-30 15:47               ` Jeff Law
2015-09-30 16:39                 ` Segher Boessenkool
2015-10-02 17:12                   ` Jeff Law
2015-09-29 15:25           ` Peter Bergner
2015-10-01 20:21             ` Peter Bergner
2015-09-11 19:50 ` David Miller
2015-09-11 20:05   ` Richard Henderson
2015-09-12 14:34   ` Eric Botcazou
2015-09-13  8:32     ` David Miller
2015-09-14 17:30       ` Richard Henderson
2015-09-14 18:32         ` David Miller
2015-09-17  8:43           ` David Miller
2015-09-17 20:22     ` David Miller
2015-09-17 21:26       ` Eric Botcazou
2015-09-17 22:54         ` David Miller
2015-12-08 10:18 ` Sebastian Huber
2015-12-08 16:55   ` David Miller
2016-11-04 10:55     ` Sebastian Huber
2016-11-04 11:56       ` Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).