OSDN Git Service

* doc/install.texi (Prerequisites): Update documentation of
[pf3gnuchains/gcc-fork.git] / gcc / regmove.c
index bafbe4c..13a6d39 100644 (file)
@@ -1,6 +1,6 @@
 /* Move registers around to reduce number of move instructions needed.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -53,11 +53,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #define STACK_GROWS_DOWNWARD 0
 #endif
 
-static int perhaps_ends_bb_p   PARAMS ((rtx));
-static int optimize_reg_copy_1 PARAMS ((rtx, rtx, rtx));
-static void optimize_reg_copy_2        PARAMS ((rtx, rtx, rtx));
-static void optimize_reg_copy_3        PARAMS ((rtx, rtx, rtx));
-static void copy_src_to_dest   PARAMS ((rtx, rtx, rtx, int));
+static int perhaps_ends_bb_p (rtx);
+static int optimize_reg_copy_1 (rtx, rtx, rtx);
+static void optimize_reg_copy_2 (rtx, rtx, rtx);
+static void optimize_reg_copy_3 (rtx, rtx, rtx);
+static void copy_src_to_dest (rtx, rtx, rtx, int);
 static int *regmove_bb_head;
 
 struct match {
@@ -67,26 +67,24 @@ struct match {
   int early_clobber[MAX_RECOG_OPERANDS];
 };
 
-static rtx discover_flags_reg PARAMS ((void));
-static void mark_flags_life_zones PARAMS ((rtx));
-static void flags_set_1 PARAMS ((rtx, rtx, void *));
-
-static int try_auto_increment PARAMS ((rtx, rtx, rtx, rtx, HOST_WIDE_INT, int));
-static int find_matches PARAMS ((rtx, struct match *));
-static void replace_in_call_usage PARAMS ((rtx *, unsigned int, rtx, rtx));
-static int fixup_match_1 PARAMS ((rtx, rtx, rtx, rtx, rtx, int, int, int, FILE *))
-;
-static int reg_is_remote_constant_p PARAMS ((rtx, rtx, rtx));
-static int stable_and_no_regs_but_for_p PARAMS ((rtx, rtx, rtx));
-static int regclass_compatible_p PARAMS ((int, int));
-static int replacement_quality PARAMS ((rtx));
-static int fixup_match_2 PARAMS ((rtx, rtx, rtx, rtx, FILE *));
+static rtx discover_flags_reg (void);
+static void mark_flags_life_zones (rtx);
+static void flags_set_1 (rtx, rtx, void *);
+
+static int try_auto_increment (rtx, rtx, rtx, rtx, HOST_WIDE_INT, int);
+static int find_matches (rtx, struct match *);
+static void replace_in_call_usage (rtx *, unsigned int, rtx, rtx);
+static int fixup_match_1 (rtx, rtx, rtx, rtx, rtx, int, int, int, FILE *);
+static int reg_is_remote_constant_p (rtx, rtx, rtx);
+static int stable_and_no_regs_but_for_p (rtx, rtx, rtx);
+static int regclass_compatible_p (int, int);
+static int replacement_quality (rtx);
+static int fixup_match_2 (rtx, rtx, rtx, rtx, FILE *);
 
 /* Return nonzero if registers with CLASS1 and CLASS2 can be merged without
    causing too much register allocation problems.  */
 static int
