1 /* Loop unswitching.
2    Copyright (C) 2004, 2005, 2007, 2008, 2010 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
9 later version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "tree.h"
25 #include "tm_p.h"
26 #include "basic-block.h"
27 #include "output.h"
28 #include "tree-flow.h"
29 #include "tree-dump.h"
30 #include "timevar.h"
31 #include "cfgloop.h"
32 #include "params.h"
33 #include "tree-pass.h"
34 #include "tree-inline.h"
35 
36 /* This file implements the loop unswitching, i.e. transformation of loops like
37 
38    while (A)
39      {
40        if (inv)
41          B;
42 
43        X;
44 
45        if (!inv)
46 	 C;
47      }
48 
49    where inv is the loop invariant, into
50 
51    if (inv)
52      {
53        while (A)
54 	 {
55            B;
56 	   X;
57 	 }
58      }
59    else
60      {
61        while (A)
62 	 {
63 	   X;
64 	   C;
65 	 }
66      }
67 
68    Inv is considered invariant iff the values it compares are both invariant;
69    tree-ssa-loop-im.c ensures that all the suitable conditions are in this
70    shape.  */
71 
72 static struct loop *tree_unswitch_loop (struct loop *, basic_block, tree);
73 static bool tree_unswitch_single_loop (struct loop *, int);
74 static tree tree_may_unswitch_on (basic_block, struct loop *);
75 
76 /* Main entry point.  Perform loop unswitching on all suitable loops.  */
77 
78 unsigned int
79 tree_ssa_unswitch_loops (void)
80 {
81   loop_iterator li;
82   struct loop *loop;
83   bool changed = false;
84 
85   /* Go through inner loops (only original ones).  */
86   FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST)
87     {
88       if (dump_file && (dump_flags & TDF_DETAILS))
89         fprintf (dump_file, ";; Considering loop %d\n", loop->num);
90 
91       /* Do not unswitch in cold regions. */
92       if (optimize_loop_for_size_p (loop))
93         {
94           if (dump_file && (dump_flags & TDF_DETAILS))
95             fprintf (dump_file, ";; Not unswitching cold loops\n");
96           continue;
97         }
98 
99       /* The loop should not be too large, to limit code growth. */
100       if (tree_num_loop_insns (loop, &eni_size_weights)
101           > (unsigned) PARAM_VALUE (PARAM_MAX_UNSWITCH_INSNS))
102         {
103           if (dump_file && (dump_flags & TDF_DETAILS))
104             fprintf (dump_file, ";; Not unswitching, loop too big\n");
105           continue;
106         }
107 
108       changed |= tree_unswitch_single_loop (loop, 0);
109     }
110 
111   if (changed)
112     return TODO_cleanup_cfg;
113   return 0;
114 }
115 
116 /* Checks whether we can unswitch LOOP on condition at end of BB -- one of its
117    basic blocks (for what it means see comments below).  */
118 
119 static tree
120 tree_may_unswitch_on (basic_block bb, struct loop *loop)
121 {
122   gimple stmt, def;
123   tree cond, use;
124   basic_block def_bb;
125   ssa_op_iter iter;
126 
127   /* BB must end in a simple conditional jump.  */
128   stmt = last_stmt (bb);
129   if (!stmt || gimple_code (stmt) != GIMPLE_COND)
130     return NULL_TREE;
131 
132   /* To keep the things simple, we do not directly remove the conditions,
133      but just replace tests with 0 != 0 resp. 1 != 0.  Prevent the infinite
134      loop where we would unswitch again on such a condition.  */
135   if (gimple_cond_true_p (stmt) || gimple_cond_false_p (stmt))
136     return NULL_TREE;
137 
138   /* Condition must be invariant.  */
139   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
140     {
141       def = SSA_NAME_DEF_STMT (use);
142       def_bb = gimple_bb (def);
143       if (def_bb
144 	  && flow_bb_inside_loop_p (loop, def_bb))
145 	return NULL_TREE;
146     }
147 
148   cond = build2 (gimple_cond_code (stmt), boolean_type_node,
149 		 gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
150 
151   return cond;
152 }
153 
154 /* Simplifies COND using checks in front of the entry of the LOOP.  Just very
155    simplish (sufficient to prevent us from duplicating loop in unswitching
156    unnecessarily).  */
157 
158 static tree
159 simplify_using_entry_checks (struct loop *loop, tree cond)
160 {
161   edge e = loop_preheader_edge (loop);
162   gimple stmt;
163 
164   while (1)
165     {
166       stmt = last_stmt (e->src);
167       if (stmt
168 	  && gimple_code (stmt) == GIMPLE_COND
169 	  && gimple_cond_code (stmt) == TREE_CODE (cond)
170 	  && operand_equal_p (gimple_cond_lhs (stmt),
171 			      TREE_OPERAND (cond, 0), 0)
172 	  && operand_equal_p (gimple_cond_rhs (stmt),
173 			      TREE_OPERAND (cond, 1), 0))
174 	return (e->flags & EDGE_TRUE_VALUE
175 		? boolean_true_node
176 		: boolean_false_node);
177 
178       if (!single_pred_p (e->src))
179 	return cond;
180 
181       e = single_pred_edge (e->src);
182       if (e->src == ENTRY_BLOCK_PTR)
183 	return cond;
184     }
185 }
186 
187 /* Unswitch single LOOP.  NUM is number of unswitchings done; we do not allow
188    it to grow too much, it is too easy to create example on that the code would
189    grow exponentially.  */
190 
191 static bool
192 tree_unswitch_single_loop (struct loop *loop, int num)
193 {
194   basic_block *bbs;
195   struct loop *nloop;
196   unsigned i, found;
197   tree cond = NULL_TREE;
198   gimple stmt;
199   bool changed = false;
200 
201   i = 0;
202   bbs = get_loop_body (loop);
203   found = loop->num_nodes;
204 
205   while (1)
206     {
207       /* Find a bb to unswitch on.  */
208       for (; i < loop->num_nodes; i++)
209 	if ((cond = tree_may_unswitch_on (bbs[i], loop)))
210 	  break;
211 
212       if (i == loop->num_nodes)
213 	{
214 	  if (dump_file
215 	      && num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL)
216 	      && (dump_flags & TDF_DETAILS))
217 	    fprintf (dump_file, ";; Not unswitching anymore, hit max level\n");
218 
219 	  if (found == loop->num_nodes)
220 	    {
221 	      free (bbs);
222 	      return changed;
223 	    }
224 	  break;
225 	}
226 
227       cond = simplify_using_entry_checks (loop, cond);
228       stmt = last_stmt (bbs[i]);
229       if (integer_nonzerop (cond))
230 	{
231 	  /* Remove false path.  */
232 	  gimple_cond_set_condition_from_tree (stmt, boolean_true_node);
233 	  changed = true;
234 	}
235       else if (integer_zerop (cond))
236 	{
237 	  /* Remove true path.  */
238 	  gimple_cond_set_condition_from_tree (stmt, boolean_false_node);
239 	  changed = true;
240 	}
241       /* Do not unswitch too much.  */
242       else if (num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL))
243 	{
244 	  i++;
245 	  continue;
246 	}
247       /* In nested tree_unswitch_single_loop first optimize all conditions
248 	 using entry checks, then discover still reachable blocks in the
249 	 loop and find the condition only among those still reachable bbs.  */
250       else if (num != 0)
251 	{
252 	  if (found == loop->num_nodes)
253 	    found = i;
254 	  i++;
255 	  continue;
256 	}
257       else
258 	{
259 	  found = i;
260 	  break;
261 	}
262 
263       update_stmt (stmt);
264       i++;
265     }
266 
267   if (num != 0)
268     {
269       basic_block *tos, *worklist;
270 
271       /* When called recursively, first do a quick discovery
272 	 of reachable bbs after the above changes and only
273 	 consider conditions in still reachable bbs.  */
274       tos = worklist = XNEWVEC (basic_block, loop->num_nodes);
275 
276       for (i = 0; i < loop->num_nodes; i++)
277 	bbs[i]->flags &= ~BB_REACHABLE;
278 
279       /* Start with marking header.  */
280       *tos++ = bbs[0];
281       bbs[0]->flags |= BB_REACHABLE;
282 
283       /* Iterate: find everything reachable from what we've already seen
284 	 within the same innermost loop.  Don't look through false edges
285 	 if condition is always true or true edges if condition is
286 	 always false.  */
287       while (tos != worklist)
288 	{
289 	  basic_block b = *--tos;
290 	  edge e;
291 	  edge_iterator ei;
292 	  int flags = 0;
293 
294 	  if (EDGE_COUNT (b->succs) == 2)
295 	    {
296 	      gimple stmt = last_stmt (b);
297 	      if (stmt
298 		  && gimple_code (stmt) == GIMPLE_COND)
299 		{
300 		  if (gimple_cond_true_p (stmt))
301 		    flags = EDGE_FALSE_VALUE;
302 		  else if (gimple_cond_false_p (stmt))
303 		    flags = EDGE_TRUE_VALUE;
304 		}
305 	    }
306 
307 	  FOR_EACH_EDGE (e, ei, b->succs)
308 	    {
309 	      basic_block dest = e->dest;
310 
311 	      if (dest->loop_father == loop
312 		  && !(dest->flags & BB_REACHABLE)
313 		  && !(e->flags & flags))
314 		{
315 		  *tos++ = dest;
316 		  dest->flags |= BB_REACHABLE;
317 		}
318 	    }
319 	}
320 
321       free (worklist);
322 
323       /* Find a bb to unswitch on.  */
324       for (; found < loop->num_nodes; found++)
325 	if ((bbs[found]->flags & BB_REACHABLE)
326 	    && (cond = tree_may_unswitch_on (bbs[found], loop)))
327 	  break;
328 
329       if (found == loop->num_nodes)
330 	{
331 	  free (bbs);
332 	  return changed;
333 	}
334     }
335 
336   if (dump_file && (dump_flags & TDF_DETAILS))
337     fprintf (dump_file, ";; Unswitching loop\n");
338 
339   initialize_original_copy_tables ();
340   /* Unswitch the loop on this condition.  */
341   nloop = tree_unswitch_loop (loop, bbs[found], cond);
342   if (!nloop)
343     {
344       free_original_copy_tables ();
345       free (bbs);
346       return changed;
347     }
348 
349   /* Update the SSA form after unswitching.  */
350   update_ssa (TODO_update_ssa);
351   free_original_copy_tables ();
352 
353   /* Invoke itself on modified loops.  */
354   tree_unswitch_single_loop (nloop, num + 1);
355   tree_unswitch_single_loop (loop, num + 1);
356   free (bbs);
357   return true;
358 }
359 
360 /* Unswitch a LOOP w.r. to given basic block UNSWITCH_ON.  We only support
361    unswitching of innermost loops.  COND is the condition determining which
362    loop is entered -- the new loop is entered if COND is true.  Returns NULL
363    if impossible, new loop otherwise.  */
364 
365 static struct loop *
366 tree_unswitch_loop (struct loop *loop,
367 		    basic_block unswitch_on, tree cond)
368 {
369   unsigned prob_true;
370   edge edge_true, edge_false;
371 
372   /* Some sanity checking.  */
373   gcc_assert (flow_bb_inside_loop_p (loop, unswitch_on));
374   gcc_assert (EDGE_COUNT (unswitch_on->succs) == 2);
375   gcc_assert (loop->inner == NULL);
376 
377   extract_true_false_edges_from_block (unswitch_on, &edge_true, &edge_false);
378   prob_true = edge_true->probability;
379   return loop_version (loop, unshare_expr (cond),
380 		       NULL, prob_true, prob_true,
381 		       REG_BR_PROB_BASE - prob_true, false);
382 }
383