This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: Add IRA support to FRV


Hi Aldy, Hi Alex,

  OK, here is my official submission of a patch to add IRA support to
  the FRV target.  Actually there are three patches, although I have
  combined them into one submission.

  The first patch fixes an ICE when trying to compile any program.
  (It shows up as a configure failure when trying to build libgcc).
  This patch is independent of the IRA addition, but it was necessary
  to fix it in order to build the frv-elf toolchain so that I could
  test the IRA patch.

  The problem is that during register class initialisation the code in
  regclass.c:init_reg_autoinc() calls secondary_reload_class() which
  goes through to default_secondary_reload() in targhooks.c which then
  tries to use the reload_[in|out]_optab[] arrays, even though they
  have not yet been initialised.  This results in the 'icode' variable
  being given a value of 0, which triggers an assertion failure
  because pattern 0 does not take 3 operands.

  My original fix for this problem was a patch to
  default_secondary_reload() to treat an icode of 0 as if it were
  CODE_FOR_nothing, but I have reconsidered this since I cannot be
  sure that on another target icode 0 might very well be a valid insn
  code.  Instead I have gone for an FRV specific fix which defines a
  new function frv_secondary_reload() just to handle this problem.

  The second part of the patch is the addition of the
  IRA_COVER_CLASSES macro.  This is quite straightforward.

  The final part of the patch is a fix for the FR550 insn reservations
  because the new register allocator triggers a latent bug in the
  restrictions on floating point and media instructions.  Specifically
  the problem is that the exclusions do not prevent a single media
  instruction from being added to a packet that already contains two
  or more floating point instructions.  I have discussed this patch
  with Alex via email, and although it is not ideal, it will do for
  now.  (Well at least that is my opinion. :-)

  So - please may I apply this patch ?

  I am running the gcc and g++ testsuites locally with the patches
  applied and I will send the results to gcc-testresults one they are
  done (and assuming that the patch is approved).

Cheers
  Nick

gcc/ChangeLog
2008-09-16  Nick Clifton  <nickc@redhat.com>

	* config/frv/frv.h (IRA_COVER_CLASSES): Define.
        (SECONDARY_INPUT_RELOAD_CLASS): Omit unused argument in call
        to frv_secondary_reload_class.
        (SECONDARY_OUTPUT_RELOAD_CLASS): Likewise.
	* config/frv/frv.c (TARGET_SECONDARY_RELOAD): Define.
        (frv_secondary_reload_class): Omit unused parameter.
        (frv_secondary_reload): New function.  Handle the case when
        secondary_reload_class() is called before the reload_(in|out)
        _optabs have been initialised.
	* config/frv/frv-protos.h (frv_secondary_reload_class): Omit
	unused parameter.
	* config/frv/frv.md: Define an exclusion set between fr550_m0
	and fr550_f0.

Index: gcc/config/frv/frv.h
===================================================================
--- gcc/config/frv/frv.h	(revision 140386)
+++ gcc/config/frv/frv.h	(working copy)
@@ -1153,6 +1153,21 @@
   { 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0x1fff}, /* ALL_REGS */\
 }
 
+/* The following macro defines cover classes for Integrated Register
+   Allocator.  Cover classes is a set of non-intersected register
+   classes covering all hard registers used for register allocation
+   purpose.  Any move between two registers of a cover class should be
+   cheaper than load or store of the registers.  The macro value is
+   array of register classes with LIM_REG_CLASSES used as the end
+   marker.  */
+
+#define IRA_COVER_CLASSES						\
+{									\
+  GPR_REGS, FPR_REGS, ACC_REGS, ICR_REGS, FCR_REGS, ICC_REGS, FCC_REGS, \
+  ACCG_REGS, SPR_REGS,							\
+  LIM_REG_CLASSES							\
+}
+
 /* A C expression whose value is a register class containing hard register
    REGNO.  In general there is more than one such class; choose a class which
    is "minimal", meaning that no smaller class also contains the register.  */
@@ -1235,10 +1250,10 @@
 #define PREFERRED_RELOAD_CLASS(X, CLASS) CLASS
 
 #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
-  frv_secondary_reload_class (CLASS, MODE, X, TRUE)
+  frv_secondary_reload_class (CLASS, MODE, X)
 
 #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
