OSDN Git Service

Support procedures for testing profile-directed optimizations.
[pf3gnuchains/gcc-fork.git] / gcc / regmove.c
index faff2e4..d26430a 100644 (file)
@@ -2,22 +2,22 @@
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001 Free Software Foundation, Inc.
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
 
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
 
 /* This module looks for cases where matching constraints would force
@@ -55,7 +55,6 @@ 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 rtx gen_add3_insn       PARAMS ((rtx, rtx, rtx));
 static void copy_src_to_dest   PARAMS ((rtx, rtx, rtx, int));
 static int *regmove_bb_head;
 
@@ -72,7 +71,7 @@ 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 *, int, rtx, rtx));
+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));
@@ -94,27 +93,6 @@ regclass_compatible_p (class0, class1)
              && ! CLASS_LIKELY_SPILLED_P (class1)));
 }
 
-/* Generate and return an insn body to add r1 and c,
-   storing the result in r0.  */
-static rtx
-gen_add3_insn (r0, r1, c)
-     rtx r0, r1, c;
-{
-  int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
-
-    if (icode == CODE_FOR_nothing
-      || ! ((*insn_data[icode].operand[0].predicate)
-           (r0, insn_data[icode].operand[0].mode))
-      || ! ((*insn_data[icode].operand[1].predicate)
-           (r1, insn_data[icode].operand[1].mode))
-      || ! ((*insn_data[icode].operand[2].predicate)
-           (c, insn_data[icode].operand[2].mode)))
-    return NULL_RTX;
-
-  return (GEN_FCN (icode) (r0, r1, c));
-}
-
-
 /* INC_INSN is an instruction that adds INCREMENT to REG.
    Try to fold INC_INSN as a post/pre in/decrement into INSN.
    Iff INC_INSN_SET is nonzero, inc_insn has a destination different from src.
@@ -437,7 +415,7 @@ optimize_reg_copy_1 (insn, dest, src)
   int sregno = REGNO (src);
   int dregno = REGNO (dest);
 
-  /* We don't want to mess with hard regs if register classes are small. */
+  /* We don't want to mess with hard regs if register classes are small.  */
   if (sregno == dregno
       || (SMALL_REGISTER_CLASSES
          && (sregno < FIRST_PSEUDO_REGISTER
@@ -1225,7 +1203,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
              if (recog_data.operand[match_no] != SET_DEST (set))
                continue;
 
-             /* If the operands already match, then there is nothing to do. */
+             /* If the operands already match, then there is nothing to do.  */
              if (operands_match_p (src, dst))
                continue;
 
@@ -1244,6 +1222,9 @@ regmove_optimize (f, nregs, regmove_dump_file)
              if (! regclass_compatible_p (src_class, dst_class))
                continue;
 
+             if (GET_MODE (src) != GET_MODE (dst))
+               continue;
+
              if (fixup_match_1 (insn, set, src, src_subreg, dst, pass,
                                 op_no, match_no,
                                 regmove_dump_file))
@@ -1301,7 +1282,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
                  || RTX_UNCHANGING_P (dst))
                continue;
 
-             /* If the operands already match, then there is nothing to do. */
+             /* If the operands already match, then there is nothing to do.  */
              if (operands_match_p (src, dst))
                continue;
 
@@ -1316,6 +1297,14 @@ regmove_optimize (f, nregs, regmove_dump_file)
              if (! set)
                continue;
 
+             /* Note that single_set ignores parts of a parallel set for
+                which one of the destinations is REG_UNUSED.  We can't
+                handle that here, since we can wind up rewriting things
+                such that a single register is set twice within a single
+                parallel.  */
+             if (reg_set_p (src, insn))
+               continue;
+
              /* match_no/dst must be a write-only operand, and
                 operand_operand/src must be a read-only operand.  */
              if (match.use[op_no] != READ
@@ -1619,7 +1608,7 @@ find_matches (insn, matchp)
 static void
 replace_in_call_usage (loc, dst_reg, src, insn)
      rtx *loc;
-     int dst_reg;
+     unsigned int dst_reg;
      rtx src;
      rtx insn;
 {
@@ -1996,7 +1985,7 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number,
        {
          /* ??? We can't scan past the end of a basic block without updating
             the register lifetime info
-            (REG_DEAD/basic_block_live_at_start). */
+            (REG_DEAD/basic_block_live_at_start).  */
          if (perhaps_ends_bb_p (q))
            break;
          else if (! INSN_P (q))