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