xref: /dflybsd-src/contrib/gcc-8.0/gcc/tree-ssa-loop-split.c (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj /* Loop splitting.
238fd1498Szrj    Copyright (C) 2015-2018 Free Software Foundation, Inc.
338fd1498Szrj 
438fd1498Szrj This file is part of GCC.
538fd1498Szrj 
638fd1498Szrj GCC is free software; you can redistribute it and/or modify it
738fd1498Szrj under the terms of the GNU General Public License as published by the
838fd1498Szrj Free Software Foundation; either version 3, or (at your option) any
938fd1498Szrj later version.
1038fd1498Szrj 
1138fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT
1238fd1498Szrj ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1338fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1438fd1498Szrj for more details.
1538fd1498Szrj 
1638fd1498Szrj You should have received a copy of the GNU General Public License
1738fd1498Szrj along with GCC; see the file COPYING3.  If not see
1838fd1498Szrj <http://www.gnu.org/licenses/>.  */
1938fd1498Szrj 
2038fd1498Szrj #include "config.h"
2138fd1498Szrj #include "system.h"
2238fd1498Szrj #include "coretypes.h"
2338fd1498Szrj #include "backend.h"
2438fd1498Szrj #include "tree.h"
2538fd1498Szrj #include "gimple.h"
2638fd1498Szrj #include "tree-pass.h"
2738fd1498Szrj #include "ssa.h"
2838fd1498Szrj #include "fold-const.h"
2938fd1498Szrj #include "tree-cfg.h"
3038fd1498Szrj #include "tree-ssa.h"
3138fd1498Szrj #include "tree-ssa-loop-niter.h"
3238fd1498Szrj #include "tree-ssa-loop.h"
3338fd1498Szrj #include "tree-ssa-loop-manip.h"
3438fd1498Szrj #include "tree-into-ssa.h"
3538fd1498Szrj #include "cfgloop.h"
3638fd1498Szrj #include "tree-scalar-evolution.h"
3738fd1498Szrj #include "gimple-iterator.h"
3838fd1498Szrj #include "gimple-pretty-print.h"
3938fd1498Szrj #include "cfghooks.h"
4038fd1498Szrj #include "gimple-fold.h"
4138fd1498Szrj #include "gimplify-me.h"
4238fd1498Szrj 
4338fd1498Szrj /* This file implements loop splitting, i.e. transformation of loops like
4438fd1498Szrj 
4538fd1498Szrj    for (i = 0; i < 100; i++)
4638fd1498Szrj      {
4738fd1498Szrj        if (i < 50)
4838fd1498Szrj          A;
4938fd1498Szrj        else
5038fd1498Szrj          B;
5138fd1498Szrj      }
5238fd1498Szrj 
5338fd1498Szrj    into:
5438fd1498Szrj 
5538fd1498Szrj    for (i = 0; i < 50; i++)
5638fd1498Szrj      {
5738fd1498Szrj        A;
5838fd1498Szrj      }
5938fd1498Szrj    for (; i < 100; i++)
6038fd1498Szrj      {
6138fd1498Szrj        B;
6238fd1498Szrj      }
6338fd1498Szrj 
6438fd1498Szrj    */
6538fd1498Szrj 
6638fd1498Szrj /* Return true when BB inside LOOP is a potential iteration space
6738fd1498Szrj    split point, i.e. ends with a condition like "IV < comp", which
6838fd1498Szrj    is true on one side of the iteration space and false on the other,
6938fd1498Szrj    and the split point can be computed.  If so, also return the border
7038fd1498Szrj    point in *BORDER and the comparison induction variable in IV.  */
7138fd1498Szrj 
7238fd1498Szrj static tree
split_at_bb_p(struct loop * loop,basic_block bb,tree * border,affine_iv * iv)7338fd1498Szrj split_at_bb_p (struct loop *loop, basic_block bb, tree *border, affine_iv *iv)
7438fd1498Szrj {
7538fd1498Szrj   gimple *last;
7638fd1498Szrj   gcond *stmt;
7738fd1498Szrj   affine_iv iv2;
7838fd1498Szrj 
7938fd1498Szrj   /* BB must end in a simple conditional jump.  */
8038fd1498Szrj   last = last_stmt (bb);
8138fd1498Szrj   if (!last || gimple_code (last) != GIMPLE_COND)
8238fd1498Szrj     return NULL_TREE;
8338fd1498Szrj   stmt = as_a <gcond *> (last);
8438fd1498Szrj 
8538fd1498Szrj   enum tree_code code = gimple_cond_code (stmt);
8638fd1498Szrj 
8738fd1498Szrj   /* Only handle relational comparisons, for equality and non-equality
8838fd1498Szrj      we'd have to split the loop into two loops and a middle statement.  */
8938fd1498Szrj   switch (code)
9038fd1498Szrj     {
9138fd1498Szrj       case LT_EXPR:
9238fd1498Szrj       case LE_EXPR:
9338fd1498Szrj       case GT_EXPR:
9438fd1498Szrj       case GE_EXPR:
9538fd1498Szrj 	break;
9638fd1498Szrj       default:
9738fd1498Szrj 	return NULL_TREE;
9838fd1498Szrj     }
9938fd1498Szrj 
10038fd1498Szrj   if (loop_exits_from_bb_p (loop, bb))
10138fd1498Szrj     return NULL_TREE;
10238fd1498Szrj 
10338fd1498Szrj   tree op0 = gimple_cond_lhs (stmt);
10438fd1498Szrj   tree op1 = gimple_cond_rhs (stmt);
10538fd1498Szrj   struct loop *useloop = loop_containing_stmt (stmt);
10638fd1498Szrj 
10738fd1498Szrj   if (!simple_iv (loop, useloop, op0, iv, false))
10838fd1498Szrj     return NULL_TREE;
10938fd1498Szrj   if (!simple_iv (loop, useloop, op1, &iv2, false))
11038fd1498Szrj     return NULL_TREE;
11138fd1498Szrj 
11238fd1498Szrj   /* Make it so that the first argument of the condition is
11338fd1498Szrj      the looping one.  */
11438fd1498Szrj   if (!integer_zerop (iv2.step))
11538fd1498Szrj     {
11638fd1498Szrj       std::swap (op0, op1);
11738fd1498Szrj       std::swap (*iv, iv2);
11838fd1498Szrj       code = swap_tree_comparison (code);
11938fd1498Szrj       gimple_cond_set_condition (stmt, code, op0, op1);
12038fd1498Szrj       update_stmt (stmt);
12138fd1498Szrj     }
12238fd1498Szrj   else if (integer_zerop (iv->step))
12338fd1498Szrj     return NULL_TREE;
12438fd1498Szrj   if (!integer_zerop (iv2.step))
12538fd1498Szrj     return NULL_TREE;
12638fd1498Szrj   if (!iv->no_overflow)
12738fd1498Szrj     return NULL_TREE;
12838fd1498Szrj 
12938fd1498Szrj   if (dump_file && (dump_flags & TDF_DETAILS))
13038fd1498Szrj     {
13138fd1498Szrj       fprintf (dump_file, "Found potential split point: ");
13238fd1498Szrj       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
13338fd1498Szrj       fprintf (dump_file, " { ");
13438fd1498Szrj       print_generic_expr (dump_file, iv->base, TDF_SLIM);
13538fd1498Szrj       fprintf (dump_file, " + I*");
13638fd1498Szrj       print_generic_expr (dump_file, iv->step, TDF_SLIM);
13738fd1498Szrj       fprintf (dump_file, " } %s ", get_tree_code_name (code));
13838fd1498Szrj       print_generic_expr (dump_file, iv2.base, TDF_SLIM);
13938fd1498Szrj       fprintf (dump_file, "\n");
14038fd1498Szrj     }
14138fd1498Szrj 
14238fd1498Szrj   *border = iv2.base;
14338fd1498Szrj   return op0;
14438fd1498Szrj }
14538fd1498Szrj 
14638fd1498Szrj /* Given a GUARD conditional stmt inside LOOP, which we want to make always
14738fd1498Szrj    true or false depending on INITIAL_TRUE, and adjusted values NEXTVAL
14838fd1498Szrj    (a post-increment IV) and NEWBOUND (the comparator) adjust the loop
14938fd1498Szrj    exit test statement to loop back only if the GUARD statement will
15038fd1498Szrj    also be true/false in the next iteration.  */
15138fd1498Szrj 
15238fd1498Szrj static void
patch_loop_exit(struct loop * loop,gcond * guard,tree nextval,tree newbound,bool initial_true)15338fd1498Szrj patch_loop_exit (struct loop *loop, gcond *guard, tree nextval, tree newbound,
15438fd1498Szrj 		 bool initial_true)
15538fd1498Szrj {
15638fd1498Szrj   edge exit = single_exit (loop);
15738fd1498Szrj   gcond *stmt = as_a <gcond *> (last_stmt (exit->src));
15838fd1498Szrj   gimple_cond_set_condition (stmt, gimple_cond_code (guard),
15938fd1498Szrj 			     nextval, newbound);
16038fd1498Szrj   update_stmt (stmt);
16138fd1498Szrj 
16238fd1498Szrj   edge stay = EDGE_SUCC (exit->src, EDGE_SUCC (exit->src, 0) == exit);
16338fd1498Szrj 
16438fd1498Szrj   exit->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
16538fd1498Szrj   stay->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
16638fd1498Szrj 
16738fd1498Szrj   if (initial_true)
16838fd1498Szrj     {
16938fd1498Szrj       exit->flags |= EDGE_FALSE_VALUE;
17038fd1498Szrj       stay->flags |= EDGE_TRUE_VALUE;
17138fd1498Szrj     }
17238fd1498Szrj   else
17338fd1498Szrj     {
17438fd1498Szrj       exit->flags |= EDGE_TRUE_VALUE;
17538fd1498Szrj       stay->flags |= EDGE_FALSE_VALUE;
17638fd1498Szrj     }
17738fd1498Szrj }
17838fd1498Szrj 
17938fd1498Szrj /* Give an induction variable GUARD_IV, and its affine descriptor IV,
18038fd1498Szrj    find the loop phi node in LOOP defining it directly, or create
18138fd1498Szrj    such phi node.  Return that phi node.  */
18238fd1498Szrj 
18338fd1498Szrj static gphi *
find_or_create_guard_phi(struct loop * loop,tree guard_iv,affine_iv *)18438fd1498Szrj find_or_create_guard_phi (struct loop *loop, tree guard_iv, affine_iv * /*iv*/)
18538fd1498Szrj {
18638fd1498Szrj   gimple *def = SSA_NAME_DEF_STMT (guard_iv);
18738fd1498Szrj   gphi *phi;
18838fd1498Szrj   if ((phi = dyn_cast <gphi *> (def))
18938fd1498Szrj       && gimple_bb (phi) == loop->header)
19038fd1498Szrj     return phi;
19138fd1498Szrj 
19238fd1498Szrj   /* XXX Create the PHI instead.  */
19338fd1498Szrj   return NULL;
19438fd1498Szrj }
19538fd1498Szrj 
19638fd1498Szrj /* Returns true if the exit values of all loop phi nodes can be
19738fd1498Szrj    determined easily (i.e. that connect_loop_phis can determine them).  */
19838fd1498Szrj 
19938fd1498Szrj static bool
easy_exit_values(struct loop * loop)20038fd1498Szrj easy_exit_values (struct loop *loop)
20138fd1498Szrj {
20238fd1498Szrj   edge exit = single_exit (loop);
20338fd1498Szrj   edge latch = loop_latch_edge (loop);
20438fd1498Szrj   gphi_iterator psi;
20538fd1498Szrj 
20638fd1498Szrj   /* Currently we regard the exit values as easy if they are the same
20738fd1498Szrj      as the value over the backedge.  Which is the case if the definition
20838fd1498Szrj      of the backedge value dominates the exit edge.  */
20938fd1498Szrj   for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
21038fd1498Szrj     {
21138fd1498Szrj       gphi *phi = psi.phi ();
21238fd1498Szrj       tree next = PHI_ARG_DEF_FROM_EDGE (phi, latch);
21338fd1498Szrj       basic_block bb;
21438fd1498Szrj       if (TREE_CODE (next) == SSA_NAME
21538fd1498Szrj 	  && (bb = gimple_bb (SSA_NAME_DEF_STMT (next)))
21638fd1498Szrj 	  && !dominated_by_p (CDI_DOMINATORS, exit->src, bb))
21738fd1498Szrj 	return false;
21838fd1498Szrj     }
21938fd1498Szrj 
22038fd1498Szrj   return true;
22138fd1498Szrj }
22238fd1498Szrj 
22338fd1498Szrj /* This function updates the SSA form after connect_loops made a new
22438fd1498Szrj    edge NEW_E leading from LOOP1 exit to LOOP2 (via in intermediate
22538fd1498Szrj    conditional).  I.e. the second loop can now be entered either
22638fd1498Szrj    via the original entry or via NEW_E, so the entry values of LOOP2
22738fd1498Szrj    phi nodes are either the original ones or those at the exit
22838fd1498Szrj    of LOOP1.  Insert new phi nodes in LOOP2 pre-header reflecting
22938fd1498Szrj    this.  The loops need to fulfill easy_exit_values().  */
23038fd1498Szrj 
23138fd1498Szrj static void
connect_loop_phis(struct loop * loop1,struct loop * loop2,edge new_e)23238fd1498Szrj connect_loop_phis (struct loop *loop1, struct loop *loop2, edge new_e)
23338fd1498Szrj {
23438fd1498Szrj   basic_block rest = loop_preheader_edge (loop2)->src;
23538fd1498Szrj   gcc_assert (new_e->dest == rest);
23638fd1498Szrj   edge skip_first = EDGE_PRED (rest, EDGE_PRED (rest, 0) == new_e);
23738fd1498Szrj 
23838fd1498Szrj   edge firste = loop_preheader_edge (loop1);
23938fd1498Szrj   edge seconde = loop_preheader_edge (loop2);
24038fd1498Szrj   edge firstn = loop_latch_edge (loop1);
24138fd1498Szrj   gphi_iterator psi_first, psi_second;
24238fd1498Szrj   for (psi_first = gsi_start_phis (loop1->header),
24338fd1498Szrj        psi_second = gsi_start_phis (loop2->header);
24438fd1498Szrj        !gsi_end_p (psi_first);
24538fd1498Szrj        gsi_next (&psi_first), gsi_next (&psi_second))
24638fd1498Szrj     {
24738fd1498Szrj       tree init, next, new_init;
24838fd1498Szrj       use_operand_p op;
24938fd1498Szrj       gphi *phi_first = psi_first.phi ();
25038fd1498Szrj       gphi *phi_second = psi_second.phi ();
25138fd1498Szrj 
25238fd1498Szrj       init = PHI_ARG_DEF_FROM_EDGE (phi_first, firste);
25338fd1498Szrj       next = PHI_ARG_DEF_FROM_EDGE (phi_first, firstn);
25438fd1498Szrj       op = PHI_ARG_DEF_PTR_FROM_EDGE (phi_second, seconde);
25538fd1498Szrj       gcc_assert (operand_equal_for_phi_arg_p (init, USE_FROM_PTR (op)));
25638fd1498Szrj 
25738fd1498Szrj       /* Prefer using original variable as a base for the new ssa name.
25838fd1498Szrj 	 This is necessary for virtual ops, and useful in order to avoid
25938fd1498Szrj 	 losing debug info for real ops.  */
26038fd1498Szrj       if (TREE_CODE (next) == SSA_NAME
26138fd1498Szrj 	  && useless_type_conversion_p (TREE_TYPE (next),
26238fd1498Szrj 					TREE_TYPE (init)))
26338fd1498Szrj 	new_init = copy_ssa_name (next);
26438fd1498Szrj       else if (TREE_CODE (init) == SSA_NAME
26538fd1498Szrj 	       && useless_type_conversion_p (TREE_TYPE (init),
26638fd1498Szrj 					     TREE_TYPE (next)))
26738fd1498Szrj 	new_init = copy_ssa_name (init);
26838fd1498Szrj       else if (useless_type_conversion_p (TREE_TYPE (next),
26938fd1498Szrj 					  TREE_TYPE (init)))
27038fd1498Szrj 	new_init = make_temp_ssa_name (TREE_TYPE (next), NULL,
27138fd1498Szrj 				       "unrinittmp");
27238fd1498Szrj       else
27338fd1498Szrj 	new_init = make_temp_ssa_name (TREE_TYPE (init), NULL,
27438fd1498Szrj 				       "unrinittmp");
27538fd1498Szrj 
27638fd1498Szrj       gphi * newphi = create_phi_node (new_init, rest);
27738fd1498Szrj       add_phi_arg (newphi, init, skip_first, UNKNOWN_LOCATION);
27838fd1498Szrj       add_phi_arg (newphi, next, new_e, UNKNOWN_LOCATION);
27938fd1498Szrj       SET_USE (op, new_init);
28038fd1498Szrj     }
28138fd1498Szrj }
28238fd1498Szrj 
28338fd1498Szrj /* The two loops LOOP1 and LOOP2 were just created by loop versioning,
28438fd1498Szrj    they are still equivalent and placed in two arms of a diamond, like so:
28538fd1498Szrj 
28638fd1498Szrj                .------if (cond)------.
28738fd1498Szrj                v                     v
28838fd1498Szrj              pre1                   pre2
28938fd1498Szrj               |                      |
29038fd1498Szrj         .--->h1                     h2<----.
29138fd1498Szrj         |     |                      |     |
29238fd1498Szrj         |    ex1---.            .---ex2    |
29338fd1498Szrj         |    /     |            |     \    |
29438fd1498Szrj         '---l1     X            |     l2---'
29538fd1498Szrj                    |            |
29638fd1498Szrj                    |            |
29738fd1498Szrj                    '--->join<---'
29838fd1498Szrj 
29938fd1498Szrj    This function transforms the program such that LOOP1 is conditionally
30038fd1498Szrj    falling through to LOOP2, or skipping it.  This is done by splitting
30138fd1498Szrj    the ex1->join edge at X in the diagram above, and inserting a condition
30238fd1498Szrj    whose one arm goes to pre2, resulting in this situation:
30338fd1498Szrj 
30438fd1498Szrj                .------if (cond)------.
30538fd1498Szrj                v                     v
30638fd1498Szrj              pre1       .---------->pre2
30738fd1498Szrj               |         |            |
30838fd1498Szrj         .--->h1         |           h2<----.
30938fd1498Szrj         |     |         |            |     |
31038fd1498Szrj         |    ex1---.    |       .---ex2    |
31138fd1498Szrj         |    /     v    |       |     \    |
31238fd1498Szrj         '---l1   skip---'       |     l2---'
31338fd1498Szrj                    |            |
31438fd1498Szrj                    |            |
31538fd1498Szrj                    '--->join<---'
31638fd1498Szrj 
31738fd1498Szrj 
31838fd1498Szrj    The condition used is the exit condition of LOOP1, which effectively means
31938fd1498Szrj    that when the first loop exits (for whatever reason) but the real original
32038fd1498Szrj    exit expression is still false the second loop will be entered.
32138fd1498Szrj    The function returns the new edge cond->pre2.
32238fd1498Szrj 
32338fd1498Szrj    This doesn't update the SSA form, see connect_loop_phis for that.  */
32438fd1498Szrj 
32538fd1498Szrj static edge
connect_loops(struct loop * loop1,struct loop * loop2)32638fd1498Szrj connect_loops (struct loop *loop1, struct loop *loop2)
32738fd1498Szrj {
32838fd1498Szrj   edge exit = single_exit (loop1);
32938fd1498Szrj   basic_block skip_bb = split_edge (exit);
33038fd1498Szrj   gcond *skip_stmt;
33138fd1498Szrj   gimple_stmt_iterator gsi;
33238fd1498Szrj   edge new_e, skip_e;
33338fd1498Szrj 
33438fd1498Szrj   gimple *stmt = last_stmt (exit->src);
33538fd1498Szrj   skip_stmt = gimple_build_cond (gimple_cond_code (stmt),
33638fd1498Szrj 				 gimple_cond_lhs (stmt),
33738fd1498Szrj 				 gimple_cond_rhs (stmt),
33838fd1498Szrj 				 NULL_TREE, NULL_TREE);
33938fd1498Szrj   gsi = gsi_last_bb (skip_bb);
34038fd1498Szrj   gsi_insert_after (&gsi, skip_stmt, GSI_NEW_STMT);
34138fd1498Szrj 
34238fd1498Szrj   skip_e = EDGE_SUCC (skip_bb, 0);
34338fd1498Szrj   skip_e->flags &= ~EDGE_FALLTHRU;
34438fd1498Szrj   new_e = make_edge (skip_bb, loop_preheader_edge (loop2)->src, 0);
34538fd1498Szrj   if (exit->flags & EDGE_TRUE_VALUE)
34638fd1498Szrj     {
34738fd1498Szrj       skip_e->flags |= EDGE_TRUE_VALUE;
34838fd1498Szrj       new_e->flags |= EDGE_FALSE_VALUE;
34938fd1498Szrj     }
35038fd1498Szrj   else
35138fd1498Szrj     {
35238fd1498Szrj       skip_e->flags |= EDGE_FALSE_VALUE;
35338fd1498Szrj       new_e->flags |= EDGE_TRUE_VALUE;
35438fd1498Szrj     }
35538fd1498Szrj 
35638fd1498Szrj   new_e->probability = profile_probability::likely ();
35738fd1498Szrj   skip_e->probability = new_e->probability.invert ();
35838fd1498Szrj 
35938fd1498Szrj   return new_e;
36038fd1498Szrj }
36138fd1498Szrj 
36238fd1498Szrj /* This returns the new bound for iterations given the original iteration
36338fd1498Szrj    space in NITER, an arbitrary new bound BORDER, assumed to be some
36438fd1498Szrj    comparison value with a different IV, the initial value GUARD_INIT of
36538fd1498Szrj    that other IV, and the comparison code GUARD_CODE that compares
36638fd1498Szrj    that other IV with BORDER.  We return an SSA name, and place any
36738fd1498Szrj    necessary statements for that computation into *STMTS.
36838fd1498Szrj 
36938fd1498Szrj    For example for such a loop:
37038fd1498Szrj 
37138fd1498Szrj      for (i = beg, j = guard_init; i < end; i++, j++)
37238fd1498Szrj        if (j < border)  // this is supposed to be true/false
37338fd1498Szrj          ...
37438fd1498Szrj 
37538fd1498Szrj    we want to return a new bound (on j) that makes the loop iterate
37638fd1498Szrj    as long as the condition j < border stays true.  We also don't want
37738fd1498Szrj    to iterate more often than the original loop, so we have to introduce
37838fd1498Szrj    some cut-off as well (via min/max), effectively resulting in:
37938fd1498Szrj 
38038fd1498Szrj      newend = min (end+guard_init-beg, border)
38138fd1498Szrj      for (i = beg; j = guard_init; j < newend; i++, j++)
38238fd1498Szrj        if (j < c)
38338fd1498Szrj          ...
38438fd1498Szrj 
38538fd1498Szrj    Depending on the direction of the IVs and if the exit tests
38638fd1498Szrj    are strict or non-strict we need to use MIN or MAX,
38738fd1498Szrj    and add or subtract 1.  This routine computes newend above.  */
38838fd1498Szrj 
38938fd1498Szrj static tree
compute_new_first_bound(gimple_seq * stmts,struct tree_niter_desc * niter,tree border,enum tree_code guard_code,tree guard_init)39038fd1498Szrj compute_new_first_bound (gimple_seq *stmts, struct tree_niter_desc *niter,
39138fd1498Szrj 			 tree border,
39238fd1498Szrj 			 enum tree_code guard_code, tree guard_init)
39338fd1498Szrj {
39438fd1498Szrj   /* The niter structure contains the after-increment IV, we need
39538fd1498Szrj      the loop-enter base, so subtract STEP once.  */
39638fd1498Szrj   tree controlbase = force_gimple_operand (niter->control.base,
39738fd1498Szrj 					   stmts, true, NULL_TREE);
39838fd1498Szrj   tree controlstep = niter->control.step;
39938fd1498Szrj   tree enddiff;
40038fd1498Szrj   if (POINTER_TYPE_P (TREE_TYPE (controlbase)))
40138fd1498Szrj     {
40238fd1498Szrj       controlstep = gimple_build (stmts, NEGATE_EXPR,
40338fd1498Szrj 				  TREE_TYPE (controlstep), controlstep);
40438fd1498Szrj       enddiff = gimple_build (stmts, POINTER_PLUS_EXPR,
40538fd1498Szrj 			      TREE_TYPE (controlbase),
40638fd1498Szrj 			      controlbase, controlstep);
40738fd1498Szrj     }
40838fd1498Szrj   else
40938fd1498Szrj     enddiff = gimple_build (stmts, MINUS_EXPR,
41038fd1498Szrj 			    TREE_TYPE (controlbase),
41138fd1498Szrj 			    controlbase, controlstep);
41238fd1498Szrj 
41338fd1498Szrj   /* Compute end-beg.  */
41438fd1498Szrj   gimple_seq stmts2;
41538fd1498Szrj   tree end = force_gimple_operand (niter->bound, &stmts2,
41638fd1498Szrj 					true, NULL_TREE);
41738fd1498Szrj   gimple_seq_add_seq_without_update (stmts, stmts2);
41838fd1498Szrj   if (POINTER_TYPE_P (TREE_TYPE (enddiff)))
41938fd1498Szrj     {
42038fd1498Szrj       tree tem = gimple_convert (stmts, sizetype, enddiff);
42138fd1498Szrj       tem = gimple_build (stmts, NEGATE_EXPR, sizetype, tem);
42238fd1498Szrj       enddiff = gimple_build (stmts, POINTER_PLUS_EXPR,
42338fd1498Szrj 			      TREE_TYPE (enddiff),
42438fd1498Szrj 			      end, tem);
42538fd1498Szrj     }
42638fd1498Szrj   else
42738fd1498Szrj     enddiff = gimple_build (stmts, MINUS_EXPR, TREE_TYPE (enddiff),
42838fd1498Szrj 			    end, enddiff);
42938fd1498Szrj 
43038fd1498Szrj   /* Compute guard_init + (end-beg).  */
43138fd1498Szrj   tree newbound;
43238fd1498Szrj   enddiff = gimple_convert (stmts, TREE_TYPE (guard_init), enddiff);
43338fd1498Szrj   if (POINTER_TYPE_P (TREE_TYPE (guard_init)))
43438fd1498Szrj     {
43538fd1498Szrj       enddiff = gimple_convert (stmts, sizetype, enddiff);
43638fd1498Szrj       newbound = gimple_build (stmts, POINTER_PLUS_EXPR,
43738fd1498Szrj 			       TREE_TYPE (guard_init),
43838fd1498Szrj 			       guard_init, enddiff);
43938fd1498Szrj     }
44038fd1498Szrj   else
44138fd1498Szrj     newbound = gimple_build (stmts, PLUS_EXPR, TREE_TYPE (guard_init),
44238fd1498Szrj 			     guard_init, enddiff);
44338fd1498Szrj 
44438fd1498Szrj   /* Depending on the direction of the IVs the new bound for the first
44538fd1498Szrj      loop is the minimum or maximum of old bound and border.
44638fd1498Szrj      Also, if the guard condition isn't strictly less or greater,
44738fd1498Szrj      we need to adjust the bound.  */
44838fd1498Szrj   int addbound = 0;
44938fd1498Szrj   enum tree_code minmax;
45038fd1498Szrj   if (niter->cmp == LT_EXPR)
45138fd1498Szrj     {
45238fd1498Szrj       /* GT and LE are the same, inverted.  */
45338fd1498Szrj       if (guard_code == GT_EXPR || guard_code == LE_EXPR)
45438fd1498Szrj 	addbound = -1;
45538fd1498Szrj       minmax = MIN_EXPR;
45638fd1498Szrj     }
45738fd1498Szrj   else
45838fd1498Szrj     {
45938fd1498Szrj       gcc_assert (niter->cmp == GT_EXPR);
46038fd1498Szrj       if (guard_code == GE_EXPR || guard_code == LT_EXPR)
46138fd1498Szrj 	addbound = 1;
46238fd1498Szrj       minmax = MAX_EXPR;
46338fd1498Szrj     }
46438fd1498Szrj 
46538fd1498Szrj   if (addbound)
46638fd1498Szrj     {
46738fd1498Szrj       tree type2 = TREE_TYPE (newbound);
46838fd1498Szrj       if (POINTER_TYPE_P (type2))
46938fd1498Szrj 	type2 = sizetype;
47038fd1498Szrj       newbound = gimple_build (stmts,
47138fd1498Szrj 			       POINTER_TYPE_P (TREE_TYPE (newbound))
47238fd1498Szrj 			       ? POINTER_PLUS_EXPR : PLUS_EXPR,
47338fd1498Szrj 			       TREE_TYPE (newbound),
47438fd1498Szrj 			       newbound,
47538fd1498Szrj 			       build_int_cst (type2, addbound));
47638fd1498Szrj     }
47738fd1498Szrj 
47838fd1498Szrj   tree newend = gimple_build (stmts, minmax, TREE_TYPE (border),
47938fd1498Szrj 			      border, newbound);
48038fd1498Szrj   return newend;
48138fd1498Szrj }
48238fd1498Szrj 
48338fd1498Szrj /* Checks if LOOP contains an conditional block whose condition
48438fd1498Szrj    depends on which side in the iteration space it is, and if so
48538fd1498Szrj    splits the iteration space into two loops.  Returns true if the
48638fd1498Szrj    loop was split.  NITER must contain the iteration descriptor for the
48738fd1498Szrj    single exit of LOOP.  */
48838fd1498Szrj 
48938fd1498Szrj static bool
split_loop(struct loop * loop1,struct tree_niter_desc * niter)49038fd1498Szrj split_loop (struct loop *loop1, struct tree_niter_desc *niter)
49138fd1498Szrj {
49238fd1498Szrj   basic_block *bbs;
49338fd1498Szrj   unsigned i;
49438fd1498Szrj   bool changed = false;
49538fd1498Szrj   tree guard_iv;
49638fd1498Szrj   tree border = NULL_TREE;
49738fd1498Szrj   affine_iv iv;
49838fd1498Szrj 
49938fd1498Szrj   bbs = get_loop_body (loop1);
50038fd1498Szrj 
50138fd1498Szrj   /* Find a splitting opportunity.  */
50238fd1498Szrj   for (i = 0; i < loop1->num_nodes; i++)
50338fd1498Szrj     if ((guard_iv = split_at_bb_p (loop1, bbs[i], &border, &iv)))
50438fd1498Szrj       {
50538fd1498Szrj 	/* Handling opposite steps is not implemented yet.  Neither
50638fd1498Szrj 	   is handling different step sizes.  */
50738fd1498Szrj 	if ((tree_int_cst_sign_bit (iv.step)
50838fd1498Szrj 	     != tree_int_cst_sign_bit (niter->control.step))
50938fd1498Szrj 	    || !tree_int_cst_equal (iv.step, niter->control.step))
51038fd1498Szrj 	  continue;
51138fd1498Szrj 
51238fd1498Szrj 	/* Find a loop PHI node that defines guard_iv directly,
51338fd1498Szrj 	   or create one doing that.  */
51438fd1498Szrj 	gphi *phi = find_or_create_guard_phi (loop1, guard_iv, &iv);
51538fd1498Szrj 	if (!phi)
51638fd1498Szrj 	  continue;
51738fd1498Szrj 	gcond *guard_stmt = as_a<gcond *> (last_stmt (bbs[i]));
51838fd1498Szrj 	tree guard_init = PHI_ARG_DEF_FROM_EDGE (phi,
51938fd1498Szrj 						 loop_preheader_edge (loop1));
52038fd1498Szrj 	enum tree_code guard_code = gimple_cond_code (guard_stmt);
52138fd1498Szrj 
52238fd1498Szrj 	/* Loop splitting is implemented by versioning the loop, placing
52338fd1498Szrj 	   the new loop after the old loop, make the first loop iterate
52438fd1498Szrj 	   as long as the conditional stays true (or false) and let the
52538fd1498Szrj 	   second (new) loop handle the rest of the iterations.
52638fd1498Szrj 
52738fd1498Szrj 	   First we need to determine if the condition will start being true
52838fd1498Szrj 	   or false in the first loop.  */
52938fd1498Szrj 	bool initial_true;
53038fd1498Szrj 	switch (guard_code)
53138fd1498Szrj 	  {
53238fd1498Szrj 	    case LT_EXPR:
53338fd1498Szrj 	    case LE_EXPR:
53438fd1498Szrj 	      initial_true = !tree_int_cst_sign_bit (iv.step);
53538fd1498Szrj 	      break;
53638fd1498Szrj 	    case GT_EXPR:
53738fd1498Szrj 	    case GE_EXPR:
53838fd1498Szrj 	      initial_true = tree_int_cst_sign_bit (iv.step);
53938fd1498Szrj 	      break;
54038fd1498Szrj 	    default:
54138fd1498Szrj 	      gcc_unreachable ();
54238fd1498Szrj 	  }
54338fd1498Szrj 
54438fd1498Szrj 	/* Build a condition that will skip the first loop when the
54538fd1498Szrj 	   guard condition won't ever be true (or false).  */
54638fd1498Szrj 	gimple_seq stmts2;
54738fd1498Szrj 	border = force_gimple_operand (border, &stmts2, true, NULL_TREE);
54838fd1498Szrj 	if (stmts2)
54938fd1498Szrj 	  gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop1),
55038fd1498Szrj 					    stmts2);
55138fd1498Szrj 	tree cond = build2 (guard_code, boolean_type_node, guard_init, border);
55238fd1498Szrj 	if (!initial_true)
55338fd1498Szrj 	  cond = fold_build1 (TRUTH_NOT_EXPR, boolean_type_node, cond);
55438fd1498Szrj 
55538fd1498Szrj 	/* Now version the loop, placing loop2 after loop1 connecting
55638fd1498Szrj 	   them, and fix up SSA form for that.  */
55738fd1498Szrj 	initialize_original_copy_tables ();
55838fd1498Szrj 	basic_block cond_bb;
55938fd1498Szrj 
56038fd1498Szrj 	struct loop *loop2 = loop_version (loop1, cond, &cond_bb,
56138fd1498Szrj 					   profile_probability::always (),
56238fd1498Szrj 					   profile_probability::always (),
56338fd1498Szrj 					   profile_probability::always (),
56438fd1498Szrj 					   profile_probability::always (),
56538fd1498Szrj 					   true);
56638fd1498Szrj 	gcc_assert (loop2);
56738fd1498Szrj 	update_ssa (TODO_update_ssa);
56838fd1498Szrj 
56938fd1498Szrj 	edge new_e = connect_loops (loop1, loop2);
57038fd1498Szrj 	connect_loop_phis (loop1, loop2, new_e);
57138fd1498Szrj 
57238fd1498Szrj 	/* The iterations of the second loop is now already
57338fd1498Szrj 	   exactly those that the first loop didn't do, but the
57438fd1498Szrj 	   iteration space of the first loop is still the original one.
57538fd1498Szrj 	   Compute the new bound for the guarding IV and patch the
57638fd1498Szrj 	   loop exit to use it instead of original IV and bound.  */
57738fd1498Szrj 	gimple_seq stmts = NULL;
57838fd1498Szrj 	tree newend = compute_new_first_bound (&stmts, niter, border,
57938fd1498Szrj 					       guard_code, guard_init);
58038fd1498Szrj 	if (stmts)
58138fd1498Szrj 	  gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop1),
58238fd1498Szrj 					    stmts);
58338fd1498Szrj 	tree guard_next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop1));
58438fd1498Szrj 	patch_loop_exit (loop1, guard_stmt, guard_next, newend, initial_true);
58538fd1498Szrj 
58638fd1498Szrj 	/* Finally patch out the two copies of the condition to be always
58738fd1498Szrj 	   true/false (or opposite).  */
58838fd1498Szrj 	gcond *force_true = as_a<gcond *> (last_stmt (bbs[i]));
58938fd1498Szrj 	gcond *force_false = as_a<gcond *> (last_stmt (get_bb_copy (bbs[i])));
59038fd1498Szrj 	if (!initial_true)
59138fd1498Szrj 	  std::swap (force_true, force_false);
59238fd1498Szrj 	gimple_cond_make_true (force_true);
59338fd1498Szrj 	gimple_cond_make_false (force_false);
59438fd1498Szrj 	update_stmt (force_true);
59538fd1498Szrj 	update_stmt (force_false);
59638fd1498Szrj 
59738fd1498Szrj 	free_original_copy_tables ();
59838fd1498Szrj 
59938fd1498Szrj 	/* We destroyed LCSSA form above.  Eventually we might be able
60038fd1498Szrj 	   to fix it on the fly, for now simply punt and use the helper.  */
60138fd1498Szrj 	rewrite_into_loop_closed_ssa_1 (NULL, 0, SSA_OP_USE, loop1);
60238fd1498Szrj 
60338fd1498Szrj 	changed = true;
60438fd1498Szrj 	if (dump_file && (dump_flags & TDF_DETAILS))
60538fd1498Szrj 	  fprintf (dump_file, ";; Loop split.\n");
60638fd1498Szrj 
60738fd1498Szrj 	/* Only deal with the first opportunity.  */
60838fd1498Szrj 	break;
60938fd1498Szrj       }
61038fd1498Szrj 
61138fd1498Szrj   free (bbs);
61238fd1498Szrj   return changed;
61338fd1498Szrj }
61438fd1498Szrj 
61538fd1498Szrj /* Main entry point.  Perform loop splitting on all suitable loops.  */
61638fd1498Szrj 
61738fd1498Szrj static unsigned int
tree_ssa_split_loops(void)61838fd1498Szrj tree_ssa_split_loops (void)
61938fd1498Szrj {
62038fd1498Szrj   struct loop *loop;
62138fd1498Szrj   bool changed = false;
62238fd1498Szrj 
62338fd1498Szrj   gcc_assert (scev_initialized_p ());
62438fd1498Szrj   FOR_EACH_LOOP (loop, LI_INCLUDE_ROOT)
62538fd1498Szrj     loop->aux = NULL;
62638fd1498Szrj 
62738fd1498Szrj   /* Go through all loops starting from innermost.  */
62838fd1498Szrj   FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
62938fd1498Szrj     {
63038fd1498Szrj       struct tree_niter_desc niter;
63138fd1498Szrj       if (loop->aux)
63238fd1498Szrj 	{
63338fd1498Szrj 	  /* If any of our inner loops was split, don't split us,
63438fd1498Szrj 	     and mark our containing loop as having had splits as well.  */
63538fd1498Szrj 	  loop_outer (loop)->aux = loop;
63638fd1498Szrj 	  continue;
63738fd1498Szrj 	}
63838fd1498Szrj 
63938fd1498Szrj       if (single_exit (loop)
64038fd1498Szrj 	  /* ??? We could handle non-empty latches when we split
64138fd1498Szrj 	     the latch edge (not the exit edge), and put the new
64238fd1498Szrj 	     exit condition in the new block.  OTOH this executes some
64338fd1498Szrj 	     code unconditionally that might have been skipped by the
64438fd1498Szrj 	     original exit before.  */
64538fd1498Szrj 	  && empty_block_p (loop->latch)
64638fd1498Szrj 	  && !optimize_loop_for_size_p (loop)
64738fd1498Szrj 	  && easy_exit_values (loop)
64838fd1498Szrj 	  && number_of_iterations_exit (loop, single_exit (loop), &niter,
64938fd1498Szrj 					false, true)
65038fd1498Szrj 	  && niter.cmp != ERROR_MARK
65138fd1498Szrj 	  /* We can't yet handle loops controlled by a != predicate.  */
652*58e805e6Szrj 	  && niter.cmp != NE_EXPR
653*58e805e6Szrj 	  && can_duplicate_loop_p (loop))
65438fd1498Szrj 	{
65538fd1498Szrj 	  if (split_loop (loop, &niter))
65638fd1498Szrj 	    {
65738fd1498Szrj 	      /* Mark our containing loop as having had some split inner
65838fd1498Szrj 	         loops.  */
65938fd1498Szrj 	      loop_outer (loop)->aux = loop;
66038fd1498Szrj 	      changed = true;
66138fd1498Szrj 	    }
66238fd1498Szrj 	}
66338fd1498Szrj     }
66438fd1498Szrj 
66538fd1498Szrj   FOR_EACH_LOOP (loop, LI_INCLUDE_ROOT)
66638fd1498Szrj     loop->aux = NULL;
66738fd1498Szrj 
66838fd1498Szrj   if (changed)
66938fd1498Szrj     return TODO_cleanup_cfg;
67038fd1498Szrj   return 0;
67138fd1498Szrj }
67238fd1498Szrj 
67338fd1498Szrj /* Loop splitting pass.  */
67438fd1498Szrj 
67538fd1498Szrj namespace {
67638fd1498Szrj 
67738fd1498Szrj const pass_data pass_data_loop_split =
67838fd1498Szrj {
67938fd1498Szrj   GIMPLE_PASS, /* type */
68038fd1498Szrj   "lsplit", /* name */
68138fd1498Szrj   OPTGROUP_LOOP, /* optinfo_flags */
68238fd1498Szrj   TV_LOOP_SPLIT, /* tv_id */
68338fd1498Szrj   PROP_cfg, /* properties_required */
68438fd1498Szrj   0, /* properties_provided */
68538fd1498Szrj   0, /* properties_destroyed */
68638fd1498Szrj   0, /* todo_flags_start */
68738fd1498Szrj   0, /* todo_flags_finish */
68838fd1498Szrj };
68938fd1498Szrj 
69038fd1498Szrj class pass_loop_split : public gimple_opt_pass
69138fd1498Szrj {
69238fd1498Szrj public:
pass_loop_split(gcc::context * ctxt)69338fd1498Szrj   pass_loop_split (gcc::context *ctxt)
69438fd1498Szrj     : gimple_opt_pass (pass_data_loop_split, ctxt)
69538fd1498Szrj   {}
69638fd1498Szrj 
69738fd1498Szrj   /* opt_pass methods: */
gate(function *)69838fd1498Szrj   virtual bool gate (function *) { return flag_split_loops != 0; }
69938fd1498Szrj   virtual unsigned int execute (function *);
70038fd1498Szrj 
70138fd1498Szrj }; // class pass_loop_split
70238fd1498Szrj 
70338fd1498Szrj unsigned int
execute(function * fun)70438fd1498Szrj pass_loop_split::execute (function *fun)
70538fd1498Szrj {
70638fd1498Szrj   if (number_of_loops (fun) <= 1)
70738fd1498Szrj     return 0;
70838fd1498Szrj 
70938fd1498Szrj   return tree_ssa_split_loops ();
71038fd1498Szrj }
71138fd1498Szrj 
71238fd1498Szrj } // anon namespace
71338fd1498Szrj 
71438fd1498Szrj gimple_opt_pass *
make_pass_loop_split(gcc::context * ctxt)71538fd1498Szrj make_pass_loop_split (gcc::context *ctxt)
71638fd1498Szrj {
71738fd1498Szrj   return new pass_loop_split (ctxt);
71838fd1498Szrj }
719