OSDN Git Service

2004-11-12 Andrew Pinski <pinskia@physics.uc.edu>
[pf3gnuchains/gcc-fork.git] / gcc / gcse.c
index daac742..25c53c7 100644 (file)
@@ -2271,7 +2271,7 @@ free_insn_expr_list_list (rtx *listp)
 static void
 clear_modify_mem_tables (void)
 {
-  int i;
+  unsigned i;
   bitmap_iterator bi;
 
   EXECUTE_IF_SET_IN_BITMAP (modify_mem_list_set, 0, i, bi)
@@ -3134,7 +3134,8 @@ do_local_cprop (rtx x, rtx insn, int alter_jumps, rtx *libcall_sp)
          rtx this_rtx = l->loc;
          rtx note;
 
-         if (l->in_libcall)
+         /* Don't CSE non-constant values out of libcall blocks.  */
+         if (l->in_libcall && ! CONSTANT_P (this_rtx))
            continue;
 
          if (gcse_constant_p (this_rtx))
@@ -3222,7 +3223,7 @@ adjust_libcall_notes (rtx oldreg, rtx newval, rtx insn, rtx *libcall_sp)
              return true;
            }
        }
-      XEXP (note, 0) = replace_rtx (XEXP (note, 0), oldreg, newval);
+      XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), oldreg, newval);
       insn = end;
     }
   return true;
@@ -3400,7 +3401,7 @@ find_implicit_sets (void)
   count = 0;
   FOR_EACH_BB (bb)
     /* Check for more than one successor.  */
