cfgloopmanip.c (update_single_exit_for_duplicated_loop, [...]): New functions.
[gcc.git] / gcc / cfgloopmanip.c
index 638b2996584052c535005b4f6b9acc61cd3dfea8..8c5a0f14a58c0b32dd8fa6cb5504720ed5302956 100644 (file)
@@ -770,6 +770,40 @@ update_single_exits_after_duplication (basic_block *bbs, unsigned nbbs,
     bbs[i]->flags &= ~BB_DUPLICATED;
 }
 
+/* Updates single exit information for the copy of LOOP.  */
+
+static void
+update_single_exit_for_duplicated_loop (struct loop *loop)
+{
+  struct loop *copy = loop->copy;
+  basic_block src, dest;
+  edge exit = loop->single_exit;
+
+  if (!exit)
+    return;
+
+  src = get_bb_copy (exit->src);
+  dest = exit->dest;
+  if (dest->flags & BB_DUPLICATED)
+    dest = get_bb_copy (dest);
+
+  exit = find_edge (src, dest);
+  gcc_assert (exit != NULL);
+  copy->single_exit = exit;
+}
+
+/* Updates single exit information for copies of ORIG_LOOPS and their subloops.
+   N is the number of the loops in the ORIG_LOOPS array.  */
+
+static void
+update_single_exit_for_duplicated_loops (struct loop *orig_loops[], unsigned n)
+{
+  unsigned i;
+
+  for (i = 0; i < n; i++)
+    update_single_exit_for_duplicated_loop (orig_loops[i]);
+}
+
 /* Duplicates body of LOOP to given edge E NDUPL times.  Takes care of updating
    LOOPS structure and dominators.  E's destination must be LOOP header for
    this to work, i.e. it must be entry or latch edge of this loop; these are
@@ -950,6 +984,15 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
                place_after);
       place_after = new_spec_edges[SE_LATCH]->src;
 
+      if (loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
+       {
+         for (i = 0; i < n; i++)
+           bbs[i]->flags |= BB_DUPLICATED;
+         update_single_exit_for_duplicated_loops (orig_loops, n_orig_loops);
+         for (i = 0; i < n; i++)
+           bbs[i]->flags &= ~BB_DUPLICATED;
+       }
+
       if (flags & DLTHE_RECORD_COPY_NUMBER)
        for (i = 0; i < n; i++)
          {
@@ -1268,7 +1311,8 @@ lv_adjust_loop_entry_edge (basic_block first_head,
                          cond_expr);
 
   /* 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);
+  e1 = make_edge (new_head, first_head,
+                 current_ir_type () == IR_GIMPLE ? EDGE_TRUE_VALUE : 0);
   set_immediate_dominator (CDI_DOMINATORS, first_head, new_head);
   set_immediate_dominator (CDI_DOMINATORS, second_head, new_head);