[v2,3/4] Rename loop_version to clone_loop_to_header_edge.

Message ID 20211027063448.1844771-4-luoxhu@linux.ibm.com
State New
Headers
Series loop split fix and functions renaming |

Commit Message

Xionghu Luo Oct. 27, 2021, 6:34 a.m. UTC
  Name loop_copy is used in gcc/cfg.c already.

gcc/ChangeLog:

	* cfgloopmanip.c (force_single_succ_latches): Rename
	loop_version to clone_loop_to_header_edge.
	(lv_adjust_loop_entry_edge): Likewise.
	(loop_version): Likewise.
	(clone_loop_to_header_edge): Likewise.
	* cfgloopmanip.h (class loop): Likewise.
	(clone_loop_to_header_edge): Likewise.
	* gimple-loop-versioning.cc (loop_versioning::version_loop): Likewise.
	* modulo-sched.c (sms_schedule): Likewise.
	* tree-if-conv.c (version_loop_for_if_conversion): Likewise.
	* tree-loop-distribution.c (version_loop_by_alias_check): Likewise.
	* tree-parloops.c (gen_parallel_loop): Likewise.
	* tree-ssa-loop-manip.c (tree_transform_and_unroll_loop): Likewise.
	* tree-ssa-loop-split.c (split_loop): Likewise.
	(get_cond_branch_to_split_loop): Likewise.
	(do_split_loop_on_cond): Likewise.
	* tree-ssa-loop-unswitch.c (tree_unswitch_loop): Likewise.
	* tree-vect-loop-manip.c (vect_loop_versioning): Likewise.
---
 gcc/cfgloopmanip.c            | 22 +++++++++++-----------
 gcc/cfgloopmanip.h            |  8 ++++----
 gcc/gimple-loop-versioning.cc | 11 ++++++-----
 gcc/modulo-sched.c            |  6 +++---
 gcc/tree-if-conv.c            | 13 +++++++------
 gcc/tree-loop-distribution.c  |  4 ++--
 gcc/tree-parloops.c           | 10 +++++-----
 gcc/tree-ssa-loop-manip.c     |  9 +++++----
 gcc/tree-ssa-loop-split.c     | 30 +++++++++++++++---------------
 gcc/tree-ssa-loop-unswitch.c  |  8 +++-----
 gcc/tree-vect-loop-manip.c    |  5 +++--
 11 files changed, 64 insertions(+), 62 deletions(-)
  

Comments

Richard Biener Nov. 3, 2021, 1:36 p.m. UTC | #1
On Wed, 27 Oct 2021, Xionghu Luo wrote:

> Name loop_copy is used in gcc/cfg.c already.

But it's not actually cloning the loop to the header edge but doing
more - adding a condition and re-wiring edges so the cloned loop
is no longer on the header edge.

So no, I don't think this is good to go.  If we can make use
of the part of loop_version that does this we should instead
split out a new API but keep loop_version with its name but
using clone_loop_to_header_edge then.

But we can leave that when we have use of such API.  I originally
thought loop splitting might be able to use such API to make
the transform it does clearer - but whether that's the case is
left as an exercise to the reader.

Thanks,
Richard.

