OSDN Git Service

* tree-sra.c (try_instantiate_multiple_fields): Needlessly
[pf3gnuchains/gcc-fork.git] / gcc / postreload-gcse.c
index cf08c09..76b7b8c 100644 (file)
@@ -224,8 +224,8 @@ alloc_mem (void)
   rtx insn;
 
   /* Find the largest UID and create a mapping from UIDs to CUIDs.  */
-  uid_cuid = xcalloc (get_max_uid () + 1, sizeof (int));
-  i = 0;
+  uid_cuid = XCNEWVEC (int, get_max_uid () + 1);
+  i = 1;
   FOR_EACH_BB (bb)
     FOR_BB_INSNS (bb, insn)
       {
@@ -671,10 +671,18 @@ record_last_set_info (rtx dest, rtx setter ATTRIBUTE_UNUSED, void *data)
 
   if (REG_P (dest))
     record_last_reg_set_info (last_set_insn, REGNO (dest));
-  else if (MEM_P (dest)
-          /* Ignore pushes, they clobber nothing.  */
-          && ! push_operand (dest, GET_MODE (dest)))
-    record_last_mem_set_info (last_set_insn);
+  else if (MEM_P (dest))
+    {
+      /* Ignore pushes, they don't clobber memory.  They may still
+        clobber the stack pointer though.  Some targets do argument
+        pushes without adding REG_INC notes.  See e.g. PR25196,
+        where a pushsi2 on i386 doesn't have REG_INC notes.  Note
+        such changes here too.  */
+      if (! push_operand (dest, GET_MODE (dest)))
+       record_last_mem_set_info (last_set_insn);
+      else
+       record_last_reg_set_info (last_set_insn, STACK_POINTER_REGNUM);
+    }
 }
 
 
@@ -745,6 +753,12 @@ hash_scan_set (rtx insn)
          can_copy_p (GET_MODE (dest))
          /* Is SET_SRC something we want to gcse?  */
          && general_operand (src, GET_MODE (src))
+#ifdef STACK_REGS
+         /* Never consider insns touching the register stack.  It may
+            create situations that reg-stack cannot handle (e.g. a stack
+            register live across an abnormal edge).  */
+         && (REGNO (dest) < FIRST_STACK_REG || REGNO (dest) > LAST_STACK_REG)
+#endif
          /* An expression is not available if its operands are
             subsequently modified, including this insn.  */
          && oprs_unchanged_p (src, insn, true))
@@ -759,6 +773,10 @@ hash_scan_set (rtx insn)
          can_copy_p (GET_MODE (src))
          /* Is SET_DEST something we want to gcse?  */
          && general_operand (dest, GET_MODE (dest))
+#ifdef STACK_REGS
+         /* As above for STACK_REGS.  */
+         && (REGNO (src) < FIRST_STACK_REG || REGNO (src) > LAST_STACK_REG)
+#endif
          && ! (flag_float_store && FLOAT_MODE_P (GET_MODE (dest)))
          /* Check if the memory expression is killed after insn.  */
          && ! load_killed_in_block_p (INSN_CUID (insn) + 1, dest, true)
@@ -1075,7 +1093,7 @@ eliminate_partially_redundant_load (basic_block bb, rtx insn,
          else /* Its a dead move no need to generate.  */
            continue;
          occr = (struct unoccr *) obstack_alloc (&unoccr_obstack,
-                                                 sizeof (struct occr));
+                                                 sizeof (struct unoccr));
          occr->insn = avail_insn;
          occr->pred = pred;
          occr->next = avail_occrs;
@@ -1085,7 +1103,7 @@ eliminate_partially_redundant_load (basic_block bb, rtx insn,
        }
       else
        {
-         /* Adding a load on a critical edge will cuase a split.  */
+         /* Adding a load on a critical edge will cause a split.  */
          if (EDGE_CRITICAL_P (pred))
            critical_edge_split = true;
          not_ok_count += pred->count;
@@ -1300,7 +1318,7 @@ delete_redundant_insns (void)
 /* Main entry point of the GCSE after reload - clean some redundant loads
    due to spilling.  */
 
-void
+static void
 gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED)
 {
 
@@ -1347,12 +1365,13 @@ gate_handle_gcse2 (void)
 }
 
 
-static void
+static unsigned int
 rest_of_handle_gcse2 (void)
 {
   gcse_after_reload_main (get_insns ());
   rebuild_jump_labels (get_insns ());
   delete_trivially_dead_insns (get_insns (), max_reg_num ());
+  return 0;
 }
 
 struct tree_opt_pass pass_gcse2 =