-regclass_compatible_p (class0, class1)
-     int class0, class1;
+regclass_compatible_p (int class0, int class1)
 {
   return (class0 == class1
          || (reg_class_subset_p (class0, class1)
@@ -100,10 +98,8 @@ regclass_compatible_p (class0, class1)
    Iff INC_INSN_SET is nonzero, inc_insn has a destination different from src.
    Return nonzero for success.  */
 static int
-try_auto_increment (insn, inc_insn, inc_insn_set, reg, increment, pre)
-     rtx reg, insn, inc_insn ,inc_insn_set;
-     HOST_WIDE_INT increment;
-     int pre;
+try_auto_increment (rtx insn, rtx inc_insn, rtx inc_insn_set, rtx reg,
+                   HOST_WIDE_INT increment, int pre)
 {
   enum rtx_code inc_code;
 
@@ -167,11 +163,11 @@ try_auto_increment (insn, inc_insn, inc_insn_set, reg, increment, pre)
    if no flags were found.  Return pc_rtx if we got confused.  */
 
 static rtx
-discover_flags_reg ()
+discover_flags_reg (void)
 {
   rtx tmp;
   tmp = gen_rtx_REG (word_mode, 10000);
-  tmp = gen_add3_insn (tmp, tmp, GEN_INT (2));
+  tmp = gen_add3_insn (tmp, tmp, const2_rtx);
 
   /* If we get something that isn't a simple set, or a
      [(set ..) (clobber ..)], this whole function will go wrong.  */
@@ -220,8 +216,7 @@ static rtx flags_set_1_rtx;
 static int flags_set_1_set;
 
 static void
-mark_flags_life_zones (flags)
-     rtx flags;
+mark_flags_life_zones (rtx flags)
 {
   int flags_regno;
   int flags_nregs;
@@ -251,7 +246,7 @@ mark_flags_life_zones (flags)
   flags_nregs = 1;
 #else
   flags_regno = REGNO (flags);
-  flags_nregs = HARD_REGNO_NREGS (flags_regno, GET_MODE (flags));
+  flags_nregs = hard_regno_nregs[flags_regno][GET_MODE (flags)];
 #endif
   flags_set_1_rtx = flags;
 
@@ -261,8 +256,8 @@ mark_flags_life_zones (flags)
       rtx insn, end;
       int live;
 
-      insn = block->head;
-      end = block->end;
+      insn = BB_HEAD (block);
+      end = BB_END (block);
 
       /* Look out for the (unlikely) case of flags being live across
         basic block boundaries.  */
@@ -296,7 +291,7 @@ mark_flags_life_zones (flags)
 #endif
              PUT_MODE (insn, (live ? HImode : VOIDmode));
 
-             /* In either case, birth is denoted simply by it's presence
+             /* In either case, birth is denoted simply by its presence
                 as the destination of a set.  */
              flags_set_1_set = 0;
              note_stores (PATTERN (insn), flags_set_1, NULL);
@@ -319,9 +314,7 @@ mark_flags_life_zones (flags)
 /* A subroutine of mark_flags_life_zones, called through note_stores.  */
 
 static void
-flags_set_1 (x, pat, data)
-     rtx x, pat;
-     void *data ATTRIBUTE_UNUSED;
+flags_set_1 (rtx x, rtx pat, void *data ATTRIBUTE_UNUSED)
 {
   if (GET_CODE (pat) == SET
       && reg_overlap_mentioned_p (x, flags_set_1_rtx))
@@ -336,8 +329,7 @@ static int *regno_src_regno;
    a candidate for tying to a hard register, since the output might in
    turn be a candidate to be tied to a different hard register.  */
 static int
-replacement_quality (reg)
-     rtx reg;
+replacement_quality (rtx reg)
 {
   int src_regno;
 
@@ -368,8 +360,7 @@ replacement_quality (reg)
 \f
 /* Return 1 if INSN might end a basic block.  */
 
-static int perhaps_ends_bb_p (insn)
-     rtx insn;
+static int perhaps_ends_bb_p (rtx insn)
 {
   switch (GET_CODE (insn))
     {
@@ -384,7 +375,7 @@ static int perhaps_ends_bb_p (insn)
         very conservative.  */
       if (nonlocal_goto_handler_labels)
        return 1;
-      /* FALLTHRU */
+      /* Fall through.  */
     default:
       return can_throw_internal (insn);
     }
@@ -402,10 +393,7 @@ static int perhaps_ends_bb_p (insn)
    register-register copy.  */
 
 static int
-optimize_reg_copy_1 (insn, dest, src)
-     rtx insn;
-     rtx dest;
-     rtx src;
+optimize_reg_copy_1 (rtx insn, rtx dest, rtx src)
 {
   rtx p, q;
   rtx note;
@@ -601,10 +589,7 @@ optimize_reg_copy_1 (insn, dest, src)
    this for hard registers since the substitutions we may make might fail.  */
 
 static void
-optimize_reg_copy_2 (insn, dest, src)
-     rtx insn;
-     rtx dest;
-     rtx src;
+optimize_reg_copy_2 (rtx insn, rtx dest, rtx src)
 {
   rtx p, q;
   rtx set;
@@ -662,10 +647,7 @@ optimize_reg_copy_2 (insn, dest, src)
    the remaining accesses to use the appropriate SUBREG.  This allows
    SRC and DEST to be tied later.  */
 static void
-optimize_reg_copy_3 (insn, dest, src)
-     rtx insn;
-     rtx dest;
-     rtx src;
+optimize_reg_copy_3 (rtx insn, rtx dest, rtx src)
 {
   rtx src_reg = XEXP (src, 0);
   int src_no = REGNO (src_reg);
@@ -724,7 +706,7 @@ optimize_reg_copy_3 (insn, dest, src)
       if (! INSN_P (p))
        continue;
 
-      /* Make a tenative change.  */
+      /* Make a tentative change.  */
       validate_replace_rtx_group (src_reg, subreg, p);
     }
 
@@ -750,11 +732,7 @@ optimize_reg_copy_3 (insn, dest, src)
    instead moving the value to dest directly before the operation.  */
 
 static void
-copy_src_to_dest (insn, src, dest, old_max_uid)
-     rtx insn;
-     rtx src;
-     rtx dest;
-     int old_max_uid;
+copy_src_to_dest (rtx insn, rtx src, rtx dest, int old_max_uid)
 {
   rtx seq;
   rtx link;
@@ -832,7 +810,7 @@ copy_src_to_dest (insn, src, dest, old_max_uid)
          bb = regmove_bb_head[insn_uid];
          if (bb >= 0)
            {
-             BLOCK_HEAD (bb) = move_insn;
+             BB_HEAD (BASIC_BLOCK (bb)) = move_insn;
              regmove_bb_head[insn_uid] = -1;
            }
        }
@@ -871,10 +849,7 @@ copy_src_to_dest (insn, src, dest, old_max_uid)
    the first insn in the function.  */
 
 static int
-reg_is_remote_constant_p (reg, insn, first)
-     rtx reg;
-     rtx insn;
-     rtx first;
+reg_is_remote_constant_p (rtx reg, rtx insn, rtx first)
 {
   rtx p;
 
@@ -939,9 +914,7 @@ reg_is_remote_constant_p (reg, insn, first)
    hard register as ultimate source, like the frame pointer.  */
 
 static int
-fixup_match_2 (insn, dst, src, offset, regmove_dump_file)
-     rtx insn, dst, src, offset;
-     FILE *regmove_dump_file;
+fixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset, FILE *regmove_dump_file)
 {
   rtx p, dst_death = 0;
   int length, num_calls = 0;
@@ -1063,10 +1036,7 @@ fixup_match_2 (insn, dst, src, offset, regmove_dump_file)
    (or 0 if none should be output).  */
 
 void
-regmove_optimize (f, nregs, regmove_dump_file)
-     rtx f;
-     int nregs;
-     FILE *regmove_dump_file;
+regmove_optimize (rtx f, int nregs, FILE *regmove_dump_file)
 {
   int old_max_uid = get_max_uid ();
   rtx insn;
@@ -1085,13 +1055,13 @@ regmove_optimize (f, nregs, regmove_dump_file)
      can suppress some optimizations in those zones.  */
   mark_flags_life_zones (discover_flags_reg ());
 
-  regno_src_regno = (int *) xmalloc (sizeof *regno_src_regno * nregs);
+  regno_src_regno = xmalloc (sizeof *regno_src_regno * nregs);
   for (i = nregs; --i >= 0; ) regno_src_regno[i] = -1;
 
-  regmove_bb_head = (int *) xmalloc (sizeof (int) * (old_max_uid + 1));
+  regmove_bb_head = xmalloc (sizeof (int) * (old_max_uid + 1));
   for (i = old_max_uid; i >= 0; i--) regmove_bb_head[i] = -1;
   FOR_EACH_BB (bb)
-    regmove_bb_head[INSN_UID (bb->head)] = bb->index;
+    regmove_bb_head[INSN_UID (BB_HEAD (bb))] = bb->index;
 
   /* A forward/backward pass.  Replace output operands with input operands.  */
 
@@ -1521,13 +1491,13 @@ regmove_optimize (f, nregs, regmove_dump_file)
      ends.  Fix that here.  */
   FOR_EACH_BB (bb)
     {
-      rtx end = bb->end;
+      rtx end = BB_END (bb);
       rtx new = end;
       rtx next = NEXT_INSN (new);
       while (next != 0 && INSN_UID (next) >= old_max_uid
-            && (bb->next_bb == EXIT_BLOCK_PTR || bb->next_bb->head != next))
+            && (bb->next_bb == EXIT_BLOCK_PTR || BB_HEAD (bb->next_bb) != next))
        new = next, next = NEXT_INSN (new);
-      bb->end = new;
+      BB_END (bb) = new;
     }
 
  done:
@@ -1543,9 +1513,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
    Initialize the info in MATCHP based on the constraints.  */
 
 static int
-find_matches (insn, matchp)
-     rtx insn;
-     struct match *matchp;
+find_matches (rtx insn, struct match *matchp)
 {
   int likely_spilled[MAX_RECOG_OPERANDS];
   int op_no;
@@ -1633,11 +1601,7 @@ find_matches (insn, matchp)
    assumed to be in INSN.  */
 
 static void
-replace_in_call_usage (loc, dst_reg, src, insn)
-     rtx *loc;
-     unsigned int dst_reg;
-     rtx src;
-     rtx insn;
+replace_in_call_usage (rtx *loc, unsigned int dst_reg, rtx src, rtx insn)
 {
   rtx x = *loc;
   enum rtx_code code;
@@ -1676,11 +1640,9 @@ replace_in_call_usage (loc, dst_reg, src, insn)
    Return nonzero for success.  */
 
 static int
-fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number,
-              match_number, regmove_dump_file)
-     rtx insn, set, src, src_subreg, dst;
-     int backward, operand_number, match_number;
-     FILE *regmove_dump_file;
+fixup_match_1 (rtx insn, rtx set, rtx src, rtx src_subreg, rtx dst,
+              int backward, int operand_number, int match_number,
+              FILE *regmove_dump_file)
 {
   rtx p;
   rtx post_inc = 0, post_inc_set = 0, search_end = 0;
@@ -2070,7 +2032,7 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number,
 }
 
 
-/* return nonzero if X is stable and mentions no regsiters but for
+/* Return nonzero if X is stable and mentions no registers but for
    mentioning SRC or mentioning / changing DST .  If in doubt, presume
    it is unstable.
    The rationale is that we want to check if we can move an insn easily
@@ -2079,13 +2041,18 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number,
    leave the burden to update REG_DEAD / REG_UNUSED notes, so we don't
    want any registers but SRC and DST.  */
 static int
-stable_and_no_regs_but_for_p (x, src, dst)
-     rtx x, src, dst;
+stable_and_no_regs_but_for_p (rtx x, rtx src, rtx dst)
 {
   RTX_CODE code = GET_CODE (x);
   switch (GET_RTX_CLASS (code))
     {
-    case '<': case '1': case 'c': case '2': case 'b': case '3':
+    case RTX_UNARY:
+    case RTX_BIN_ARITH:
+    case RTX_COMM_ARITH:
+    case RTX_COMPARE:
+    case RTX_COMM_COMPARE:
+    case RTX_TERNARY:
+    case RTX_BITFIELD_OPS:
       {
        int i;
        const char *fmt = GET_RTX_FORMAT (code);
@@ -2095,7 +2062,7 @@ stable_and_no_regs_but_for_p (x, src, dst)
              return 0;
        return 1;
       }
-    case 'o':
+    case RTX_OBJ:
       if (code == REG)
        return x == src || x == dst;
       /* If this is a MEM, look inside - there might be a register hidden in
@@ -2103,7 +2070,7 @@ stable_and_no_regs_but_for_p (x, src, dst)
       if (code == MEM
          && ! stable_and_no_regs_but_for_p (XEXP (x, 0), src, dst))
        return 0;
-      /* fall through */
+      /* Fall through.  */
     default:
       return ! rtx_unstable_p (x);
     }
@@ -2140,21 +2107,21 @@ struct csa_memlist
   struct csa_memlist *next;
 };
 
-static int stack_memref_p              PARAMS ((rtx));
-static rtx single_set_for_csa          PARAMS ((rtx));
-static void free_csa_memlist           PARAMS ((struct csa_memlist *));
-static struct csa_memlist *record_one_stack_memref
-  PARAMS ((rtx, rtx *, struct csa_memlist *));
-static int try_apply_stack_adjustment
-  PARAMS ((rtx, struct csa_memlist *, HOST_WIDE_INT, HOST_WIDE_INT));
-static void combine_stack_adjustments_for_block PARAMS ((basic_block));
-static int record_stack_memrefs        PARAMS ((rtx *, void *));
+static int stack_memref_p (rtx);
+static rtx single_set_for_csa (rtx);
+static void free_csa_memlist (struct csa_memlist *);
+static struct csa_memlist *record_one_stack_memref (rtx, rtx *,
+                                                   struct csa_memlist *);
+static int try_apply_stack_adjustment (rtx, struct csa_memlist *,
+                                      HOST_WIDE_INT, HOST_WIDE_INT);
+static void combine_stack_adjustments_for_block (basic_block);
+static int record_stack_memrefs (rtx *, void *);
 
 
 /* Main entry point for stack adjustment combination.  */
 
 void
-combine_stack_adjustments ()
+combine_stack_adjustments (void)
 {
   basic_block bb;
 
@@ -2165,8 +2132,7 @@ combine_stack_adjustments ()
 /* Recognize a MEM of the form (sp) or (plus sp const).  */
 
 static int
-stack_memref_p (x)
-     rtx x;
+stack_memref_p (rtx x)
 {
   if (GET_CODE (x) != MEM)
     return 0;
@@ -2186,8 +2152,7 @@ stack_memref_p (x)
    tying fp and sp adjustments.  */
 
 static rtx
-single_set_for_csa (insn)
-     rtx insn;
+single_set_for_csa (rtx insn)
 {
   int i;
   rtx tmp = single_set (insn);
@@ -2221,8 +2186,7 @@ single_set_for_csa (insn)
 /* Free the list of csa_memlist nodes.  */
 
 static void
-free_csa_memlist (memlist)
-     struct csa_memlist *memlist;
+free_csa_memlist (struct csa_memlist *memlist)
 {
   struct csa_memlist *next;
   for (; memlist ; memlist = next)
@@ -2236,13 +2200,11 @@ free_csa_memlist (memlist)
    It is already known that the memory is stack_memref_p.  */
 
 static struct csa_memlist *
-record_one_stack_memref (insn, mem, next_memlist)
-     rtx insn, *mem;
-     struct csa_memlist *next_memlist;
+record_one_stack_memref (rtx insn, rtx *mem, struct csa_memlist *next_memlist)
 {
   struct csa_memlist *ml;
 
-  ml = (struct csa_memlist *) xmalloc (sizeof (*ml));
+  ml = xmalloc (sizeof (*ml));
 
   if (XEXP (*mem, 0) == stack_pointer_rtx)
     ml->sp_offset = 0;
@@ -2260,10 +2222,8 @@ record_one_stack_memref (insn, mem, next_memlist)
    as each of the memories in MEMLIST.  Return true on success.  */
 
 static int
-try_apply_stack_adjustment (insn, memlist, new_adjust, delta)
-     rtx insn;
-     struct csa_memlist *memlist;
-     HOST_WIDE_INT new_adjust, delta;
+try_apply_stack_adjustment (rtx insn, struct csa_memlist *memlist, HOST_WIDE_INT new_adjust,
+                           HOST_WIDE_INT delta)
 {
   struct csa_memlist *ml;
   rtx set;
@@ -2299,9 +2259,7 @@ struct record_stack_memrefs_data
 };
 
 static int
-record_stack_memrefs (xp, data)
-     rtx *xp;
-     void *data;
+record_stack_memrefs (rtx *xp, void *data)
 {
   rtx x = *xp;
   struct record_stack_memrefs_data *d =
@@ -2323,14 +2281,14 @@ record_stack_memrefs (xp, data)
       return 1;
     case REG:
       /* ??? We want be able to handle non-memory stack pointer
-        references later.  For now just discard all insns refering to
+        references later.  For now just discard all insns referring to
         stack pointer outside mem expressions.  We would probably
         want to teach validate_replace to simplify expressions first.
 
         We can't just compare with STACK_POINTER_RTX because the
         reference to the stack pointer might be in some other mode.
         In particular, an explicit clobber in an asm statement will
-        result in a QImode clober.  */
+        result in a QImode clobber.  */
       if (REGNO (x) == STACK_POINTER_REGNUM)
        return 1;
       break;
@@ -2343,8 +2301,7 @@ record_stack_memrefs (xp, data)
 /* Subroutine of combine_stack_adjustments, called for each basic block.  */
 
 static void
-combine_stack_adjustments_for_block (bb)
-     basic_block bb;
+combine_stack_adjustments_for_block (basic_block bb)
 {
   HOST_WIDE_INT last_sp_adjust = 0;
   rtx last_sp_set = NULL_RTX;
@@ -2353,9 +2310,9 @@ combine_stack_adjustments_for_block (bb)
   struct record_stack_memrefs_data data;
   bool end_of_block = false;
 
-  for (insn = bb->head; !end_of_block ; insn = next)
+  for (insn = BB_HEAD (bb); !end_of_block ; insn = next)
     {
-      end_of_block = insn == bb->end;
+      end_of_block = insn == BB_END (bb);
       next = NEXT_INSN (insn);
 
       if (! INSN_P (insn))