comparison gcc/graphite-scop-detection.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 /* Detection of Static Control Parts (SCoP) for Graphite. 1 /* Detection of Static Control Parts (SCoP) for Graphite.
2 Copyright (C) 2009 Free Software Foundation, Inc. 2 Copyright (C) 2009, 2010 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <sebastian.pop@amd.com> and 3 Contributed by Sebastian Pop <sebastian.pop@amd.com> and
4 Tobias Grosser <grosser@fim.uni-passau.de>. 4 Tobias Grosser <grosser@fim.uni-passau.de>.
5 5
6 This file is part of GCC. 6 This file is part of GCC.
7 7
223 case MULT_EXPR: 223 case MULT_EXPR:
224 return !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 0))) 224 return !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 0)))
225 && !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 1))) 225 && !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 1)))
226 && !(chrec_contains_symbols (TREE_OPERAND (scev, 0)) 226 && !(chrec_contains_symbols (TREE_OPERAND (scev, 0))
227 && chrec_contains_symbols (TREE_OPERAND (scev, 1))) 227 && chrec_contains_symbols (TREE_OPERAND (scev, 1)))
228 && graphite_can_represent_init (scev)
228 && graphite_can_represent_scev (TREE_OPERAND (scev, 0), outermost_loop) 229 && graphite_can_represent_scev (TREE_OPERAND (scev, 0), outermost_loop)
229 && graphite_can_represent_scev (TREE_OPERAND (scev, 1), outermost_loop); 230 && graphite_can_represent_scev (TREE_OPERAND (scev, 1), outermost_loop);
230 231
231 case POLYNOMIAL_CHREC: 232 case POLYNOMIAL_CHREC:
232 /* Check for constant strides. With a non constant stride of 233 /* Check for constant strides. With a non constant stride of
293 } 294 }
294 295
295 done: 296 done:
296 free_data_refs (drs); 297 free_data_refs (drs);
297 return res; 298 return res;
298 }
299
300 /* Return false if the TREE_CODE of the operand OP or any of its operands
301 is a COMPONENT_REF. */
302
303 static bool
304 exclude_component_ref (tree op)
305 {
306 int i;
307 int len;
308
309 if (!op)
310 return true;
311
312 if (TREE_CODE (op) == COMPONENT_REF)
313 return false;
314
315 len = TREE_OPERAND_LENGTH (op);
316 for (i = 0; i < len; ++i)
317 if (!exclude_component_ref (TREE_OPERAND (op, i)))
318 return false;
319
320 return true;
321 }
322
323 /* Return true if the operand OP used in STMT is simple in regards to
324 OUTERMOST_LOOP. */
325
326 static inline bool
327 is_simple_operand (tree op)
328 {
329 /* It is not a simple operand when it is a declaration or a
330 structure. */
331 return !DECL_P (op) && !AGGREGATE_TYPE_P (TREE_TYPE (op))
332 && exclude_component_ref (op);
333 } 299 }
334 300
335 /* Return true only when STMT is simple enough for being handled by 301 /* Return true only when STMT is simple enough for being handled by
336 Graphite. This depends on SCOP_ENTRY, as the parameters are 302 Graphite. This depends on SCOP_ENTRY, as the parameters are
337 initialized relatively to this basic block, the linear functions 303 initialized relatively to this basic block, the linear functions
393 359
394 return true; 360 return true;
395 } 361 }
396 362
397 case GIMPLE_ASSIGN: 363 case GIMPLE_ASSIGN:
398 {
399 enum tree_code code = gimple_assign_rhs_code (stmt);
400
401 switch (get_gimple_rhs_class (code))
402 {
403 case GIMPLE_UNARY_RHS:
404 case GIMPLE_SINGLE_RHS:
405 return (is_simple_operand (gimple_assign_lhs (stmt))
406 && is_simple_operand (gimple_assign_rhs1 (stmt)));
407
408 case GIMPLE_BINARY_RHS:
409 return (is_simple_operand (gimple_assign_lhs (stmt))
410 && is_simple_operand (gimple_assign_rhs1 (stmt))
411 && is_simple_operand (gimple_assign_rhs2 (stmt)));
412
413 case GIMPLE_INVALID_RHS:
414 default:
415 gcc_unreachable ();
416 }
417 }
418
419 case GIMPLE_CALL: 364 case GIMPLE_CALL:
420 { 365 return true;
421 size_t i;
422 size_t n = gimple_call_num_args (stmt);
423 tree lhs = gimple_call_lhs (stmt);
424
425 if (lhs && !is_simple_operand (lhs))
426 return false;
427
428 for (i = 0; i < n; i++)
429 if (!is_simple_operand (gimple_call_arg (stmt, i)))
430 return false;
431
432 return true;
433 }
434 366
435 default: 367 default:
436 /* These nodes cut a new scope. */ 368 /* These nodes cut a new scope. */
437 return false; 369 return false;
438 } 370 }
1001 edge e; 933 edge e;
1002 edge_iterator ei; 934 edge_iterator ei;
1003 edge forwarder = NULL; 935 edge forwarder = NULL;
1004 basic_block exit; 936 basic_block exit;
1005 937
1006 if (find_single_exit_edge (region))
1007 return;
1008
1009 /* We create a forwarder bb (5) for all edges leaving this region 938 /* We create a forwarder bb (5) for all edges leaving this region
1010 (3->5, 4->5). All other edges leading to the same bb, are moved 939 (3->5, 4->5). All other edges leading to the same bb, are moved
1011 to a new bb (6). If these edges where part of another region (2->5) 940 to a new bb (6). If these edges where part of another region (2->5)
1012 we update the region->exit pointer, of this region. 941 we update the region->exit pointer, of this region.
1013 942
1097 create_single_entry_edge (s); 1026 create_single_entry_edge (s);
1098 1027
1099 mark_exit_edges (regions); 1028 mark_exit_edges (regions);
1100 1029
1101 for (i = 0; VEC_iterate (sd_region, regions, i, s); i++) 1030 for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
1102 create_single_exit_edge (s); 1031 /* Don't handle multiple edges exiting the function. */
1032 if (!find_single_exit_edge (s)
1033 && s->exit != EXIT_BLOCK_PTR)
1034 create_single_exit_edge (s);
1103 1035
1104 unmark_exit_edges (regions); 1036 unmark_exit_edges (regions);
1105 1037
1106 fix_loop_structure (NULL); 1038 fix_loop_structure (NULL);
1107 1039
1123 1055
1124 for (i = 0; VEC_iterate (sd_region, regions, i, s); i++) 1056 for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
1125 { 1057 {
1126 edge entry = find_single_entry_edge (s); 1058 edge entry = find_single_entry_edge (s);
1127 edge exit = find_single_exit_edge (s); 1059 edge exit = find_single_exit_edge (s);
1128 scop_p scop = new_scop (new_sese (entry, exit)); 1060 scop_p scop;
1061
1062 if (!exit)
1063 continue;
1064
1065 scop = new_scop (new_sese (entry, exit));
1129 VEC_safe_push (scop_p, heap, *scops, scop); 1066 VEC_safe_push (scop_p, heap, *scops, scop);
1130 1067
1131 /* Are there overlapping SCoPs? */ 1068 /* Are there overlapping SCoPs? */
1132 #ifdef ENABLE_CHECKING 1069 #ifdef ENABLE_CHECKING
1133 { 1070 {
1364 { 1301 {
1365 loop_iterator li; 1302 loop_iterator li;
1366 loop_p loop; 1303 loop_p loop;
1367 1304
1368 #ifdef ENABLE_CHECKING 1305 #ifdef ENABLE_CHECKING
1369 verify_loop_closed_ssa (); 1306 verify_loop_closed_ssa (true);
1370 #endif 1307 #endif
1371 1308
1372 FOR_EACH_LOOP (li, loop, 0) 1309 FOR_EACH_LOOP (li, loop, 0)
1373 canonicalize_loop_closed_ssa (loop); 1310 canonicalize_loop_closed_ssa (loop);
1374 1311
1375 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); 1312 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
1376 update_ssa (TODO_update_ssa); 1313 update_ssa (TODO_update_ssa);
1377 1314
1378 #ifdef ENABLE_CHECKING 1315 #ifdef ENABLE_CHECKING
1379 verify_loop_closed_ssa (); 1316 verify_loop_closed_ssa (true);
1380 #endif 1317 #endif
1381 } 1318 }
1382 1319
1383 /* Find Static Control Parts (SCoP) in the current function and pushes 1320 /* Find Static Control Parts (SCoP) in the current function and pushes
1384 them to SCOPS. */ 1321 them to SCOPS. */
1389 struct loop *loop = current_loops->tree_root; 1326 struct loop *loop = current_loops->tree_root;
1390 VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3); 1327 VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3);
1391 1328
1392 canonicalize_loop_closed_ssa_form (); 1329 canonicalize_loop_closed_ssa_form ();
1393 build_scops_1 (single_succ (ENTRY_BLOCK_PTR), ENTRY_BLOCK_PTR->loop_father, 1330 build_scops_1 (single_succ (ENTRY_BLOCK_PTR), ENTRY_BLOCK_PTR->loop_father,
1394 &regions, loop); 1331 &regions, loop);
1395 create_sese_edges (regions); 1332 create_sese_edges (regions);
1396 build_graphite_scops (regions, scops); 1333 build_graphite_scops (regions, scops);
1397 1334
1398 if (dump_file && (dump_flags & TDF_DETAILS)) 1335 if (dump_file && (dump_flags & TDF_DETAILS))
1399 print_graphite_statistics (dump_file, *scops); 1336 print_graphite_statistics (dump_file, *scops);
1564 gcc_assert (stream); 1501 gcc_assert (stream);
1565 1502
1566 dot_all_scops_1 (stream, scops); 1503 dot_all_scops_1 (stream, scops);
1567 fclose (stream); 1504 fclose (stream);
1568 1505
1569 x = system ("dotty /tmp/allscops.dot"); 1506 x = system ("dotty /tmp/allscops.dot &");
1570 #else 1507 #else
1571 dot_all_scops_1 (stderr, scops); 1508 dot_all_scops_1 (stderr, scops);
1572 #endif 1509 #endif
1573 } 1510 }
1574 1511
1590 FILE *stream = fopen ("/tmp/allscops.dot", "w"); 1527 FILE *stream = fopen ("/tmp/allscops.dot", "w");
1591 gcc_assert (stream); 1528 gcc_assert (stream);
1592 1529
1593 dot_all_scops_1 (stream, scops); 1530 dot_all_scops_1 (stream, scops);
1594 fclose (stream); 1531 fclose (stream);
1595 x = system ("dotty /tmp/allscops.dot"); 1532 x = system ("dotty /tmp/allscops.dot &");
1596 } 1533 }
1597 #else 1534 #else
1598 dot_all_scops_1 (stderr, scops); 1535 dot_all_scops_1 (stderr, scops);
1599 #endif 1536 #endif
1600 1537