]> gcc.gnu.org Git - gcc.git/commitdiff
Change MEMORY_MOVE_COST defs and uses to be able to take register class into account.
authorKen Raeburn <raeburn@cygnus.com>
Mon, 16 Mar 1998 11:56:25 +0000 (11:56 +0000)
committerKen Raeburn <raeburn@gcc.gnu.org>
Mon, 16 Mar 1998 11:56:25 +0000 (11:56 +0000)
Change MEMORY_MOVE_COST defs and uses to be able to take register class into
account.  Change mips def to actually do so, others to just ignore extra args.
Doc changes too.

From-SVN: r18621

16 files changed:
gcc/ChangeLog
gcc/config/1750a/1750a.h
gcc/config/a29k/a29k.h
gcc/config/alpha/alpha.h
gcc/config/arc/arc.h
gcc/config/arm/arm.h
gcc/config/dsp16xx/dsp16xx.h
gcc/config/i386/i386.h
gcc/config/m32r/m32r.h
gcc/config/m88k/m88k.h
gcc/config/mips/mips.h
gcc/config/rs6000/rs6000.h
gcc/regclass.c
gcc/reload.h
gcc/reload1.c
gcc/tm.texi

index 532625af90c5744f2a6fd602e35a39be3e595b78..8f95e8751cdb2d60ee1957613cad6ca041eb43ce 100644 (file)
@@ -1,3 +1,22 @@
+Mon Mar 16 12:12:36 1998  Ken Raeburn  <raeburn@cygnus.com>
+
+       * reload.h (MEMORY_MOVE_COST): Define here if not already defined;
+       if HAVE_SECONDARY_RELOADS, factor in copying cost.
+       (memory_move_secondary_cost): Declare.
+       * regclass.c (MEMORY_MOVE_COST): Don't define default here.
+       (memory_move_secondary_cost) [HAVE_SECONDARY_RELOADS]: New
+       function.
+       (regclass, record_reg_classes, copy_cost, record_address_regs):
+       Pass register class and direction of move to MEMORY_MOVE_COST.
+       * reload1.c (MEMORY_MOVE_COST): Don't define default here.
+       (emit_reload_insns, reload_cse_simplify_set): Pass register class
+       and direction of move to MEMORY_MOVE_COST.
+       * 1750a.c, a29k.h, alpha.h, arc.h, arm.h, dsp16xx.h, i386.h,
+       m32r.h, m88k.h, rs6000.h (MEMORY_MOVE_COST): Add extra ignored
+       arguments to definition, even in comments.
+       * mips.h (MEMORY_MOVE_COST): Add extra arguments; add
+       memory_move_secondary_cost result to cpu-specific cost.
+
 Mon Mar 16 11:16:50 1998  Jim Wilson  <wilson@cygnus.com>
 
        * README.gnat: New file.
