xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/tree-ssa-loop-unswitch.c (revision 1debfc3d3fad8af6f31804271c18e67f77b4d718)
1*1debfc3dSmrg /* Loop unswitching.
2*1debfc3dSmrg    Copyright (C) 2004-2017 Free Software Foundation, Inc.
3*1debfc3dSmrg 
4*1debfc3dSmrg This file is part of GCC.
5*1debfc3dSmrg 
6*1debfc3dSmrg GCC is free software; you can redistribute it and/or modify it
7*1debfc3dSmrg under the terms of the GNU General Public License as published by the
8*1debfc3dSmrg Free Software Foundation; either version 3, or (at your option) any
9*1debfc3dSmrg later version.
10*1debfc3dSmrg 
11*1debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT
12*1debfc3dSmrg ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*1debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*1debfc3dSmrg for more details.
15*1debfc3dSmrg 
16*1debfc3dSmrg You should have received a copy of the GNU General Public License
17*1debfc3dSmrg along with GCC; see the file COPYING3.  If not see
18*1debfc3dSmrg <http://www.gnu.org/licenses/>.  */
19*1debfc3dSmrg 
20*1debfc3dSmrg #include "config.h"
21*1debfc3dSmrg #include "system.h"
22*1debfc3dSmrg #include "coretypes.h"
23*1debfc3dSmrg #include "backend.h"
24*1debfc3dSmrg #include "tree.h"
25*1debfc3dSmrg #include "gimple.h"
26*1debfc3dSmrg #include "tree-pass.h"
27*1debfc3dSmrg #include "ssa.h"
28*1debfc3dSmrg #include "fold-const.h"
29*1debfc3dSmrg #include "gimplify.h"
30*1debfc3dSmrg #include "tree-cfg.h"
31*1debfc3dSmrg #include "tree-ssa.h"
32*1debfc3dSmrg #include "tree-ssa-loop-niter.h"
33*1debfc3dSmrg #include "tree-ssa-loop.h"
34*1debfc3dSmrg #include "tree-into-ssa.h"
35*1debfc3dSmrg #include "cfgloop.h"
36*1debfc3dSmrg #include "params.h"
37*1debfc3dSmrg #include "tree-inline.h"
38*1debfc3dSmrg #include "gimple-iterator.h"
39*1debfc3dSmrg #include "cfghooks.h"
40*1debfc3dSmrg #include "tree-ssa-loop-manip.h"
41*1debfc3dSmrg 
42*1debfc3dSmrg /* This file implements the loop unswitching, i.e. transformation of loops like
43*1debfc3dSmrg 
44*1debfc3dSmrg    while (A)
45*1debfc3dSmrg      {
46*1debfc3dSmrg        if (inv)
47*1debfc3dSmrg          B;
48*1debfc3dSmrg 
49*1debfc3dSmrg        X;
50*1debfc3dSmrg 
51*1debfc3dSmrg        if (!inv)
52*1debfc3dSmrg 	 C;
53*1debfc3dSmrg      }
54*1debfc3dSmrg 
55*1debfc3dSmrg    where inv is the loop invariant, into
56*1debfc3dSmrg 
57*1debfc3dSmrg    if (inv)
58*1debfc3dSmrg      {
59*1debfc3dSmrg        while (A)
60*1debfc3dSmrg 	 {
61*1debfc3dSmrg            B;
62*1debfc3dSmrg 	   X;
63*1debfc3dSmrg 	 }
64*1debfc3dSmrg      }
65*1debfc3dSmrg    else
66*1debfc3dSmrg      {
67*1debfc3dSmrg        while (A)
68*1debfc3dSmrg 	 {
69*1debfc3dSmrg 	   X;
70*1debfc3dSmrg 	   C;
71*1debfc3dSmrg 	 }
72*1debfc3dSmrg      }
73*1debfc3dSmrg 
74*1debfc3dSmrg    Inv is considered invariant iff the values it compares are both invariant;
75*1debfc3dSmrg    tree-ssa-loop-im.c ensures that all the suitable conditions are in this
76*1debfc3dSmrg    shape.  */
77*1debfc3dSmrg 
78*1debfc3dSmrg static struct loop *tree_unswitch_loop (struct loop *, basic_block, tree);
79*1debfc3dSmrg static bool tree_unswitch_single_loop (struct loop *, int);
80*1debfc3dSmrg static tree tree_may_unswitch_on (basic_block, struct loop *);
81*1debfc3dSmrg static bool tree_unswitch_outer_loop (struct loop *);
82*1debfc3dSmrg static edge find_loop_guard (struct loop *);
83*1debfc3dSmrg static bool empty_bb_without_guard_p (struct loop *, basic_block);
84*1debfc3dSmrg static bool used_outside_loop_p (struct loop *, tree);
85*1debfc3dSmrg static void hoist_guard (struct loop *, edge);
86*1debfc3dSmrg static bool check_exit_phi (struct loop *);
87*1debfc3dSmrg static tree get_vop_from_header (struct loop *);
88*1debfc3dSmrg 
89*1debfc3dSmrg /* Main entry point.  Perform loop unswitching on all suitable loops.  */
90*1debfc3dSmrg 
91*1debfc3dSmrg unsigned int
92*1debfc3dSmrg tree_ssa_unswitch_loops (void)
93*1debfc3dSmrg {
94*1debfc3dSmrg   struct loop *loop;
95*1debfc3dSmrg   bool changed = false;
96*1debfc3dSmrg 
97*1debfc3dSmrg   /* Go through all loops starting from innermost.  */
98*1debfc3dSmrg   FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
99*1debfc3dSmrg     {
100*1debfc3dSmrg       if (!loop->inner)
101*1debfc3dSmrg 	/* Unswitch innermost loop.  */
102*1debfc3dSmrg 	changed |= tree_unswitch_single_loop (loop, 0);
103*1debfc3dSmrg       else
104*1debfc3dSmrg 	changed |= tree_unswitch_outer_loop (loop);
105*1debfc3dSmrg     }
106*1debfc3dSmrg 
107*1debfc3dSmrg   if (changed)
108*1debfc3dSmrg     return TODO_cleanup_cfg;
109*1debfc3dSmrg   return 0;
110*1debfc3dSmrg }
111*1debfc3dSmrg 
112*1debfc3dSmrg /* Return TRUE if an SSA_NAME maybe undefined and is therefore
113*1debfc3dSmrg    unsuitable for unswitching.  STMT is the statement we are
114*1debfc3dSmrg    considering for unswitching and LOOP is the loop it appears in.  */
115*1debfc3dSmrg 
116*1debfc3dSmrg static bool
117*1debfc3dSmrg is_maybe_undefined (const tree name, gimple *stmt, struct loop *loop)
118*1debfc3dSmrg {
119*1debfc3dSmrg   /* The loop header is the only block we can trivially determine that
120*1debfc3dSmrg      will always be executed.  If the comparison is in the loop
121*1debfc3dSmrg      header, we know it's OK to unswitch on it.  */
122*1debfc3dSmrg   if (gimple_bb (stmt) == loop->header)
123*1debfc3dSmrg     return false;
124*1debfc3dSmrg 
125*1debfc3dSmrg   auto_bitmap visited_ssa;
126*1debfc3dSmrg   auto_vec<tree> worklist;
127*1debfc3dSmrg   worklist.safe_push (name);
128*1debfc3dSmrg   bitmap_set_bit (visited_ssa, SSA_NAME_VERSION (name));
129*1debfc3dSmrg   while (!worklist.is_empty ())
130*1debfc3dSmrg     {
131*1debfc3dSmrg       tree t = worklist.pop ();
132*1debfc3dSmrg 
133*1debfc3dSmrg       /* If it's obviously undefined, avoid further computations.  */
134*1debfc3dSmrg       if (ssa_undefined_value_p (t, true))
135*1debfc3dSmrg 	return true;
136*1debfc3dSmrg 
137*1debfc3dSmrg       if (ssa_defined_default_def_p (t))
138*1debfc3dSmrg 	continue;
139*1debfc3dSmrg 
140*1debfc3dSmrg       gimple *def = SSA_NAME_DEF_STMT (t);
141*1debfc3dSmrg 
142*1debfc3dSmrg       /* Check that all the PHI args are fully defined.  */
143*1debfc3dSmrg       if (gphi *phi = dyn_cast <gphi *> (def))
144*1debfc3dSmrg 	{
145*1debfc3dSmrg 	  for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
146*1debfc3dSmrg 	    {
147*1debfc3dSmrg 	      tree t = gimple_phi_arg_def (phi, i);
148*1debfc3dSmrg 	      /* If an SSA has already been seen, it may be a loop,
149*1debfc3dSmrg 		 but we can continue and ignore this use.  Otherwise,
150*1debfc3dSmrg 		 add the SSA_NAME to the queue and visit it later.  */
151*1debfc3dSmrg 	      if (TREE_CODE (t) == SSA_NAME
152*1debfc3dSmrg 		  && bitmap_set_bit (visited_ssa, SSA_NAME_VERSION (t)))
153*1debfc3dSmrg 		worklist.safe_push (t);
154*1debfc3dSmrg 	    }
155*1debfc3dSmrg 	  continue;
156*1debfc3dSmrg 	}
157*1debfc3dSmrg 
158*1debfc3dSmrg       /* Uses in stmts always executed when the region header executes
159*1debfc3dSmrg 	 are fine.  */
160*1debfc3dSmrg       if (dominated_by_p (CDI_DOMINATORS, loop->header, gimple_bb (def)))
161*1debfc3dSmrg 	continue;
162*1debfc3dSmrg 
163*1debfc3dSmrg       /* Handle calls and memory loads conservatively.  */
164*1debfc3dSmrg       if (!is_gimple_assign (def)
165*1debfc3dSmrg 	  || (gimple_assign_single_p (def)
166*1debfc3dSmrg 	      && gimple_vuse (def)))
167*1debfc3dSmrg 	return true;
168*1debfc3dSmrg 
169*1debfc3dSmrg       /* Check that any SSA names used to define NAME are also fully
170*1debfc3dSmrg 	 defined.  */
171*1debfc3dSmrg       use_operand_p use_p;
172*1debfc3dSmrg       ssa_op_iter iter;
173*1debfc3dSmrg       FOR_EACH_SSA_USE_OPERAND (use_p, def, iter, SSA_OP_USE)
174*1debfc3dSmrg 	{
175*1debfc3dSmrg 	  tree t = USE_FROM_PTR (use_p);
176*1debfc3dSmrg 	  /* If an SSA has already been seen, it may be a loop,
177*1debfc3dSmrg 	     but we can continue and ignore this use.  Otherwise,
178*1debfc3dSmrg 	     add the SSA_NAME to the queue and visit it later.  */
179*1debfc3dSmrg 	  if (bitmap_set_bit (visited_ssa, SSA_NAME_VERSION (t)))
180*1debfc3dSmrg 	    worklist.safe_push (t);
181*1debfc3dSmrg 	}
182*1debfc3dSmrg     }
183*1debfc3dSmrg   return false;
184*1debfc3dSmrg }
185*1debfc3dSmrg 
186*1debfc3dSmrg /* Checks whether we can unswitch LOOP on condition at end of BB -- one of its
187*1debfc3dSmrg    basic blocks (for what it means see comments below).  */
188*1debfc3dSmrg 
189*1debfc3dSmrg static tree
190*1debfc3dSmrg tree_may_unswitch_on (basic_block bb, struct loop *loop)
191*1debfc3dSmrg {
192*1debfc3dSmrg   gimple *last, *def;
193*1debfc3dSmrg   gcond *stmt;
194*1debfc3dSmrg   tree cond, use;
195*1debfc3dSmrg   basic_block def_bb;
196*1debfc3dSmrg   ssa_op_iter iter;
197*1debfc3dSmrg 
198*1debfc3dSmrg   /* BB must end in a simple conditional jump.  */
199*1debfc3dSmrg   last = last_stmt (bb);
200*1debfc3dSmrg   if (!last || gimple_code (last) != GIMPLE_COND)
201*1debfc3dSmrg     return NULL_TREE;
202*1debfc3dSmrg   stmt = as_a <gcond *> (last);
203*1debfc3dSmrg 
204*1debfc3dSmrg   /* To keep the things simple, we do not directly remove the conditions,
205*1debfc3dSmrg      but just replace tests with 0 != 0 resp. 1 != 0.  Prevent the infinite
206*1debfc3dSmrg      loop where we would unswitch again on such a condition.  */
207*1debfc3dSmrg   if (gimple_cond_true_p (stmt) || gimple_cond_false_p (stmt))
208*1debfc3dSmrg     return NULL_TREE;
209*1debfc3dSmrg 
210*1debfc3dSmrg   /* Condition must be invariant.  */
211*1debfc3dSmrg   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
212*1debfc3dSmrg     {
213*1debfc3dSmrg       def = SSA_NAME_DEF_STMT (use);
214*1debfc3dSmrg       def_bb = gimple_bb (def);
215*1debfc3dSmrg       if (def_bb
216*1debfc3dSmrg 	  && flow_bb_inside_loop_p (loop, def_bb))
217*1debfc3dSmrg 	return NULL_TREE;
218*1debfc3dSmrg       /* Unswitching on undefined values would introduce undefined
219*1debfc3dSmrg 	 behavior that the original program might never exercise.  */
220*1debfc3dSmrg       if (is_maybe_undefined (use, stmt, loop))
221*1debfc3dSmrg 	return NULL_TREE;
222*1debfc3dSmrg     }
223*1debfc3dSmrg 
224*1debfc3dSmrg   cond = build2 (gimple_cond_code (stmt), boolean_type_node,
225*1debfc3dSmrg 		 gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
226*1debfc3dSmrg 
227*1debfc3dSmrg   return cond;
228*1debfc3dSmrg }
229*1debfc3dSmrg 
230*1debfc3dSmrg /* Simplifies COND using checks in front of the entry of the LOOP.  Just very
231*1debfc3dSmrg    simplish (sufficient to prevent us from duplicating loop in unswitching
232*1debfc3dSmrg    unnecessarily).  */
233*1debfc3dSmrg 
234*1debfc3dSmrg static tree
235*1debfc3dSmrg simplify_using_entry_checks (struct loop *loop, tree cond)
236*1debfc3dSmrg {
237*1debfc3dSmrg   edge e = loop_preheader_edge (loop);
238*1debfc3dSmrg   gimple *stmt;
239*1debfc3dSmrg 
240*1debfc3dSmrg   while (1)
241*1debfc3dSmrg     {
242*1debfc3dSmrg       stmt = last_stmt (e->src);
243*1debfc3dSmrg       if (stmt
244*1debfc3dSmrg 	  && gimple_code (stmt) == GIMPLE_COND
245*1debfc3dSmrg 	  && gimple_cond_code (stmt) == TREE_CODE (cond)
246*1debfc3dSmrg 	  && operand_equal_p (gimple_cond_lhs (stmt),
247*1debfc3dSmrg 			      TREE_OPERAND (cond, 0), 0)
248*1debfc3dSmrg 	  && operand_equal_p (gimple_cond_rhs (stmt),
249*1debfc3dSmrg 			      TREE_OPERAND (cond, 1), 0))
250*1debfc3dSmrg 	return (e->flags & EDGE_TRUE_VALUE
251*1debfc3dSmrg 		? boolean_true_node
252*1debfc3dSmrg 		: boolean_false_node);
253*1debfc3dSmrg 
254*1debfc3dSmrg       if (!single_pred_p (e->src))
255*1debfc3dSmrg 	return cond;
256*1debfc3dSmrg 
257*1debfc3dSmrg       e = single_pred_edge (e->src);
258*1debfc3dSmrg       if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
259*1debfc3dSmrg 	return cond;
260*1debfc3dSmrg     }
261*1debfc3dSmrg }
262*1debfc3dSmrg 
263*1debfc3dSmrg /* Unswitch single LOOP.  NUM is number of unswitchings done; we do not allow
264*1debfc3dSmrg    it to grow too much, it is too easy to create example on that the code would
265*1debfc3dSmrg    grow exponentially.  */
266*1debfc3dSmrg 
267*1debfc3dSmrg static bool
268*1debfc3dSmrg tree_unswitch_single_loop (struct loop *loop, int num)
269*1debfc3dSmrg {
270*1debfc3dSmrg   basic_block *bbs;
271*1debfc3dSmrg   struct loop *nloop;
272*1debfc3dSmrg   unsigned i, found;
273*1debfc3dSmrg   tree cond = NULL_TREE;
274*1debfc3dSmrg   gimple *stmt;
275*1debfc3dSmrg   bool changed = false;
276*1debfc3dSmrg   HOST_WIDE_INT iterations;
277*1debfc3dSmrg 
278*1debfc3dSmrg   /* Perform initial tests if unswitch is eligible.  */
279*1debfc3dSmrg   if (num == 0)
280*1debfc3dSmrg     {
281*1debfc3dSmrg       /* Do not unswitch in cold regions. */
282*1debfc3dSmrg       if (optimize_loop_for_size_p (loop))
283*1debfc3dSmrg 	{
284*1debfc3dSmrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
285*1debfc3dSmrg 	    fprintf (dump_file, ";; Not unswitching cold loops\n");
286*1debfc3dSmrg 	  return false;
287*1debfc3dSmrg 	}
288*1debfc3dSmrg 
289*1debfc3dSmrg       /* The loop should not be too large, to limit code growth. */
290*1debfc3dSmrg       if (tree_num_loop_insns (loop, &eni_size_weights)
291*1debfc3dSmrg 	  > (unsigned) PARAM_VALUE (PARAM_MAX_UNSWITCH_INSNS))
292*1debfc3dSmrg 	{
293*1debfc3dSmrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
294*1debfc3dSmrg 	    fprintf (dump_file, ";; Not unswitching, loop too big\n");
295*1debfc3dSmrg 	  return false;
296*1debfc3dSmrg 	}
297*1debfc3dSmrg 
298*1debfc3dSmrg       /* If the loop is not expected to iterate, there is no need
299*1debfc3dSmrg 	 for unswitching.  */
300*1debfc3dSmrg       iterations = estimated_loop_iterations_int (loop);
301*1debfc3dSmrg       if (iterations < 0)
302*1debfc3dSmrg         iterations = likely_max_loop_iterations_int (loop);
303*1debfc3dSmrg       if (iterations >= 0 && iterations <= 1)
304*1debfc3dSmrg 	{
305*1debfc3dSmrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
306*1debfc3dSmrg 	    fprintf (dump_file, ";; Not unswitching, loop is not expected"
307*1debfc3dSmrg 		     " to iterate\n");
308*1debfc3dSmrg 	  return false;
309*1debfc3dSmrg 	}
310*1debfc3dSmrg     }
311*1debfc3dSmrg 
312*1debfc3dSmrg   i = 0;
313*1debfc3dSmrg   bbs = get_loop_body (loop);
314*1debfc3dSmrg   found = loop->num_nodes;
315*1debfc3dSmrg 
316*1debfc3dSmrg   while (1)
317*1debfc3dSmrg     {
318*1debfc3dSmrg       /* Find a bb to unswitch on.  */
319*1debfc3dSmrg       for (; i < loop->num_nodes; i++)
320*1debfc3dSmrg 	if ((cond = tree_may_unswitch_on (bbs[i], loop)))
321*1debfc3dSmrg 	  break;
322*1debfc3dSmrg 
323*1debfc3dSmrg       if (i == loop->num_nodes)
324*1debfc3dSmrg 	{
325*1debfc3dSmrg 	  if (dump_file
326*1debfc3dSmrg 	      && num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL)
327*1debfc3dSmrg 	      && (dump_flags & TDF_DETAILS))
328*1debfc3dSmrg 	    fprintf (dump_file, ";; Not unswitching anymore, hit max level\n");
329*1debfc3dSmrg 
330*1debfc3dSmrg 	  if (found == loop->num_nodes)
331*1debfc3dSmrg 	    {
332*1debfc3dSmrg 	      free (bbs);
333*1debfc3dSmrg 	      return changed;
334*1debfc3dSmrg 	    }
335*1debfc3dSmrg 	  break;
336*1debfc3dSmrg 	}
337*1debfc3dSmrg 
338*1debfc3dSmrg       cond = simplify_using_entry_checks (loop, cond);
339*1debfc3dSmrg       stmt = last_stmt (bbs[i]);
340*1debfc3dSmrg       if (integer_nonzerop (cond))
341*1debfc3dSmrg 	{
342*1debfc3dSmrg 	  /* Remove false path.  */
343*1debfc3dSmrg 	  gimple_cond_set_condition_from_tree (as_a <gcond *> (stmt),
344*1debfc3dSmrg 					       boolean_true_node);
345*1debfc3dSmrg 	  changed = true;
346*1debfc3dSmrg 	}
347*1debfc3dSmrg       else if (integer_zerop (cond))
348*1debfc3dSmrg 	{
349*1debfc3dSmrg 	  /* Remove true path.  */
350*1debfc3dSmrg 	  gimple_cond_set_condition_from_tree (as_a <gcond *> (stmt),
351*1debfc3dSmrg 					       boolean_false_node);
352*1debfc3dSmrg 	  changed = true;
353*1debfc3dSmrg 	}
354*1debfc3dSmrg       /* Do not unswitch too much.  */
355*1debfc3dSmrg       else if (num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL))
356*1debfc3dSmrg 	{
357*1debfc3dSmrg 	  i++;
358*1debfc3dSmrg 	  continue;
359*1debfc3dSmrg 	}
360*1debfc3dSmrg       /* In nested tree_unswitch_single_loop first optimize all conditions
361*1debfc3dSmrg 	 using entry checks, then discover still reachable blocks in the
362*1debfc3dSmrg 	 loop and find the condition only among those still reachable bbs.  */
363*1debfc3dSmrg       else if (num != 0)
364*1debfc3dSmrg 	{
365*1debfc3dSmrg 	  if (found == loop->num_nodes)
366*1debfc3dSmrg 	    found = i;
367*1debfc3dSmrg 	  i++;
368*1debfc3dSmrg 	  continue;
369*1debfc3dSmrg 	}
370*1debfc3dSmrg       else
371*1debfc3dSmrg 	{
372*1debfc3dSmrg 	  found = i;
373*1debfc3dSmrg 	  break;
374*1debfc3dSmrg 	}
375*1debfc3dSmrg 
376*1debfc3dSmrg       update_stmt (stmt);
377*1debfc3dSmrg       i++;
378*1debfc3dSmrg     }
379*1debfc3dSmrg 
380*1debfc3dSmrg   if (num != 0)
381*1debfc3dSmrg     {
382*1debfc3dSmrg       basic_block *tos, *worklist;
383*1debfc3dSmrg 
384*1debfc3dSmrg       /* When called recursively, first do a quick discovery
385*1debfc3dSmrg 	 of reachable bbs after the above changes and only
386*1debfc3dSmrg 	 consider conditions in still reachable bbs.  */
387*1debfc3dSmrg       tos = worklist = XNEWVEC (basic_block, loop->num_nodes);
388*1debfc3dSmrg 
389*1debfc3dSmrg       for (i = 0; i < loop->num_nodes; i++)
390*1debfc3dSmrg 	bbs[i]->flags &= ~BB_REACHABLE;
391*1debfc3dSmrg 
392*1debfc3dSmrg       /* Start with marking header.  */
393*1debfc3dSmrg       *tos++ = bbs[0];
394*1debfc3dSmrg       bbs[0]->flags |= BB_REACHABLE;
395*1debfc3dSmrg 
396*1debfc3dSmrg       /* Iterate: find everything reachable from what we've already seen
397*1debfc3dSmrg 	 within the same innermost loop.  Don't look through false edges
398*1debfc3dSmrg 	 if condition is always true or true edges if condition is
399*1debfc3dSmrg 	 always false.  */
400*1debfc3dSmrg       while (tos != worklist)
401*1debfc3dSmrg 	{
402*1debfc3dSmrg 	  basic_block b = *--tos;
403*1debfc3dSmrg 	  edge e;
404*1debfc3dSmrg 	  edge_iterator ei;
405*1debfc3dSmrg 	  int flags = 0;
406*1debfc3dSmrg 
407*1debfc3dSmrg 	  if (EDGE_COUNT (b->succs) == 2)
408*1debfc3dSmrg 	    {
409*1debfc3dSmrg 	      gimple *stmt = last_stmt (b);
410*1debfc3dSmrg 	      if (stmt
411*1debfc3dSmrg 		  && gimple_code (stmt) == GIMPLE_COND)
412*1debfc3dSmrg 		{
413*1debfc3dSmrg 		  gcond *cond_stmt = as_a <gcond *> (stmt);
414*1debfc3dSmrg 		  if (gimple_cond_true_p (cond_stmt))
415*1debfc3dSmrg 		    flags = EDGE_FALSE_VALUE;
416*1debfc3dSmrg 		  else if (gimple_cond_false_p (cond_stmt))
417*1debfc3dSmrg 		    flags = EDGE_TRUE_VALUE;
418*1debfc3dSmrg 		}
419*1debfc3dSmrg 	    }
420*1debfc3dSmrg 
421*1debfc3dSmrg 	  FOR_EACH_EDGE (e, ei, b->succs)
422*1debfc3dSmrg 	    {
423*1debfc3dSmrg 	      basic_block dest = e->dest;
424*1debfc3dSmrg 
425*1debfc3dSmrg 	      if (dest->loop_father == loop
426*1debfc3dSmrg 		  && !(dest->flags & BB_REACHABLE)
427*1debfc3dSmrg 		  && !(e->flags & flags))
428*1debfc3dSmrg 		{
429*1debfc3dSmrg 		  *tos++ = dest;
430*1debfc3dSmrg 		  dest->flags |= BB_REACHABLE;
431*1debfc3dSmrg 		}
432*1debfc3dSmrg 	    }
433*1debfc3dSmrg 	}
434*1debfc3dSmrg 
435*1debfc3dSmrg       free (worklist);
436*1debfc3dSmrg 
437*1debfc3dSmrg       /* Find a bb to unswitch on.  */
438*1debfc3dSmrg       for (; found < loop->num_nodes; found++)
439*1debfc3dSmrg 	if ((bbs[found]->flags & BB_REACHABLE)
440*1debfc3dSmrg 	    && (cond = tree_may_unswitch_on (bbs[found], loop)))
441*1debfc3dSmrg 	  break;
442*1debfc3dSmrg 
443*1debfc3dSmrg       if (found == loop->num_nodes)
444*1debfc3dSmrg 	{
445*1debfc3dSmrg 	  free (bbs);
446*1debfc3dSmrg 	  return changed;
447*1debfc3dSmrg 	}
448*1debfc3dSmrg     }
449*1debfc3dSmrg 
450*1debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS))
451*1debfc3dSmrg     fprintf (dump_file, ";; Unswitching loop\n");
452*1debfc3dSmrg 
453*1debfc3dSmrg   initialize_original_copy_tables ();
454*1debfc3dSmrg   /* Unswitch the loop on this condition.  */
455*1debfc3dSmrg   nloop = tree_unswitch_loop (loop, bbs[found], cond);
456*1debfc3dSmrg   if (!nloop)
457*1debfc3dSmrg     {
458*1debfc3dSmrg       free_original_copy_tables ();
459*1debfc3dSmrg       free (bbs);
460*1debfc3dSmrg       return changed;
461*1debfc3dSmrg     }
462*1debfc3dSmrg 
463*1debfc3dSmrg   /* Update the SSA form after unswitching.  */
464*1debfc3dSmrg   update_ssa (TODO_update_ssa);
465*1debfc3dSmrg   free_original_copy_tables ();
466*1debfc3dSmrg 
467*1debfc3dSmrg   /* Invoke itself on modified loops.  */
468*1debfc3dSmrg   tree_unswitch_single_loop (nloop, num + 1);
469*1debfc3dSmrg   tree_unswitch_single_loop (loop, num + 1);
470*1debfc3dSmrg   free (bbs);
471*1debfc3dSmrg   return true;
472*1debfc3dSmrg }
473*1debfc3dSmrg 
474*1debfc3dSmrg /* Unswitch a LOOP w.r. to given basic block UNSWITCH_ON.  We only support
475*1debfc3dSmrg    unswitching of innermost loops.  COND is the condition determining which
476*1debfc3dSmrg    loop is entered -- the new loop is entered if COND is true.  Returns NULL
477*1debfc3dSmrg    if impossible, new loop otherwise.  */
478*1debfc3dSmrg 
479*1debfc3dSmrg static struct loop *
480*1debfc3dSmrg tree_unswitch_loop (struct loop *loop,
481*1debfc3dSmrg 		    basic_block unswitch_on, tree cond)
482*1debfc3dSmrg {
483*1debfc3dSmrg   unsigned prob_true;
484*1debfc3dSmrg   edge edge_true, edge_false;
485*1debfc3dSmrg 
486*1debfc3dSmrg   /* Some sanity checking.  */
487*1debfc3dSmrg   gcc_assert (flow_bb_inside_loop_p (loop, unswitch_on));
488*1debfc3dSmrg   gcc_assert (EDGE_COUNT (unswitch_on->succs) == 2);
489*1debfc3dSmrg   gcc_assert (loop->inner == NULL);
490*1debfc3dSmrg 
491*1debfc3dSmrg   extract_true_false_edges_from_block (unswitch_on, &edge_true, &edge_false);
492*1debfc3dSmrg   prob_true = edge_true->probability;
493*1debfc3dSmrg   return loop_version (loop, unshare_expr (cond),
494*1debfc3dSmrg 		       NULL, prob_true, REG_BR_PROB_BASE - prob_true, prob_true,
495*1debfc3dSmrg 		       REG_BR_PROB_BASE - prob_true, false);
496*1debfc3dSmrg }
497*1debfc3dSmrg 
498*1debfc3dSmrg /* Unswitch outer loops by hoisting invariant guard on
499*1debfc3dSmrg    inner loop without code duplication.  */
500*1debfc3dSmrg static bool
501*1debfc3dSmrg tree_unswitch_outer_loop (struct loop *loop)
502*1debfc3dSmrg {
503*1debfc3dSmrg   edge exit, guard;
504*1debfc3dSmrg   HOST_WIDE_INT iterations;
505*1debfc3dSmrg 
506*1debfc3dSmrg   gcc_assert (loop->inner);
507*1debfc3dSmrg   if (loop->inner->next)
508*1debfc3dSmrg     return false;
509*1debfc3dSmrg   /* Accept loops with single exit only which is not from inner loop.  */
510*1debfc3dSmrg   exit = single_exit (loop);
511*1debfc3dSmrg   if (!exit || exit->src->loop_father != loop)
512*1debfc3dSmrg     return false;
513*1debfc3dSmrg   /* Check that phi argument of exit edge is not defined inside loop.  */
514*1debfc3dSmrg   if (!check_exit_phi (loop))
515*1debfc3dSmrg     return false;
516*1debfc3dSmrg   /* If the loop is not expected to iterate, there is no need
517*1debfc3dSmrg       for unswitching.  */
518*1debfc3dSmrg   iterations = estimated_loop_iterations_int (loop);
519*1debfc3dSmrg   if (iterations < 0)
520*1debfc3dSmrg     iterations = likely_max_loop_iterations_int (loop);
521*1debfc3dSmrg   if (iterations >= 0 && iterations <= 1)
522*1debfc3dSmrg     {
523*1debfc3dSmrg       if (dump_file && (dump_flags & TDF_DETAILS))
524*1debfc3dSmrg 	fprintf (dump_file, ";; Not unswitching, loop is not expected"
525*1debfc3dSmrg 		 " to iterate\n");
526*1debfc3dSmrg       return false;
527*1debfc3dSmrg     }
528*1debfc3dSmrg 
529*1debfc3dSmrg   bool changed = false;
530*1debfc3dSmrg   while ((guard = find_loop_guard (loop)))
531*1debfc3dSmrg     {
532*1debfc3dSmrg       if (! changed)
533*1debfc3dSmrg 	rewrite_virtuals_into_loop_closed_ssa (loop);
534*1debfc3dSmrg       hoist_guard (loop, guard);
535*1debfc3dSmrg       changed = true;
536*1debfc3dSmrg     }
537*1debfc3dSmrg   return changed;
538*1debfc3dSmrg }
539*1debfc3dSmrg 
540*1debfc3dSmrg /* Checks if the body of the LOOP is within an invariant guard.  If this
541*1debfc3dSmrg    is the case, returns the edge that jumps over the real body of the loop,
542*1debfc3dSmrg    otherwise returns NULL.  */
543*1debfc3dSmrg 
544*1debfc3dSmrg static edge
545*1debfc3dSmrg find_loop_guard (struct loop *loop)
546*1debfc3dSmrg {
547*1debfc3dSmrg   basic_block header = loop->header;
548*1debfc3dSmrg   edge guard_edge, te, fe;
549*1debfc3dSmrg   basic_block *body = NULL;
550*1debfc3dSmrg   unsigned i;
551*1debfc3dSmrg   tree use;
552*1debfc3dSmrg   ssa_op_iter iter;
553*1debfc3dSmrg 
554*1debfc3dSmrg   /* We check for the following situation:
555*1debfc3dSmrg 
556*1debfc3dSmrg      while (1)
557*1debfc3dSmrg        {
558*1debfc3dSmrg 	 [header]]
559*1debfc3dSmrg          loop_phi_nodes;
560*1debfc3dSmrg 	 something1;
561*1debfc3dSmrg 	 if (cond1)
562*1debfc3dSmrg 	   body;
563*1debfc3dSmrg 	 nvar = phi(orig, bvar) ... for all variables changed in body;
564*1debfc3dSmrg 	 [guard_end]
565*1debfc3dSmrg 	 something2;
566*1debfc3dSmrg 	 if (cond2)
567*1debfc3dSmrg 	   break;
568*1debfc3dSmrg 	 something3;
569*1debfc3dSmrg        }
570*1debfc3dSmrg 
571*1debfc3dSmrg      where:
572*1debfc3dSmrg 
573*1debfc3dSmrg      1) cond1 is loop invariant
574*1debfc3dSmrg      2) If cond1 is false, then the loop is essentially empty; i.e.,
575*1debfc3dSmrg 	a) nothing in something1, something2 and something3 has side
576*1debfc3dSmrg 	   effects
577*1debfc3dSmrg 	b) anything defined in something1, something2 and something3
578*1debfc3dSmrg 	   is not used outside of the loop.  */
579*1debfc3dSmrg 
580*1debfc3dSmrg   gcond *cond;
581*1debfc3dSmrg   do
582*1debfc3dSmrg     {
583*1debfc3dSmrg       basic_block next = NULL;
584*1debfc3dSmrg       if (single_succ_p (header))
585*1debfc3dSmrg 	next = single_succ (header);
586*1debfc3dSmrg       else
587*1debfc3dSmrg 	{
588*1debfc3dSmrg 	  cond = dyn_cast <gcond *> (last_stmt (header));
589*1debfc3dSmrg 	  if (! cond)
590*1debfc3dSmrg 	    return NULL;
591*1debfc3dSmrg 	  extract_true_false_edges_from_block (header, &te, &fe);
592*1debfc3dSmrg 	  /* Make sure to skip earlier hoisted guards that are left
593*1debfc3dSmrg 	     in place as if (true).  */
594*1debfc3dSmrg 	  if (gimple_cond_true_p (cond))
595*1debfc3dSmrg 	    next = te->dest;
596*1debfc3dSmrg 	  else if (gimple_cond_false_p (cond))
597*1debfc3dSmrg 	    next = fe->dest;
598*1debfc3dSmrg 	  else
599*1debfc3dSmrg 	    break;
600*1debfc3dSmrg 	}
601*1debfc3dSmrg       /* Never traverse a backedge.  */
602*1debfc3dSmrg       if (header->loop_father->header == next)
603*1debfc3dSmrg 	return NULL;
604*1debfc3dSmrg       header = next;
605*1debfc3dSmrg     }
606*1debfc3dSmrg   while (1);
607*1debfc3dSmrg   if (!flow_bb_inside_loop_p (loop, te->dest)
608*1debfc3dSmrg       || !flow_bb_inside_loop_p (loop, fe->dest))
609*1debfc3dSmrg     return NULL;
610*1debfc3dSmrg 
611*1debfc3dSmrg   if (just_once_each_iteration_p (loop, te->dest)
612*1debfc3dSmrg       || (single_succ_p (te->dest)
613*1debfc3dSmrg 	  && just_once_each_iteration_p (loop, single_succ (te->dest))))
614*1debfc3dSmrg     {
615*1debfc3dSmrg       if (just_once_each_iteration_p (loop, fe->dest))
616*1debfc3dSmrg 	return NULL;
617*1debfc3dSmrg       guard_edge = te;
618*1debfc3dSmrg     }
619*1debfc3dSmrg   else if (just_once_each_iteration_p (loop, fe->dest)
620*1debfc3dSmrg 	   || (single_succ_p (fe->dest)
621*1debfc3dSmrg 	       && just_once_each_iteration_p (loop, single_succ (fe->dest))))
622*1debfc3dSmrg     guard_edge = fe;
623*1debfc3dSmrg   else
624*1debfc3dSmrg     return NULL;
625*1debfc3dSmrg 
626*1debfc3dSmrg   /* Guard edge must skip inner loop.  */
627*1debfc3dSmrg   if (!dominated_by_p (CDI_DOMINATORS, loop->inner->header,
628*1debfc3dSmrg       guard_edge == fe ? te->dest : fe->dest))
629*1debfc3dSmrg     {
630*1debfc3dSmrg       if (dump_file && (dump_flags & TDF_DETAILS))
631*1debfc3dSmrg 	fprintf (dump_file, "Guard edge %d --> %d is not around the loop!\n",
632*1debfc3dSmrg 		 guard_edge->src->index, guard_edge->dest->index);
633*1debfc3dSmrg       return NULL;
634*1debfc3dSmrg     }
635*1debfc3dSmrg   if (guard_edge->dest == loop->latch)
636*1debfc3dSmrg     {
637*1debfc3dSmrg       if (dump_file && (dump_flags & TDF_DETAILS))
638*1debfc3dSmrg 	fprintf (dump_file, "Guard edge destination is loop latch.\n");
639*1debfc3dSmrg       return NULL;
640*1debfc3dSmrg     }
641*1debfc3dSmrg 
642*1debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS))
643*1debfc3dSmrg     fprintf (dump_file,
644*1debfc3dSmrg 	     "Considering guard %d -> %d in loop %d\n",
645*1debfc3dSmrg 	     guard_edge->src->index, guard_edge->dest->index, loop->num);
646*1debfc3dSmrg   /* Check if condition operands do not have definitions inside loop since
647*1debfc3dSmrg      any bb copying is not performed.  */
648*1debfc3dSmrg   FOR_EACH_SSA_TREE_OPERAND (use, cond, iter, SSA_OP_USE)
649*1debfc3dSmrg     {
650*1debfc3dSmrg       gimple *def = SSA_NAME_DEF_STMT (use);
651*1debfc3dSmrg       basic_block def_bb = gimple_bb (def);
652*1debfc3dSmrg       if (def_bb
653*1debfc3dSmrg           && flow_bb_inside_loop_p (loop, def_bb))
654*1debfc3dSmrg 	{
655*1debfc3dSmrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
656*1debfc3dSmrg 	    fprintf (dump_file, "  guard operands have definitions"
657*1debfc3dSmrg 				" inside loop\n");
658*1debfc3dSmrg 	  return NULL;
659*1debfc3dSmrg 	}
660*1debfc3dSmrg     }
661*1debfc3dSmrg 
662*1debfc3dSmrg   body = get_loop_body (loop);
663*1debfc3dSmrg   for (i = 0; i < loop->num_nodes; i++)
664*1debfc3dSmrg     {
665*1debfc3dSmrg       basic_block bb = body[i];
666*1debfc3dSmrg       if (bb->loop_father != loop)
667*1debfc3dSmrg 	continue;
668*1debfc3dSmrg       if (bb->flags & BB_IRREDUCIBLE_LOOP)
669*1debfc3dSmrg 	{
670*1debfc3dSmrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
671*1debfc3dSmrg 	    fprintf (dump_file, "Block %d is marked as irreducible in loop\n",
672*1debfc3dSmrg 		      bb->index);
673*1debfc3dSmrg 	  guard_edge = NULL;
674*1debfc3dSmrg 	  goto end;
675*1debfc3dSmrg 	}
676*1debfc3dSmrg       if (!empty_bb_without_guard_p (loop, bb))
677*1debfc3dSmrg 	{
678*1debfc3dSmrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
679*1debfc3dSmrg 	    fprintf (dump_file, "  block %d has side effects\n", bb->index);
680*1debfc3dSmrg 	  guard_edge = NULL;
681*1debfc3dSmrg 	  goto end;
682*1debfc3dSmrg 	}
683*1debfc3dSmrg     }
684*1debfc3dSmrg 
685*1debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS))
686*1debfc3dSmrg     fprintf (dump_file, "  suitable to hoist\n");
687*1debfc3dSmrg end:
688*1debfc3dSmrg   if (body)
689*1debfc3dSmrg     free (body);
690*1debfc3dSmrg   return guard_edge;
691*1debfc3dSmrg }
692*1debfc3dSmrg 
693*1debfc3dSmrg /* Returns true if
694*1debfc3dSmrg    1) no statement in BB has side effects
695*1debfc3dSmrg    2) assuming that edge GUARD is always taken, all definitions in BB
696*1debfc3dSmrg       are noy used outside of the loop.
697*1debfc3dSmrg    KNOWN_INVARIANTS is a set of ssa names we know to be invariant, and
698*1debfc3dSmrg    PROCESSED is a set of ssa names for that we already tested whether they
699*1debfc3dSmrg    are invariant or not.  */
700*1debfc3dSmrg 
701*1debfc3dSmrg static bool
702*1debfc3dSmrg empty_bb_without_guard_p (struct loop *loop, basic_block bb)
703*1debfc3dSmrg {
704*1debfc3dSmrg   basic_block exit_bb = single_exit (loop)->src;
705*1debfc3dSmrg   bool may_be_used_outside = (bb == exit_bb
706*1debfc3dSmrg 			      || !dominated_by_p (CDI_DOMINATORS, bb, exit_bb));
707*1debfc3dSmrg   tree name;
708*1debfc3dSmrg   ssa_op_iter op_iter;
709*1debfc3dSmrg 
710*1debfc3dSmrg   /* Phi nodes do not have side effects, but their results might be used
711*1debfc3dSmrg      outside of the loop.  */
712*1debfc3dSmrg   if (may_be_used_outside)
713*1debfc3dSmrg     {
714*1debfc3dSmrg       for (gphi_iterator gsi = gsi_start_phis (bb);
715*1debfc3dSmrg 	   !gsi_end_p (gsi); gsi_next (&gsi))
716*1debfc3dSmrg 	{
717*1debfc3dSmrg 	  gphi *phi = gsi.phi ();
718*1debfc3dSmrg 	  name = PHI_RESULT (phi);
719*1debfc3dSmrg 	  if (virtual_operand_p (name))
720*1debfc3dSmrg 	    continue;
721*1debfc3dSmrg 
722*1debfc3dSmrg 	  if (used_outside_loop_p (loop, name))
723*1debfc3dSmrg 	    return false;
724*1debfc3dSmrg 	}
725*1debfc3dSmrg     }
726*1debfc3dSmrg 
727*1debfc3dSmrg   for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
728*1debfc3dSmrg        !gsi_end_p (gsi); gsi_next (&gsi))
729*1debfc3dSmrg     {
730*1debfc3dSmrg       gimple *stmt = gsi_stmt (gsi);
731*1debfc3dSmrg       if (gimple_has_side_effects (stmt))
732*1debfc3dSmrg 	return false;
733*1debfc3dSmrg 
734*1debfc3dSmrg       if (gimple_vdef(stmt))
735*1debfc3dSmrg 	return false;
736*1debfc3dSmrg 
737*1debfc3dSmrg       FOR_EACH_SSA_TREE_OPERAND (name, stmt, op_iter, SSA_OP_DEF)
738*1debfc3dSmrg 	{
739*1debfc3dSmrg 	  if (may_be_used_outside
740*1debfc3dSmrg 	      && used_outside_loop_p (loop, name))
741*1debfc3dSmrg 	    return false;
742*1debfc3dSmrg 	}
743*1debfc3dSmrg     }
744*1debfc3dSmrg   return true;
745*1debfc3dSmrg }
746*1debfc3dSmrg 
747*1debfc3dSmrg /* Return true if NAME is used outside of LOOP.  */
748*1debfc3dSmrg 
749*1debfc3dSmrg static bool
750*1debfc3dSmrg used_outside_loop_p (struct loop *loop, tree name)
751*1debfc3dSmrg {
752*1debfc3dSmrg   imm_use_iterator it;
753*1debfc3dSmrg   use_operand_p use;
754*1debfc3dSmrg 
755*1debfc3dSmrg   FOR_EACH_IMM_USE_FAST (use, it, name)
756*1debfc3dSmrg     {
757*1debfc3dSmrg       gimple *stmt = USE_STMT (use);
758*1debfc3dSmrg       if (!flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
759*1debfc3dSmrg 	return true;
760*1debfc3dSmrg     }
761*1debfc3dSmrg 
762*1debfc3dSmrg   return false;
763*1debfc3dSmrg }
764*1debfc3dSmrg 
765*1debfc3dSmrg /* Return argument for loop preheader edge in header virtual phi if any.  */
766*1debfc3dSmrg 
767*1debfc3dSmrg static tree
768*1debfc3dSmrg get_vop_from_header (struct loop *loop)
769*1debfc3dSmrg {
770*1debfc3dSmrg   for (gphi_iterator gsi = gsi_start_phis (loop->header);
771*1debfc3dSmrg        !gsi_end_p (gsi); gsi_next (&gsi))
772*1debfc3dSmrg     {
773*1debfc3dSmrg       gphi *phi = gsi.phi ();
774*1debfc3dSmrg       if (!virtual_operand_p (gimple_phi_result (phi)))
775*1debfc3dSmrg 	continue;
776*1debfc3dSmrg       return PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
777*1debfc3dSmrg     }
778*1debfc3dSmrg   return NULL_TREE;
779*1debfc3dSmrg }
780*1debfc3dSmrg 
781*1debfc3dSmrg /* Move the check of GUARD outside of LOOP.  */
782*1debfc3dSmrg 
783*1debfc3dSmrg static void
784*1debfc3dSmrg hoist_guard (struct loop *loop, edge guard)
785*1debfc3dSmrg {
786*1debfc3dSmrg   edge exit = single_exit (loop);
787*1debfc3dSmrg   edge preh = loop_preheader_edge (loop);
788*1debfc3dSmrg   basic_block pre_header = preh->src;
789*1debfc3dSmrg   basic_block bb;
790*1debfc3dSmrg   edge te, fe, e, new_edge;
791*1debfc3dSmrg   gimple *stmt;
792*1debfc3dSmrg   basic_block guard_bb = guard->src;
793*1debfc3dSmrg   edge not_guard;
794*1debfc3dSmrg   gimple_stmt_iterator gsi;
795*1debfc3dSmrg   int flags = 0;
796*1debfc3dSmrg   bool fix_dom_of_exit;
797*1debfc3dSmrg   gcond *cond_stmt, *new_cond_stmt;
798*1debfc3dSmrg 
799*1debfc3dSmrg   bb = get_immediate_dominator (CDI_DOMINATORS, exit->dest);
800*1debfc3dSmrg   fix_dom_of_exit = flow_bb_inside_loop_p (loop, bb);
801*1debfc3dSmrg   gsi = gsi_last_bb (guard_bb);
802*1debfc3dSmrg   stmt = gsi_stmt (gsi);
803*1debfc3dSmrg   gcc_assert (gimple_code (stmt) == GIMPLE_COND);
804*1debfc3dSmrg   cond_stmt = as_a <gcond *> (stmt);
805*1debfc3dSmrg   extract_true_false_edges_from_block (guard_bb, &te, &fe);
806*1debfc3dSmrg   /* Insert guard to PRE_HEADER.  */
807*1debfc3dSmrg   if (!empty_block_p (pre_header))
808*1debfc3dSmrg     gsi = gsi_last_bb (pre_header);
809*1debfc3dSmrg   else
810*1debfc3dSmrg     gsi = gsi_start_bb (pre_header);
811*1debfc3dSmrg   /* Create copy of COND_STMT.  */
812*1debfc3dSmrg   new_cond_stmt = gimple_build_cond (gimple_cond_code (cond_stmt),
813*1debfc3dSmrg 				     gimple_cond_lhs (cond_stmt),
814*1debfc3dSmrg 				     gimple_cond_rhs (cond_stmt),
815*1debfc3dSmrg 				     NULL_TREE, NULL_TREE);
816*1debfc3dSmrg   gsi_insert_after (&gsi, new_cond_stmt, GSI_NEW_STMT);
817*1debfc3dSmrg   /* Convert COND_STMT to true/false conditional.  */
818*1debfc3dSmrg   if (guard == te)
819*1debfc3dSmrg     gimple_cond_make_false (cond_stmt);
820*1debfc3dSmrg   else
821*1debfc3dSmrg     gimple_cond_make_true (cond_stmt);
822*1debfc3dSmrg   update_stmt (cond_stmt);
823*1debfc3dSmrg   /* Create new loop pre-header.  */
824*1debfc3dSmrg   e = split_block (pre_header, last_stmt (pre_header));
825*1debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS))
826*1debfc3dSmrg     fprintf (dump_file, "  Moving guard %i->%i (prob %i) to bb %i, "
827*1debfc3dSmrg 	     "new preheader is %i\n",
828*1debfc3dSmrg 	     guard->src->index, guard->dest->index, guard->probability,
829*1debfc3dSmrg 	     e->src->index, e->dest->index);
830*1debfc3dSmrg 
831*1debfc3dSmrg   gcc_assert (loop_preheader_edge (loop)->src == e->dest);
832*1debfc3dSmrg 
833*1debfc3dSmrg   if (guard == fe)
834*1debfc3dSmrg     {
835*1debfc3dSmrg       e->flags = EDGE_TRUE_VALUE;
836*1debfc3dSmrg       flags |= EDGE_FALSE_VALUE;
837*1debfc3dSmrg       not_guard = te;
838*1debfc3dSmrg     }
839*1debfc3dSmrg   else
840*1debfc3dSmrg     {
841*1debfc3dSmrg       e->flags = EDGE_FALSE_VALUE;
842*1debfc3dSmrg       flags |= EDGE_TRUE_VALUE;
843*1debfc3dSmrg       not_guard = fe;
844*1debfc3dSmrg     }
845*1debfc3dSmrg   new_edge = make_edge (pre_header, exit->dest, flags);
846*1debfc3dSmrg 
847*1debfc3dSmrg   /* Determine the probability that we skip the loop.  Assume that loop has
848*1debfc3dSmrg      same average number of iterations regardless outcome of guard.  */
849*1debfc3dSmrg   new_edge->probability = guard->probability;
850*1debfc3dSmrg   int skip_count = guard->src->count
851*1debfc3dSmrg 		   ? RDIV (guard->count * pre_header->count, guard->src->count)
852*1debfc3dSmrg 		   : apply_probability (guard->count, new_edge->probability);
853*1debfc3dSmrg 
854*1debfc3dSmrg   if (skip_count > e->count)
855*1debfc3dSmrg     {
856*1debfc3dSmrg       fprintf (dump_file, "  Capping count; expect profile inconsistency\n");
857*1debfc3dSmrg       skip_count = e->count;
858*1debfc3dSmrg     }
859*1debfc3dSmrg   new_edge->count = skip_count;
860*1debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS))
861*1debfc3dSmrg     fprintf (dump_file, "  Estimated probability of skipping loop is %i\n",
862*1debfc3dSmrg 	     new_edge->probability);
863*1debfc3dSmrg 
864*1debfc3dSmrg   /* Update profile after the transform:
865*1debfc3dSmrg 
866*1debfc3dSmrg      First decrease count of path from newly hoisted loop guard
867*1debfc3dSmrg      to loop header...  */
868*1debfc3dSmrg   e->count -= skip_count;
869*1debfc3dSmrg   e->probability = REG_BR_PROB_BASE - new_edge->probability;
870*1debfc3dSmrg   e->dest->count = e->count;
871*1debfc3dSmrg   e->dest->frequency = EDGE_FREQUENCY (e);
872*1debfc3dSmrg 
873*1debfc3dSmrg   /* ... now update profile to represent that original guard will be optimized
874*1debfc3dSmrg      away ...  */
875*1debfc3dSmrg   guard->probability = 0;
876*1debfc3dSmrg   guard->count = 0;
877*1debfc3dSmrg   not_guard->probability = REG_BR_PROB_BASE;
878*1debfc3dSmrg   /* This count is wrong (frequency of not_guard does not change),
879*1debfc3dSmrg      but will be scaled later.  */
880*1debfc3dSmrg   not_guard->count = guard->src->count;
881*1debfc3dSmrg 
882*1debfc3dSmrg   /* ... finally scale everything in the loop except for guarded basic blocks
883*1debfc3dSmrg      where profile does not change.  */
884*1debfc3dSmrg   basic_block *body = get_loop_body (loop);
885*1debfc3dSmrg 
886*1debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS))
887*1debfc3dSmrg     fprintf (dump_file, "  Scaling nonguarded BBs in loop:");
888*1debfc3dSmrg   for (unsigned int i = 0; i < loop->num_nodes; i++)
889*1debfc3dSmrg     {
890*1debfc3dSmrg       basic_block bb = body[i];
891*1debfc3dSmrg       if (!dominated_by_p (CDI_DOMINATORS, bb, not_guard->dest))
892*1debfc3dSmrg 	{
893*1debfc3dSmrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
894*1debfc3dSmrg 	    fprintf (dump_file, " %i", bb->index);
895*1debfc3dSmrg           scale_bbs_frequencies_int (&bb, 1, e->probability, REG_BR_PROB_BASE);
896*1debfc3dSmrg   	}
897*1debfc3dSmrg     }
898*1debfc3dSmrg 
899*1debfc3dSmrg   if (fix_dom_of_exit)
900*1debfc3dSmrg     set_immediate_dominator (CDI_DOMINATORS, exit->dest, pre_header);
901*1debfc3dSmrg   /* Add NEW_ADGE argument for all phi in post-header block.  */
902*1debfc3dSmrg   bb = exit->dest;
903*1debfc3dSmrg   for (gphi_iterator gsi = gsi_start_phis (bb);
904*1debfc3dSmrg        !gsi_end_p (gsi); gsi_next (&gsi))
905*1debfc3dSmrg     {
906*1debfc3dSmrg       gphi *phi = gsi.phi ();
907*1debfc3dSmrg       tree arg;
908*1debfc3dSmrg       if (virtual_operand_p (gimple_phi_result (phi)))
909*1debfc3dSmrg 	{
910*1debfc3dSmrg 	  arg = get_vop_from_header (loop);
911*1debfc3dSmrg 	  if (arg == NULL_TREE)
912*1debfc3dSmrg 	    /* Use exit edge argument.  */
913*1debfc3dSmrg 	    arg =  PHI_ARG_DEF_FROM_EDGE (phi, exit);
914*1debfc3dSmrg 	  add_phi_arg (phi, arg, new_edge, UNKNOWN_LOCATION);
915*1debfc3dSmrg 	}
916*1debfc3dSmrg       else
917*1debfc3dSmrg 	{
918*1debfc3dSmrg 	  /* Use exit edge argument.  */
919*1debfc3dSmrg 	  arg = PHI_ARG_DEF_FROM_EDGE (phi, exit);
920*1debfc3dSmrg 	  add_phi_arg (phi, arg, new_edge, UNKNOWN_LOCATION);
921*1debfc3dSmrg 	}
922*1debfc3dSmrg     }
923*1debfc3dSmrg 
924*1debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS))
925*1debfc3dSmrg     fprintf (dump_file, "\n  guard hoisted.\n");
926*1debfc3dSmrg 
927*1debfc3dSmrg   free (body);
928*1debfc3dSmrg }
929*1debfc3dSmrg 
930*1debfc3dSmrg /* Return true if phi argument for exit edge can be used
931*1debfc3dSmrg    for edge around loop.  */
932*1debfc3dSmrg 
933*1debfc3dSmrg static bool
934*1debfc3dSmrg check_exit_phi (struct loop *loop)
935*1debfc3dSmrg {
936*1debfc3dSmrg   edge exit = single_exit (loop);
937*1debfc3dSmrg   basic_block pre_header = loop_preheader_edge (loop)->src;
938*1debfc3dSmrg 
939*1debfc3dSmrg   for (gphi_iterator gsi = gsi_start_phis (exit->dest);
940*1debfc3dSmrg        !gsi_end_p (gsi); gsi_next (&gsi))
941*1debfc3dSmrg     {
942*1debfc3dSmrg       gphi *phi = gsi.phi ();
943*1debfc3dSmrg       tree arg;
944*1debfc3dSmrg       gimple *def;
945*1debfc3dSmrg       basic_block def_bb;
946*1debfc3dSmrg       if (virtual_operand_p (gimple_phi_result (phi)))
947*1debfc3dSmrg 	continue;
948*1debfc3dSmrg       arg = PHI_ARG_DEF_FROM_EDGE (phi, exit);
949*1debfc3dSmrg       if (TREE_CODE (arg) != SSA_NAME)
950*1debfc3dSmrg 	continue;
951*1debfc3dSmrg       def = SSA_NAME_DEF_STMT (arg);
952*1debfc3dSmrg       if (!def)
953*1debfc3dSmrg 	continue;
954*1debfc3dSmrg       def_bb = gimple_bb (def);
955*1debfc3dSmrg       if (!def_bb)
956*1debfc3dSmrg 	continue;
957*1debfc3dSmrg       if (!dominated_by_p (CDI_DOMINATORS, pre_header, def_bb))
958*1debfc3dSmrg 	/* Definition inside loop!  */
959*1debfc3dSmrg 	return false;
960*1debfc3dSmrg       /* Check loop closed phi invariant.  */
961*1debfc3dSmrg       if (!flow_bb_inside_loop_p (def_bb->loop_father, pre_header))
962*1debfc3dSmrg 	return false;
963*1debfc3dSmrg     }
964*1debfc3dSmrg   return true;
965*1debfc3dSmrg }
966*1debfc3dSmrg 
967*1debfc3dSmrg /* Loop unswitching pass.  */
968*1debfc3dSmrg 
969*1debfc3dSmrg namespace {
970*1debfc3dSmrg 
971*1debfc3dSmrg const pass_data pass_data_tree_unswitch =
972*1debfc3dSmrg {
973*1debfc3dSmrg   GIMPLE_PASS, /* type */
974*1debfc3dSmrg   "unswitch", /* name */
975*1debfc3dSmrg   OPTGROUP_LOOP, /* optinfo_flags */
976*1debfc3dSmrg   TV_TREE_LOOP_UNSWITCH, /* tv_id */
977*1debfc3dSmrg   PROP_cfg, /* properties_required */
978*1debfc3dSmrg   0, /* properties_provided */
979*1debfc3dSmrg   0, /* properties_destroyed */
980*1debfc3dSmrg   0, /* todo_flags_start */
981*1debfc3dSmrg   0, /* todo_flags_finish */
982*1debfc3dSmrg };
983*1debfc3dSmrg 
984*1debfc3dSmrg class pass_tree_unswitch : public gimple_opt_pass
985*1debfc3dSmrg {
986*1debfc3dSmrg public:
987*1debfc3dSmrg   pass_tree_unswitch (gcc::context *ctxt)
988*1debfc3dSmrg     : gimple_opt_pass (pass_data_tree_unswitch, ctxt)
989*1debfc3dSmrg   {}
990*1debfc3dSmrg 
991*1debfc3dSmrg   /* opt_pass methods: */
992*1debfc3dSmrg   virtual bool gate (function *) { return flag_unswitch_loops != 0; }
993*1debfc3dSmrg   virtual unsigned int execute (function *);
994*1debfc3dSmrg 
995*1debfc3dSmrg }; // class pass_tree_unswitch
996*1debfc3dSmrg 
997*1debfc3dSmrg unsigned int
998*1debfc3dSmrg pass_tree_unswitch::execute (function *fun)
999*1debfc3dSmrg {
1000*1debfc3dSmrg   if (number_of_loops (fun) <= 1)
1001*1debfc3dSmrg     return 0;
1002*1debfc3dSmrg 
1003*1debfc3dSmrg   return tree_ssa_unswitch_loops ();
1004*1debfc3dSmrg }
1005*1debfc3dSmrg 
1006*1debfc3dSmrg } // anon namespace
1007*1debfc3dSmrg 
1008*1debfc3dSmrg gimple_opt_pass *
1009*1debfc3dSmrg make_pass_tree_unswitch (gcc::context *ctxt)
1010*1debfc3dSmrg {
1011*1debfc3dSmrg   return new pass_tree_unswitch (ctxt);
1012*1debfc3dSmrg }
1013*1debfc3dSmrg 
1014*1debfc3dSmrg 
1015