comparison gcc/tree-if-conv.c @ 63:b7f97abdc517 gcc-4.6-20100522

update gcc from gcc-4.5.0 to gcc-4.6
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 24 May 2010 12:47:05 +0900
parents 77e2b8dfacca
children f6334be47118
comparison
equal deleted inserted replaced
56:3c8a44c06a95 63:b7f97abdc517
1 /* If-conversion for vectorizer. 1 /* If-conversion for vectorizer.
2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 Contributed by Devang Patel <dpatel@apple.com> 4 Contributed by Devang Patel <dpatel@apple.com>
5 5
6 This file is part of GCC. 6 This file is part of GCC.
7 7
17 17
18 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see 19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */ 20 <http://www.gnu.org/licenses/>. */
21 21
22 /* This pass implements tree level if-conversion transformation of loops. 22 /* This pass implements a tree level if-conversion of loops. Its
23 Initial goal is to help vectorizer vectorize loops with conditions. 23 initial goal is to help the vectorizer to vectorize loops with
24 conditions.
24 25
25 A short description of if-conversion: 26 A short description of if-conversion:
26 27
27 o Decide if a loop is if-convertible or not. 28 o Decide if a loop is if-convertible or not.
28 o Walk all loop basic blocks in breadth first order (BFS order). 29 o Walk all loop basic blocks in breadth first order (BFS order).
85 #include "coretypes.h" 86 #include "coretypes.h"
86 #include "tm.h" 87 #include "tm.h"
87 #include "tree.h" 88 #include "tree.h"
88 #include "flags.h" 89 #include "flags.h"
89 #include "timevar.h" 90 #include "timevar.h"
90 #include "varray.h"
91 #include "rtl.h"
92 #include "basic-block.h" 91 #include "basic-block.h"
93 #include "diagnostic.h" 92 #include "diagnostic.h"
93 #include "tree-pretty-print.h"
94 #include "gimple-pretty-print.h"
94 #include "tree-flow.h" 95 #include "tree-flow.h"
95 #include "tree-dump.h" 96 #include "tree-dump.h"
96 #include "cfgloop.h" 97 #include "cfgloop.h"
97 #include "tree-chrec.h" 98 #include "tree-chrec.h"
98 #include "tree-data-ref.h" 99 #include "tree-data-ref.h"
99 #include "tree-scalar-evolution.h" 100 #include "tree-scalar-evolution.h"
100 #include "tree-pass.h" 101 #include "tree-pass.h"
101 #include "target.h"
102
103
104 /* local function prototypes */
105 static unsigned int main_tree_if_conversion (void);
106 static tree tree_if_convert_stmt (struct loop *loop, gimple, tree,
107 gimple_stmt_iterator *);
108 static void tree_if_convert_cond_stmt (struct loop *, gimple, tree,
109 gimple_stmt_iterator *);
110 static bool if_convertible_phi_p (struct loop *, basic_block, gimple);
111 static bool if_convertible_gimple_assign_stmt_p (struct loop *, basic_block,
112 gimple);
113 static bool if_convertible_stmt_p (struct loop *, basic_block, gimple);
114 static bool if_convertible_bb_p (struct loop *, basic_block, basic_block);
115 static bool if_convertible_loop_p (struct loop *, bool);
116 static void add_to_predicate_list (basic_block, tree);
117 static tree add_to_dst_predicate_list (struct loop * loop, edge,
118 tree, tree,
119 gimple_stmt_iterator *);
120 static void clean_predicate_lists (struct loop *loop);
121 static basic_block find_phi_replacement_condition (struct loop *loop,
122 basic_block, tree *,
123 gimple_stmt_iterator *);
124 static void replace_phi_with_cond_gimple_assign_stmt (gimple, tree,
125 basic_block,
126 gimple_stmt_iterator *);
127 static void process_phi_nodes (struct loop *);
128 static void combine_blocks (struct loop *);
129 static gimple ifc_temp_var (tree, tree);
130 static bool pred_blocks_visited_p (basic_block, bitmap *);
131 static basic_block * get_loop_body_in_if_conv_order (const struct loop *loop);
132 static bool bb_with_exit_edge_p (struct loop *, basic_block);
133 102
134 /* List of basic blocks in if-conversion-suitable order. */ 103 /* List of basic blocks in if-conversion-suitable order. */
135 static basic_block *ifc_bbs; 104 static basic_block *ifc_bbs;
136 105
137 /* Main entry point. 106 /* Create a new temp variable of type TYPE. Add GIMPLE_ASSIGN to assign EXP
138 Apply if-conversion to the LOOP. Return true if successful otherwise return 107 to the new variable. */
139 false. If false is returned then loop remains unchanged. 108
140 FOR_VECTORIZER is a boolean flag. It indicates whether if-conversion is used 109 static gimple
141 for vectorizer or not. If it is used for vectorizer, additional checks are 110 ifc_temp_var (tree type, tree exp)
142 used. (Vectorization checks are not yet implemented). */ 111 {
112 const char *name = "_ifc_";
113 tree var, new_name;
114 gimple stmt;
115
116 /* Create new temporary variable. */
117 var = create_tmp_var (type, name);
118 add_referenced_var (var);
119
120 /* Build new statement to assign EXP to new variable. */
121 stmt = gimple_build_assign (var, exp);
122
123 /* Get SSA name for the new variable and set make new statement
124 its definition statement. */
125 new_name = make_ssa_name (var, stmt);
126 gimple_assign_set_lhs (stmt, new_name);
127 SSA_NAME_DEF_STMT (new_name) = stmt;
128 update_stmt (stmt);
129
130 return stmt;
131 }
132
133 /* Add condition NEW_COND to the predicate list of basic block BB. */
134
135 static void
136 add_to_predicate_list (basic_block bb, tree new_cond)
137 {
138 tree cond = (tree) bb->aux;
139
140 if (cond)
141 cond = fold_build2_loc (EXPR_LOCATION (cond),
142 TRUTH_OR_EXPR, boolean_type_node,
143 unshare_expr (cond), new_cond);
144 else
145 cond = new_cond;
146
147 bb->aux = cond;
148 }
149
150 /* Add the condition COND to the previous condition PREV_COND, and add this
151 to the predicate list of the destination of edge E. GSI is the
152 place where the gimplification of the resulting condition should
153 output code. LOOP is the loop to be if-converted. */
154
155 static tree
156 add_to_dst_predicate_list (struct loop *loop, edge e,
157 tree prev_cond, tree cond,
158 gimple_stmt_iterator *gsi)
159 {
160 tree new_cond = NULL_TREE;
161
162 if (!flow_bb_inside_loop_p (loop, e->dest))
163 return NULL_TREE;
164
165 if (prev_cond == boolean_true_node || !prev_cond)
166 new_cond = unshare_expr (cond);
167 else
168 {
169 tree tmp;
170 gimple tmp_stmt = NULL;
171
172 prev_cond = force_gimple_operand_gsi (gsi, unshare_expr (prev_cond),
173 true, NULL, true, GSI_SAME_STMT);
174
175 cond = force_gimple_operand_gsi (gsi, unshare_expr (cond),
176 true, NULL, true, GSI_SAME_STMT);
177
178 /* Add the condition COND to the e->aux field. In case the edge
179 destination is a PHI node, this condition will be added to
180 the block predicate to construct a complete condition. */
181 e->aux = cond;
182
183 tmp = build2 (TRUTH_AND_EXPR, boolean_type_node,
184 unshare_expr (prev_cond), cond);
185 tmp_stmt = ifc_temp_var (boolean_type_node, tmp);
186 gsi_insert_before (gsi, tmp_stmt, GSI_SAME_STMT);
187 new_cond = gimple_assign_lhs (tmp_stmt);
188 }
189
190 add_to_predicate_list (e->dest, new_cond);
191 return new_cond;
192 }
193
194 /* Return true if one of the successor edges of BB exits LOOP. */
143 195
144 static bool 196 static bool
145 tree_if_conversion (struct loop *loop, bool for_vectorizer) 197 bb_with_exit_edge_p (struct loop *loop, basic_block bb)
146 { 198 {
147 basic_block bb; 199 edge e;
148 gimple_stmt_iterator itr; 200 edge_iterator ei;
149 unsigned int i; 201
150 202 FOR_EACH_EDGE (e, ei, bb->succs)
151 ifc_bbs = NULL; 203 if (loop_exit_edge_p (loop, e))
152 204 return true;
153 /* if-conversion is not appropriate for all loops. First, check if loop is 205
154 if-convertible or not. */ 206 return false;
155 if (!if_convertible_loop_p (loop, for_vectorizer)) 207 }
156 { 208
157 if (dump_file && (dump_flags & TDF_DETAILS)) 209 /* STMT is a GIMPLE_COND. Update two destination's predicate list.
158 fprintf (dump_file,"-------------------------\n"); 210 Remove COND_EXPR, if it is not the exit condition of LOOP.
159 if (ifc_bbs) 211 Otherwise update the exit condition of LOOP appropriately. GSI
160 { 212 points to the statement STMT. */
161 free (ifc_bbs); 213
162 ifc_bbs = NULL; 214 static void
163 } 215 tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond,
164 free_dominance_info (CDI_POST_DOMINATORS); 216 gimple_stmt_iterator *gsi)
165 return false; 217 {
166 } 218 tree c2;
167 219 edge true_edge, false_edge;
168 /* Do actual work now. */ 220 location_t loc = gimple_location (stmt);
169 for (i = 0; i < loop->num_nodes; i++) 221 tree c = fold_build2_loc (loc, gimple_cond_code (stmt), boolean_type_node,
170 { 222 gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
171 tree cond; 223
172 224 extract_true_false_edges_from_block (gimple_bb (stmt),
173 bb = ifc_bbs [i]; 225 &true_edge, &false_edge);
174 226
175 /* Update condition using predicate list. */ 227 /* Add new condition into destination's predicate list. */
176 cond = (tree) bb->aux; 228
177 229 /* If C is true, then TRUE_EDGE is taken. */
178 /* Process all statements in this basic block. 230 add_to_dst_predicate_list (loop, true_edge, cond, c, gsi);
179 Remove conditional expression, if any, and annotate 231
180 destination basic block(s) appropriately. */ 232 /* If C is false, then FALSE_EDGE is taken. */
181 for (itr = gsi_start_bb (bb); !gsi_end_p (itr); /* empty */) 233 c2 = invert_truthvalue_loc (loc, unshare_expr (c));
182 { 234 add_to_dst_predicate_list (loop, false_edge, cond, c2, gsi);
183 gimple t = gsi_stmt (itr); 235
184 cond = tree_if_convert_stmt (loop, t, cond, &itr); 236 /* Now this conditional statement is redundant. Remove it. But, do
185 if (!gsi_end_p (itr)) 237 not remove the exit condition! Update the exit condition using
186 gsi_next (&itr); 238 the new condition. */
187 } 239 if (!bb_with_exit_edge_p (loop, gimple_bb (stmt)))
188 240 {
189 /* If current bb has only one successor, then consider it as an 241 gsi_remove (gsi, true);
190 unconditional goto. */ 242 cond = NULL_TREE;
191 if (single_succ_p (bb)) 243 }
192 { 244 }
193 basic_block bb_n = single_succ (bb); 245
194 246 /* If-convert stmt T which is part of LOOP.
195 /* Successor bb inherits predicate of its predecessor. If there 247
196 is no predicate in predecessor bb, then consider successor bb 248 If T is a GIMPLE_ASSIGN then it is converted into a conditional
197 as always executed. */ 249 modify expression using COND. For conditional expressions, add
198 if (cond == NULL_TREE) 250 a condition in the destination basic block's predicate list and
199 cond = boolean_true_node; 251 remove the conditional expression itself. GSI points to the
200 252 statement T. */
201 add_to_predicate_list (bb_n, cond);
202 }
203 }
204
205 /* Now, all statements are if-converted and basic blocks are
206 annotated appropriately. Combine all basic block into one huge
207 basic block. */
208 combine_blocks (loop);
209
210 /* clean up */
211 clean_predicate_lists (loop);
212 free (ifc_bbs);
213 ifc_bbs = NULL;
214
215 return true;
216 }
217
218 /* if-convert stmt T which is part of LOOP.
219 If T is a GIMPLE_ASSIGN then it is converted into conditional modify
220 expression using COND. For conditional expressions, add condition in the
221 destination basic block's predicate list and remove conditional
222 expression itself. BSI is the iterator used to traverse statements of
223 loop. It is used here when it is required to delete current statement. */
224 253
225 static tree 254 static tree
226 tree_if_convert_stmt (struct loop * loop, gimple t, tree cond, 255 tree_if_convert_stmt (struct loop *loop, gimple t, tree cond,
227 gimple_stmt_iterator *gsi) 256 gimple_stmt_iterator *gsi)
228 { 257 {
229 if (dump_file && (dump_flags & TDF_DETAILS)) 258 if (dump_file && (dump_flags & TDF_DETAILS))
230 { 259 {
231 fprintf (dump_file, "------if-convert stmt\n"); 260 fprintf (dump_file, "------if-convert stmt\n");
247 update_stmt (gsi_stmt (*gsi)); 276 update_stmt (gsi_stmt (*gsi));
248 } 277 }
249 break; 278 break;
250 279
251 case GIMPLE_ASSIGN: 280 case GIMPLE_ASSIGN:
252 /* This GIMPLE_ASSIGN is killing previous value of LHS. Appropriate 281 /* This GIMPLE_ASSIGN is killing previous value of LHS. Appropriate
253 value will be selected by PHI node based on condition. It is possible 282 value will be selected by PHI node based on condition. It is possible
254 that before this transformation, PHI nodes was selecting default 283 that before this transformation, PHI nodes was selecting default
255 value and now it will use this new value. This is OK because it does 284 value and now it will use this new value. This is OK because it does
256 not change validity the program. */ 285 not change the validity of the program. */
257 break; 286 break;
258 287
259 case GIMPLE_COND: 288 case GIMPLE_COND:
260 /* Update destination blocks' predicate list and remove this 289 /* Update destination blocks' predicate list and remove this
261 condition expression. */ 290 condition expression. */
264 break; 293 break;
265 294
266 default: 295 default:
267 gcc_unreachable (); 296 gcc_unreachable ();
268 } 297 }
298
269 return cond; 299 return cond;
270 } 300 }
271 301
272 /* STMT is a GIMPLE_COND. Update two destination's predicate list. 302 /* Return true when PHI is if-convertible. PHI is part of loop LOOP
273 Remove COND_EXPR, if it is not the loop exit condition. Otherwise
274 update loop exit condition appropriately. GSI is the iterator
275 used to traverse statement list. STMT is part of loop LOOP. */
276
277 static void
278 tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond,
279 gimple_stmt_iterator *gsi)
280 {
281 tree c, c2;
282 edge true_edge, false_edge;
283 location_t loc = gimple_location (stmt);
284
285 gcc_assert (gimple_code (stmt) == GIMPLE_COND);
286
287 c = fold_build2_loc (loc, gimple_cond_code (stmt), boolean_type_node,
288 gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
289
290 extract_true_false_edges_from_block (gimple_bb (stmt),
291 &true_edge, &false_edge);
292
293 /* Add new condition into destination's predicate list. */
294
295 /* If C is true then TRUE_EDGE is taken. */
296 add_to_dst_predicate_list (loop, true_edge, cond, c, gsi);
297
298 /* If 'c' is false then FALSE_EDGE is taken. */
299 c2 = invert_truthvalue_loc (loc, unshare_expr (c));
300 add_to_dst_predicate_list (loop, false_edge, cond, c2, gsi);
301
302 /* Now this conditional statement is redundant. Remove it.
303 But, do not remove exit condition! Update exit condition
304 using new condition. */
305 if (!bb_with_exit_edge_p (loop, gimple_bb (stmt)))
306 {
307 gsi_remove (gsi, true);
308 cond = NULL_TREE;
309 }
310 return;
311 }
312
313 /* Return true, iff PHI is if-convertible. PHI is part of loop LOOP
314 and it belongs to basic block BB. 303 and it belongs to basic block BB.
315 PHI is not if-convertible 304
316 - if it has more than 2 arguments. 305 PHI is not if-convertible if:
317 - Virtual PHI is immediately used in another PHI node. 306 - it has more than 2 arguments,
318 - Virtual PHI on BB other than header. */ 307 - virtual PHI is immediately used in another PHI node,
308 - virtual PHI on BB other than header. */
319 309
320 static bool 310 static bool
321 if_convertible_phi_p (struct loop *loop, basic_block bb, gimple phi) 311 if_convertible_phi_p (struct loop *loop, basic_block bb, gimple phi)
322 { 312 {
323 if (dump_file && (dump_flags & TDF_DETAILS)) 313 if (dump_file && (dump_flags & TDF_DETAILS))
356 } 346 }
357 347
358 return true; 348 return true;
359 } 349 }
360 350
361 /* Return true, if STMT is if-convertible. 351 /* Return true when STMT is if-convertible.
352
362 GIMPLE_ASSIGN statement is not if-convertible if, 353 GIMPLE_ASSIGN statement is not if-convertible if,
363 - It is not movable. 354 - it is not movable,
364 - It could trap. 355 - it could trap,
365 - LHS is not var decl. 356 - LHS is not var decl.
366 GIMPLE_ASSIGN is part of block BB, which is inside loop LOOP. */ 357
358 GIMPLE_ASSIGN is part of block BB, which is inside loop LOOP. */
367 359
368 static bool 360 static bool
369 if_convertible_gimple_assign_stmt_p (struct loop *loop, basic_block bb, 361 if_convertible_gimple_assign_stmt_p (struct loop *loop, basic_block bb,
370 gimple stmt) 362 gimple stmt)
371 { 363 {
372 tree lhs; 364 tree lhs = gimple_assign_lhs (stmt);
373
374 if (!is_gimple_assign (stmt))
375 return false;
376 365
377 if (dump_file && (dump_flags & TDF_DETAILS)) 366 if (dump_file && (dump_flags & TDF_DETAILS))
378 { 367 {
379 fprintf (dump_file, "-------------------------\n"); 368 fprintf (dump_file, "-------------------------\n");
380 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); 369 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
381 } 370 }
382
383 lhs = gimple_assign_lhs (stmt);
384 371
385 /* Some of these constrains might be too conservative. */ 372 /* Some of these constrains might be too conservative. */
386 if (stmt_ends_bb_p (stmt) 373 if (stmt_ends_bb_p (stmt)
387 || gimple_has_volatile_ops (stmt) 374 || gimple_has_volatile_ops (stmt)
388 || (TREE_CODE (lhs) == SSA_NAME 375 || (TREE_CODE (lhs) == SSA_NAME
416 } 403 }
417 404
418 return true; 405 return true;
419 } 406 }
420 407
421 /* Return true, iff STMT is if-convertible. 408 /* Return true when STMT is if-convertible.
422 Statement is if-convertible if, 409
423 - It is if-convertible GIMPLE_ASSGIN 410 A statement is if-convertible if:
424 - It is GIMPLE_LABEL or GIMPLE_COND. 411 - it is an if-convertible GIMPLE_ASSGIN,
425 STMT is inside block BB, which is inside loop LOOP. */ 412 - it is a GIMPLE_LABEL or a GIMPLE_COND.
413
414 STMT is inside BB, which is inside loop LOOP. */
426 415
427 static bool 416 static bool
428 if_convertible_stmt_p (struct loop *loop, basic_block bb, gimple stmt) 417 if_convertible_stmt_p (struct loop *loop, basic_block bb, gimple stmt)
429 { 418 {
430 switch (gimple_code (stmt)) 419 switch (gimple_code (stmt))
431 { 420 {
432 case GIMPLE_LABEL: 421 case GIMPLE_LABEL:
433 break;
434
435 case GIMPLE_DEBUG: 422 case GIMPLE_DEBUG:
436 break; 423 case GIMPLE_COND:
424 return true;
437 425
438 case GIMPLE_ASSIGN: 426 case GIMPLE_ASSIGN:
439 if (!if_convertible_gimple_assign_stmt_p (loop, bb, stmt)) 427 return if_convertible_gimple_assign_stmt_p (loop, bb, stmt);
440 return false;
441 break;
442
443 case GIMPLE_COND:
444 break;
445 428
446 default: 429 default:
447 /* Don't know what to do with 'em so don't do anything. */ 430 /* Don't know what to do with 'em so don't do anything. */
448 if (dump_file && (dump_flags & TDF_DETAILS)) 431 if (dump_file && (dump_flags & TDF_DETAILS))
449 { 432 {
455 } 438 }
456 439
457 return true; 440 return true;
458 } 441 }
459 442
460 /* Return true, iff BB is if-convertible. 443 /* Return true when BB is if-convertible. This routine does not check
461 Note: This routine does _not_ check basic block statements and phis. 444 basic block's statements and phis.
462 Basic block is not if-convertible if, 445
463 - Basic block is non-empty and it is after exit block (in BFS order). 446 A basic block is not if-convertible if:
464 - Basic block is after exit block but before latch. 447 - it is non-empty and it is after the exit block (in BFS order),
465 - Basic block edge(s) is not normal. 448 - it is after the exit block but before the latch,
466 EXIT_BB_SEEN is true if basic block with exit edge is already seen. 449 - its edges are not normal.
467 BB is inside loop LOOP. */ 450
451 EXIT_BB is the basic block containing the exit of the LOOP. BB is
452 inside LOOP. */
468 453
469 static bool 454 static bool
470 if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb) 455 if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb)
471 { 456 {
472 edge e; 457 edge e;
503 FOR_EACH_EDGE (e, ei, bb->succs) 488 FOR_EACH_EDGE (e, ei, bb->succs)
504 if (e->flags & 489 if (e->flags &
505 (EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP)) 490 (EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP))
506 { 491 {
507 if (dump_file && (dump_flags & TDF_DETAILS)) 492 if (dump_file && (dump_flags & TDF_DETAILS))
508 fprintf (dump_file,"Difficult to handle edges\n"); 493 fprintf (dump_file, "Difficult to handle edges\n");
509 return false; 494 return false;
510 } 495 }
511 496
512 return true; 497 return true;
513 } 498 }
514 499
515 /* Return true, iff LOOP is if-convertible. 500 /* Return true when all predecessor blocks of BB are visited. The
516 LOOP is if-convertible if, 501 VISITED bitmap keeps track of the visited blocks. */
517 - It is innermost.
518 - It has two or more basic blocks.
519 - It has only one exit.
520 - Loop header is not the exit edge.
521 - If its basic blocks and phi nodes are if convertible. See above for
522 more info.
523 FOR_VECTORIZER enables vectorizer specific checks. For example, support
524 for vector conditions, data dependency checks etc.. (Not implemented yet). */
525 502
526 static bool 503 static bool
527 if_convertible_loop_p (struct loop *loop, bool for_vectorizer ATTRIBUTE_UNUSED) 504 pred_blocks_visited_p (basic_block bb, bitmap *visited)
505 {
506 edge e;
507 edge_iterator ei;
508 FOR_EACH_EDGE (e, ei, bb->preds)
509 if (!bitmap_bit_p (*visited, e->src->index))
510 return false;
511
512 return true;
513 }
514
515 /* Get body of a LOOP in suitable order for if-conversion. It is
516 caller's responsibility to deallocate basic block list.
517 If-conversion suitable order is, breadth first sort (BFS) order
518 with an additional constraint: select a block only if all its
519 predecessors are already selected. */
520
521 static basic_block *
522 get_loop_body_in_if_conv_order (const struct loop *loop)
523 {
524 basic_block *blocks, *blocks_in_bfs_order;
525 basic_block bb;
526 bitmap visited;
527 unsigned int index = 0;
528 unsigned int visited_count = 0;
529
530 gcc_assert (loop->num_nodes);
531 gcc_assert (loop->latch != EXIT_BLOCK_PTR);
532
533 blocks = XCNEWVEC (basic_block, loop->num_nodes);
534 visited = BITMAP_ALLOC (NULL);
535
536 blocks_in_bfs_order = get_loop_body_in_bfs_order (loop);
537
538 index = 0;
539 while (index < loop->num_nodes)
540 {
541 bb = blocks_in_bfs_order [index];
542
543 if (bb->flags & BB_IRREDUCIBLE_LOOP)
544 {
545 free (blocks_in_bfs_order);
546 BITMAP_FREE (visited);
547 free (blocks);
548 return NULL;
549 }
550
551 if (!bitmap_bit_p (visited, bb->index))
552 {
553 if (pred_blocks_visited_p (bb, &visited)
554 || bb == loop->header)
555 {
556 /* This block is now visited. */
557 bitmap_set_bit (visited, bb->index);
558 blocks[visited_count++] = bb;
559 }
560 }
561
562 index++;
563
564 if (index == loop->num_nodes
565 && visited_count != loop->num_nodes)
566 /* Not done yet. */
567 index = 0;
568 }
569 free (blocks_in_bfs_order);
570 BITMAP_FREE (visited);
571 return blocks;
572 }
573
574 /* Return true when LOOP is if-convertible.
575 LOOP is if-convertible if:
576 - it is innermost,
577 - it has two or more basic blocks,
578 - it has only one exit,
579 - loop header is not the exit edge,
580 - if its basic blocks and phi nodes are if convertible. */
581
582 static bool
583 if_convertible_loop_p (struct loop *loop)
528 { 584 {
529 basic_block bb; 585 basic_block bb;
530 gimple_stmt_iterator itr; 586 gimple_stmt_iterator itr;
531 unsigned int i; 587 unsigned int i;
532 edge e; 588 edge e;
585 bb = ifc_bbs[i]; 641 bb = ifc_bbs[i];
586 642
587 if (!if_convertible_bb_p (loop, bb, exit_bb)) 643 if (!if_convertible_bb_p (loop, bb, exit_bb))
588 return false; 644 return false;
589 645
590 /* Check statements. */
591 for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr)) 646 for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr))
592 if (!if_convertible_stmt_p (loop, bb, gsi_stmt (itr))) 647 if (!if_convertible_stmt_p (loop, bb, gsi_stmt (itr)))
593 return false; 648 return false;
594 /* ??? Check data dependency for vectorizer. */ 649
595
596 /* What about phi nodes ? */
597 itr = gsi_start_phis (bb); 650 itr = gsi_start_phis (bb);
598 651
599 /* Clear aux field of incoming edges to a bb with a phi node. */
600 if (!gsi_end_p (itr)) 652 if (!gsi_end_p (itr))
601 FOR_EACH_EDGE (e, ei, bb->preds) 653 FOR_EACH_EDGE (e, ei, bb->preds)
602 e->aux = NULL; 654 e->aux = NULL;
603 655
604 /* Check statements. */
605 for (; !gsi_end_p (itr); gsi_next (&itr)) 656 for (; !gsi_end_p (itr); gsi_next (&itr))
606 if (!if_convertible_phi_p (loop, bb, gsi_stmt (itr))) 657 if (!if_convertible_phi_p (loop, bb, gsi_stmt (itr)))
607 return false; 658 return false;
608 659
609 if (bb_with_exit_edge_p (loop, bb)) 660 if (bb_with_exit_edge_p (loop, bb))
610 exit_bb = bb; 661 exit_bb = bb;
611 } 662 }
612 663
613 /* OK. Did not find any potential issues so go ahead in if-convert
614 this loop. Now there is no looking back. */
615 if (dump_file) 664 if (dump_file)
616 fprintf (dump_file,"Applying if-conversion\n"); 665 fprintf (dump_file,"Applying if-conversion\n");
617 666
618 free_dominance_info (CDI_POST_DOMINATORS); 667 free_dominance_info (CDI_POST_DOMINATORS);
619 return true; 668 return true;
620 } 669 }
621 670
622 /* Add condition COND into predicate list of basic block BB. */ 671 /* During if-conversion, the bb->aux field is used to hold a predicate
623 672 list. This function cleans for all the basic blocks in the given
624 static void 673 LOOP their predicate list. It also cleans up the e->aux field of
625 add_to_predicate_list (basic_block bb, tree new_cond) 674 all the successor edges: e->aux is used to hold the true and false
626 { 675 conditions for conditional expressions. */
627 tree cond = (tree) bb->aux;
628
629 if (cond)
630 cond = fold_build2_loc (EXPR_LOCATION (cond),
631 TRUTH_OR_EXPR, boolean_type_node,
632 unshare_expr (cond), new_cond);
633 else
634 cond = new_cond;
635
636 bb->aux = cond;
637 }
638
639 /* Add condition COND into BB's predicate list. PREV_COND is
640 existing condition. */
641
642 static tree
643 add_to_dst_predicate_list (struct loop * loop, edge e,
644 tree prev_cond, tree cond,
645 gimple_stmt_iterator *gsi)
646 {
647 tree new_cond = NULL_TREE;
648
649 if (!flow_bb_inside_loop_p (loop, e->dest))
650 return NULL_TREE;
651
652 if (prev_cond == boolean_true_node || !prev_cond)
653 new_cond = unshare_expr (cond);
654 else
655 {
656 tree tmp;
657 gimple tmp_stmt = NULL;
658
659 prev_cond = force_gimple_operand_gsi (gsi, unshare_expr (prev_cond),
660 true, NULL, true, GSI_SAME_STMT);
661
662 cond = force_gimple_operand_gsi (gsi, unshare_expr (cond),
663 true, NULL, true, GSI_SAME_STMT);
664
665 /* Add the condition to aux field of the edge. In case edge
666 destination is a PHI node, this condition will be ANDed with
667 block predicate to construct complete condition. */
668 e->aux = cond;
669
670 /* new_cond == prev_cond AND cond */
671 tmp = build2 (TRUTH_AND_EXPR, boolean_type_node,
672 unshare_expr (prev_cond), cond);
673 tmp_stmt = ifc_temp_var (boolean_type_node, tmp);
674 gsi_insert_before (gsi, tmp_stmt, GSI_SAME_STMT);
675 new_cond = gimple_assign_lhs (tmp_stmt);
676 }
677 add_to_predicate_list (e->dest, new_cond);
678 return new_cond;
679 }
680
681 /* During if-conversion aux field from basic block structure is used to hold
682 predicate list. Clean each basic block's predicate list for the given LOOP.
683 Also clean aux field of successor edges, used to hold true and false
684 condition from conditional expression. */
685 676
686 static void 677 static void
687 clean_predicate_lists (struct loop *loop) 678 clean_predicate_lists (struct loop *loop)
688 { 679 {
689 basic_block *bb; 680 basic_block *bb;
699 e->aux = NULL; 690 e->aux = NULL;
700 } 691 }
701 free (bb); 692 free (bb);
702 } 693 }
703 694
704 /* Basic block BB has two predecessors. Using predecessor's aux field, set 695 /* Basic block BB has two predecessors. Using predecessor's bb->aux
705 appropriate condition COND for the PHI node replacement. Return true block 696 field, set appropriate condition COND for the PHI node replacement.
706 whose phi arguments are selected when cond is true. */ 697 Return true block whose phi arguments are selected when cond is
698 true. LOOP is the loop containing the if-converted region, GSI is
699 the place to insert the code for the if-conversion. */
707 700
708 static basic_block 701 static basic_block
709 find_phi_replacement_condition (struct loop *loop, 702 find_phi_replacement_condition (struct loop *loop,
710 basic_block bb, tree *cond, 703 basic_block bb, tree *cond,
711 gimple_stmt_iterator *gsi) 704 gimple_stmt_iterator *gsi)
760 || dominated_by_p (CDI_DOMINATORS, 753 || dominated_by_p (CDI_DOMINATORS,
761 second_edge->src, first_edge->src)) 754 second_edge->src, first_edge->src))
762 { 755 {
763 *cond = (tree) (second_edge->src)->aux; 756 *cond = (tree) (second_edge->src)->aux;
764 757
765 /* If there is a condition on an incoming edge, 758 /* If there is a condition on an incoming edge, add it to the
766 AND it with the incoming bb predicate. */ 759 incoming bb predicate. */
767 if (second_edge->aux) 760 if (second_edge->aux)
768 *cond = build2 (TRUTH_AND_EXPR, boolean_type_node, 761 *cond = build2 (TRUTH_AND_EXPR, boolean_type_node,
769 *cond, (tree) second_edge->aux); 762 *cond, (tree) second_edge->aux);
770 763
771 if (TREE_CODE (*cond) == TRUTH_NOT_EXPR) 764 if (TREE_CODE (*cond) == TRUTH_NOT_EXPR)
772 /* We can be smart here and choose inverted
773 condition without switching bbs. */
774 *cond = invert_truthvalue (*cond); 765 *cond = invert_truthvalue (*cond);
775 else 766 else
776 /* Select non loop header bb. */ 767 /* Select non loop header bb. */
777 first_edge = second_edge; 768 first_edge = second_edge;
778 } 769 }
779 else 770 else
780 { 771 {
781 /* FIRST_BB is not loop header */
782 *cond = (tree) (first_edge->src)->aux; 772 *cond = (tree) (first_edge->src)->aux;
783 773
784 /* If there is a condition on an incoming edge, 774 /* If there is a condition on an incoming edge, add it to the
785 AND it with the incoming bb predicate. */ 775 incoming bb predicate. */
786 if (first_edge->aux) 776 if (first_edge->aux)
787 *cond = build2 (TRUTH_AND_EXPR, boolean_type_node, 777 *cond = build2 (TRUTH_AND_EXPR, boolean_type_node,
788 *cond, (tree) first_edge->aux); 778 *cond, (tree) first_edge->aux);
789 } 779 }
790 780
791 /* Create temp. for the condition. Vectorizer prefers to have gimple 781 /* Gimplify the condition: the vectorizer prefers to have gimple
792 value as condition. Various targets use different means to communicate 782 values as conditions. Various targets use different means to
793 condition in vector compare operation. Using gimple value allows 783 communicate conditions in vector compare operations. Using a
794 compiler to emit vector compare and select RTL without exposing 784 gimple value allows the compiler to emit vector compare and
795 compare's result. */ 785 select RTL without exposing compare's result. */
796 *cond = force_gimple_operand_gsi (gsi, unshare_expr (*cond), 786 *cond = force_gimple_operand_gsi (gsi, unshare_expr (*cond),
797 false, NULL_TREE, 787 false, NULL_TREE,
798 true, GSI_SAME_STMT); 788 true, GSI_SAME_STMT);
799 if (!is_gimple_reg (*cond) && !is_gimple_condexpr (*cond)) 789 if (!is_gimple_reg (*cond) && !is_gimple_condexpr (*cond))
800 { 790 {
808 gcc_assert (*cond); 798 gcc_assert (*cond);
809 799
810 return first_edge->src; 800 return first_edge->src;
811 } 801 }
812 802
813 803 /* Replace PHI node with conditional modify expr using COND. This
814 /* Replace PHI node with conditional modify expr using COND. 804 routine does not handle PHI nodes with more than two arguments.
815 This routine does not handle PHI nodes with more than two arguments. 805
816 For example, 806 For example,
817 S1: A = PHI <x1(1), x2(5) 807 S1: A = PHI <x1(1), x2(5)
818 is converted into, 808 is converted into,
819 S2: A = cond ? x1 : x2; 809 S2: A = cond ? x1 : x2;
820 S2 is inserted at the top of basic block's statement list. 810
821 When COND is true, phi arg from TRUE_BB is selected. 811 The generated code is inserted at GSI that points to the top of
822 */ 812 basic block's statement list. When COND is true, phi arg from
813 TRUE_BB is selected. */
823 814
824 static void 815 static void
825 replace_phi_with_cond_gimple_assign_stmt (gimple phi, tree cond, 816 replace_phi_with_cond_gimple_assign_stmt (gimple phi, tree cond,
826 basic_block true_bb, 817 basic_block true_bb,
827 gimple_stmt_iterator *gsi) 818 gimple_stmt_iterator *gsi)
829 gimple new_stmt; 820 gimple new_stmt;
830 basic_block bb; 821 basic_block bb;
831 tree rhs; 822 tree rhs;
832 tree arg_0, arg_1; 823 tree arg_0, arg_1;
833 824
834 gcc_assert (gimple_code (phi) == GIMPLE_PHI); 825 gcc_assert (gimple_code (phi) == GIMPLE_PHI
835 826 && gimple_phi_num_args (phi) == 2);
836 /* If this is not filtered earlier, then now it is too late. */ 827
837 gcc_assert (gimple_phi_num_args (phi) == 2);
838
839 /* Find basic block and initialize iterator. */
840 bb = gimple_bb (phi); 828 bb = gimple_bb (phi);
841 829
842 /* Use condition that is not TRUTH_NOT_EXPR in conditional modify expr. */ 830 /* Use condition that is not TRUTH_NOT_EXPR in conditional modify expr. */
843 if (EDGE_PRED (bb, 1)->src == true_bb) 831 if (EDGE_PRED (bb, 1)->src == true_bb)
844 { 832 {
854 /* Build new RHS using selected condition and arguments. */ 842 /* Build new RHS using selected condition and arguments. */
855 rhs = build3 (COND_EXPR, TREE_TYPE (PHI_RESULT (phi)), 843 rhs = build3 (COND_EXPR, TREE_TYPE (PHI_RESULT (phi)),
856 unshare_expr (cond), unshare_expr (arg_0), 844 unshare_expr (cond), unshare_expr (arg_0),
857 unshare_expr (arg_1)); 845 unshare_expr (arg_1));
858 846
859 /* Create new GIMPLE_ASSIGN statement using RHS. */
860 new_stmt = gimple_build_assign (unshare_expr (PHI_RESULT (phi)), rhs); 847 new_stmt = gimple_build_assign (unshare_expr (PHI_RESULT (phi)), rhs);
861
862 /* Make new statement definition of the original phi result. */
863 SSA_NAME_DEF_STMT (gimple_phi_result (phi)) = new_stmt; 848 SSA_NAME_DEF_STMT (gimple_phi_result (phi)) = new_stmt;
864
865 /* Insert using iterator. */
866 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); 849 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
867 update_stmt (new_stmt); 850 update_stmt (new_stmt);
868 851
869 if (dump_file && (dump_flags & TDF_DETAILS)) 852 if (dump_file && (dump_flags & TDF_DETAILS))
870 { 853 {
871 fprintf (dump_file, "new phi replacement stmt\n"); 854 fprintf (dump_file, "new phi replacement stmt\n");
872 print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM); 855 print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
873 } 856 }
874 } 857 }
875 858
876 /* Process phi nodes for the given LOOP. Replace phi nodes with cond 859 /* Process phi nodes for the given LOOP. Replace phi nodes with
877 modify expr. */ 860 conditional modify expressions. */
878 861
879 static void 862 static void
880 process_phi_nodes (struct loop *loop) 863 process_phi_nodes (struct loop *loop)
881 { 864 {
882 basic_block bb; 865 basic_block bb;
883 unsigned int orig_loop_num_nodes = loop->num_nodes; 866 unsigned int orig_loop_num_nodes = loop->num_nodes;
884 unsigned int i; 867 unsigned int i;
885 868
886 /* Replace phi nodes with cond. modify expr. */
887 for (i = 1; i < orig_loop_num_nodes; i++) 869 for (i = 1; i < orig_loop_num_nodes; i++)
888 { 870 {
889 gimple phi; 871 gimple phi;
890 tree cond = NULL_TREE; 872 tree cond = NULL_TREE;
891 gimple_stmt_iterator gsi, phi_gsi; 873 gimple_stmt_iterator gsi, phi_gsi;
896 continue; 878 continue;
897 879
898 phi_gsi = gsi_start_phis (bb); 880 phi_gsi = gsi_start_phis (bb);
899 gsi = gsi_after_labels (bb); 881 gsi = gsi_after_labels (bb);
900 882
901 /* BB has two predecessors. Using predecessor's aux field, set 883 /* BB has two predecessors. Using predecessor's aux field, set
902 appropriate condition for the PHI node replacement. */ 884 appropriate condition for the PHI node replacement. */
903 if (!gsi_end_p (phi_gsi)) 885 if (!gsi_end_p (phi_gsi))
904 true_bb = find_phi_replacement_condition (loop, bb, &cond, &gsi); 886 true_bb = find_phi_replacement_condition (loop, bb, &cond, &gsi);
905 887
906 while (!gsi_end_p (phi_gsi)) 888 while (!gsi_end_p (phi_gsi))
910 release_phi_node (phi); 892 release_phi_node (phi);
911 gsi_next (&phi_gsi); 893 gsi_next (&phi_gsi);
912 } 894 }
913 set_phi_nodes (bb, NULL); 895 set_phi_nodes (bb, NULL);
914 } 896 }
915 return; 897 }
916 } 898
917 899 /* Combine all the basic blocks from LOOP into one or two super basic
918 /* Combine all basic block from the given LOOP into one or two super 900 blocks. Replace PHI nodes with conditional modify expressions. */
919 basic block. Replace PHI nodes with conditional modify expression. */
920 901
921 static void 902 static void
922 combine_blocks (struct loop *loop) 903 combine_blocks (struct loop *loop)
923 { 904 {
924 basic_block bb, exit_bb, merge_target_bb; 905 basic_block bb, exit_bb, merge_target_bb;
928 edge_iterator ei; 909 edge_iterator ei;
929 910
930 /* Process phi nodes to prepare blocks for merge. */ 911 /* Process phi nodes to prepare blocks for merge. */
931 process_phi_nodes (loop); 912 process_phi_nodes (loop);
932 913
933 /* Merge basic blocks. First remove all the edges in the loop, except 914 /* Merge basic blocks: first remove all the edges in the loop,
934 for those from the exit block. */ 915 except for those from the exit block. */
935 exit_bb = NULL; 916 exit_bb = NULL;
936 for (i = 0; i < orig_loop_num_nodes; i++) 917 for (i = 0; i < orig_loop_num_nodes; i++)
937 { 918 {
938 bb = ifc_bbs[i]; 919 bb = ifc_bbs[i];
939 if (bb_with_exit_edge_p (loop, bb)) 920 if (bb_with_exit_edge_p (loop, bb))
959 940
960 if (exit_bb != NULL) 941 if (exit_bb != NULL)
961 { 942 {
962 if (exit_bb != loop->header) 943 if (exit_bb != loop->header)
963 { 944 {
964 /* Connect this node with loop header. */ 945 /* Connect this node to loop header. */
965 make_edge (loop->header, exit_bb, EDGE_FALLTHRU); 946 make_edge (loop->header, exit_bb, EDGE_FALLTHRU);
966 set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header); 947 set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header);
967 } 948 }
968 949
969 /* Redirect non-exit edges to loop->latch. */ 950 /* Redirect non-exit edges to loop->latch. */
974 } 955 }
975 set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb); 956 set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb);
976 } 957 }
977 else 958 else
978 { 959 {
979 /* If the loop does not have exit then reconnect header and latch. */ 960 /* If the loop does not have an exit, reconnect header and latch. */
980 make_edge (loop->header, loop->latch, EDGE_FALLTHRU); 961 make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
981 set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header); 962 set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
982 } 963 }
983 964
984 merge_target_bb = loop->header; 965 merge_target_bb = loop->header;
1010 set_bb_seq (bb, NULL); 991 set_bb_seq (bb, NULL);
1011 992
1012 delete_basic_block (bb); 993 delete_basic_block (bb);
1013 } 994 }
1014 995
1015 /* Now if possible, merge loop header and block with exit edge. 996 /* If possible, merge loop header to the block with the exit edge.
1016 This reduces number of basic blocks to 2. Auto vectorizer addresses 997 This reduces the number of basic blocks to two, to please the
1017 loops with two nodes only. FIXME: Use cleanup_tree_cfg(). */ 998 vectorizer that handles only loops with two nodes.
999
1000 FIXME: Call cleanup_tree_cfg. */
1018 if (exit_bb 1001 if (exit_bb
1019 && exit_bb != loop->header 1002 && exit_bb != loop->header
1020 && can_merge_blocks_p (loop->header, exit_bb)) 1003 && can_merge_blocks_p (loop->header, exit_bb))
1021 merge_blocks (loop->header, exit_bb); 1004 merge_blocks (loop->header, exit_bb);
1022 } 1005 }
1023 1006
1024 /* Make a new temp variable of type TYPE. Add GIMPLE_ASSIGN to assign EXP 1007 /* Main entry point: return true when LOOP is if-converted, otherwise
1025 to the new variable. */ 1008 the loop remains unchanged. */
1026
1027 static gimple
1028 ifc_temp_var (tree type, tree exp)
1029 {
1030 const char *name = "_ifc_";
1031 tree var, new_name;
1032 gimple stmt;
1033
1034 /* Create new temporary variable. */
1035 var = create_tmp_var (type, name);
1036 add_referenced_var (var);
1037
1038 /* Build new statement to assign EXP to new variable. */
1039 stmt = gimple_build_assign (var, exp);
1040
1041 /* Get SSA name for the new variable and set make new statement
1042 its definition statement. */
1043 new_name = make_ssa_name (var, stmt);
1044 gimple_assign_set_lhs (stmt, new_name);
1045 SSA_NAME_DEF_STMT (new_name) = stmt;
1046 update_stmt (stmt);
1047
1048 return stmt;
1049 }
1050
1051
1052 /* Return TRUE iff, all pred blocks of BB are visited.
1053 Bitmap VISITED keeps history of visited blocks. */
1054 1009
1055 static bool 1010 static bool
1056 pred_blocks_visited_p (basic_block bb, bitmap *visited) 1011 tree_if_conversion (struct loop *loop)
1057 { 1012 {
1058 edge e; 1013 gimple_stmt_iterator itr;
1059 edge_iterator ei; 1014 unsigned int i;
1060 FOR_EACH_EDGE (e, ei, bb->preds) 1015
1061 if (!bitmap_bit_p (*visited, e->src->index)) 1016 ifc_bbs = NULL;
1017
1018 /* If-conversion is not appropriate for all loops. First, check if
1019 the loop is if-convertible. */
1020 if (!if_convertible_loop_p (loop))
1021 {
1022 if (dump_file && (dump_flags & TDF_DETAILS))
1023 fprintf (dump_file,"-------------------------\n");
1024 if (ifc_bbs)
1025 {
1026 free (ifc_bbs);
1027 ifc_bbs = NULL;
1028 }
1029 free_dominance_info (CDI_POST_DOMINATORS);
1062 return false; 1030 return false;
1031 }
1032
1033 for (i = 0; i < loop->num_nodes; i++)
1034 {
1035 basic_block bb = ifc_bbs [i];
1036 tree cond = (tree) bb->aux;
1037
1038 /* Process all the statements in this basic block.
1039 Remove conditional expression, if any, and annotate
1040 destination basic block(s) appropriately. */
1041 for (itr = gsi_start_bb (bb); !gsi_end_p (itr); /* empty */)
1042 {
1043 gimple t = gsi_stmt (itr);
1044 cond = tree_if_convert_stmt (loop, t, cond, &itr);
1045 if (!gsi_end_p (itr))
1046 gsi_next (&itr);
1047 }
1048
1049 /* If current bb has only one successor, then consider it as an
1050 unconditional goto. */
1051 if (single_succ_p (bb))
1052 {
1053 basic_block bb_n = single_succ (bb);
1054
1055 /* The successor bb inherits the predicate of its
1056 predecessor. If there is no predicate in the predecessor
1057 bb, then consider the successor bb as always executed. */
1058 if (cond == NULL_TREE)
1059 cond = boolean_true_node;
1060
1061 add_to_predicate_list (bb_n, cond);
1062 }
1063 }
1064
1065 /* Now, all statements are if-converted and basic blocks are
1066 annotated appropriately. Combine all the basic blocks into one
1067 huge basic block. */
1068 combine_blocks (loop);
1069
1070 /* clean up */
1071 clean_predicate_lists (loop);
1072 free (ifc_bbs);
1073 ifc_bbs = NULL;
1063 1074
1064 return true; 1075 return true;
1065 }
1066
1067 /* Get body of a LOOP in suitable order for if-conversion.
1068 It is caller's responsibility to deallocate basic block
1069 list. If-conversion suitable order is, BFS order with one
1070 additional constraint. Select block in BFS block, if all
1071 pred are already selected. */
1072
1073 static basic_block *
1074 get_loop_body_in_if_conv_order (const struct loop *loop)
1075 {
1076 basic_block *blocks, *blocks_in_bfs_order;
1077 basic_block bb;
1078 bitmap visited;
1079 unsigned int index = 0;
1080 unsigned int visited_count = 0;
1081
1082 gcc_assert (loop->num_nodes);
1083 gcc_assert (loop->latch != EXIT_BLOCK_PTR);
1084
1085 blocks = XCNEWVEC (basic_block, loop->num_nodes);
1086 visited = BITMAP_ALLOC (NULL);
1087
1088 blocks_in_bfs_order = get_loop_body_in_bfs_order (loop);
1089
1090 index = 0;
1091 while (index < loop->num_nodes)
1092 {
1093 bb = blocks_in_bfs_order [index];
1094
1095 if (bb->flags & BB_IRREDUCIBLE_LOOP)
1096 {
1097 free (blocks_in_bfs_order);
1098 BITMAP_FREE (visited);
1099 free (blocks);
1100 return NULL;
1101 }
1102 if (!bitmap_bit_p (visited, bb->index))
1103 {
1104 if (pred_blocks_visited_p (bb, &visited)
1105 || bb == loop->header)
1106 {
1107 /* This block is now visited. */
1108 bitmap_set_bit (visited, bb->index);
1109 blocks[visited_count++] = bb;
1110 }
1111 }
1112 index++;
1113 if (index == loop->num_nodes
1114 && visited_count != loop->num_nodes)
1115 {
1116 /* Not done yet. */
1117 index = 0;
1118 }
1119 }
1120 free (blocks_in_bfs_order);
1121 BITMAP_FREE (visited);
1122 return blocks;
1123 }
1124
1125 /* Return true if one of the basic block BB edge is exit of LOOP. */
1126
1127 static bool
1128 bb_with_exit_edge_p (struct loop *loop, basic_block bb)
1129 {
1130 edge e;
1131 edge_iterator ei;
1132 bool exit_edge_found = false;
1133
1134 FOR_EACH_EDGE (e, ei, bb->succs)
1135 if (loop_exit_edge_p (loop, e))
1136 {
1137 exit_edge_found = true;
1138 break;
1139 }
1140
1141 return exit_edge_found;
1142 } 1076 }
1143 1077
1144 /* Tree if-conversion pass management. */ 1078 /* Tree if-conversion pass management. */
1145 1079
1146 static unsigned int 1080 static unsigned int
1151 1085
1152 if (number_of_loops () <= 1) 1086 if (number_of_loops () <= 1)
1153 return 0; 1087 return 0;
1154 1088
1155 FOR_EACH_LOOP (li, loop, 0) 1089 FOR_EACH_LOOP (li, loop, 0)
1156 { 1090 tree_if_conversion (loop);
1157 tree_if_conversion (loop, true); 1091
1158 }
1159 return 0; 1092 return 0;
1160 } 1093 }
1161 1094
1162 static bool 1095 static bool
1163 gate_tree_if_conversion (void) 1096 gate_tree_if_conversion (void)
1178 TV_NONE, /* tv_id */ 1111 TV_NONE, /* tv_id */
1179 PROP_cfg | PROP_ssa, /* properties_required */ 1112 PROP_cfg | PROP_ssa, /* properties_required */
1180 0, /* properties_provided */ 1113 0, /* properties_provided */
1181 0, /* properties_destroyed */ 1114 0, /* properties_destroyed */
1182 0, /* todo_flags_start */ 1115 0, /* todo_flags_start */
1183 TODO_dump_func | TODO_verify_loops | TODO_verify_stmts | TODO_verify_flow 1116 TODO_dump_func | TODO_verify_stmts | TODO_verify_flow
1184 /* todo_flags_finish */ 1117 /* todo_flags_finish */
1185 } 1118 }
1186 }; 1119 };