flow.c (insn_dead_p): Allow for AUTO_INC notes all the time.
[platform/upstream/gcc.git] / gcc / flow.c
index b5a6e37..fbe570b 100644 (file)
@@ -296,7 +296,7 @@ static void mark_regs_live_at_end   PARAMS ((regset));
 static int set_phi_alternative_reg      PARAMS ((rtx, int, int, void *));
 static void calculate_global_regs_live PARAMS ((sbitmap, sbitmap, int));
 static void propagate_block_delete_insn PARAMS ((basic_block, rtx));
-static rtx propagate_block_delete_libcall PARAMS ((basic_block, rtx, rtx));
+static rtx propagate_block_delete_libcall PARAMS ((rtx, rtx));
 static int insn_dead_p                 PARAMS ((struct propagate_block_info *,
                                                 rtx, int, rtx));
 static int libcall_dead_p              PARAMS ((struct propagate_block_info *,
@@ -344,6 +344,7 @@ static void invalidate_mems_from_autoinc PARAMS ((struct propagate_block_info *,
 static void invalidate_mems_from_set   PARAMS ((struct propagate_block_info *,
                                                 rtx));
 static void delete_dead_jumptables     PARAMS ((void));
+static void clear_log_links            PARAMS ((sbitmap));
 \f
 
 void
@@ -377,8 +378,6 @@ check_function_return_warnings ()
        {
          /* Recompute insn->block mapping, since the initial mapping is
             set before we delete unreachable blocks.  */
-         compute_bb_for_insn (max_uid);
-
          if (BLOCK_FOR_INSN (cfun->x_clobber_return_insn) != NULL)
            warning ("control reaches end of non-void function");
        }
@@ -418,8 +417,8 @@ life_analysis (f, file, flags)
      int flags;
 {
 #ifdef ELIMINABLE_REGS
-  register int i;
-  static struct {int from, to; } eliminables[] = ELIMINABLE_REGS;
+  int i;
+  static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
 #endif
 
   /* Record which registers will be eliminated.  We use this in
@@ -457,6 +456,7 @@ life_analysis (f, file, flags)
   /* Always remove no-op moves.  Do this before other processing so
      that we don't have to keep re-scanning them.  */
   delete_noop_moves (f);
+  purge_all_dead_edges (false);
 
   /* Some targets can emit simpler epilogues if they know that sp was
      not ever modified during the function.  After reload, of course,
@@ -630,12 +630,19 @@ update_life_info (blocks, extent, prop_flags)
 
   tmp = INITIALIZE_REG_SET (tmp_head);
 
+  timevar_push ((extent == UPDATE_LIFE_LOCAL || blocks)
+               ? TV_LIFE_UPDATE : TV_LIFE);
+
   /* Changes to the CFG are only allowed when
      doing a global update for the entire CFG.  */
   if ((prop_flags & PROP_ALLOW_CFG_CHANGES)
       && (extent == UPDATE_LIFE_LOCAL || blocks))
     abort ();
 
+  /* Clear log links in case we are asked to (re)compute them.  */
+  if (prop_flags & PROP_LOG_LINKS)
+    clear_log_links (blocks);
+
   /* For a global update, we go through the relaxation process again.  */
   if (extent != UPDATE_LIFE_LOCAL)
     {
@@ -729,6 +736,8 @@ update_life_info (blocks, extent, prop_flags)
                                     }
                                 });
     }
+  timevar_pop ((extent == UPDATE_LIFE_LOCAL || blocks)
+              ? TV_LIFE_UPDATE : TV_LIFE);
 }
 
 /* Free the variables allocated by find_basic_blocks.
@@ -739,12 +748,6 @@ void
 free_basic_block_vars (keep_head_end_p)
      int keep_head_end_p;
 {
-  if (basic_block_for_insn)
-    {
-      VARRAY_FREE (basic_block_for_insn);
-      basic_block_for_insn = NULL;
-    }
-
   if (! keep_head_end_p)
     {
       if (basic_block_info)
@@ -779,13 +782,28 @@ delete_noop_moves (f)
          next = NEXT_INSN (insn);
          if (INSN_P (insn) && noop_move_p (insn))
            {
-             /* Do not call flow_delete_insn here to not confuse backward
-                pointers of LIBCALL block.  */
+             rtx note;
+
+             /* If we're about to remove the first insn of a libcall
+                then move the libcall note to the next real insn and
+                update the retval note.  */
+             if ((note = find_reg_note (insn, REG_LIBCALL, NULL_RTX))
+                      && XEXP (note, 0) != insn)
+               {
+                 rtx new_libcall_insn = next_real_insn (insn);
+                 rtx retval_note = find_reg_note (XEXP (note, 0),
+                                                  REG_RETVAL, NULL_RTX);
+                 REG_NOTES (new_libcall_insn)
+                   = gen_rtx_INSN_LIST (REG_LIBCALL, XEXP (note, 0),
+                                        REG_NOTES (new_libcall_insn));
+                 XEXP (retval_note, 0) = new_libcall_insn;
+               }
+
+             /* Do not call delete_insn here since that may change
+                the basic block boundaries which upsets some callers.  */
              PUT_CODE (insn, NOTE);
              NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
              NOTE_SOURCE_FILE (insn) = 0;
-             if (insn == bb->end)
-               purge_dead_edges (bb);
            }
        }
     }
