OSDN Git Service

* cppinit.c (cpp_start_read): Free the imacros list as we
[pf3gnuchains/gcc-fork.git] / gcc / emit-rtl.c
index 7518614..d04e3d2 100644 (file)
@@ -2,22 +2,22 @@
    Copyright (C) 1987, 1988, 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.  */
 
 
 /* Middle-to-low level generation of rtx code and insns.
@@ -54,6 +54,7 @@ Boston, MA 02111-1307, USA.  */
 #include "bitmap.h"
 #include "basic-block.h"
 #include "ggc.h"
+#include "debug.h"
 
 /* Commonly used modes.  */
 
@@ -184,6 +185,10 @@ static int const_int_htab_eq            PARAMS ((const void *,
 static int rtx_htab_mark_1              PARAMS ((void **, void *));
 static void rtx_htab_mark               PARAMS ((void *));
 
+/* Probability of the conditional branch currently proceeded by try_split.
+   Set to -1 otherwise.  */
+int split_branch_probability = -1;
+
 \f
 /* Returns a hash code for X (which is a really a CONST_INT).  */
 
@@ -374,7 +379,7 @@ gen_rtx_SUBREG (mode, reg, offset)
 
 /* Generate a SUBREG representing the least-significant part
  * of REG if MODE is smaller than mode of REG, otherwise
- * paradoxical SUBREG. */
+ * paradoxical SUBREG.  */
 rtx
 gen_lowpart_SUBREG (mode, reg)
      enum machine_mode mode;
@@ -419,21 +424,13 @@ gen_lowpart_SUBREG (mode, reg)
 rtx
 gen_rtx VPARAMS ((enum rtx_code code, enum machine_mode mode, ...))
 {
-#ifndef ANSI_PROTOTYPES
-  enum rtx_code code;
-  enum machine_mode mode;
-#endif
-  va_list p;
   register int i;              /* Array indices...                     */
   register const char *fmt;    /* Current rtx's format...              */
   register rtx rt_val;         /* RTX to return to caller...           */
 
-  VA_START (p, mode);
-
-#ifndef ANSI_PROTOTYPES
-  code = va_arg (p, enum rtx_code);
-  mode = va_arg (p, enum machine_mode);
-#endif
+  VA_OPEN (p, mode);
+  VA_FIXEDARG (p, enum rtx_code, code);
+  VA_FIXEDARG (p, enum machine_mode, mode);
 
   switch (code)
     {
@@ -506,7 +503,7 @@ gen_rtx VPARAMS ((enum rtx_code code, enum machine_mode mode, ...))
       break;
     }
 
-  va_end (p);
+  VA_CLOSE (p);
   return rt_val;
 }
 
@@ -520,18 +517,11 @@ gen_rtx VPARAMS ((enum rtx_code code, enum machine_mode mode, ...))
 rtvec
 gen_rtvec VPARAMS ((int n, ...))
 {
-#ifndef ANSI_PROTOTYPES
-  int n;
-#endif
-  int i;
-  va_list p;
+  int i, save_n;
   rtx *vector;
 
-  VA_START (p, n);
-
-#ifndef ANSI_PROTOTYPES
-  n = va_arg (p, int);
-#endif
+  VA_OPEN (p, n);
+  VA_FIXEDARG (p, int, n);
 
   if (n == 0)
     return NULL_RTVEC;         /* Don't allocate an empty rtvec...     */
@@ -540,9 +530,12 @@ gen_rtvec VPARAMS ((int n, ...))
 
   for (i = 0; i < n; i++)
     vector[i] = va_arg (p, rtx);
-  va_end (p);
 
-  return gen_rtvec_v (n, vector);
+  /* The definition of VA_* in K&R C causes `n' to go out of scope.  */
+  save_n = n;
+  VA_CLOSE (p);
+
+  return gen_rtvec_v (save_n, vector);
 }
 
 rtvec
@@ -1478,12 +1471,12 @@ operand_subword (op, offset, validate_address, mode)
   if (mode == VOIDmode)
     abort ();
 
-  /* If OP is narrower than a word, fail. */
+  /* If OP is narrower than a word, fail.  */
   if (mode != BLKmode
       && (GET_MODE_SIZE (mode) < UNITS_PER_WORD))
     return 0;
 
-  /* If we want a word outside OP, return zero. */
+  /* If we want a word outside OP, return zero.  */
   if (mode != BLKmode
       && (offset + 1) * UNITS_PER_WORD > GET_MODE_SIZE (mode))
     return const0_rtx;
@@ -1631,11 +1624,15 @@ adjust_address (memref, mode, offset)
      will do memref tracking.  */
   rtx addr = XEXP (memref, 0);
 
+  /* ??? Prefer to create garbage instead of creating shared rtl.  */
+  addr = copy_rtx (addr);
+
   /* If MEMREF is a LO_SUM and the offset is within the alignment of the
      object, we can merge it into the LO_SUM.  */
   if (GET_MODE (memref) != BLKmode && GET_CODE (addr) == LO_SUM
       && offset >= 0
-      && offset < GET_MODE_ALIGNMENT (GET_MODE (memref)) / BITS_PER_UNIT)
+      && (unsigned HOST_WIDE_INT) offset
+         < GET_MODE_ALIGNMENT (GET_MODE (memref)) / BITS_PER_UNIT)
     addr = gen_rtx_LO_SUM (mode, XEXP (addr, 0),
                           plus_constant (XEXP (addr, 1), offset));
   else
@@ -1660,7 +1657,8 @@ adjust_address_nv (memref, mode, offset)
      object, we can merge it into the LO_SUM.  */
   if (GET_MODE (memref) != BLKmode && GET_CODE (addr) == LO_SUM
       && offset >= 0
-      && offset < GET_MODE_ALIGNMENT (GET_MODE (memref)) / BITS_PER_UNIT)
+      && (unsigned HOST_WIDE_INT) offset
+         < GET_MODE_ALIGNMENT (GET_MODE (memref)) / BITS_PER_UNIT)
     addr = gen_rtx_LO_SUM (mode, XEXP (addr, 0),
                           plus_constant (XEXP (addr, 1), offset));
   else