index ad6c4be9c2e684515e8072d0472ba663009c9f61..6c5e9e3dfcabb5b4a97927f4a1eebd0d3bb80139 100644 (file)
@@ -910,7 +910,7 @@ enum reg_class { NO_REGS, R2, R0_1, INDEX_REGS, BASE_REGS, ALL_REGS, LIM_REG_CLA
 
 #define REGISTER_MOVE_COST(FROM,TO)    2
 
-#define MEMORY_MOVE_COST(M)            4
+#define MEMORY_MOVE_COST(M,C,I)                4
 
 /* Tell final.c how to eliminate redundant test instructions.  */
 
index 71c270068beffb4624352e3af1b92b737ce29f54..d65beb4ff2812bf9ee4ac6e20083d12ddf4d7430 100644 (file)
@@ -681,7 +681,7 @@ extern struct rtx_def *a29k_get_reloaded_address ();
    this higher.  In addition, we need to keep it more expensive than the
    most expensive register-register copy.  */
 
-#define MEMORY_MOVE_COST(MODE) 6
+#define MEMORY_MOVE_COST(MODE,CLASS,IN) 6
 
 /* A C statement (sans semicolon) to update the integer variable COST
    based on the relationship between INSN that is dependent on
index 3e52db740ad1e9ee96d6a98a8377ac1fe22b93d2..be3030ea19930cd1f06aa11ac4eaf5f2dd912a3c 100644 (file)
@@ -789,7 +789,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
    On the Alpha, bump this up a bit.  */
 
 extern int alpha_memory_latency;
-#define MEMORY_MOVE_COST(MODE)  (2*alpha_memory_latency)
+#define MEMORY_MOVE_COST(MODE,CLASS,IN)  (2*alpha_memory_latency)
 
 /* Provide the cost of a branch.  Exact meaning under development.  */
 #define BRANCH_COST 5
index 3d7f2b2910f5823477ac2c9f1a5264c0fd4b7b24..c4696ea5542b0f4fb21c05d20d77a4ddf131d27f 100644 (file)
@@ -1102,7 +1102,7 @@ arc_select_cc_mode (OP, X, Y)
 /* Compute the cost of moving data between registers and memory.  */
 /* Memory is 3 times as expensive as registers.
    ??? Is that the right way to look at it?  */
-#define MEMORY_MOVE_COST(MODE) \
+#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
 (GET_MODE_SIZE (MODE) <= UNITS_PER_WORD ? 6 : 12)
 
 /* The cost of a branch insn.  */
index 7c28c646ce115c48b5b5f5db206242e67a1f1ceb..0adf6dc6eabfbf45bdaffb503a234f077ee532b9 100644 (file)
@@ -1624,7 +1624,7 @@ extern struct rtx_def *legitimize_pic_address ();
    return arm_rtx_costs (X, CODE, OUTER_CODE);
 
 /* Moves to and from memory are quite expensive */
-#define MEMORY_MOVE_COST(MODE)  10
+#define MEMORY_MOVE_COST(MODE,CLASS,IN)  10
 
 /* All address computations that can be done are free, but rtx cost returns
    the same for practically all of them.  So we weight the different types
index 1c0f4dd53085aacbdad099cd1d3f40311aba16e6..61e6bf873efd11c55ccb84c7fef5da7b62bee40d 100644 (file)
@@ -1556,7 +1556,7 @@ extern struct dsp16xx_frame_info current_frame_info;
 
 /* A C expression for the cost of moving data of mode MODE between
    a register and memory. A value of 2 is the default. */
-#define MEMORY_MOVE_COST(MODE)                                  \
+#define MEMORY_MOVE_COST(MODE,CLASS,IN_P)                        \
   (GET_MODE_CLASS(MODE) == MODE_INT && MODE == QImode ? 12       \
    : 16)
 
index 53c08b03b197df23c5410e5d64cea18de6274eca..b910e77fd65405b958518dc6e912559e14883502 100644 (file)
@@ -2079,7 +2079,7 @@ while (0)
    between two registers, you should define this macro to express the
    relative cost.  */
 
-/* #define MEMORY_MOVE_COST(M) 2  */
+/* #define MEMORY_MOVE_COST(M,C,I) 2  */
 
 /* A C expression for the cost of a branch instruction.  A value of 1
    is the default; other values are interpreted relative to that.  */
index 79233e5d56054db8c7a61ee266085b2a810090fd..d438b49548800ddc7e12b6356093afad1f1e8ffb 100644 (file)
@@ -1268,7 +1268,7 @@ m32r_select_cc_mode (OP, X, Y)
 /* Compute the cost of moving data between registers and memory.  */
 /* Memory is 3 times as expensive as registers.
    ??? Is that the right way to look at it?  */
-#define MEMORY_MOVE_COST(MODE) \
+#define MEMORY_MOVE_COST(MODE,CLASS,IN_P) \
 (GET_MODE_SIZE (MODE) <= UNITS_PER_WORD ? 6 : 12)
 
 /* The cost of a branch insn.  */
index e35b87e70d77a10e35ad4279e67cfb1404a8726d..f0dac24a0dd7398bdbdfed0a0c8cdf4c617da82a 100644 (file)
@@ -1690,7 +1690,7 @@ enum reg_class { NO_REGS, AP_REG, XRF_REGS, GENERAL_REGS, AGRF_REGS,
 
 /* A C expressions returning the cost of moving data of MODE from a register
    to or from memory.  This is more costly than between registers.  */
-#define MEMORY_MOVE_COST(MODE) 4
+#define MEMORY_MOVE_COST(MODE,CLASS,IN) 4
 
 /* Provide the cost of a branch.  Exact meaning under development.  */
 #define BRANCH_COST (TARGET_88100 ? 1 : 2)
index 92368f65eb4ca44f911e3cf8ec6f3f3c9e62aa1b..4de5f5c66a0e51e809ec83617c8f350593ae9eef 100644 (file)
@@ -3534,8 +3534,9 @@ while (0)
    : 12)
 
 /* ??? Fix this to be right for the R8000.  */
-#define MEMORY_MOVE_COST(MODE) \
-  ((mips_cpu == PROCESSOR_R4000 || mips_cpu == PROCESSOR_R6000) ? 6 : 4)
+#define MEMORY_MOVE_COST(MODE,CLASS,TO_P) \
+  (((mips_cpu == PROCESSOR_R4000 || mips_cpu == PROCESSOR_R6000) ? 6 : 4) \
+   + memory_move_secondary_cost ((MODE), (CLASS), (TO_P)))
 
 /* A C expression for the cost of a branch instruction.  A value of
    1 is the default; other values are interpreted relative to that.  */
index 0982a641fbaeb2a26cd29989ee778ce6ea19de6b..cdc4bdc748d39db3da4551fa5bec12e18418986f 100644 (file)
@@ -800,7 +800,7 @@ extern int rs6000_debug_arg;                /* debug argument handling */
 
    On the RS/6000, bump this up a bit.  */
 
-#define MEMORY_MOVE_COST(MODE        \
+#define MEMORY_MOVE_COST(MODE,CLASS,IN)        \
   ((GET_MODE_CLASS (MODE) == MODE_FLOAT        \
     && (rs6000_cpu == PROCESSOR_RIOS1 || rs6000_cpu == PROCESSOR_PPC601) \
     ? 3 : 2) \
index 3432c79124f039ea2504665f0e012884c2d675e7..4cc02080c9faff3cde9570e0d6a59274cb5431a1 100644 (file)
@@ -42,10 +42,6 @@ Boston, MA 02111-1307, USA.  */
 #define REGISTER_MOVE_COST(x, y) 2
 #endif
 
-#ifndef MEMORY_MOVE_COST
-#define MEMORY_MOVE_COST(x) 4
-#endif
-
 /* If we have auto-increment or auto-decrement and we can have secondary
    reloads, we are not allowed to use classes requiring secondary
    reloads for pseudos auto-incremented since reload can't handle it.  */
@@ -431,6 +427,50 @@ init_regs ()
   init_reg_modes ();
 }
 
+#ifdef HAVE_SECONDARY_RELOADS
+/* Compute extra cost of moving registers to/from memory due to reloads.
+   Only needed if secondary reloads are required for memory moves.  */
+int
+memory_move_secondary_cost (mode, class, in)
+     enum machine_mode mode;
+     enum reg_class class;
+     int in;
+{
+  enum reg_class altclass;
+  int partial_cost = 0;
+  rtx mem;
+
+  /* We need a memory reference to feed to SECONDARY... macros.  */
+  mem = gen_rtx (MEM, mode, stack_pointer_rtx);
+
+  if (in)
+    altclass = SECONDARY_INPUT_RELOAD_CLASS (class, mode, mem);
+  else
+    altclass = SECONDARY_OUTPUT_RELOAD_CLASS (class, mode, mem);
+  if (altclass == NO_REGS)
+    return 0;
+
+  if (in)
+    partial_cost = REGISTER_MOVE_COST (altclass, class);
+  else
+    partial_cost = REGISTER_MOVE_COST (class, altclass);
+
+  if (class == altclass)
+    /* This isn't simply a copy-to-temporary situation.  Can't guess
+       what it is, so MEMORY_MOVE_COST really ought not to be calling
+       here in that case.
+
+       I'm tempted to put in an abort here, but returning this will
+       probably only give poor estimates, which is what we would've
+       had before this code anyways.  */
+    return partial_cost;
+
+  /* Check if the secondary reload register will also need a
+     secondary reload.  */
+  return memory_move_secondary_cost (mode, altclass, in) + partial_cost;
+}
+#endif
+
 /* Return a machine mode that is legitimate for hard reg REGNO and large
    enough to save nregs.  If we can't find one, return VOIDmode.  */
 
@@ -773,7 +813,8 @@ regclass (f, nregs)
                      && GET_CODE (XEXP (note, 0)) == MEM)
                    {
                      costs[REGNO (SET_DEST (set))].mem_cost
-                       -= (MEMORY_MOVE_COST (GET_MODE (SET_DEST (set)))
+                       -= (MEMORY_MOVE_COST (GET_MODE (SET_DEST (set)),
+                                             GENERAL_REGS, 1)
                            * loop_cost);
                      record_address_regs (XEXP (SET_SRC (set), 0),
                                           BASE_REG_CLASS, loop_cost * 2);
@@ -1290,7 +1331,8 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
                     a bit cheaper since we won't need an extra insn to
                     load it.  */
 
-                 pp->mem_cost = MEMORY_MOVE_COST (mode) - allows_mem;
+                 pp->mem_cost = (MEMORY_MOVE_COST (mode, classes[i], 1)
+                                 - allows_mem);
 
                  /* If we have assigned a class to this register in our
                     first pass, add a cost to this alternative corresponding
@@ -1328,7 +1370,7 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
             constant that could be placed into memory.  */
 
          else if (CONSTANT_P (op) && allows_mem)
-           alt_cost += MEMORY_MOVE_COST (mode);
+           alt_cost += MEMORY_MOVE_COST (mode, classes[i], 1);
          else
            alt_fail = 1;
        }
@@ -1447,7 +1489,7 @@ copy_cost (x, mode, class, to_p)
      else (constants).  */
 
   if (GET_CODE (x) == MEM || class == NO_REGS)
-    return MEMORY_MOVE_COST (mode);
+    return MEMORY_MOVE_COST (mode, class, to_p);
 
   else if (GET_CODE (x) == REG)
     return move_cost[(int) REGNO_REG_CLASS (REGNO (x))][(int) class];
@@ -1613,7 +1655,7 @@ record_address_regs (x, class, scale)
        register struct costs *pp = &costs[REGNO (x)];
        register int i;
 
-       pp->mem_cost += (MEMORY_MOVE_COST (Pmode) * scale) / 2;
+       pp->mem_cost += (MEMORY_MOVE_COST (Pmode, class, 1) * scale) / 2;
 
        for (i = 0; i < N_REG_CLASSES; i++)
          pp->cost[i] += (may_move_cost[i][(int) class] * scale) / 2;
index 14197299608a2e909f6d639b3b74d9f8a549e7d5..d86542fa5053c8e270a8f5e11e6dd4da71d65e18 100644 (file)
@@ -34,6 +34,17 @@ Boston, MA 02111-1307, USA.  */
 #define HAVE_SECONDARY_RELOADS
 #endif
 
+/* If MEMORY_MOVE_COST isn't defined, give it a default here.  */
+#ifndef MEMORY_MOVE_COST
+#ifdef HAVE_SECONDARY_RELOADS
+#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
+  (4 + memory_move_secondary_cost ((MODE), (CLASS), (IN)))
+#else
+#define MEMORY_MOVE_COST(MODE,CLASS,IN) 4
+#endif
+#endif
+extern int memory_move_secondary_cost PROTO ((enum machine_mode, enum reg_class, int));
+
 /* See reload.c and reload1.c for comments on these variables.  */
 
 /* Maximum number of reloads we can need.  */
index f416a8704df96c97d3bc1c129202d4a08c9948a8..e843ceabe92528e9b2d7b6b1238ecdd38e9c44da 100644 (file)
@@ -76,10 +76,6 @@ Boston, MA 02111-1307, USA.  */
 #ifndef REGISTER_MOVE_COST
 #define REGISTER_MOVE_COST(x, y) 2
 #endif
-
-#ifndef MEMORY_MOVE_COST
-#define MEMORY_MOVE_COST(x) 4
-#endif
 \f
 /* During reload_as_needed, element N contains a REG rtx for the hard reg
    into which reg N has been reloaded (perhaps for a previous insn).  */
@@ -6141,7 +6137,8 @@ emit_reload_insns (insn)
                  && ((REGNO_REG_CLASS (regno) != reload_reg_class[j]
                       && (REGISTER_MOVE_COST (REGNO_REG_CLASS (regno),
                                               reload_reg_class[j])
-                          >= MEMORY_MOVE_COST (mode)))
+                          >= MEMORY_MOVE_COST (mode, REGNO_REG_CLASS (regno),
+                                               1)))
 #ifdef SECONDARY_INPUT_RELOAD_CLASS
                      || (SECONDARY_INPUT_RELOAD_CLASS (reload_reg_class[j],
                                                        mode, oldequiv)
@@ -8204,13 +8201,15 @@ reload_cse_simplify_set (set, insn)
   if (side_effects_p (src) || true_regnum (src) >= 0)
     return 0;
 
+  dclass = REGNO_REG_CLASS (dreg);
+
   /* If memory loads are cheaper than register copies, don't change
      them.  */
-  if (GET_CODE (src) == MEM && MEMORY_MOVE_COST (GET_MODE (src)) < 2)
+  if (GET_CODE (src) == MEM
+      && MEMORY_MOVE_COST (GET_MODE (src), dclass, 1) < 2)
     return 0;
 
   dest_mode = GET_MODE (SET_DEST (set));
-  dclass = REGNO_REG_CLASS (dreg);
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     {
       if (i != dreg
index 00311bf792b9942cdbbf1783131e299d6b842b03..d8fb72407751824aefc0be2203531d68dd736965 100644 (file)
@@ -4512,14 +4512,26 @@ allow reload to verify that the constraints are met.  You should do this
 if the @samp{mov@var{m}} pattern's constraints do not allow such copying.
 
 @findex MEMORY_MOVE_COST
-@item MEMORY_MOVE_COST (@var{m})
-A C expression for the cost of moving data of mode @var{m} between a
-register and memory.  A value of 4 is the default; this cost is relative
-to those in @code{REGISTER_MOVE_COST}.
+@item MEMORY_MOVE_COST (@var{mode}, @var{class}, @var{in})
+A C expression for the cost of moving data of mode @var{mode} between a
+register of class @var{class} and memory; @var{in} is zero if the value
+is to be written to memory, non-zero if it is to be read in.  If this
+macro is not defined, the default cost is assumed to be 4, plus any costs
+that would be incurred copying via a secondary reload register, if
+needed.  This cost is relative to those in @code{REGISTER_MOVE_COST}.
 
 If moving between registers and memory is more expensive than between
 two registers, you should define this macro to express the relative cost.
 
+If a secondary reload register would be required for @var{class}, but the
+reload mechanism is more complex than copying via an intermediate, this
+macro should be defined to reflect the actual cost of the move.
+
+The function @code{memory_move_secondary_cost}, which is defined if
+secondary reloads are needed, will compute the costs due to copying; you
+can use this function if you need to take other factors into account as
+well, or if the default base value of 4 is not correct for your machine.
+
 @findex BRANCH_COST
 @item BRANCH_COST
 A C expression for the cost of a branch instruction.  A value of 1 is
This page took 0.116225 seconds and 5 git commands to generate.