> gcc/ChangeLog:
> 
> 	* cfgloopmanip.c (force_single_succ_latches): Rename
> 	loop_version to clone_loop_to_header_edge.
> 	(lv_adjust_loop_entry_edge): Likewise.
> 	(loop_version): Likewise.
> 	(clone_loop_to_header_edge): Likewise.
> 	* cfgloopmanip.h (class loop): Likewise.
> 	(clone_loop_to_header_edge): Likewise.
> 	* gimple-loop-versioning.cc (loop_versioning::version_loop): Likewise.
> 	* modulo-sched.c (sms_schedule): Likewise.
> 	* tree-if-conv.c (version_loop_for_if_conversion): Likewise.
> 	* tree-loop-distribution.c (version_loop_by_alias_check): Likewise.
> 	* tree-parloops.c (gen_parallel_loop): Likewise.
> 	* tree-ssa-loop-manip.c (tree_transform_and_unroll_loop): Likewise.
> 	* tree-ssa-loop-split.c (split_loop): Likewise.
> 	(get_cond_branch_to_split_loop): Likewise.
> 	(do_split_loop_on_cond): Likewise.
> 	* tree-ssa-loop-unswitch.c (tree_unswitch_loop): Likewise.
> 	* tree-vect-loop-manip.c (vect_loop_versioning): Likewise.
> ---
>  gcc/cfgloopmanip.c            | 22 +++++++++++-----------
>  gcc/cfgloopmanip.h            |  8 ++++----
>  gcc/gimple-loop-versioning.cc | 11 ++++++-----
>  gcc/modulo-sched.c            |  6 +++---
>  gcc/tree-if-conv.c            | 13 +++++++------
>  gcc/tree-loop-distribution.c  |  4 ++--
>  gcc/tree-parloops.c           | 10 +++++-----
>  gcc/tree-ssa-loop-manip.c     |  9 +++++----
>  gcc/tree-ssa-loop-split.c     | 30 +++++++++++++++---------------
>  gcc/tree-ssa-loop-unswitch.c  |  8 +++-----
>  gcc/tree-vect-loop-manip.c    |  5 +++--
>  11 files changed, 64 insertions(+), 62 deletions(-)
> 
> diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
> index a30ebe1cdb4..066fbddbcfe 100644
> --- a/gcc/cfgloopmanip.c
> +++ b/gcc/cfgloopmanip.c
> @@ -1535,11 +1535,10 @@ force_single_succ_latches (void)
>    loops_state_set (LOOPS_HAVE_SIMPLE_LATCHES);
>  }
>  
> -/* This function is called from loop_version.  It splits the entry edge
> -   of the loop we want to version, adds the versioning condition, and
> -   adjust the edges to the two versions of the loop appropriately.
> -   e is an incoming edge. Returns the basic block containing the
> -   condition.
> +/* This function is called from clone_loop_to_header_edge.  It splits the entry
> +  edge of the loop we want to version, adds the versioning condition, and adjust
> +  the edges to the two versions of the loop appropriately. e is an incoming
> +  edge. Returns the basic block containing the condition.
>  
>     --- edge e ---- > [second_head]
>  
> @@ -1588,7 +1587,7 @@ lv_adjust_loop_entry_edge (basic_block first_head, basic_block second_head,
>    return new_head;
>  }
>  
> -/* Main entry point for Loop Versioning transformation.
> +/* Main entry point for Loop copy transformation.
>  
>     This transformation given a condition and a loop, creates
>     -if (condition) { loop_copy1 } else { loop_copy2 },
> @@ -1609,11 +1608,12 @@ lv_adjust_loop_entry_edge (basic_block first_head, basic_block second_head,
>     instruction stream, otherwise it is placed before LOOP.  */
>  
>  class loop *
> -loop_version (class loop *loop,
> -	      void *cond_expr, basic_block *condition_bb,
> -	      profile_probability then_prob, profile_probability else_prob,
> -	      profile_probability then_scale, profile_probability else_scale,
> -	      bool place_after)
> +clone_loop_to_header_edge (class loop *loop, void *cond_expr,
> +			   basic_block *condition_bb,
> +			   profile_probability then_prob,
> +			   profile_probability else_prob,
> +			   profile_probability then_scale,
> +			   profile_probability else_scale, bool place_after)
>  {
>    basic_block first_head, second_head;
>    edge entry, latch_edge;
> diff --git a/gcc/cfgloopmanip.h b/gcc/cfgloopmanip.h
> index 312a3b48d05..eac09518702 100644
> --- a/gcc/cfgloopmanip.h
> +++ b/gcc/cfgloopmanip.h
> @@ -55,9 +55,9 @@ extern bool mfb_keep_just (edge);
>  basic_block create_preheader (class loop *, int);
>  extern void create_preheaders (int);
>  extern void force_single_succ_latches (void);
> -class loop * loop_version (class loop *, void *,
> -			    basic_block *,
> -			    profile_probability, profile_probability,
> -			    profile_probability, profile_probability, bool);
> +class loop *
> +clone_loop_to_header_edge (class loop *, void *, basic_block *,
> +			   profile_probability, profile_probability,
> +			   profile_probability, profile_probability, bool);
>  
>  #endif /* GCC_CFGLOOPMANIP_H */
> diff --git a/gcc/gimple-loop-versioning.cc b/gcc/gimple-loop-versioning.cc
> index 15e0803dc29..c0fa60b91f8 100644
> --- a/gcc/gimple-loop-versioning.cc
> +++ b/gcc/gimple-loop-versioning.cc
> @@ -1686,11 +1686,12 @@ loop_versioning::version_loop (class loop *loop)
>    /* Version the loop.  */
>    initialize_original_copy_tables ();
>    basic_block cond_bb;
> -  li.optimized_loop = loop_version (loop, cond, &cond_bb,
> -				    profile_probability::unlikely (),
> -				    profile_probability::likely (),
> -				    profile_probability::unlikely (),
> -				    profile_probability::likely (), true);
> +  li.optimized_loop
> +    = clone_loop_to_header_edge (loop, cond, &cond_bb,
> +				 profile_probability::unlikely (),
> +				 profile_probability::likely (),
> +				 profile_probability::unlikely (),
> +				 profile_probability::likely (), true);
>    free_original_copy_tables ();
>    if (!li.optimized_loop)
>      {
> diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
> index 1c1b459d34f..26cd76a279c 100644
> --- a/gcc/modulo-sched.c
> +++ b/gcc/modulo-sched.c
> @@ -1737,9 +1737,9 @@ sms_schedule (void)
>  	      profile_probability prob = profile_probability::guessed_always ()
>  				.apply_scale (PROB_SMS_ENOUGH_ITERATIONS, 100);
>  
> -	      loop_version (loop, comp_rtx, &condition_bb,
> -	  		    prob, prob.invert (),
> -			    prob, prob.invert (), true);
> +	      clone_loop_to_header_edge (loop, comp_rtx, &condition_bb, prob,
> +					 prob.invert (), prob, prob.invert (),
> +					 true);
>  	    }
>  
>  	  /* Now apply the scheduled kernel to the RTL of the loop.  */
> diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
> index d7b7b309309..893231a2d16 100644
> --- a/gcc/tree-if-conv.c
> +++ b/gcc/tree-if-conv.c
> @@ -2871,7 +2871,8 @@ version_loop_for_if_conversion (class loop *loop, vec<gimple *> *preds)
>  				  integer_zero_node);
>    gimple_call_set_lhs (g, cond);
>  
> -  /* Save BB->aux around loop_version as that uses the same field.  */
> +  /* Save BB->aux around clone_loop_to_header_edge as that uses the same field.
> +   */
>    save_length = loop->inner ? loop->inner->num_nodes : loop->num_nodes;
>    void **saved_preds = XALLOCAVEC (void *, save_length);
>    for (unsigned i = 0; i < save_length; i++)
> @@ -2880,11 +2881,11 @@ version_loop_for_if_conversion (class loop *loop, vec<gimple *> *preds)
>    initialize_original_copy_tables ();
>    /* At this point we invalidate porfile confistency until IFN_LOOP_VECTORIZED
>       is re-merged in the vectorizer.  */
> -  new_loop = loop_version (loop, cond, &cond_bb,
> -			   profile_probability::always (),
> -			   profile_probability::always (),
> -			   profile_probability::always (),
> -			   profile_probability::always (), true);
> +  new_loop = clone_loop_to_header_edge (loop, cond, &cond_bb,
> +					profile_probability::always (),
> +					profile_probability::always (),
> +					profile_probability::always (),
> +					profile_probability::always (), true);
>    free_original_copy_tables ();
>  
>    for (unsigned i = 0; i < save_length; i++)
> diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
> index 2df762c8aa8..ae543fa022d 100644
> --- a/gcc/tree-loop-distribution.c
> +++ b/gcc/tree-loop-distribution.c
> @@ -2705,8 +2705,8 @@ version_loop_by_alias_check (vec<struct partition *> *partitions,
>  
>    prob = profile_probability::guessed_always ().apply_scale (9, 10);
>    initialize_original_copy_tables ();
> -  nloop = loop_version (loop, lhs, &cond_bb, prob, prob.invert (),
> -			prob, prob.invert (), true);
> +  nloop = clone_loop_to_header_edge (loop, lhs, &cond_bb, prob, prob.invert (),
> +				     prob, prob.invert (), true);
>    free_original_copy_tables ();
>    /* Record the original loop number in newly generated loops.  In case of
>       distribution, the original loop will be distributed and the new loop
> diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
> index 5e64d5ed7a3..e19fc52f38b 100644
> --- a/gcc/tree-parloops.c
> +++ b/gcc/tree-parloops.c
> @@ -3083,11 +3083,11 @@ gen_parallel_loop (class loop *loop,
>        initialize_original_copy_tables ();
>  
>        /* We assume that the loop usually iterates a lot.  */
> -      loop_version (loop, many_iterations_cond, NULL,
> -		    profile_probability::likely (),
> -		    profile_probability::unlikely (),
> -		    profile_probability::likely (),
> -		    profile_probability::unlikely (), true);
> +      clone_loop_to_header_edge (loop, many_iterations_cond, NULL,
> +				 profile_probability::likely (),
> +				 profile_probability::unlikely (),
> +				 profile_probability::likely (),
> +				 profile_probability::unlikely (), true);
>        update_ssa (TODO_update_ssa);
>        free_original_copy_tables ();
>      }
> diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
> index c7a2f67b129..350e25bb8d2 100644
> --- a/gcc/tree-ssa-loop-manip.c
> +++ b/gcc/tree-ssa-loop-manip.c
> @@ -1282,10 +1282,11 @@ tree_transform_and_unroll_loop (class loop *loop, unsigned factor,
>  	 frequencies in its body because of this change (scale the frequencies
>  	 of blocks before and after the exit by appropriate factors).  */
>        profile_probability scale_unrolled = prob_entry;
> -      new_loop = loop_version (loop, enter_main_cond, NULL, prob_entry,
> -			       prob_entry.invert (), scale_unrolled,
> -			       profile_probability::guessed_always (),
> -			       true);
> +      new_loop
> +	= clone_loop_to_header_edge (loop, enter_main_cond, NULL, prob_entry,
> +				     prob_entry.invert (), scale_unrolled,
> +				     profile_probability::guessed_always (),
> +				     true);
>        gcc_assert (new_loop != NULL);
>        update_ssa (TODO_update_ssa);
>  
> diff --git a/gcc/tree-ssa-loop-split.c b/gcc/tree-ssa-loop-split.c
> index d30782888f3..5bc9c0f6443 100644
> --- a/gcc/tree-ssa-loop-split.c
> +++ b/gcc/tree-ssa-loop-split.c
> @@ -586,12 +586,12 @@ split_loop (class loop *loop1)
>  	initialize_original_copy_tables ();
>  	basic_block cond_bb;
>  
> -	class loop *loop2 = loop_version (loop1, cond, &cond_bb,
> -					   true_edge->probability,
> -					   true_edge->probability.invert (),
> -					   true_edge->probability,
> -					   true_edge->probability.invert (),
> -					   true);
> +	class loop *loop2
> +	  = clone_loop_to_header_edge (loop1, cond, &cond_bb,
> +				       true_edge->probability,
> +				       true_edge->probability.invert (),
> +				       true_edge->probability,
> +				       true_edge->probability.invert (), true);
>  	gcc_assert (loop2);
>  
>  	edge new_e = connect_loops (loop1, loop2);
> @@ -1465,9 +1465,9 @@ get_cond_branch_to_split_loop (struct loop *loop, gcond *cond)
>                               exits
>  
>     In the graph, loop1 represents the part derived from original one, and
> -   loop2 is duplicated using loop_version (), which corresponds to the part
> -   of original one being splitted out.  In original latch edge of loop1, we
> -   insert a new conditional statement duplicated from the semi-invariant cond,
> +   loop2 is duplicated using clone_loop_to_header_edge (), which corresponds to
> +   the part of original one being splitted out.  In original latch edge of loop1,
> +   we insert a new conditional statement duplicated from the semi-invariant cond,
>     and one of its branch goes back to loop1 header as a latch edge, and the
>     other branch goes to loop2 pre-header as an entry edge.  And also in loop2,
>     we abandon the variant branch of the conditional statement by setting a
> @@ -1489,12 +1489,12 @@ do_split_loop_on_cond (struct loop *loop1, edge invar_branch)
>  
>    initialize_original_copy_tables ();
>  
> -  struct loop *loop2 = loop_version (loop1, boolean_true_node, NULL,
> -				     invar_branch->probability.invert (),
> -				     invar_branch->probability,
> -				     invar_branch->probability.invert (),
> -				     invar_branch->probability,
> -				     true);
> +  struct loop *loop2
> +    = clone_loop_to_header_edge (loop1, boolean_true_node, NULL,
> +				 invar_branch->probability.invert (),
> +				 invar_branch->probability,
> +				 invar_branch->probability.invert (),
> +				 invar_branch->probability, true);
>    if (!loop2)
>      {
>        free_original_copy_tables ();
> diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c
> index fe4dacc0833..6beebe368a7 100644
> --- a/gcc/tree-ssa-loop-unswitch.c
> +++ b/gcc/tree-ssa-loop-unswitch.c
> @@ -488,11 +488,9 @@ tree_unswitch_loop (class loop *loop,
>  
>    extract_true_false_edges_from_block (unswitch_on, &edge_true, &edge_false);
>    prob_true = edge_true->probability;
> -  return loop_version (loop, unshare_expr (cond),
> -		       NULL, prob_true,
> -		       prob_true.invert (),
> -		       prob_true, prob_true.invert (),
> -		       false);
> +  return clone_loop_to_header_edge (loop, unshare_expr (cond), NULL, prob_true,
> +				    prob_true.invert (), prob_true,
> +				    prob_true.invert (), false);
>  }
>  
>  /* Unswitch outer loops by hoisting invariant guard on
> diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
> index 4988c93fdb6..ebc013f195e 100644
> --- a/gcc/tree-vect-loop-manip.c
> +++ b/gcc/tree-vect-loop-manip.c
> @@ -3558,8 +3558,9 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
>  			 loop_to_version->num);
>  
>        initialize_original_copy_tables ();
> -      nloop = loop_version (loop_to_version, cond_expr, &condition_bb,
> -			    prob, prob.invert (), prob, prob.invert (), true);
> +      nloop = clone_loop_to_header_edge (loop_to_version, cond_expr,
> +					 &condition_bb, prob, prob.invert (),
> +					 prob, prob.invert (), true);
>        gcc_assert (nloop);
>        nloop = get_loop_copy (loop);
>  
>
  

Patch

diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index a30ebe1cdb4..066fbddbcfe 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -1535,11 +1535,10 @@  force_single_succ_latches (void)
   loops_state_set (LOOPS_HAVE_SIMPLE_LATCHES);
 }
 
-/* This function is called from loop_version.  It splits the entry edge
-   of the loop we want to version, adds the versioning condition, and
-   adjust the edges to the two versions of the loop appropriately.
-   e is an incoming edge. Returns the basic block containing the
-   condition.
+/* This function is called from clone_loop_to_header_edge.  It splits the entry
+  edge of the loop we want to version, adds the versioning condition, and adjust
+  the edges to the two versions of the loop appropriately. e is an incoming
+  edge. Returns the basic block containing the condition.
 
    --- edge e ---- > [second_head]
 
@@ -1588,7 +1587,7 @@  lv_adjust_loop_entry_edge (basic_block first_head, basic_block second_head,
   return new_head;
 }
 
-/* Main entry point for Loop Versioning transformation.
+/* Main entry point for Loop copy transformation.
 
    This transformation given a condition and a loop, creates
    -if (condition) { loop_copy1 } else { loop_copy2 },
@@ -1609,11 +1608,12 @@  lv_adjust_loop_entry_edge (basic_block first_head, basic_block second_head,
    instruction stream, otherwise it is placed before LOOP.  */
 
 class loop *
-loop_version (class loop *loop,
-	      void *cond_expr, basic_block *condition_bb,
-	      profile_probability then_prob, profile_probability else_prob,
-	      profile_probability then_scale, profile_probability else_scale,
-	      bool place_after)
+clone_loop_to_header_edge (class loop *loop, void *cond_expr,
+			   basic_block *condition_bb,
+			   profile_probability then_prob,
+			   profile_probability else_prob,
+			   profile_probability then_scale,
+			   profile_probability else_scale, bool place_after)
 {
   basic_block first_head, second_head;
   edge entry, latch_edge;
diff --git a/gcc/cfgloopmanip.h b/gcc/cfgloopmanip.h
index 312a3b48d05..eac09518702 100644
--- a/gcc/cfgloopmanip.h
+++ b/gcc/cfgloopmanip.h
@@ -55,9 +55,9 @@  extern bool mfb_keep_just (edge);
 basic_block create_preheader (class loop *, int);
 extern void create_preheaders (int);
 extern void force_single_succ_latches (void);
-class loop * loop_version (class loop *, void *,
-			    basic_block *,
-			    profile_probability, profile_probability,
-			    profile_probability, profile_probability, bool);
+class loop *
+clone_loop_to_header_edge (class loop *, void *, basic_block *,
+			   profile_probability, profile_probability,
+			   profile_probability, profile_probability, bool);
 
 #endif /* GCC_CFGLOOPMANIP_H */
diff --git a/gcc/gimple-loop-versioning.cc b/gcc/gimple-loop-versioning.cc
index 15e0803dc29..c0fa60b91f8 100644
--- a/gcc/gimple-loop-versioning.cc
+++ b/gcc/gimple-loop-versioning.cc
@@ -1686,11 +1686,12 @@  loop_versioning::version_loop (class loop *loop)
   /* Version the loop.  */
   initialize_original_copy_tables ();
   basic_block cond_bb;
-  li.optimized_loop = loop_version (loop, cond, &cond_bb,
-				    profile_probability::unlikely (),
-				    profile_probability::likely (),
-				    profile_probability::unlikely (),
-				    profile_probability::likely (), true);
+  li.optimized_loop
+    = clone_loop_to_header_edge (loop, cond, &cond_bb,
+				 profile_probability::unlikely (),
+				 profile_probability::likely (),
+				 profile_probability::unlikely (),
+				 profile_probability::likely (), true);
   free_original_copy_tables ();
   if (!li.optimized_loop)
     {
diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
index 1c1b459d34f..26cd76a279c 100644
--- a/gcc/modulo-sched.c
+++ b/gcc/modulo-sched.c
@@ -1737,9 +1737,9 @@  sms_schedule (void)
 	      profile_probability prob = profile_probability::guessed_always ()
 				.apply_scale (PROB_SMS_ENOUGH_ITERATIONS, 100);
 
-	      loop_version (loop, comp_rtx, &condition_bb,
-	  		    prob, prob.invert (),
-			    prob, prob.invert (), true);
+	      clone_loop_to_header_edge (loop, comp_rtx, &condition_bb, prob,
+					 prob.invert (), prob, prob.invert (),
+					 true);
 	    }
 
 	  /* Now apply the scheduled kernel to the RTL of the loop.  */
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index d7b7b309309..893231a2d16 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -2871,7 +2871,8 @@  version_loop_for_if_conversion (class loop *loop, vec<gimple *> *preds)
 				  integer_zero_node);
   gimple_call_set_lhs (g, cond);
 
-  /* Save BB->aux around loop_version as that uses the same field.  */
+  /* Save BB->aux around clone_loop_to_header_edge as that uses the same field.
+   */
   save_length = loop->inner ? loop->inner->num_nodes : loop->num_nodes;
   void **saved_preds = XALLOCAVEC (void *, save_length);
   for (unsigned i = 0; i < save_length; i++)
@@ -2880,11 +2881,11 @@  version_loop_for_if_conversion (class loop *loop, vec<gimple *> *preds)
   initialize_original_copy_tables ();
   /* At this point we invalidate porfile confistency until IFN_LOOP_VECTORIZED
      is re-merged in the vectorizer.  */
-  new_loop = loop_version (loop, cond, &cond_bb,
-			   profile_probability::always (),
-			   profile_probability::always (),
-			   profile_probability::always (),
-			   profile_probability::always (), true);
+  new_loop = clone_loop_to_header_edge (loop, cond, &cond_bb,
+					profile_probability::always (),
+					profile_probability::always (),
+					profile_probability::always (),
+					profile_probability::always (), true);
   free_original_copy_tables ();
 
   for (unsigned i = 0; i < save_length; i++)
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index 2df762c8aa8..ae543fa022d 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -2705,8 +2705,8 @@  version_loop_by_alias_check (vec<struct partition *> *partitions,
 
   prob = profile_probability::guessed_always ().apply_scale (9, 10);
   initialize_original_copy_tables ();
-  nloop = loop_version (loop, lhs, &cond_bb, prob, prob.invert (),
-			prob, prob.invert (), true);
+  nloop = clone_loop_to_header_edge (loop, lhs, &cond_bb, prob, prob.invert (),
+				     prob, prob.invert (), true);
   free_original_copy_tables ();
   /* Record the original loop number in newly generated loops.  In case of
      distribution, the original loop will be distributed and the new loop
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 5e64d5ed7a3..e19fc52f38b 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -3083,11 +3083,11 @@  gen_parallel_loop (class loop *loop,
       initialize_original_copy_tables ();
 
       /* We assume that the loop usually iterates a lot.  */
-      loop_version (loop, many_iterations_cond, NULL,
-		    profile_probability::likely (),
-		    profile_probability::unlikely (),
-		    profile_probability::likely (),
-		    profile_probability::unlikely (), true);
+      clone_loop_to_header_edge (loop, many_iterations_cond, NULL,
+				 profile_probability::likely (),
+				 profile_probability::unlikely (),
+				 profile_probability::likely (),
+				 profile_probability::unlikely (), true);
       update_ssa (TODO_update_ssa);
       free_original_copy_tables ();
     }
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index c7a2f67b129..350e25bb8d2 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -1282,10 +1282,11 @@  tree_transform_and_unroll_loop (class loop *loop, unsigned factor,
 	 frequencies in its body because of this change (scale the frequencies
 	 of blocks before and after the exit by appropriate factors).  */
       profile_probability scale_unrolled = prob_entry;
-      new_loop = loop_version (loop, enter_main_cond, NULL, prob_entry,
-			       prob_entry.invert (), scale_unrolled,
-			       profile_probability::guessed_always (),
-			       true);
+      new_loop
+	= clone_loop_to_header_edge (loop, enter_main_cond, NULL, prob_entry,
+				     prob_entry.invert (), scale_unrolled,
+				     profile_probability::guessed_always (),
+				     true);
       gcc_assert (new_loop != NULL);
       update_ssa (TODO_update_ssa);
 
diff --git a/gcc/tree-ssa-loop-split.c b/gcc/tree-ssa-loop-split.c
index d30782888f3..5bc9c0f6443 100644
--- a/gcc/tree-ssa-loop-split.c
+++ b/gcc/tree-ssa-loop-split.c
@@ -586,12 +586,12 @@  split_loop (class loop *loop1)
 	initialize_original_copy_tables ();
 	basic_block cond_bb;
 
-	class loop *loop2 = loop_version (loop1, cond, &cond_bb,
-					   true_edge->probability,
-					   true_edge->probability.invert (),
-					   true_edge->probability,
-					   true_edge->probability.invert (),
-					   true);
+	class loop *loop2
+	  = clone_loop_to_header_edge (loop1, cond, &cond_bb,
+				       true_edge->probability,
+				       true_edge->probability.invert (),
+				       true_edge->probability,
+				       true_edge->probability.invert (), true);
 	gcc_assert (loop2);
 
 	edge new_e = connect_loops (loop1, loop2);
@@ -1465,9 +1465,9 @@  get_cond_branch_to_split_loop (struct loop *loop, gcond *cond)
                              exits
 
    In the graph, loop1 represents the part derived from original one, and
-   loop2 is duplicated using loop_version (), which corresponds to the part
-   of original one being splitted out.  In original latch edge of loop1, we
-   insert a new conditional statement duplicated from the semi-invariant cond,
+   loop2 is duplicated using clone_loop_to_header_edge (), which corresponds to
+   the part of original one being splitted out.  In original latch edge of loop1,
+   we insert a new conditional statement duplicated from the semi-invariant cond,
    and one of its branch goes back to loop1 header as a latch edge, and the
    other branch goes to loop2 pre-header as an entry edge.  And also in loop2,
    we abandon the variant branch of the conditional statement by setting a
@@ -1489,12 +1489,12 @@  do_split_loop_on_cond (struct loop *loop1, edge invar_branch)
 
   initialize_original_copy_tables ();
 
-  struct loop *loop2 = loop_version (loop1, boolean_true_node, NULL,
-				     invar_branch->probability.invert (),
-				     invar_branch->probability,
-				     invar_branch->probability.invert (),
-				     invar_branch->probability,
-				     true);
+  struct loop *loop2
+    = clone_loop_to_header_edge (loop1, boolean_true_node, NULL,
+				 invar_branch->probability.invert (),
+				 invar_branch->probability,
+				 invar_branch->probability.invert (),
+				 invar_branch->probability, true);
   if (!loop2)
     {
       free_original_copy_tables ();
diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c
index fe4dacc0833..6beebe368a7 100644
--- a/gcc/tree-ssa-loop-unswitch.c
+++ b/gcc/tree-ssa-loop-unswitch.c
@@ -488,11 +488,9 @@  tree_unswitch_loop (class loop *loop,
 
   extract_true_false_edges_from_block (unswitch_on, &edge_true, &edge_false);
   prob_true = edge_true->probability;
-  return loop_version (loop, unshare_expr (cond),
-		       NULL, prob_true,
-		       prob_true.invert (),
-		       prob_true, prob_true.invert (),
-		       false);
+  return clone_loop_to_header_edge (loop, unshare_expr (cond), NULL, prob_true,
+				    prob_true.invert (), prob_true,
+				    prob_true.invert (), false);
 }
 
 /* Unswitch outer loops by hoisting invariant guard on
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index 4988c93fdb6..ebc013f195e 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -3558,8 +3558,9 @@  vect_loop_versioning (loop_vec_info loop_vinfo,
 			 loop_to_version->num);
 
       initialize_original_copy_tables ();
-      nloop = loop_version (loop_to_version, cond_expr, &condition_bb,
-			    prob, prob.invert (), prob, prob.invert (), true);
+      nloop = clone_loop_to_header_edge (loop_to_version, cond_expr,
+					 &condition_bb, prob, prob.invert (),
+					 prob, prob.invert (), true);
       gcc_assert (nloop);
       nloop = get_loop_copy (loop);