@@ -1876,7 +1874,7 @@ unshare_all_decls (blk)
 }
 
 /* Go through all virtual stack slots of a function and mark them as
-   not shared. */
+   not shared.  */
 static void
 reset_used_decls (blk)
      tree blk;
@@ -2485,9 +2483,19 @@ try_split (pat, trial, last)
 {
   rtx before = PREV_INSN (trial);
   rtx after = NEXT_INSN (trial);
-  rtx seq = split_insns (pat, trial);
   int has_barrier = 0;
   rtx tem;
+  rtx note, seq;
+  int probability;
+
+  if (any_condjump_p (trial)
+      && (note = find_reg_note (trial, REG_BR_PROB, 0)))
+    split_branch_probability = INTVAL (XEXP (note, 0));
+  probability = split_branch_probability;
+
+  seq = split_insns (pat, trial);
+
+  split_branch_probability = -1;
 
   /* If we are splitting a JUMP_INSN, it might be followed by a BARRIER.
      We may need to handle this specially.  */
@@ -2504,7 +2512,7 @@ try_split (pat, trial, last)
         it, in turn, will be split (SFmode on the 29k is an example).  */
       if (GET_CODE (seq) == SEQUENCE)
        {
-         int i;
+         int i, njumps = 0;
          rtx eh_note;
 
          /* Avoid infinite loop if any insn of the result matches
@@ -2517,9 +2525,27 @@ try_split (pat, trial, last)
          /* Mark labels.  */
          for (i = XVECLEN (seq, 0) - 1; i >= 0; i--)
            if (GET_CODE (XVECEXP (seq, 0, i)) == JUMP_INSN)
-             mark_jump_label (PATTERN (XVECEXP (seq, 0, i)),
-                              XVECEXP (seq, 0, i), 0);
-
+             {
+               rtx insn = XVECEXP (seq, 0, i);
+               mark_jump_label (PATTERN (insn),
+                                XVECEXP (seq, 0, i), 0);
+               njumps++;
+               if (probability != -1
+                   && any_condjump_p (insn)
+                   && !find_reg_note (insn, REG_BR_PROB, 0))
+                 {
+                   /* We can preserve the REG_BR_PROB notes only if exactly
+                      one jump is created, otherwise the machinde description
+                      is responsible for this step using
+                      split_branch_probability variable.  */
+                   if (njumps != 1)
+                     abort ();
+                   REG_NOTES (insn)
+                     = gen_rtx_EXPR_LIST (REG_BR_PROB,
+                                          GEN_INT (probability),
+                                          REG_NOTES (insn));
+                 }
+             }
          /* If we are splitting a CALL_INSN, look for the CALL_INSN
             in SEQ and copy our CALL_INSN_FUNCTION_USAGE to it.  */
          if (GET_CODE (trial) == CALL_INSN)
@@ -2576,8 +2602,8 @@ try_split (pat, trial, last)
       /* Return either the first or the last insn, depending on which was
         requested.  */
       return last
-               ? (after ? prev_active_insn (after) : last_insn)
-               : next_active_insn (before);
+               ? (after ? PREV_INSN (after) : last_insn)
+               : NEXT_INSN (before);
     }
 
   return trial;
@@ -3003,9 +3029,13 @@ remove_unnecessary_notes ()
 
              if (NOTE_LINE_NUMBER (tmp) == NOTE_INSN_BLOCK_BEG)
                {
-                 /* We just verified that this BLOCK matches us
-                    with the block_stack check above.  */
-                 if (debug_ignore_block (NOTE_BLOCK (insn)))
+                 /* We just verified that this BLOCK matches us with
+                    the block_stack check above.  Never delete the
+                    BLOCK for the outermost scope of the function; we
+                    can refer to names from that scope even if the
+                    block notes are messed up.  */
+                 if (! is_body_block (NOTE_BLOCK (insn))
+                     && (*debug_hooks->ignore_block) (NOTE_BLOCK (insn)))
                    {
                      remove_insn (tmp);
                      remove_insn (insn);
@@ -3564,7 +3594,7 @@ force_next_line_note ()
 }
 
 /* Place a note of KIND on insn INSN with DATUM as the datum. If a
-   note of this type already exists, remove it first. */
+   note of this type already exists, remove it first.  */
 
 void
 set_unique_reg_note (insn, kind, datum)
@@ -3825,7 +3855,7 @@ gen_sequence ()
   if (len == 1
       && ! RTX_FRAME_RELATED_P (first_insn)
       && GET_CODE (first_insn) == INSN
-      /* Don't throw away any reg notes. */
+      /* Don't throw away any reg notes.  */
       && REG_NOTES (first_insn) == 0)
     return PATTERN (first_insn);