OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / cfgloopmanip.c
index 1e36427..bb7aca0 100644 (file)
@@ -52,22 +52,6 @@ static void unloop (struct loops *, struct loop *);
 
 #define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
 
-/* Splits basic block BB after INSN, returns created edge.  Updates loops
-   and dominators.  */
-edge
-split_loop_bb (basic_block bb, void *insn)
-{
-  edge e;
-
-  /* Split the block.  */
-  e = split_block (bb, insn);
-
-  /* Add dest to loop.  */
-  add_bb_to_loop (e->dest, e->src->loop_father);
-
-  return e;
-}
-
 /* Checks whether basic block BB is dominated by DATA.  */
 static bool
 rpe_enum_p (basic_block bb, void *data)
@@ -101,7 +85,7 @@ find_path (edge e, basic_block **bbs)
   gcc_assert (EDGE_COUNT (e->dest->preds) <= 1);
 
   /* Find bbs in the path.  */
-  *bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
+  *bbs = XCNEWVEC (basic_block, n_basic_blocks);
   return dfs_enumerate_from (e->dest, 0, rpe_enum_p, *bbs,
                             n_basic_blocks, e->dest);
 }
@@ -175,7 +159,7 @@ fix_bb_placements (struct loops *loops, basic_block from)
   /* Prevent us from going out of the base_loop.  */
   SET_BIT (in_queue, base_loop->header->index);
 
-  queue = xmalloc ((base_loop->num_nodes + 1) * sizeof (basic_block));
+  queue = XNEWVEC (basic_block, base_loop->num_nodes + 1);
   qtop = queue + base_loop->num_nodes + 1;
   qbeg = queue;
   qend = queue + 1;
@@ -260,7 +244,7 @@ fix_irreducible_loops (basic_block from)
   on_stack = sbitmap_alloc (last_basic_block);
   sbitmap_zero (on_stack);
   SET_BIT (on_stack, from->index);
-  stack = xmalloc (from->loop_father->num_nodes * sizeof (basic_block));
+  stack = XNEWVEC (basic_block, from->loop_father->num_nodes);
   stack[0] = from;
   stack_top = 1;
 
@@ -282,7 +266,7 @@ fix_irreducible_loops (basic_block from)
       else
        {
          num_edges = EDGE_COUNT (bb->succs);
-         edges = xmalloc (num_edges * sizeof (edge));
+         edges = XNEWVEC (edge, num_edges);
          FOR_EACH_EDGE (e, ei, bb->succs)
            edges[ei.index] = e;
        }
@@ -347,7 +331,7 @@ remove_path (struct loops *loops, edge e)
   nrem = find_path (e, &rem_bbs);
 
   n_bord_bbs = 0;
-  bord_bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
+  bord_bbs = XCNEWVEC (basic_block, n_basic_blocks);
   seen = sbitmap_alloc (last_basic_block);
   sbitmap_zero (seen);
 
@@ -370,7 +354,7 @@ remove_path (struct loops *loops, edge e)
   from = e->src;
   deleted = loop_delete_branch_edge (e, 1);
   gcc_assert (deleted);
-  dom_bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
+  dom_bbs = XCNEWVEC (basic_block, n_basic_blocks);
 
   /* Cancel loops contained in the path.  */
   for (i = 0; i < nrem; i++)
@@ -439,7 +423,7 @@ add_loop (struct loops *loops, struct loop *loop)
   loop->level = 1;
 
   /* Find its nodes.  */
-  bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
+  bbs = XCNEWVEC (basic_block, n_basic_blocks);
   n = dfs_enumerate_from (loop->latch, 1, alp_enum_p,
                          bbs, n_basic_blocks, loop->header);
 
