diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 646e2928035626e0fe9c2c51521c2008c46d2f02..24d6dc652583d13d4da85274e9690bc5b7ccbc42 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2007-01-14  Zdenek Dvorak <dvorakz@suse.cz>
+
+	* loop-unswitch.c (unswitch_loop): Do not call fix_loop_placement.
+	* cfgloopmanip.c (fix_loop_placement): Made static.  Use
+	get_loop_exit_edges.  Changed return type to bool.
+	* cfgloop.h (fix_loop_placement): Declaration removed.
+
 2007-01-14  Dorit Nuzman  <dorit@il.ibm.com>
 
 	* param.h (MIN_VECT_LOOP_BOUND): New.
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index ec1149c8bb822d2d4cf0f548c0d8f5e21abddffc..47bfa576103c528c0bda6ff1af16e5a7ff3bf996 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -242,8 +242,6 @@ extern void remove_bb_from_loops (basic_block);
 extern void cancel_loop_tree (struct loop *);
 extern void delete_loop (struct loop *);
 
-extern int fix_loop_placement (struct loop *);
-
 enum
 {
   CP_SIMPLE_PREHEADERS = 1
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 222bcb3623c14900816368ff0aedc2804996e916..74f7b0781a74586ef5aa14dfb16d0d83669f4367 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -120,6 +120,46 @@ fix_bb_placement (basic_block bb)
   return true;
 }
 
+/* Fix placement of LOOP inside loop tree, i.e. find the innermost superloop
+   of LOOP to that leads at least one exit edge of LOOP, and set it
+   as the immediate superloop of LOOP.  Return true if the immediate superloop
+   of LOOP changed.  */
+
+static bool
+fix_loop_placement (struct loop *loop)
+{
+  unsigned i;
+  edge e;
+  VEC (edge, heap) *exits = get_loop_exit_edges (loop);
+  struct loop *father = current_loops->tree_root, *act;
+  bool ret = false;
+
+  for (i = 0; VEC_iterate (edge, exits, i, e); i++)
+    {
+      act = find_common_loop (loop, e->dest->loop_father);
+      if (flow_loop_nested_p (father, act))
+	father = act;
+    }
+
+  if (father != loop->outer)
+    {
+      for (act = loop->outer; act != father; act = act->outer)
+	act->num_nodes -= loop->num_nodes;
+      flow_loop_tree_node_remove (loop);
+      flow_loop_tree_node_add (father, loop);
+
+      /* The exit edges of LOOP no longer exits its original immediate
+	 superloops; remove them from the appropriate exit lists.  */
+      for (i = 0; VEC_iterate (edge, exits, i, e); i++)
+	rescan_loop_exit (e, false, false);
+
+      ret = true;
+    }
+
+  VEC_free (edge, heap, exits);
+  return ret;
+}
+
 /* Fix placements of basic blocks inside loop hierarchy stored in loops; i.e.
    enforce condition condition stated in description of fix_bb_placement. We
    start from basic block FROM that had some of its successors removed, so that
@@ -563,42 +603,6 @@ unloop (struct loop *loop, bool *irred_invalidated)
   fix_bb_placements (latch, &dummy);
 }
 
-/* Fix placement of LOOP inside loop tree, i.e. find the innermost superloop
-   FATHER of LOOP such that all of the edges coming out of LOOP belong to
-   FATHER, and set it as outer loop of LOOP.  Return true if placement of
-   LOOP changed.  */
-
-int
-fix_loop_placement (struct loop *loop)
-{
-  basic_block *body;
-  unsigned i;
-  edge e;
-  edge_iterator ei;
-  struct loop *father = loop->pred[0], *act;
-
-  body = get_loop_body (loop);
-  for (i = 0; i < loop->num_nodes; i++)
-    FOR_EACH_EDGE (e, ei, body[i]->succs)
-      if (!flow_bb_inside_loop_p (loop, e->dest))
-	{
-	  act = find_common_loop (loop, e->dest->loop_father);
-	  if (flow_loop_nested_p (father, act))
-	    father = act;
-	}
-  free (body);
-
-  if (father != loop->outer)
-    {
-      for (act = loop->outer; act != father; act = act->outer)
-	act->num_nodes -= loop->num_nodes;
-      flow_loop_tree_node_remove (loop);
-      flow_loop_tree_node_add (father, loop);
-      return 1;
-    }
-  return 0;
-}
-
 /* Fix placement of superloops of LOOP inside loop tree, i.e. ensure that
    condition stated in description of fix_loop_placement holds for them.
    It is used in case when we removed some edges coming out of LOOP, which
diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c
index b0e2aaa12be3feb4d1b28c0a52346d349f3a9a8c..05530adcfaf942805c6664e4b9d84fd1ca90f27e 100644
--- a/gcc/loop-unswitch.c
+++ b/gcc/loop-unswitch.c
@@ -458,11 +458,6 @@ unswitch_loop (struct loop *loop, basic_block unswitch_on, rtx cond, rtx cinsn)
   remove_path (true_edge);
   remove_path (false_edge);
 
-  /* One of created loops do not have to be subloop of the outer loop now,
-     so fix its placement in loop data structure.  */
-  fix_loop_placement (loop);
-  fix_loop_placement (nloop);
-
   /* Preserve the simple loop preheaders.  */
   split_edge (loop_preheader_edge (loop));
   split_edge (loop_preheader_edge (nloop));