-    if (bb->succ && bb->succ->succ_next)
+    if (EDGE_COUNT (bb->succs) > 1)
       {
        cond = fis_get_condition (BB_END (bb));
 
@@ -3413,7 +3414,7 @@ find_implicit_sets (void)
            dest = GET_CODE (cond) == EQ ? BRANCH_EDGE (bb)->dest
                                         : FALLTHRU_EDGE (bb)->dest;
 
-           if (dest && ! dest->pred->pred_next
+           if (dest && EDGE_COUNT (dest->preds) == 1
                && dest != EXIT_BLOCK_PTR)
              {
                new = gen_rtx_SET (VOIDmode, XEXP (cond, 0),
@@ -3570,9 +3571,11 @@ static int
 bypass_block (basic_block bb, rtx setcc, rtx jump)
 {
   rtx insn, note;
-  edge e, enext, edest;
+  edge e, edest;
   int i, change;
   int may_be_loop_header;
+  unsigned removed_p;
+  edge_iterator ei;
 
   insn = (setcc != NULL) ? setcc : jump;
 
@@ -3584,7 +3587,7 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
     find_used_regs (&XEXP (note, 0), NULL);
 
   may_be_loop_header = false;
-  for (e = bb->pred; e; e = e->pred_next)
+  FOR_EACH_EDGE (e, ei, bb->preds)
     if (e->flags & EDGE_DFS_BACK)
       {
        may_be_loop_header = true;
@@ -3592,22 +3595,32 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
       }
 
   change = 0;
-  for (e = bb->pred; e; e = enext)
+  for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
     {
-      enext = e->pred_next;
+      removed_p = 0;
+         
       if (e->flags & EDGE_COMPLEX)
-       continue;
+       {
+         ei_next (&ei);
+         continue;
+       }
 
       /* We can't redirect edges from new basic blocks.  */
       if (e->src->index >= bypass_last_basic_block)
-       continue;
+       {
+         ei_next (&ei);
+         continue;
+       }
 
       /* The irreducible loops created by redirecting of edges entering the
         loop from outside would decrease effectiveness of some of the following
         optimizations, so prevent this.  */
       if (may_be_loop_header
          && !(e->flags & EDGE_DFS_BACK))
-       continue;
+       {
+         ei_next (&ei);
+         continue;
+       }
 
       for (i = 0; i < reg_use_count; i++)
        {
@@ -3651,9 +3664,11 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
            }
          else if (GET_CODE (new) == LABEL_REF)
            {
+             edge_iterator ei2;
+
              dest = BLOCK_FOR_INSN (XEXP (new, 0));
              /* Don't bypass edges containing instructions.  */
-             for (edest = bb->succ; edest; edest = edest->succ_next)
+             FOR_EACH_EDGE (edest, ei2, bb->succs)
                if (edest->dest == dest && edest->insns.r)
                  {
                    dest = NULL;
@@ -3670,7 +3685,9 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
          if (dest && setcc && !CC0_P (SET_DEST (PATTERN (setcc))))
            {
              edge e2;
-             for (e2 = e->src->succ; e2; e2 = e2->succ_next)
+             edge_iterator ei2;
+
+             FOR_EACH_EDGE (e2, ei2, e->src->succs)
                if (e2->dest == dest)
                  {
                    dest = NULL;
@@ -3704,9 +3721,12 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
                           e->src->index, old_dest->index, dest->index);
                }
              change = 1;
+             removed_p = 1;
              break;
            }
        }
+      if (!removed_p)
+       ei_next (&ei);
     }
   return change;
 }
@@ -3739,7 +3759,7 @@ bypass_conditional_jumps (void)
                  EXIT_BLOCK_PTR, next_bb)
     {
       /* Check for more than one predecessor.  */
-      if (bb->pred && bb->pred->pred_next)
+      if (EDGE_COUNT (bb->preds) > 1)
        {
          setcc = NULL_RTX;
          for (insn = BB_HEAD (bb);
@@ -3886,12 +3906,13 @@ compute_pre_data (void)
   FOR_EACH_BB (bb)
     {
       edge e;
+      edge_iterator ei;
 
       /* If the current block is the destination of an abnormal edge, we
         kill all trapping expressions because we won't be able to properly
         place the instruction on the edge.  So make them neither
         anticipatable nor transparent.  This is fairly conservative.  */
-      for (e = bb->pred; e ; e = e->pred_next)
+      FOR_EACH_EDGE (e, ei, bb->preds)
        if (e->flags & EDGE_ABNORMAL)
          {
            sbitmap_difference (antloc[bb->index], antloc[bb->index], trapping_expr);
@@ -3931,8 +3952,9 @@ static int
 pre_expr_reaches_here_p_work (basic_block occr_bb, struct expr *expr, basic_block bb, char *visited)
 {
   edge pred;
-
-  for (pred = bb->pred; pred != NULL; pred = pred->pred_next)
+  edge_iterator ei;
+  
+  FOR_EACH_EDGE (pred, ei, bb->preds)
     {
       basic_block pred_bb = pred->src;
 
@@ -4051,7 +4073,8 @@ insert_insn_end_bb (struct expr *expr, basic_block bb, int pre)
 
   if (JUMP_P (insn)
       || (NONJUMP_INSN_P (insn)
-         && (bb->succ->succ_next || (bb->succ->flags & EDGE_ABNORMAL))))
+         && (EDGE_COUNT (bb->succs) > 1
+             || EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL)))
     {
 #ifdef HAVE_cc0
       rtx note;
@@ -4086,13 +4109,13 @@ insert_insn_end_bb (struct expr *expr, basic_block bb, int pre)
        }
 #endif
       /* FIXME: What if something in cc0/jump uses value set in new insn?  */
-      new_insn = emit_insn_before (pat, insn);
+      new_insn = emit_insn_before_noloc (pat, insn);
     }
 
   /* Likewise if the last insn is a call, as will happen in the presence
      of exception handling.  */
   else if (CALL_P (insn)
-          && (bb->succ->succ_next || (bb->succ->flags & EDGE_ABNORMAL)))
+          && (EDGE_COUNT (bb->succs) > 1 || EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL))
     {
       /* Keeping in mind SMALL_REGISTER_CLASSES and parameters in registers,
         we search backward and place the instructions before the first
@@ -4124,10 +4147,10 @@ insert_insn_end_bb (struct expr *expr, basic_block bb, int pre)
             || NOTE_INSN_BASIC_BLOCK_P (insn))
        insn = NEXT_INSN (insn);
 
-      new_insn = emit_insn_before (pat, insn);
+      new_insn = emit_insn_before_noloc (pat, insn);
     }
   else
-    new_insn = emit_insn_after (pat, insn);
+    new_insn = emit_insn_after_noloc (pat, insn);
 
   while (1)
     {
@@ -4810,6 +4833,7 @@ static int
 hoist_expr_reaches_here_p (basic_block expr_bb, int expr_index, basic_block bb, char *visited)
 {
   edge pred;
+  edge_iterator ei;
   int visited_allocated_locally = 0;
 
 
@@ -4819,7 +4843,7 @@ hoist_expr_reaches_here_p (basic_block expr_bb, int expr_index, basic_block bb,
       visited = xcalloc (last_basic_block, 1);
     }
 
-  for (pred = bb->pred; pred != NULL; pred = pred->pred_next)
+  FOR_EACH_EDGE (pred, ei, bb->preds)
     {
       basic_block pred_bb = pred->src;
 
@@ -6167,7 +6191,7 @@ insert_insn_start_bb (rtx insn, basic_block bb)
       before = NEXT_INSN (before);
     }
 
-  insn = emit_insn_after (insn, prev);
+  insn = emit_insn_after_noloc (insn, prev);
 
   if (gcse_file)
     {
@@ -6188,6 +6212,7 @@ insert_store (struct ls_expr * expr, edge e)
   rtx reg, insn;
   basic_block bb;
   edge tmp;
+  edge_iterator ei;
 
   /* We did all the deleted before this insert, so if we didn't delete a
      store, then we haven't set the reaching reg yet either.  */
@@ -6204,7 +6229,7 @@ insert_store (struct ls_expr * expr, edge e)
      insert it at the start of the BB, and reset the insert bits on the other
      edges so we don't try to insert it on the other edges.  */
   bb = e->dest;
-  for (tmp = e->dest->pred; tmp ; tmp = tmp->pred_next)
+  FOR_EACH_EDGE (tmp, ei, e->dest->preds)
     if (!(tmp->flags & EDGE_FAKE))
       {
        int index = EDGE_INDEX (edge_list, tmp->src, tmp->dest);
@@ -6218,7 +6243,7 @@ insert_store (struct ls_expr * expr, edge e)
      insertion vector for these edges, and insert at the start of the BB.  */
   if (!tmp && bb != EXIT_BLOCK_PTR)
     {
-      for (tmp = e->dest->pred; tmp ; tmp = tmp->pred_next)
+      FOR_EACH_EDGE (tmp, ei, e->dest->preds)
        {
          int index = EDGE_INDEX (edge_list, tmp->src, tmp->dest);
          RESET_BIT (pre_insert_map[index], expr->index);
@@ -6256,33 +6281,40 @@ insert_store (struct ls_expr * expr, edge e)
 static void
 remove_reachable_equiv_notes (basic_block bb, struct ls_expr *smexpr)
 {
-  edge *stack = xmalloc (sizeof (edge) * n_basic_blocks), act;
+  edge_iterator *stack, ei;
+  int sp;
+  edge act;
   sbitmap visited = sbitmap_alloc (last_basic_block);
-  int stack_top = 0;
   rtx last, insn, note;
   rtx mem = smexpr->pattern;
 
+  stack = xmalloc (sizeof (edge_iterator) * n_basic_blocks);
+  sp = 0;
+  ei = ei_start (bb->succs);
+
   sbitmap_zero (visited);
-  act = bb->succ;
 
+  act = (EDGE_COUNT (ei_container (ei)) > 0 ? EDGE_I (ei_container (ei), 0) : NULL);
   while (1)
     {
       if (!act)
        {
-         if (!stack_top)
+         if (!sp)
            {
              free (stack);
              sbitmap_free (visited);
              return;
            }
-         act = stack[--stack_top];
+         act = ei_edge (stack[--sp]);
        }
       bb = act->dest;
 
       if (bb == EXIT_BLOCK_PTR
          || TEST_BIT (visited, bb->index))
        {
-         act = act->succ_next;
+         if (!ei_end_p (ei))
+             ei_next (&ei);
+         act = (! ei_end_p (ei)) ? ei_edge (ei) : NULL;
          continue;
        }
       SET_BIT (visited, bb->index);
@@ -6310,12 +6342,17 @@ remove_reachable_equiv_notes (basic_block bb, struct ls_expr *smexpr)
                       INSN_UID (insn));
            remove_note (insn, note);
          }
-      act = act->succ_next;
-      if (bb->succ)
+
+      if (!ei_end_p (ei))
+       ei_next (&ei);
+      act = (! ei_end_p (ei)) ? ei_edge (ei) : NULL;
+
+      if (EDGE_COUNT (bb->succs) > 0)
        {
          if (act)
-           stack[stack_top++] = act;
-         act = bb->succ;
+           stack[sp++] = ei;
+         ei = ei_start (bb->succs);
+         act = (EDGE_COUNT (ei_container (ei)) > 0 ? EDGE_I (ei_container (ei), 0) : NULL);
        }
     }
 }