@@ -480,7 +464,7 @@ loopify (struct loops *loops, edge latch_edge, edge header_edge,
   basic_block *dom_bbs, *body;
   unsigned n_dom_bbs, i;
   sbitmap seen;
-  struct loop *loop = xcalloc (1, sizeof (struct loop));
+  struct loop *loop = XCNEW (struct loop);
   struct loop *outer = succ_bb->loop_father->outer;
   int freq, prob, tot_prob;
   gcov_type cnt;
@@ -531,7 +515,7 @@ loopify (struct loops *loops, edge latch_edge, edge header_edge,
   scale_loop_frequencies (succ_bb->loop_father, tot_prob - prob, tot_prob);
 
   /* Update dominators of blocks outside of LOOP.  */
-  dom_bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
+  dom_bbs = XCNEWVEC (basic_block, n_basic_blocks);
   n_dom_bbs = 0;
   seen = sbitmap_alloc (last_basic_block);
   sbitmap_zero (seen);
@@ -697,7 +681,7 @@ struct loop *
 duplicate_loop (struct loops *loops, struct loop *loop, struct loop *target)
 {
   struct loop *cloop;
-  cloop = xcalloc (1, sizeof (struct loop));
+  cloop = XCNEW (struct loop);
   place_new_loop (loops, cloop);
 
   /* Initialize copied loop.  */
@@ -860,6 +844,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
   int p, freq_in, freq_le, freq_out_orig;
   int prob_pass_thru, prob_pass_wont_exit, prob_pass_main;
   int add_irreducible_flag;
+  basic_block place_after;
 
   gcc_assert (e->dest == loop->header);
   gcc_assert (ndupl > 0);
@@ -871,7 +856,10 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
       gcc_assert (!flow_bb_inside_loop_p (loop, orig->dest));
     }
 
-  bbs = get_loop_body (loop);
+  n = loop->num_nodes;
+  bbs = get_loop_body_in_dom_order (loop);
+  gcc_assert (bbs[0] == loop->header);
+  gcc_assert (bbs[n  - 1] == loop->latch);
 
   /* Check whether duplication is possible.  */
   if (!can_copy_bbs_p (bbs, loop->num_nodes))
@@ -879,7 +867,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
       free (bbs);
       return false;
     }
-  new_bbs = xmalloc (sizeof (basic_block) * loop->num_nodes);
+  new_bbs = XNEWVEC (basic_block, loop->num_nodes);
 
   /* In case we are doing loop peeling and the loop is in the middle of
      irreducible region, the peeled copies will be inside it too.  */
@@ -906,14 +894,14 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
       prob_pass_wont_exit =
              RDIV (REG_BR_PROB_BASE * (freq_le + freq_out_orig), freq_in);
 
-      scale_step = xmalloc (ndupl * sizeof (int));
+      scale_step = XNEWVEC (int, ndupl);
 
        for (i = 1; i <= ndupl; i++)
          scale_step[i - 1] = TEST_BIT (wont_exit, i)
                                ? prob_pass_wont_exit
                                : prob_pass_thru;
 
-      /* Complette peeling is special as the probability of exit in last
+      /* Complete peeling is special as the probability of exit in last
          copy becomes 1.  */
       if (flags & DLTHE_FLAG_COMPLETTE_PEEL)
        {
@@ -923,7 +911,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
            wanted_freq = freq_in;
 
          gcc_assert (!is_latch);
-         /* First copy has frequency of incomming edge.  Each subseqeuent
+         /* First copy has frequency of incoming edge.  Each subsequent
             frequency should be reduced by prob_pass_wont_exit.  Caller
             should've managed the flags so all except for original loop
             has won't exist set.  */
@@ -969,15 +957,13 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
   n_orig_loops = 0;
   for (aloop = loop->inner; aloop; aloop = aloop->next)
     n_orig_loops++;
-  orig_loops = xcalloc (n_orig_loops, sizeof (struct loop *));
+  orig_loops = XCNEWVEC (struct loop *, n_orig_loops);
   for (aloop = loop->inner, i = 0; aloop; aloop = aloop->next, i++)
     orig_loops[i] = aloop;
 
   loop->copy = target;
 
-  n = loop->num_nodes;
-
-  first_active = xmalloc (n * sizeof (basic_block));
+  first_active = XNEWVEC (basic_block, n);
   if (is_latch)
     {
       memcpy (first_active, bbs, n * sizeof (basic_block));
@@ -995,13 +981,16 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
   spec_edges[SE_ORIG] = orig;
   spec_edges[SE_LATCH] = latch_edge;
 
+  place_after = e->src;
   for (j = 0; j < ndupl; j++)
     {
       /* Copy loops.  */
       copy_loops_to (loops, orig_loops, n_orig_loops, target);
 
       /* Copy bbs.  */
-      copy_bbs (bbs, n, new_bbs, spec_edges, 2, new_spec_edges, loop);
+      copy_bbs (bbs, n, new_bbs, spec_edges, 2, new_spec_edges, loop,
+               place_after);
+      place_after = new_spec_edges[SE_LATCH]->src;
 
       if (flags & DLTHE_RECORD_COPY_NUMBER)
        for (i = 0; i < n; i++)
@@ -1039,7 +1028,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
          redirect_edge_and_branch_force (new_spec_edges[SE_LATCH],
                                          loop->header);
          set_immediate_dominator (CDI_DOMINATORS, new_bbs[0], latch);
-         latch = loop->latch = new_bbs[1];
+         latch = loop->latch = new_bbs[n - 1];
          e = latch_edge = new_spec_edges[SE_LATCH];
        }
       else
@@ -1060,7 +1049,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
       if (!first_active_latch)
        {
          memcpy (first_active, new_bbs, n * sizeof (basic_block));
-         first_active_latch = new_bbs[1];
+         first_active_latch = new_bbs[n - 1];
        }
 
       /* Set counts and frequencies.  */
@@ -1307,7 +1296,7 @@ create_loop_notes (void)
   free_dominance_info (CDI_DOMINATORS);
   if (loops.num > 1)
     {
-      last = xcalloc (loops.num, sizeof (basic_block));
+      last = XCNEWVEC (basic_block, loops.num);
 
       FOR_EACH_BB (bb)
        {
@@ -1315,8 +1304,8 @@ create_loop_notes (void)
            last[loop->num] = bb;
        }
 
-      first = xcalloc (loops.num, sizeof (basic_block));
-      stack = xcalloc (loops.num, sizeof (struct loop *));
+      first = XCNEWVEC (basic_block, loops.num);
+      stack = XCNEWVEC (struct loop *, loops.num);
       top = stack;
 
       FOR_EACH_BB (bb)
@@ -1399,7 +1388,7 @@ static basic_block
 lv_adjust_loop_entry_edge (basic_block first_head,
                           basic_block second_head,
                           edge e,
-                          tree cond_expr)
+                          void *cond_expr)
 {
   basic_block new_head = NULL;
   edge e1;
@@ -1414,7 +1403,8 @@ lv_adjust_loop_entry_edge (basic_block first_head,
   lv_add_condition_to_bb (first_head, second_head, new_head,
                          cond_expr);
 
-  e1 = make_edge (new_head, first_head, EDGE_TRUE_VALUE);
+  /* Don't set EDGE_TRUE_VALUE in RTL mode, as it's invalid there.  */
+  e1 = make_edge (new_head, first_head, ir_type () ? EDGE_TRUE_VALUE : 0);
   set_immediate_dominator (CDI_DOMINATORS, first_head, new_head);
   set_immediate_dominator (CDI_DOMINATORS, second_head, new_head);
 
@@ -1426,21 +1416,26 @@ lv_adjust_loop_entry_edge (basic_block first_head,
 
 /* Main entry point for Loop Versioning transformation.
    
-This transformation given a condition and a loop, creates
--if (condition) { loop_copy1 } else { loop_copy2 },
-where loop_copy1 is the loop transformed in one way, and loop_copy2
-is the loop transformed in another way (or unchanged). 'condition'
-may be a run time test for things that were not resolved by static
-analysis (overlapping ranges (anti-aliasing), alignment, etc.).  */
+   This transformation given a condition and a loop, creates
+   -if (condition) { loop_copy1 } else { loop_copy2 },
+   where loop_copy1 is the loop transformed in one way, and loop_copy2
+   is the loop transformed in another way (or unchanged). 'condition'
+   may be a run time test for things that were not resolved by static
+   analysis (overlapping ranges (anti-aliasing), alignment, etc.).
+
+   If PLACE_AFTER is true, we place the new loop after LOOP in the
+   instruction stream, otherwise it is placed before LOOP.  */
 
 struct loop *
 loop_version (struct loops *loops, struct loop * loop, 
-             void *cond_expr, basic_block *condition_bb)
+             void *cond_expr, basic_block *condition_bb,
+             bool place_after)
 {
   basic_block first_head, second_head;
   edge entry, latch_edge, exit, true_edge, false_edge;
   int irred_flag;
   struct loop *nloop;
+  basic_block cond_bb;
 
   /* CHECKME: Loop versioning does not handle nested loop at this point.  */
   if (loop->inner)
@@ -1464,9 +1459,12 @@ loop_version (struct loops *loops, struct loop * loop,
   second_head = entry->dest;
 
   /* Split loop entry edge and insert new block with cond expr.  */
-  *condition_bb =  lv_adjust_loop_entry_edge (first_head, second_head,
-                                             entry, cond_expr);
-  if (!*condition_bb)
+  cond_bb =  lv_adjust_loop_entry_edge (first_head, second_head,
+                                       entry, cond_expr);
+  if (condition_bb)
+    *condition_bb = cond_bb;
+
+  if (!cond_bb)
     {
       entry->flags |= irred_flag;
       return NULL;
@@ -1474,11 +1472,11 @@ loop_version (struct loops *loops, struct loop * loop,
 
   latch_edge = single_succ_edge (get_bb_copy (loop->latch));
   
-  extract_cond_bb_edges (*condition_bb, &true_edge, &false_edge);
+  extract_cond_bb_edges (cond_bb, &true_edge, &false_edge);
   nloop = loopify (loops,
                   latch_edge,
                   single_pred_edge (get_bb_copy (loop->header)),
-                  *condition_bb, true_edge, false_edge,
+                  cond_bb, true_edge, false_edge,
                   false /* Do not redirect all edges.  */);
 
   exit = loop->single_exit;
@@ -1489,15 +1487,30 @@ loop_version (struct loops *loops, struct loop * loop,
   lv_flush_pending_stmts (latch_edge);
 
   /* loopify redirected condition_bb's succ edge. Update its PENDING_STMTS.  */ 
-  extract_cond_bb_edges (*condition_bb, &true_edge, &false_edge);
+  extract_cond_bb_edges (cond_bb, &true_edge, &false_edge);
   lv_flush_pending_stmts (false_edge);
   /* Adjust irreducible flag.  */
   if (irred_flag)
     {
-      (*condition_bb)->flags |= BB_IRREDUCIBLE_LOOP;
+      cond_bb->flags |= BB_IRREDUCIBLE_LOOP;
       loop_preheader_edge (loop)->flags |= EDGE_IRREDUCIBLE_LOOP;
       loop_preheader_edge (nloop)->flags |= EDGE_IRREDUCIBLE_LOOP;
-      single_pred_edge ((*condition_bb))->flags |= EDGE_IRREDUCIBLE_LOOP;
+      single_pred_edge (cond_bb)->flags |= EDGE_IRREDUCIBLE_LOOP;
+    }
+
+  if (place_after)
+    {
+      basic_block *bbs = get_loop_body_in_dom_order (nloop), after;
+      unsigned i;
+
+      after = loop->latch;
+
+      for (i = 0; i < nloop->num_nodes; i++)
+       {
+         move_block_after (bbs[i], after);
+         after = bbs[i];
+       }
+      free (bbs);
     }
 
   /* At this point condition_bb is loop predheader with two successors, 
@@ -1535,7 +1548,7 @@ fix_loop_structure (struct loops *loops, bitmap changed_bbs)
     }
 
   /* Remove the dead loops from structures.  */
-  loops->tree_root->num_nodes = n_basic_blocks + 2;
+  loops->tree_root->num_nodes = n_basic_blocks
   for (i = 1; i < loops->num; i++)
     {
       loop = loops->parray[i];
@@ -1604,6 +1617,8 @@ fix_loop_structure (struct loops *loops, bitmap changed_bbs)
       bb->aux = NULL;
     }
 
-  mark_single_exit_loops (loops);
-  mark_irreducible_loops (loops);
+  if (loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
+    mark_single_exit_loops (loops);
+  if (loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
+    mark_irreducible_loops (loops);
 }