-  frv_secondary_reload_class (CLASS, MODE, X, FALSE)
+  frv_secondary_reload_class (CLASS, MODE, X)
 
 /* A C expression whose value is nonzero if pseudos that have been assigned to
    registers of class CLASS would likely be spilled because registers of CLASS
Index: gcc/config/frv/frv.md
===================================================================
--- gcc/config/frv/frv.md	(revision 140386)
+++ gcc/config/frv/frv.md	(working copy)
@@ -1179,6 +1179,18 @@
 (define_cpu_unit "fr550_f0,fr550_f1,fr550_f2,fr550_f3" "fr550_float_media")
 (define_cpu_unit "fr550_m0,fr550_m1,fr550_m2,fr550_m3" "fr550_float_media")
 (exclusion_set "fr550_f1,fr550_f2,fr550_f3" "fr550_m1,fr550_m2,fr550_m3")
+(exclusion_set "fr550_m0" "fr550_f1,fr550_f2,fr550_f3")
+;; FIXME: This next exclusion set should be defined as well, so that we do
+;; not get a packet containing multiple media instructions plus a single
+;; floating point instruction.  At the moment we can get away with not
+;; defining it because gcc does not seem to generate such packets.
+;;
+;; If we do enable the exclusion however the insertion of fnop insns into
+;; a packet containing media instructions will stop working, because the
+;; fnop insn counts as a floating point instruction.  The correct solution
+;; is to fix the reservation for the fnop insn so that it does not have the
+;; same restrictions as ordinary floating point insns.
+;;(exclusion_set "fr550_f0" "fr550_m1,fr550_m2,fr550_m3")
 
 (define_reservation "fr550_float" "fr550_f0|fr550_f1|fr550_f2|fr550_f3")
 (define_reservation "fr550_media" "fr550_m0|fr550_m1|fr550_m2|fr550_m3")
Index: gcc/config/frv/frv-protos.h
===================================================================
--- gcc/config/frv/frv-protos.h	(revision 140386)
+++ gcc/config/frv/frv-protos.h	(working copy)
@@ -104,9 +104,8 @@
 extern int frv_trampoline_size		(void);
 extern void frv_initialize_trampoline	(rtx, rtx, rtx);
 extern enum reg_class frv_secondary_reload_class
-					(enum reg_class rclass,
-					 enum machine_mode mode,
-					 rtx x, int);
+					(enum reg_class,
+					 enum machine_mode, rtx);
 extern int frv_class_likely_spilled_p	(enum reg_class rclass);
 extern int frv_hard_regno_mode_ok	(int, enum machine_mode);
 extern int frv_hard_regno_nregs		(int, enum machine_mode);
Index: gcc/config/frv/frv.c
===================================================================
--- gcc/config/frv/frv.c	(revision 140386)
+++ gcc/config/frv/frv.c	(working copy)
@@ -381,6 +381,9 @@
 				  tree, bool);
 static void frv_output_dwarf_dtprel		(FILE *, int, rtx)
   ATTRIBUTE_UNUSED;
+static bool frv_secondary_reload                (bool, rtx, enum reg_class,
+						 enum machine_mode,
+						 secondary_reload_info *);
 
 /* Allow us to easily change the default for -malloc-cc.  */
 #ifndef DEFAULT_NO_ALLOC_CC
@@ -462,6 +465,9 @@
 #define TARGET_ASM_OUTPUT_DWARF_DTPREL frv_output_dwarf_dtprel
 #endif
 
+#undef  TARGET_SECONDARY_RELOAD
+#define TARGET_SECONDARY_RELOAD frv_secondary_reload
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #define FRV_SYMBOL_REF_TLS_P(RTX) \
@@ -6343,8 +6349,7 @@
 enum reg_class
 frv_secondary_reload_class (enum reg_class rclass,
                             enum machine_mode mode ATTRIBUTE_UNUSED,
-                            rtx x,
-                            int in_p ATTRIBUTE_UNUSED)
+                            rtx x)
 {
   enum reg_class ret;
 
@@ -6403,6 +6408,42 @@
   return ret;
 }
 
+/* This hook exists to catch the case where secondary_reload_class() is
+   called from init_reg_autoinc() in regclass.c - before the reload optabs
+   have been initialised.  */
+   
+static bool
+frv_secondary_reload (bool in_p, rtx x, enum reg_class reload_class,
+		      enum machine_mode reload_mode,
+		      secondary_reload_info * sri)
+{
+  enum reg_class rclass = NO_REGS;
+
+  if (sri->prev_sri && sri->prev_sri->t_icode != CODE_FOR_nothing)
+    {
+      sri->icode = sri->prev_sri->t_icode;
+      return NO_REGS;
+    }
+
+  rclass = frv_secondary_reload_class (reload_class, reload_mode, x);
+
+  if (rclass != NO_REGS)
+    {
+      enum insn_code icode = (in_p ? reload_in_optab[(int) reload_mode]
+			      : reload_out_optab[(int) reload_mode]);
+      if (icode == 0)
+	{
+	  /* This happens when then the reload_[in|out]_optabs have
+	     not been initialised.  */
+	  sri->t_icode = CODE_FOR_nothing;
+	  return rclass;
+	}
+    }
+
+  /* Fall back to the default secondary reload handler.  */
+  return default_secondary_reload (in_p, x, reload_class, reload_mode, sri);
+
+}
 
 /* A C expression whose value is nonzero if pseudos that have been assigned to
    registers of class RCLASS would likely be spilled because registers of RCLASS

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]