@@ -803,15 +821,15 @@ delete_dead_jumptables ()
     {
       next = NEXT_INSN (insn);
       if (GET_CODE (insn) == CODE_LABEL
-         && LABEL_NUSES (insn) == 0
+         && LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn)
          && GET_CODE (next) == JUMP_INSN
          && (GET_CODE (PATTERN (next)) == ADDR_VEC
              || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
        {
          if (rtl_dump_file)
            fprintf (rtl_dump_file, "Dead jumptable %i removed\n", INSN_UID (insn));
-         flow_delete_insn (NEXT_INSN (insn));
-         flow_delete_insn (insn);
+         delete_insn (NEXT_INSN (insn));
+         delete_insn (insn);
          next = NEXT_INSN (next);
        }
     }
@@ -1281,7 +1299,7 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
 void
 allocate_bb_life_data ()
 {
-  register int i;
+  int i;
 
   for (i = 0; i < n_basic_blocks; i++)
     {
@@ -1331,6 +1349,7 @@ propagate_block_delete_insn (bb, insn)
      rtx insn;
 {
   rtx inote = find_reg_note (insn, REG_LABEL, NULL_RTX);
+  bool purge = false;
 
   /* If the insn referred to a label, and that label was attached to
      an ADDR_VEC, it's safe to delete the ADDR_VEC.  In fact, it's
@@ -1368,33 +1387,28 @@ propagate_block_delete_insn (bb, insn)
          for (i = 0; i < len; i++)
            LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0))--;
 
-         flow_delete_insn (next);
+         delete_insn (next);
        }
     }
 
   if (bb->end == insn)
-    {
-      bb->end = PREV_INSN (insn);
-      purge_dead_edges (bb);
-    }
-  flow_delete_insn (insn);
+    purge = true;
+  delete_insn (insn);
+  if (purge)
+    purge_dead_edges (bb);
 }
 
 /* Delete dead libcalls for propagate_block.  Return the insn
    before the libcall.  */
 
 static rtx
-propagate_block_delete_libcall (bb, insn, note)
-     basic_block bb;
+propagate_block_delete_libcall ( insn, note)
      rtx insn, note;
 {
   rtx first = XEXP (note, 0);
   rtx before = PREV_INSN (first);
 
-  if (insn == bb->end)
-    bb->end = before;
-
-  flow_delete_insn_chain (first, insn);
+  delete_insn_chain (first, insn);
   return before;
 }
 
@@ -1453,7 +1467,7 @@ propagate_one_insn (pbi, insn)
       pbi->cc0_live = 0;
 
       if (libcall_is_dead)
-       prev = propagate_block_delete_libcall (pbi->bb, insn, note);
+       prev = propagate_block_delete_libcall ( insn, note);
       else
        propagate_block_delete_insn (pbi->bb, insn);
 
@@ -1464,7 +1478,7 @@ propagate_one_insn (pbi, insn)
      a following memory address.  */
 #ifdef AUTO_INC_DEC
   {
-    register rtx x = single_set (insn);
+    rtx x = single_set (insn);
 
     /* Does this instruction increment or decrement a register?  */
     if ((flags & PROP_AUTOINC)
@@ -1522,7 +1536,7 @@ propagate_one_insn (pbi, insn)
 
       if (GET_CODE (insn) == CALL_INSN)
        {
-         register int i;
+         int i;
          rtx note, cond;
 
          cond = NULL_RTX;
@@ -1572,7 +1586,7 @@ propagate_one_insn (pbi, insn)
 
       if (! insn_is_dead && GET_CODE (insn) == CALL_INSN)
        {
-         register int i;
+         int i;
          rtx note, cond;
 
          cond = NULL_RTX;
@@ -1827,7 +1841,7 @@ propagate_block (bb, live, local_set, cond_local_set, flags)
 
   if (flags & PROP_REG_INFO)
     {
-      register int i;
+      int i;
 
       /* Process the regs live at the end of the block.
         Mark them as not local to any one basic block.  */
@@ -1878,21 +1892,18 @@ insn_dead_p (pbi, x, call_ok, notes)
   enum rtx_code code = GET_CODE (x);
 
 #ifdef AUTO_INC_DEC
-  /* If flow is invoked after reload, we must take existing AUTO_INC
-     expresions into account.  */
-  if (reload_completed)
+  /* As flow is invoked after combine, we must take existing AUTO_INC
+     expressions into account.  */
+  for (; notes; notes = XEXP (notes, 1))
     {
-      for (; notes; notes = XEXP (notes, 1))
+      if (REG_NOTE_KIND (notes) == REG_INC)
        {
-         if (REG_NOTE_KIND (notes) == REG_INC)
-           {
-             int regno = REGNO (XEXP (notes, 0));
-
-             /* Don't delete insns to set global regs.  */
-             if ((regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
-                 || REGNO_REG_SET_P (pbi->reg_live, regno))
-               return 0;
-           }
+         int regno = REGNO (XEXP (notes, 0));
+         
+         /* Don't delete insns to set global regs.  */
+         if ((regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
+             || REGNO_REG_SET_P (pbi->reg_live, regno))
+           return 0;
        }
     }
 #endif
@@ -2074,13 +2085,13 @@ libcall_dead_p (pbi, note, insn)
 
   if (x)
     {
-      register rtx r = SET_SRC (x);
+      rtx r = SET_SRC (x);
 
       if (GET_CODE (r) == REG)
        {
          rtx call = XEXP (note, 0);
          rtx call_pat;
-         register int i;
+         int i;
 
          /* Find the call insn.  */
          while (call != insn && GET_CODE (call) != CALL_INSN)
@@ -2213,7 +2224,7 @@ invalidate_mems_from_autoinc (pbi, insn)
       invalidate_mems_from_set (pbi, XEXP (note, 0));
 }
 
-/* EXP is a REG.  Remove any dependant entries from pbi->mem_set_list.  */
+/* EXP is a REG.  Remove any dependent entries from pbi->mem_set_list.  */
 
 static void
 invalidate_mems_from_set (pbi, exp)
@@ -2283,7 +2294,8 @@ mark_set_regs (pbi, x, insn)
 
     case PARALLEL:
       {
-       register int i;
+       int i;
+
        for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
          {
            rtx sub = XVECEXP (x, 0, i);
@@ -2498,8 +2510,8 @@ mark_set_1 (pbi, code, reg, cond, insn, flags)
       if (flags & (PROP_LOG_LINKS | PROP_REG_INFO
                   | PROP_DEATH_NOTES | PROP_AUTOINC))
        {
-         register rtx y;
-         register int blocknum = pbi->bb->index;
+         rtx y;
+         int blocknum = pbi->bb->index;
 
          y = NULL_RTX;
          if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
@@ -3099,10 +3111,6 @@ attempt_auto_inc (pbi, inc, insn, mem, incr, incr_reg)
       insns = get_insns ();
       end_sequence ();
 
-      if (basic_block_for_insn)
-       for (temp = insns; temp; temp = NEXT_INSN (temp))
-         set_block_for_insn (temp, pbi->bb);
-
       /* If we can't make the auto-inc, or can't make the
         replacement into Y, exit.  There's no point in making
         the change below if we can't do the auto-inc and doing
@@ -3347,7 +3355,7 @@ mark_used_reg (pbi, reg, cond, insn)
        {
          /* Keep track of which basic block each reg appears in.  */
 
-         register int blocknum = pbi->bb->index;
+         int blocknum = pbi->bb->index;
          if (REG_BASIC_BLOCK (regno_first) == REG_BLOCK_UNKNOWN)
            REG_BASIC_BLOCK (regno_first) = blocknum;
          else if (REG_BASIC_BLOCK (regno_first) != blocknum)
@@ -3479,8 +3487,8 @@ mark_used_regs (pbi, x, cond, insn)
      struct propagate_block_info *pbi;
      rtx x, cond, insn;
 {
-  register RTX_CODE code;
-  register int regno;
+  RTX_CODE code;
+  int regno;
   int flags = pbi->flags;
 
  retry:
@@ -3581,7 +3589,7 @@ mark_used_regs (pbi, x, cond, insn)
 
     case SET:
       {
-       register rtx testreg = SET_DEST (x);
+       rtx testreg = SET_DEST (x);
        int mark_dest = 0;
 
        /* If storing into MEM, don't show it as being used.  But do
@@ -3720,8 +3728,8 @@ mark_used_regs (pbi, x, cond, insn)
   /* Recursively scan the operands of this expression.  */
 
   {
-    register const char * const fmt = GET_RTX_FORMAT (code);
-    register int i;
+    const char * const fmt = GET_RTX_FORMAT (code);
+    int i;
 
     for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
       {
@@ -3737,7 +3745,7 @@ mark_used_regs (pbi, x, cond, insn)
          }
        else if (fmt[i] == 'E')
          {
-           register int j;
+           int j;
            for (j = 0; j < XVECLEN (x, i); j++)
              mark_used_regs (pbi, XVECEXP (x, i, j), cond, insn);
          }
@@ -3800,7 +3808,7 @@ try_pre_increment (insn, reg, amount)
      rtx insn, reg;
      HOST_WIDE_INT amount;
 {
-  register rtx use;
+  rtx use;
 
   /* Nonzero if we can try to make a pre-increment or pre-decrement.
      For example, addl $4,r1; movl (r1),... can become movl +(r1),...  */
@@ -3877,15 +3885,15 @@ try_pre_increment (insn, reg, amount)
 
 rtx
 find_use_as_address (x, reg, plusconst)
-     register rtx x;
+     rtx x;
      rtx reg;
      HOST_WIDE_INT plusconst;
 {
   enum rtx_code code = GET_CODE (x);
   const char * const fmt = GET_RTX_FORMAT (code);
-  register int i;
-  register rtx value = 0;
-  register rtx tem;
+  int i;
+  rtx value = 0;
+  rtx tem;
 
   if (code == MEM && XEXP (x, 0) == reg && plusconst == 0)
     return x;
@@ -3919,7 +3927,7 @@ find_use_as_address (x, reg, plusconst)
        }
       else if (fmt[i] == 'E')
        {
-         register int j;
+         int j;
          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
            {
              tem = find_use_as_address (XVECEXP (x, i, j), reg, plusconst);
@@ -4086,31 +4094,32 @@ count_or_remove_death_notes (blocks, kill)
 
   return count;
 }
-/* Clear LOG_LINKS fields of insns in a chain.
-   Also clear the global_live_at_{start,end} fields of the basic block
-   structures.  */
+/* Clear LOG_LINKS fields of insns in a selected blocks or whole chain
+   if blocks is NULL.  */
 
-void
-clear_log_links (insns)
-     rtx insns;
+static void
+clear_log_links (blocks)
+     sbitmap blocks;
 {
-  rtx i;
-  int b;
-
-  for (i = insns; i; i = NEXT_INSN (i))
-    if (INSN_P (i))
-      LOG_LINKS (i) = 0;
+  rtx insn;
+  int i;
 
-  for (b = 0; b < n_basic_blocks; b++)
+  if (!blocks)
     {
-      basic_block bb = BASIC_BLOCK (b);
-
-      bb->global_live_at_start = NULL;
-      bb->global_live_at_end = NULL;
+      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+       if (INSN_P (insn))
+         free_INSN_LIST_list (&LOG_LINKS (insn));
     }
+  else
+    EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
+      {
+       basic_block bb = BASIC_BLOCK (i);
 
-  ENTRY_BLOCK_PTR->global_live_at_end = NULL;
-  EXIT_BLOCK_PTR->global_live_at_start = NULL;
+       for (insn = bb->head; insn != NEXT_INSN (bb->end);
+            insn = NEXT_INSN (insn))
+         if (INSN_P (insn))
+           free_INSN_LIST_list (&LOG_LINKS (insn));
+      });
 }
 
 /* Given a register bitmap, turn on the bits in a HARD_REG_SET that