OSDN Git Service

* configure.in (all_headers, all_lib2funcs): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / cselib.c
index c0aa0e6..a3120d2 100644 (file)
@@ -2,26 +2,25 @@
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001 Free Software Foundation, Inc.
 
    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
 
 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.  */
 
 #include "config.h"
 #include "system.h"
 
 #include "config.h"
 #include "system.h"
-#include <setjmp.h>
 
 #include "rtl.h"
 #include "tm_p.h"
 
 #include "rtl.h"
 #include "tm_p.h"
@@ -60,7 +59,6 @@ static cselib_val *new_cselib_val     PARAMS ((unsigned int,
 static void add_mem_for_addr           PARAMS ((cselib_val *, cselib_val *,
                                                 rtx));
 static cselib_val *cselib_lookup_mem   PARAMS ((rtx, int));
 static void add_mem_for_addr           PARAMS ((cselib_val *, cselib_val *,
                                                 rtx));
 static cselib_val *cselib_lookup_mem   PARAMS ((rtx, int));
-static rtx cselib_subst_to_values      PARAMS ((rtx));
 static void cselib_invalidate_regno    PARAMS ((unsigned int,
                                                 enum machine_mode));
 static int cselib_mem_conflict_p       PARAMS ((rtx, rtx));
 static void cselib_invalidate_regno    PARAMS ((unsigned int,
                                                 enum machine_mode));
 static int cselib_mem_conflict_p       PARAMS ((rtx, rtx));
@@ -566,8 +564,6 @@ hash_rtx (x, mode, create)
   const char *fmt;
   unsigned int hash = 0;
 
   const char *fmt;
   unsigned int hash = 0;
 
-  /* repeat is used to turn tail-recursion into iteration.  */
- repeat:
   code = GET_CODE (x);
   hash += (unsigned) code + (unsigned) GET_MODE (x);
 
   code = GET_CODE (x);
   hash += (unsigned) code + (unsigned) GET_MODE (x);
 
@@ -637,18 +633,8 @@ hash_rtx (x, mode, create)
       if (fmt[i] == 'e')
        {
          rtx tem = XEXP (x, i);
       if (fmt[i] == 'e')
        {
          rtx tem = XEXP (x, i);
-         unsigned int tem_hash;
+         unsigned int tem_hash = hash_rtx (tem, 0, create);
 
 
-         /* If we are about to do the last recursive call
-            needed at this level, change it into iteration.
-            This function  is called enough to be worth it.  */
-         if (i == 0)
-           {
-             x = tem;
-             goto repeat;
-           }
-
-         tem_hash = hash_rtx (tem, 0, create);
          if (tem_hash == 0)
            return 0;
 
          if (tem_hash == 0)
            return 0;
 
@@ -718,7 +704,6 @@ add_mem_for_addr (addr_elt, mem_elt, x)
      cselib_val *addr_elt, *mem_elt;
      rtx x;
 {
      cselib_val *addr_elt, *mem_elt;
      rtx x;
 {
-  rtx new;
   struct elt_loc_list *l;
 
   /* Avoid duplicates.  */
   struct elt_loc_list *l;
 
   /* Avoid duplicates.  */
@@ -727,11 +712,10 @@ add_mem_for_addr (addr_elt, mem_elt, x)
        && CSELIB_VAL_PTR (XEXP (l->loc, 0)) == addr_elt)
       return;
 
        && CSELIB_VAL_PTR (XEXP (l->loc, 0)) == addr_elt)
       return;
 
-  new = gen_rtx_MEM (GET_MODE (x), addr_elt->u.val_rtx);
-  MEM_COPY_ATTRIBUTES (new, x);
-
   addr_elt->addr_list = new_elt_list (addr_elt->addr_list, mem_elt);
   addr_elt->addr_list = new_elt_list (addr_elt->addr_list, mem_elt);
-  mem_elt->locs = new_elt_loc_list (mem_elt->locs, new);
+  mem_elt->locs
+    = new_elt_loc_list (mem_elt->locs,
+                       replace_equiv_address_nv (x, addr_elt->u.val_rtx));
 }
 
 /* Subroutine of cselib_lookup.  Return a value for X, which is a MEM rtx.
 }
 
 /* Subroutine of cselib_lookup.  Return a value for X, which is a MEM rtx.
@@ -779,7 +763,7 @@ cselib_lookup_mem (x, create)
    X isn't actually modified; if modifications are needed, new rtl is
    allocated.  However, the return value can share rtl with X.  */
 
    X isn't actually modified; if modifications are needed, new rtl is
    allocated.  However, the return value can share rtl with X.  */
 
-static rtx
+rtx
 cselib_subst_to_values (x)
      rtx x;
 {
 cselib_subst_to_values (x)
      rtx x;
 {
@@ -802,15 +786,26 @@ cselib_subst_to_values (x)
     case MEM:
       e = cselib_lookup_mem (x, 0);
       if (! e)
     case MEM:
       e = cselib_lookup_mem (x, 0);
       if (! e)
-       abort ();
+       {
+         /* This happens for autoincrements.  Assign a value that doesn't
+            match any other.  */
+         e = new_cselib_val (++next_unknown_value, GET_MODE (x));
+       }
       return e->u.val_rtx;
 
       return e->u.val_rtx;
 
-      /* CONST_DOUBLEs must be special-cased here so that we won't try to
-        look up the CONST_DOUBLE_MEM inside.  */
     case CONST_DOUBLE:
     case CONST_INT:
       return x;
 
     case CONST_DOUBLE:
     case CONST_INT:
       return x;
 
+    case POST_INC:
+    case PRE_INC:
+    case POST_DEC:
+    case PRE_DEC:
+    case POST_MODIFY:
+    case PRE_MODIFY:
+      e = new_cselib_val (++next_unknown_value, GET_MODE (x));
+      return e->u.val_rtx;
+      
     default:
       break;
     }
     default:
       break;
     }
@@ -1006,7 +1001,7 @@ cselib_mem_conflict_p (mem_base, val)
   code = GET_CODE (val);
   switch (code)
     {
   code = GET_CODE (val);
   switch (code)
     {
-      /* Get rid of a few simple cases quickly. */
+      /* Get rid of a few simple cases quickly.  */
     case REG:
     case PC:
     case CC0:
     case REG:
     case PC:
     case CC0:
@@ -1193,8 +1188,15 @@ cselib_record_sets (insn)
   int i;
   struct set sets[MAX_SETS];
   rtx body = PATTERN (insn);
   int i;
   struct set sets[MAX_SETS];
   rtx body = PATTERN (insn);
+  rtx cond = 0;
 
   body = PATTERN (insn);
 
   body = PATTERN (insn);
+  if (GET_CODE (body) == COND_EXEC)
+    {
+      cond = COND_EXEC_TEST (body);
+      body = COND_EXEC_CODE (body);
+    }
+
   /* Find all sets.  */
   if (GET_CODE (body) == SET)
     {
   /* Find all sets.  */
   if (GET_CODE (body) == SET)
     {
@@ -1233,6 +1235,9 @@ cselib_record_sets (insn)
       /* We don't know how to record anything but REG or MEM.  */
       if (GET_CODE (dest) == REG || GET_CODE (dest) == MEM)
         {
       /* We don't know how to record anything but REG or MEM.  */
       if (GET_CODE (dest) == REG || GET_CODE (dest) == MEM)
         {
+         rtx src = sets[i].src;
+         if (cond)
+           src = gen_rtx_IF_THEN_ELSE (GET_MODE (src), cond, src, dest);
          sets[i].src_elt = cselib_lookup (sets[i].src, GET_MODE (dest), 1);
          if (GET_CODE (dest) == MEM)
            sets[i].dest_addr_elt = cselib_lookup (XEXP (dest, 0), Pmode, 1);
          sets[i].src_elt = cselib_lookup (sets[i].src, GET_MODE (dest), 1);
          if (GET_CODE (dest) == MEM)
            sets[i].dest_addr_elt = cselib_lookup (XEXP (dest, 0), Pmode, 1);
@@ -1268,8 +1273,8 @@ cselib_process_insn (insn)
 
   /* Forget everything at a CODE_LABEL, a volatile asm, or a setjmp.  */
   if (GET_CODE (insn) == CODE_LABEL
 
   /* Forget everything at a CODE_LABEL, a volatile asm, or a setjmp.  */
   if (GET_CODE (insn) == CODE_LABEL
-      || (GET_CODE (insn) == NOTE
-         && NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
+      || (GET_CODE (insn) == CALL_INSN
+         && find_reg_note (insn, REG_SETJMP, NULL))
       || (GET_CODE (insn) == INSN
          && GET_CODE (PATTERN (insn)) == ASM_OPERANDS
          && MEM_VOLATILE_P (PATTERN (insn))))
       || (GET_CODE (insn) == INSN
          && GET_CODE (PATTERN (insn)) == ASM_OPERANDS
          && MEM_VOLATILE_P (PATTERN (insn))))
@@ -1293,7 +1298,7 @@ cselib_process_insn (insn)
        if (call_used_regs[i])
          cselib_invalidate_regno (i, VOIDmode);
 
        if (call_used_regs[i])
          cselib_invalidate_regno (i, VOIDmode);
 
-      if (! CONST_CALL_P (insn))
+      if (! CONST_OR_PURE_CALL_P (insn))
        cselib_invalidate_mem (callmem);
     }
 
        cselib_invalidate_mem (callmem);
     }