OSDN Git Service

* config/s390/s390.c (s390_emit_epilogue): Always restore registers
[pf3gnuchains/gcc-fork.git] / gcc / gcse.c
index 6efd39b..56c26a4 100644 (file)
@@ -159,6 +159,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "output.h"
 #include "function.h"
 #include "expr.h" 
+#include "except.h"
 #include "ggc.h"
 #include "params.h"
 
@@ -696,6 +697,7 @@ static void delete_store            PARAMS ((struct ls_expr *,
                                                 basic_block));
 static void free_store_memory          PARAMS ((void));
 static void store_motion               PARAMS ((void));
+static void free_insn_expr_list_list   PARAMS ((rtx *));
 static void clear_modify_mem_tables    PARAMS ((void));
 static void free_modify_mem_tables     PARAMS ((void));
 \f
@@ -2386,6 +2388,7 @@ canon_list_insert (dest, unused1, v_insn)
      void * v_insn;
 {
   rtx dest_addr, insn;
+  int bb;
 
   while (GET_CODE (dest) == SUBREG
       || GET_CODE (dest) == ZERO_EXTRACT
@@ -2403,12 +2406,13 @@ canon_list_insert (dest, unused1, v_insn)
   dest_addr = get_addr (XEXP (dest, 0));
   dest_addr = canon_rtx (dest_addr);
   insn = (rtx) v_insn;  
+  bb = BLOCK_NUM (insn);
 
-  canon_modify_mem_list[BLOCK_NUM (insn)] = 
-    alloc_INSN_LIST (dest_addr, canon_modify_mem_list[BLOCK_NUM (insn)]);
-  canon_modify_mem_list[BLOCK_NUM (insn)] = 
-    alloc_INSN_LIST (dest, canon_modify_mem_list[BLOCK_NUM (insn)]);
-  bitmap_set_bit (canon_modify_mem_list_set, BLOCK_NUM (insn));
+  canon_modify_mem_list[bb] = 
+    alloc_EXPR_LIST (VOIDmode, dest_addr, canon_modify_mem_list[bb]);
+  canon_modify_mem_list[bb] = 
+    alloc_EXPR_LIST (VOIDmode, dest, canon_modify_mem_list[bb]);
+  bitmap_set_bit (canon_modify_mem_list_set, bb);
 }
 
 /* Record memory modification information for INSN.  We do not actually care
@@ -2419,23 +2423,24 @@ static void
 record_last_mem_set_info (insn)
      rtx insn;
 {
+  int bb = BLOCK_NUM (insn);
+
   /* load_killed_in_block_p will handle the case of calls clobbering
      everything.  */
-  modify_mem_list[BLOCK_NUM (insn)] = 
-    alloc_INSN_LIST (insn, modify_mem_list[BLOCK_NUM (insn)]);
-  bitmap_set_bit (modify_mem_list_set, BLOCK_NUM (insn));
+  modify_mem_list[bb] = alloc_INSN_LIST (insn, modify_mem_list[bb]);
+  bitmap_set_bit (modify_mem_list_set, bb);
 
   if (GET_CODE (insn) == CALL_INSN)
     {
       /* Note that traversals of this loop (other than for free-ing)
         will break after encountering a CALL_INSN.  So, there's no
         need to insert a pair of items, as canon_list_insert does.  */
-      canon_modify_mem_list[BLOCK_NUM (insn)] = 
-        alloc_INSN_LIST (insn, canon_modify_mem_list[BLOCK_NUM (insn)]);
-      bitmap_set_bit (canon_modify_mem_list_set, BLOCK_NUM (insn));
+      canon_modify_mem_list[bb] = 
+        alloc_INSN_LIST (insn, canon_modify_mem_list[bb]);
+      bitmap_set_bit (canon_modify_mem_list_set, bb);
     }
   else
-    note_stores (PATTERN (insn), canon_list_insert, (void*) insn );
+    note_stores (PATTERN (insn), canon_list_insert, (void*) insn);
 }
 
 /* Called from compute_hash_table via note_stores to handle one
@@ -2711,6 +2716,27 @@ next_set (regno, expr)
   return expr;
 }
 
+/* Like free_INSN_LIST_list or free_EXPR_LIST_list, except that the node
+   types may be mixed.  */
+
+static void
+free_insn_expr_list_list (listp)
+     rtx *listp;
+{
+  rtx list, next;
+
+  for (list = *listp; list ; list = next)
+    {
+      next = XEXP (list, 1);
+      if (GET_CODE (list) == EXPR_LIST)
+       free_EXPR_LIST_node (list);
+      else
+       free_INSN_LIST_node (list);
+    }
+
+  *listp = NULL;
+}
+
 /* Clear canon_modify_mem_list and modify_mem_list tables.  */
 static void
 clear_modify_mem_tables ()
@@ -2718,14 +2744,13 @@ clear_modify_mem_tables ()
   int i;
 
   EXECUTE_IF_SET_IN_BITMAP
-    (canon_modify_mem_list_set, 0, i,
-     free_INSN_LIST_list (modify_mem_list + i));
-  bitmap_clear (canon_modify_mem_list_set);
+    (modify_mem_list_set, 0, i, free_INSN_LIST_list (modify_mem_list + i));
+  bitmap_clear (modify_mem_list_set);
 
   EXECUTE_IF_SET_IN_BITMAP
     (canon_modify_mem_list_set, 0, i,
-     free_INSN_LIST_list (canon_modify_mem_list + i));
-  bitmap_clear (modify_mem_list_set);
+     free_insn_expr_list_list (canon_modify_mem_list + i));
+  bitmap_clear (canon_modify_mem_list_set);
 }
 
 /* Release memory used by modify_mem_list_set and canon_modify_mem_list_set.  */
@@ -3022,8 +3047,8 @@ compute_rd ()
       for (bb = 0; bb < n_basic_blocks; bb++)
        {
          sbitmap_union_of_preds (reaching_defs[bb], rd_out, bb);
-         changed |= sbitmap_union_of_diff (rd_out[bb], rd_gen[bb],
-                                           reaching_defs[bb], rd_kill[bb]);
+         changed |= sbitmap_union_of_diff_cg (rd_out[bb], rd_gen[bb],
+                                              reaching_defs[bb], rd_kill[bb]);
        }
       passes++;
     }
@@ -5558,8 +5583,8 @@ compute_code_hoist_vbeinout ()
         the convergence.  */
       for (bb = n_basic_blocks - 1; bb >= 0; bb--)
        {
-         changed |= sbitmap_a_or_b_and_c (hoist_vbein[bb], antloc[bb],
-                                          hoist_vbeout[bb], transp[bb]);
+         changed |= sbitmap_a_or_b_and_c_cg (hoist_vbein[bb], antloc[bb],
+                                             hoist_vbeout[bb], transp[bb]);
          if (bb != n_basic_blocks - 1)
            sbitmap_intersection_of_succs (hoist_vbeout[bb], hoist_vbein, bb);
        }
@@ -6527,21 +6552,7 @@ store_killed_in_insn (x, insn)
     {
       /* A normal or pure call might read from pattern,
         but a const call will not.  */
-      if (CONST_OR_PURE_CALL_P (insn))
-       {
-         rtx link;
-
-         for (link = CALL_INSN_FUNCTION_USAGE (insn);
-              link;
-              link = XEXP (link, 1))
-           if (GET_CODE (XEXP (link, 0)) == USE
-               && GET_CODE (XEXP (XEXP (link, 0), 0)) == MEM
-               && GET_CODE (XEXP (XEXP (XEXP (link, 0), 0), 0)) == SCRATCH)
-             return 1;
-         return 0;
-       }
-      else
-       return 1;
+      return ! CONST_OR_PURE_CALL_P (insn) || pure_call_p (insn);
     }
   
   if (GET_CODE (PATTERN (insn)) == SET)