graphite-sese-to-poly.c (partition_drs_to_sets): Drs is not modified, so don't pass...
[gcc.git] / gcc / graphite-sese-to-poly.c
1 /* Conversion of SESE regions to Polyhedra.
2 Copyright (C) 2009 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <sebastian.pop@amd.com>.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "ggc.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "basic-block.h"
29 #include "diagnostic.h"
30 #include "tree-flow.h"
31 #include "toplev.h"
32 #include "tree-dump.h"
33 #include "timevar.h"
34 #include "cfgloop.h"
35 #include "tree-chrec.h"
36 #include "tree-data-ref.h"
37 #include "tree-scalar-evolution.h"
38 #include "tree-pass.h"
39 #include "domwalk.h"
40 #include "value-prof.h"
41 #include "pointer-set.h"
42 #include "gimple.h"
43 #include "sese.h"
44
45 #ifdef HAVE_cloog
46 #include "cloog/cloog.h"
47 #include "ppl_c.h"
48 #include "graphite-ppl.h"
49 #include "graphite.h"
50 #include "graphite-poly.h"
51 #include "graphite-scop-detection.h"
52 #include "graphite-clast-to-gimple.h"
53 #include "graphite-sese-to-poly.h"
54
55 /* Check if VAR is used in a phi node, that is no loop header. */
56
57 static bool
58 var_used_in_not_loop_header_phi_node (tree var)
59 {
60
61 imm_use_iterator imm_iter;
62 gimple stmt;
63 bool result = false;
64
65 FOR_EACH_IMM_USE_STMT (stmt, imm_iter, var)
66 {
67 basic_block bb = gimple_bb (stmt);
68
69 if (gimple_code (stmt) == GIMPLE_PHI
70 && bb->loop_father->header != bb)
71 result = true;
72 }
73
74 return result;
75 }
76
77 /* Returns the index of the phi argument corresponding to the initial
78 value in the loop. */
79
80 static size_t
81 loop_entry_phi_arg (gimple phi)
82 {
83 loop_p loop = gimple_bb (phi)->loop_father;
84 size_t i;
85
86 for (i = 0; i < gimple_phi_num_args (phi); i++)
87 if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
88 return i;
89
90 gcc_unreachable ();
91 return 0;
92 }
93
94 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
95 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
96
97 static void
98 remove_simple_copy_phi (gimple_stmt_iterator *psi)
99 {
100 gimple phi = gsi_stmt (*psi);
101 tree res = gimple_phi_result (phi);
102 size_t entry = loop_entry_phi_arg (phi);
103 tree init = gimple_phi_arg_def (phi, entry);
104 gimple stmt = gimple_build_assign (res, init);
105 edge e = gimple_phi_arg_edge (phi, entry);
106
107 remove_phi_node (psi, false);
108 gsi_insert_on_edge_immediate (e, stmt);
109 SSA_NAME_DEF_STMT (res) = stmt;
110 }
111
112 /* Removes an invariant phi node at position PSI by inserting on the
113 loop ENTRY edge the assignment RES = INIT. */
114
115 static void
116 remove_invariant_phi (sese region, gimple_stmt_iterator *psi)
117 {
118 gimple phi = gsi_stmt (*psi);
119 loop_p loop = loop_containing_stmt (phi);
120 tree res = gimple_phi_result (phi);
121 tree scev = scalar_evolution_in_region (region, loop, res);
122 size_t entry = loop_entry_phi_arg (phi);
123 edge e = gimple_phi_arg_edge (phi, entry);
124 tree var;
125 gimple stmt;
126 gimple_seq stmts;
127 gimple_stmt_iterator gsi;
128
129 if (tree_contains_chrecs (scev, NULL))
130 scev = gimple_phi_arg_def (phi, entry);
131
132 var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
133 stmt = gimple_build_assign (res, var);
134 remove_phi_node (psi, false);
135
136 if (!stmts)
137 stmts = gimple_seq_alloc ();
138
139 gsi = gsi_last (stmts);
140 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
141 gsi_insert_seq_on_edge (e, stmts);
142 gsi_commit_edge_inserts ();
143 SSA_NAME_DEF_STMT (res) = stmt;
144 }
145
146 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
147
148 static inline bool
149 simple_copy_phi_p (gimple phi)
150 {
151 tree res;
152
153 if (gimple_phi_num_args (phi) != 2)
154 return false;
155
156 res = gimple_phi_result (phi);
157 return (res == gimple_phi_arg_def (phi, 0)
158 || res == gimple_phi_arg_def (phi, 1));
159 }
160
161 /* Returns true when the phi node at position PSI is a reduction phi
162 node in REGION. Otherwise moves the pointer PSI to the next phi to
163 be considered. */
164
165 static bool
166 reduction_phi_p (sese region, gimple_stmt_iterator *psi)
167 {
168 loop_p loop;
169 tree scev;
170 affine_iv iv;
171 gimple phi = gsi_stmt (*psi);
172 tree res = gimple_phi_result (phi);
173
174 if (!is_gimple_reg (res))
175 {
176 gsi_next (psi);
177 return false;
178 }
179
180 loop = loop_containing_stmt (phi);
181
182 if (simple_copy_phi_p (phi))
183 {
184 /* FIXME: PRE introduces phi nodes like these, for an example,
185 see id-5.f in the fortran graphite testsuite:
186
187 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
188 */
189 remove_simple_copy_phi (psi);
190 return false;
191 }
192
193 /* Main induction variables with constant strides in LOOP are not
194 reductions. */
195 if (simple_iv (loop, loop, res, &iv, true))
196 {
197 gsi_next (psi);
198 return false;
199 }
200
201 scev = scalar_evolution_in_region (region, loop, res);
202 if (chrec_contains_undetermined (scev))
203 return true;
204
205 if (evolution_function_is_invariant_p (scev, loop->num))
206 {
207 remove_invariant_phi (region, psi);
208 return false;
209 }
210
211 /* All the other cases are considered reductions. */
212 return true;
213 }
214
215 /* Returns true when BB will be represented in graphite. Return false
216 for the basic blocks that contain code eliminated in the code
217 generation pass: i.e. induction variables and exit conditions. */
218
219 static bool
220 graphite_stmt_p (sese region, basic_block bb,
221 VEC (data_reference_p, heap) *drs)
222 {
223 gimple_stmt_iterator gsi;
224 loop_p loop = bb->loop_father;
225
226 if (VEC_length (data_reference_p, drs) > 0)
227 return true;
228
229 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
230 {
231 gimple stmt = gsi_stmt (gsi);
232
233 switch (gimple_code (stmt))
234 {
235 case GIMPLE_DEBUG:
236 /* Control flow expressions can be ignored, as they are
237 represented in the iteration domains and will be
238 regenerated by graphite. */
239 case GIMPLE_COND:
240 case GIMPLE_GOTO:
241 case GIMPLE_SWITCH:
242 break;
243
244 case GIMPLE_ASSIGN:
245 {
246 tree var = gimple_assign_lhs (stmt);
247
248 /* We need these bbs to be able to construct the phi nodes. */
249 if (var_used_in_not_loop_header_phi_node (var))
250 return true;
251
252 var = scalar_evolution_in_region (region, loop, var);
253 if (chrec_contains_undetermined (var))
254 return true;
255
256 break;
257 }
258
259 default:
260 return true;
261 }
262 }
263
264 return false;
265 }
266
267 /* Store the GRAPHITE representation of BB. */
268
269 static gimple_bb_p
270 new_gimple_bb (basic_block bb, VEC (data_reference_p, heap) *drs)
271 {
272 struct gimple_bb *gbb;
273
274 gbb = XNEW (struct gimple_bb);
275 bb->aux = gbb;
276 GBB_BB (gbb) = bb;
277 GBB_DATA_REFS (gbb) = drs;
278 GBB_CONDITIONS (gbb) = NULL;
279 GBB_CONDITION_CASES (gbb) = NULL;
280 GBB_CLOOG_IV_TYPES (gbb) = NULL;
281
282 return gbb;
283 }
284
285 static void
286 free_data_refs_aux (VEC (data_reference_p, heap) *datarefs)
287 {
288 unsigned int i;
289 struct data_reference *dr;
290
291 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
292 if (!dr->aux)
293 {
294 free (dr->aux);
295 dr->aux = NULL;
296 }
297 }
298
299 /* Frees GBB. */
300
301 static void
302 free_gimple_bb (struct gimple_bb *gbb)
303 {
304 if (GBB_CLOOG_IV_TYPES (gbb))
305 htab_delete (GBB_CLOOG_IV_TYPES (gbb));
306
307 free_data_refs_aux (GBB_DATA_REFS (gbb));
308 free_data_refs (GBB_DATA_REFS (gbb));
309
310 VEC_free (gimple, heap, GBB_CONDITIONS (gbb));
311 VEC_free (gimple, heap, GBB_CONDITION_CASES (gbb));
312 GBB_BB (gbb)->aux = 0;
313 XDELETE (gbb);
314 }
315
316 /* Deletes all gimple bbs in SCOP. */
317
318 static void
319 remove_gbbs_in_scop (scop_p scop)
320 {
321 int i;
322 poly_bb_p pbb;
323
324 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
325 free_gimple_bb (PBB_BLACK_BOX (pbb));
326 }
327
328 /* Deletes all scops in SCOPS. */
329
330 void
331 free_scops (VEC (scop_p, heap) *scops)
332 {
333 int i;
334 scop_p scop;
335
336 for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++)
337 {
338 remove_gbbs_in_scop (scop);
339 free_sese (SCOP_REGION (scop));
340 free_scop (scop);
341 }
342
343 VEC_free (scop_p, heap, scops);
344 }
345
346 /* Generates a polyhedral black box only if the bb contains interesting
347 information. */
348
349 static void
350 try_generate_gimple_bb (scop_p scop, basic_block bb)
351 {
352 VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
353 loop_p nest = outermost_loop_in_sese (SCOP_REGION (scop), bb);
354 gimple_stmt_iterator gsi;
355
356 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
357 {
358 gimple stmt = gsi_stmt (gsi);
359 if (!is_gimple_debug (stmt))
360 graphite_find_data_references_in_stmt (nest, stmt, &drs);
361 }
362
363 if (!graphite_stmt_p (SCOP_REGION (scop), bb, drs))
364 free_data_refs (drs);
365 else
366 new_poly_bb (scop, new_gimple_bb (bb, drs));
367 }
368
369 /* Returns true if all predecessors of BB, that are not dominated by BB, are
370 marked in MAP. The predecessors dominated by BB are loop latches and will
371 be handled after BB. */
372
373 static bool
374 all_non_dominated_preds_marked_p (basic_block bb, sbitmap map)
375 {
376 edge e;
377 edge_iterator ei;
378
379 FOR_EACH_EDGE (e, ei, bb->preds)
380 if (!TEST_BIT (map, e->src->index)
381 && !dominated_by_p (CDI_DOMINATORS, e->src, bb))
382 return false;
383
384 return true;
385 }
386
387 /* Compare the depth of two basic_block's P1 and P2. */
388
389 static int
390 compare_bb_depths (const void *p1, const void *p2)
391 {
392 const_basic_block const bb1 = *(const_basic_block const*)p1;
393 const_basic_block const bb2 = *(const_basic_block const*)p2;
394 int d1 = loop_depth (bb1->loop_father);
395 int d2 = loop_depth (bb2->loop_father);
396
397 if (d1 < d2)
398 return 1;
399
400 if (d1 > d2)
401 return -1;
402
403 return 0;
404 }
405
406 /* Sort the basic blocks from DOM such that the first are the ones at
407 a deepest loop level. */
408
409 static void
410 graphite_sort_dominated_info (VEC (basic_block, heap) *dom)
411 {
412 size_t len = VEC_length (basic_block, dom);
413
414 qsort (VEC_address (basic_block, dom), len, sizeof (basic_block),
415 compare_bb_depths);
416 }
417
418 /* Recursive helper function for build_scops_bbs. */
419
420 static void
421 build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
422 {
423 sese region = SCOP_REGION (scop);
424 VEC (basic_block, heap) *dom;
425
426 if (TEST_BIT (visited, bb->index)
427 || !bb_in_sese_p (bb, region))
428 return;
429
430 try_generate_gimple_bb (scop, bb);
431 SET_BIT (visited, bb->index);
432
433 dom = get_dominated_by (CDI_DOMINATORS, bb);
434
435 if (dom == NULL)
436 return;
437
438 graphite_sort_dominated_info (dom);
439
440 while (!VEC_empty (basic_block, dom))
441 {
442 int i;
443 basic_block dom_bb;
444
445 for (i = 0; VEC_iterate (basic_block, dom, i, dom_bb); i++)
446 if (all_non_dominated_preds_marked_p (dom_bb, visited))
447 {
448 build_scop_bbs_1 (scop, visited, dom_bb);
449 VEC_unordered_remove (basic_block, dom, i);
450 break;
451 }
452 }
453
454 VEC_free (basic_block, heap, dom);
455 }
456
457 /* Gather the basic blocks belonging to the SCOP. */
458
459 void
460 build_scop_bbs (scop_p scop)
461 {
462 sbitmap visited = sbitmap_alloc (last_basic_block);
463 sese region = SCOP_REGION (scop);
464
465 sbitmap_zero (visited);
466 build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region));
467
468 sbitmap_free (visited);
469 }
470
471 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
472 We generate SCATTERING_DIMENSIONS scattering dimensions.
473
474 CLooG 0.15.0 and previous versions require, that all
475 scattering functions of one CloogProgram have the same number of
476 scattering dimensions, therefore we allow to specify it. This
477 should be removed in future versions of CLooG.
478
479 The scattering polyhedron consists of these dimensions: scattering,
480 loop_iterators, parameters.
481
482 Example:
483
484 | scattering_dimensions = 5
485 | used_scattering_dimensions = 3
486 | nb_iterators = 1
487 | scop_nb_params = 2
488 |
489 | Schedule:
490 | i
491 | 4 5
492 |
493 | Scattering polyhedron:
494 |
495 | scattering: {s1, s2, s3, s4, s5}
496 | loop_iterators: {i}
497 | parameters: {p1, p2}
498 |
499 | s1 s2 s3 s4 s5 i p1 p2 1
500 | 1 0 0 0 0 0 0 0 -4 = 0
501 | 0 1 0 0 0 -1 0 0 0 = 0
502 | 0 0 1 0 0 0 0 0 -5 = 0 */
503
504 static void
505 build_pbb_scattering_polyhedrons (ppl_Linear_Expression_t static_schedule,
506 poly_bb_p pbb, int scattering_dimensions)
507 {
508 int i;
509 scop_p scop = PBB_SCOP (pbb);
510 int nb_iterators = pbb_dim_iter_domain (pbb);
511 int used_scattering_dimensions = nb_iterators * 2 + 1;
512 int nb_params = scop_nb_params (scop);
513 ppl_Coefficient_t c;
514 ppl_dimension_type dim = scattering_dimensions + nb_iterators + nb_params;
515 Value v;
516
517 gcc_assert (scattering_dimensions >= used_scattering_dimensions);
518
519 value_init (v);
520 ppl_new_Coefficient (&c);
521 PBB_TRANSFORMED (pbb) = poly_scattering_new ();
522 ppl_new_C_Polyhedron_from_space_dimension
523 (&PBB_TRANSFORMED_SCATTERING (pbb), dim, 0);
524
525 PBB_NB_SCATTERING_TRANSFORM (pbb) = scattering_dimensions;
526
527 for (i = 0; i < scattering_dimensions; i++)
528 {
529 ppl_Constraint_t cstr;
530 ppl_Linear_Expression_t expr;
531
532 ppl_new_Linear_Expression_with_dimension (&expr, dim);
533 value_set_si (v, 1);
534 ppl_assign_Coefficient_from_mpz_t (c, v);
535 ppl_Linear_Expression_add_to_coefficient (expr, i, c);
536
537 /* Textual order inside this loop. */
538 if ((i % 2) == 0)
539 {
540 ppl_Linear_Expression_coefficient (static_schedule, i / 2, c);
541 ppl_Coefficient_to_mpz_t (c, v);
542 value_oppose (v, v);
543 ppl_assign_Coefficient_from_mpz_t (c, v);
544 ppl_Linear_Expression_add_to_inhomogeneous (expr, c);
545 }
546
547 /* Iterations of this loop. */
548 else /* if ((i % 2) == 1) */
549 {
550 int loop = (i - 1) / 2;
551
552 value_set_si (v, -1);
553 ppl_assign_Coefficient_from_mpz_t (c, v);
554 ppl_Linear_Expression_add_to_coefficient
555 (expr, scattering_dimensions + loop, c);
556 }
557
558 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL);
559 ppl_Polyhedron_add_constraint (PBB_TRANSFORMED_SCATTERING (pbb), cstr);
560 ppl_delete_Linear_Expression (expr);
561 ppl_delete_Constraint (cstr);
562 }
563
564 value_clear (v);
565 ppl_delete_Coefficient (c);
566
567 PBB_ORIGINAL (pbb) = poly_scattering_copy (PBB_TRANSFORMED (pbb));
568 }
569
570 /* Build for BB the static schedule.
571
572 The static schedule is a Dewey numbering of the abstract syntax
573 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
574
575 The following example informally defines the static schedule:
576
577 A
578 for (i: ...)
579 {
580 for (j: ...)
581 {
582 B
583 C
584 }
585
586 for (k: ...)
587 {
588 D
589 E
590 }
591 }
592 F
593
594 Static schedules for A to F:
595
596 DEPTH
597 0 1 2
598 A 0
599 B 1 0 0
600 C 1 0 1
601 D 1 1 0
602 E 1 1 1
603 F 2
604 */
605
606 static void
607 build_scop_scattering (scop_p scop)
608 {
609 int i;
610 poly_bb_p pbb;
611 gimple_bb_p previous_gbb = NULL;
612 ppl_Linear_Expression_t static_schedule;
613 ppl_Coefficient_t c;
614 Value v;
615
616 value_init (v);
617 ppl_new_Coefficient (&c);
618 ppl_new_Linear_Expression (&static_schedule);
619
620 /* We have to start schedules at 0 on the first component and
621 because we cannot compare_prefix_loops against a previous loop,
622 prefix will be equal to zero, and that index will be
623 incremented before copying. */
624 value_set_si (v, -1);
625 ppl_assign_Coefficient_from_mpz_t (c, v);
626 ppl_Linear_Expression_add_to_coefficient (static_schedule, 0, c);
627
628 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
629 {
630 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
631 ppl_Linear_Expression_t common;
632 int prefix;
633 int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1;
634
635 if (previous_gbb)
636 prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
637 else
638 prefix = 0;
639
640 previous_gbb = gbb;
641 ppl_new_Linear_Expression_with_dimension (&common, prefix + 1);
642 ppl_assign_Linear_Expression_from_Linear_Expression (common,
643 static_schedule);
644
645 value_set_si (v, 1);
646 ppl_assign_Coefficient_from_mpz_t (c, v);
647 ppl_Linear_Expression_add_to_coefficient (common, prefix, c);
648 ppl_assign_Linear_Expression_from_Linear_Expression (static_schedule,
649 common);
650
651 build_pbb_scattering_polyhedrons (common, pbb, nb_scat_dims);
652
653 ppl_delete_Linear_Expression (common);
654 }
655
656 value_clear (v);
657 ppl_delete_Coefficient (c);
658 ppl_delete_Linear_Expression (static_schedule);
659 }
660
661 /* Add the value K to the dimension D of the linear expression EXPR. */
662
663 static void
664 add_value_to_dim (ppl_dimension_type d, ppl_Linear_Expression_t expr,
665 Value k)
666 {
667 Value val;
668 ppl_Coefficient_t coef;
669
670 ppl_new_Coefficient (&coef);
671 ppl_Linear_Expression_coefficient (expr, d, coef);
672 value_init (val);
673 ppl_Coefficient_to_mpz_t (coef, val);
674
675 value_addto (val, val, k);
676
677 ppl_assign_Coefficient_from_mpz_t (coef, val);
678 ppl_Linear_Expression_add_to_coefficient (expr, d, coef);
679 value_clear (val);
680 ppl_delete_Coefficient (coef);
681 }
682
683 /* In the context of scop S, scan E, the right hand side of a scalar
684 evolution function in loop VAR, and translate it to a linear
685 expression EXPR. */
686
687 static void
688 scan_tree_for_params_right_scev (sese s, tree e, int var,
689 ppl_Linear_Expression_t expr)
690 {
691 if (expr)
692 {
693 loop_p loop = get_loop (var);
694 ppl_dimension_type l = sese_loop_depth (s, loop) - 1;
695 Value val;
696
697 /* Scalar evolutions should happen in the sese region. */
698 gcc_assert (sese_loop_depth (s, loop) > 0);
699
700 /* We can not deal with parametric strides like:
701
702 | p = parameter;
703 |
704 | for i:
705 | a [i * p] = ... */
706 gcc_assert (TREE_CODE (e) == INTEGER_CST);
707
708 value_init (val);
709 value_set_si (val, int_cst_value (e));
710 add_value_to_dim (l, expr, val);
711 value_clear (val);
712 }
713 }
714
715 /* Scan the integer constant CST, and add it to the inhomogeneous part of the
716 linear expression EXPR. K is the multiplier of the constant. */
717
718 static void
719 scan_tree_for_params_int (tree cst, ppl_Linear_Expression_t expr, Value k)
720 {
721 Value val;
722 ppl_Coefficient_t coef;
723 int v = int_cst_value (cst);
724
725 value_init (val);
726 value_set_si (val, 0);
727
728 /* Necessary to not get "-1 = 2^n - 1". */
729 if (v < 0)
730 value_sub_int (val, val, -v);
731 else
732 value_add_int (val, val, v);
733
734 value_multiply (val, val, k);
735 ppl_new_Coefficient (&coef);
736 ppl_assign_Coefficient_from_mpz_t (coef, val);
737 ppl_Linear_Expression_add_to_inhomogeneous (expr, coef);
738 value_clear (val);
739 ppl_delete_Coefficient (coef);
740 }
741
742 /* Saves in NV at index I a new name for variable P. */
743
744 static void
745 save_var_name (char **nv, int i, tree p)
746 {
747 const char *name = get_name (SSA_NAME_VAR (p));
748
749 if (name)
750 {
751 int len = strlen (name) + 16;
752 nv[i] = XNEWVEC (char, len);
753 snprintf (nv[i], len, "%s_%d", name, SSA_NAME_VERSION (p));
754 }
755 else
756 {
757 nv[i] = XNEWVEC (char, 16);
758 snprintf (nv[i], 2 + 16, "T_%d", SSA_NAME_VERSION (p));
759 }
760 }
761
762 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
763 Otherwise returns -1. */
764
765 static inline int
766 parameter_index_in_region_1 (tree name, sese region)
767 {
768 int i;
769 tree p;
770
771 gcc_assert (TREE_CODE (name) == SSA_NAME);
772
773 for (i = 0; VEC_iterate (tree, SESE_PARAMS (region), i, p); i++)
774 if (p == name)
775 return i;
776
777 return -1;
778 }
779
780 /* When the parameter NAME is in REGION, returns its index in
781 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
782 and returns the index of NAME. */
783
784 static int
785 parameter_index_in_region (tree name, sese region)
786 {
787 int i;
788
789 gcc_assert (TREE_CODE (name) == SSA_NAME);
790
791 i = parameter_index_in_region_1 (name, region);
792 if (i != -1)
793 return i;
794
795 gcc_assert (SESE_ADD_PARAMS (region));
796
797 i = VEC_length (tree, SESE_PARAMS (region));
798 save_var_name (SESE_PARAMS_NAMES (region), i, name);
799 save_clast_name_index (SESE_PARAMS_INDEX (region),
800 SESE_PARAMS_NAMES (region)[i], i);
801 VEC_safe_push (tree, heap, SESE_PARAMS (region), name);
802 return i;
803 }
804
805 /* In the context of sese S, scan the expression E and translate it to
806 a linear expression C. When parsing a symbolic multiplication, K
807 represents the constant multiplier of an expression containing
808 parameters. */
809
810 static void
811 scan_tree_for_params (sese s, tree e, ppl_Linear_Expression_t c,
812 Value k)
813 {
814 if (e == chrec_dont_know)
815 return;
816
817 switch (TREE_CODE (e))
818 {
819 case POLYNOMIAL_CHREC:
820 scan_tree_for_params_right_scev (s, CHREC_RIGHT (e),
821 CHREC_VARIABLE (e), c);
822 scan_tree_for_params (s, CHREC_LEFT (e), c, k);
823 break;
824
825 case MULT_EXPR:
826 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
827 {
828 if (c)
829 {
830 Value val;
831 gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0));
832 value_init (val);
833 value_set_si (val, int_cst_value (TREE_OPERAND (e, 1)));
834 value_multiply (val, val, k);
835 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, val);
836 value_clear (val);
837 }
838 else
839 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
840 }
841 else
842 {
843 if (c)
844 {
845 Value val;
846 gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0));
847 value_init (val);
848 value_set_si (val, int_cst_value (TREE_OPERAND (e, 0)));
849 value_multiply (val, val, k);
850 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, val);
851 value_clear (val);
852 }
853 else
854 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k);
855 }
856 break;
857
858 case PLUS_EXPR:
859 case POINTER_PLUS_EXPR:
860 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
861 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k);
862 break;
863
864 case MINUS_EXPR:
865 {
866 ppl_Linear_Expression_t tmp_expr = NULL;
867
868 if (c)
869 {
870 ppl_dimension_type dim;
871 ppl_Linear_Expression_space_dimension (c, &dim);
872 ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
873 }
874
875 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
876 scan_tree_for_params (s, TREE_OPERAND (e, 1), tmp_expr, k);
877
878 if (c)
879 {
880 ppl_subtract_Linear_Expression_from_Linear_Expression (c,
881 tmp_expr);
882 ppl_delete_Linear_Expression (tmp_expr);
883 }
884
885 break;
886 }
887
888 case NEGATE_EXPR:
889 {
890 ppl_Linear_Expression_t tmp_expr = NULL;
891
892 if (c)
893 {
894 ppl_dimension_type dim;
895 ppl_Linear_Expression_space_dimension (c, &dim);
896 ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
897 }
898
899 scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k);
900
901 if (c)
902 {
903 ppl_subtract_Linear_Expression_from_Linear_Expression (c,
904 tmp_expr);
905 ppl_delete_Linear_Expression (tmp_expr);
906 }
907
908 break;
909 }
910
911 case BIT_NOT_EXPR:
912 {
913 ppl_Linear_Expression_t tmp_expr = NULL;
914
915 if (c)
916 {
917 ppl_dimension_type dim;
918 ppl_Linear_Expression_space_dimension (c, &dim);
919 ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
920 }
921
922 scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k);
923
924 if (c)
925 {
926 ppl_Coefficient_t coef;
927 Value minus_one;
928
929 ppl_subtract_Linear_Expression_from_Linear_Expression (c,
930 tmp_expr);
931 ppl_delete_Linear_Expression (tmp_expr);
932 value_init (minus_one);
933 value_set_si (minus_one, -1);
934 ppl_new_Coefficient_from_mpz_t (&coef, minus_one);
935 ppl_Linear_Expression_add_to_inhomogeneous (c, coef);
936 value_clear (minus_one);
937 ppl_delete_Coefficient (coef);
938 }
939
940 break;
941 }
942
943 case SSA_NAME:
944 {
945 ppl_dimension_type p = parameter_index_in_region (e, s);
946
947 if (c)
948 {
949 ppl_dimension_type dim;
950 ppl_Linear_Expression_space_dimension (c, &dim);
951 p += dim - sese_nb_params (s);
952 add_value_to_dim (p, c, k);
953 }
954 break;
955 }
956
957 case INTEGER_CST:
958 if (c)
959 scan_tree_for_params_int (e, c, k);
960 break;
961
962 CASE_CONVERT:
963 case NON_LVALUE_EXPR:
964 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
965 break;
966
967 default:
968 gcc_unreachable ();
969 break;
970 }
971 }
972
973 /* Find parameters with respect to REGION in BB. We are looking in memory
974 access functions, conditions and loop bounds. */
975
976 static void
977 find_params_in_bb (sese region, gimple_bb_p gbb)
978 {
979 int i;
980 unsigned j;
981 data_reference_p dr;
982 gimple stmt;
983 loop_p loop = GBB_BB (gbb)->loop_father;
984 Value one;
985
986 value_init (one);
987 value_set_si (one, 1);
988
989 /* Find parameters in the access functions of data references. */
990 for (i = 0; VEC_iterate (data_reference_p, GBB_DATA_REFS (gbb), i, dr); i++)
991 for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
992 scan_tree_for_params (region, DR_ACCESS_FN (dr, j), NULL, one);
993
994 /* Find parameters in conditional statements. */
995 for (i = 0; VEC_iterate (gimple, GBB_CONDITIONS (gbb), i, stmt); i++)
996 {
997 tree lhs = scalar_evolution_in_region (region, loop,
998 gimple_cond_lhs (stmt));
999 tree rhs = scalar_evolution_in_region (region, loop,
1000 gimple_cond_rhs (stmt));
1001
1002 scan_tree_for_params (region, lhs, NULL, one);
1003 scan_tree_for_params (region, rhs, NULL, one);
1004 }
1005
1006 value_clear (one);
1007 }
1008
1009 /* Record the parameters used in the SCOP. A variable is a parameter
1010 in a scop if it does not vary during the execution of that scop. */
1011
1012 static void
1013 find_scop_parameters (scop_p scop)
1014 {
1015 poly_bb_p pbb;
1016 unsigned i;
1017 sese region = SCOP_REGION (scop);
1018 struct loop *loop;
1019 Value one;
1020
1021 value_init (one);
1022 value_set_si (one, 1);
1023
1024 /* Find the parameters used in the loop bounds. */
1025 for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1026 {
1027 tree nb_iters = number_of_latch_executions (loop);
1028
1029 if (!chrec_contains_symbols (nb_iters))
1030 continue;
1031
1032 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1033 scan_tree_for_params (region, nb_iters, NULL, one);
1034 }
1035
1036 value_clear (one);
1037
1038 /* Find the parameters used in data accesses. */
1039 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1040 find_params_in_bb (region, PBB_BLACK_BOX (pbb));
1041
1042 scop_set_nb_params (scop, sese_nb_params (region));
1043 SESE_ADD_PARAMS (region) = false;
1044 }
1045
1046 /* Returns a gimple_bb from BB. */
1047
1048 static inline gimple_bb_p
1049 gbb_from_bb (basic_block bb)
1050 {
1051 return (gimple_bb_p) bb->aux;
1052 }
1053
1054 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
1055 the constraints for the surrounding loops. */
1056
1057 static void
1058 build_loop_iteration_domains (scop_p scop, struct loop *loop,
1059 ppl_Polyhedron_t outer_ph, int nb)
1060
1061 {
1062 int i;
1063 ppl_Polyhedron_t ph;
1064 tree nb_iters = number_of_latch_executions (loop);
1065 ppl_dimension_type dim = nb + 1 + scop_nb_params (scop);
1066 sese region = SCOP_REGION (scop);
1067
1068 {
1069 ppl_const_Constraint_System_t pcs;
1070 ppl_dimension_type *map
1071 = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim);
1072
1073 ppl_new_C_Polyhedron_from_space_dimension (&ph, dim, 0);
1074 ppl_Polyhedron_get_constraints (outer_ph, &pcs);
1075 ppl_Polyhedron_add_constraints (ph, pcs);
1076
1077 for (i = 0; i < (int) nb; i++)
1078 map[i] = i;
1079 for (i = (int) nb; i < (int) dim - 1; i++)
1080 map[i] = i + 1;
1081 map[dim - 1] = nb;
1082
1083 ppl_Polyhedron_map_space_dimensions (ph, map, dim);
1084 free (map);
1085 }
1086
1087 /* 0 <= loop_i */
1088 {
1089 ppl_Constraint_t lb;
1090 ppl_Linear_Expression_t lb_expr;
1091
1092 ppl_new_Linear_Expression_with_dimension (&lb_expr, dim);
1093 ppl_set_coef (lb_expr, nb, 1);
1094 ppl_new_Constraint (&lb, lb_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1095 ppl_delete_Linear_Expression (lb_expr);
1096 ppl_Polyhedron_add_constraint (ph, lb);
1097 ppl_delete_Constraint (lb);
1098 }
1099
1100 if (TREE_CODE (nb_iters) == INTEGER_CST)
1101 {
1102 ppl_Constraint_t ub;
1103 ppl_Linear_Expression_t ub_expr;
1104
1105 ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1106
1107 /* loop_i <= cst_nb_iters */
1108 ppl_set_coef (ub_expr, nb, -1);
1109 ppl_set_inhomogeneous_tree (ub_expr, nb_iters);
1110 ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1111 ppl_Polyhedron_add_constraint (ph, ub);
1112 ppl_delete_Linear_Expression (ub_expr);
1113 ppl_delete_Constraint (ub);
1114 }
1115 else if (!chrec_contains_undetermined (nb_iters))
1116 {
1117 Value one;
1118 ppl_Constraint_t ub;
1119 ppl_Linear_Expression_t ub_expr;
1120
1121 value_init (one);
1122 value_set_si (one, 1);
1123 ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1124 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1125 scan_tree_for_params (SCOP_REGION (scop), nb_iters, ub_expr, one);
1126 value_clear (one);
1127
1128 /* loop_i <= expr_nb_iters */
1129 ppl_set_coef (ub_expr, nb, -1);
1130 ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1131 ppl_Polyhedron_add_constraint (ph, ub);
1132 ppl_delete_Linear_Expression (ub_expr);
1133 ppl_delete_Constraint (ub);
1134 }
1135 else
1136 gcc_unreachable ();
1137
1138 if (loop->inner && loop_in_sese_p (loop->inner, region))
1139 build_loop_iteration_domains (scop, loop->inner, ph, nb + 1);
1140
1141 if (nb != 0
1142 && loop->next
1143 && loop_in_sese_p (loop->next, region))
1144 build_loop_iteration_domains (scop, loop->next, outer_ph, nb);
1145
1146 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1147 ((ppl_Pointset_Powerset_C_Polyhedron_t *) &loop->aux, ph);
1148
1149 ppl_delete_Polyhedron (ph);
1150 }
1151
1152 /* Returns a linear expression for tree T evaluated in PBB. */
1153
1154 static ppl_Linear_Expression_t
1155 create_linear_expr_from_tree (poly_bb_p pbb, tree t)
1156 {
1157 Value one;
1158 ppl_Linear_Expression_t res;
1159 ppl_dimension_type dim;
1160 sese region = SCOP_REGION (PBB_SCOP (pbb));
1161 loop_p loop = GBB_BB (PBB_BLACK_BOX (pbb))->loop_father;
1162
1163 dim = pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb);
1164 ppl_new_Linear_Expression_with_dimension (&res, dim);
1165
1166 t = scalar_evolution_in_region (region, loop, t);
1167 gcc_assert (!automatically_generated_chrec_p (t));
1168
1169 value_init (one);
1170 value_set_si (one, 1);
1171 scan_tree_for_params (region, t, res, one);
1172 value_clear (one);
1173
1174 return res;
1175 }
1176
1177 /* Returns the ppl constraint type from the gimple tree code CODE. */
1178
1179 static enum ppl_enum_Constraint_Type
1180 ppl_constraint_type_from_tree_code (enum tree_code code)
1181 {
1182 switch (code)
1183 {
1184 /* We do not support LT and GT to be able to work with C_Polyhedron.
1185 As we work on integer polyhedron "a < b" can be expressed by
1186 "a + 1 <= b". */
1187 case LT_EXPR:
1188 case GT_EXPR:
1189 gcc_unreachable ();
1190
1191 case LE_EXPR:
1192 return PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL;
1193
1194 case GE_EXPR:
1195 return PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL;
1196
1197 case EQ_EXPR:
1198 return PPL_CONSTRAINT_TYPE_EQUAL;
1199
1200 default:
1201 gcc_unreachable ();
1202 }
1203 }
1204
1205 /* Add conditional statement STMT to PS. It is evaluated in PBB and
1206 CODE is used as the comparison operator. This allows us to invert the
1207 condition or to handle inequalities. */
1208
1209 static void
1210 add_condition_to_domain (ppl_Pointset_Powerset_C_Polyhedron_t ps, gimple stmt,
1211 poly_bb_p pbb, enum tree_code code)
1212 {
1213 Value v;
1214 ppl_Coefficient_t c;
1215 ppl_Linear_Expression_t left, right;
1216 ppl_Constraint_t cstr;
1217 enum ppl_enum_Constraint_Type type;
1218
1219 left = create_linear_expr_from_tree (pbb, gimple_cond_lhs (stmt));
1220 right = create_linear_expr_from_tree (pbb, gimple_cond_rhs (stmt));
1221
1222 /* If we have < or > expressions convert them to <= or >= by adding 1 to
1223 the left or the right side of the expression. */
1224 if (code == LT_EXPR)
1225 {
1226 value_init (v);
1227 value_set_si (v, 1);
1228 ppl_new_Coefficient (&c);
1229 ppl_assign_Coefficient_from_mpz_t (c, v);
1230 ppl_Linear_Expression_add_to_inhomogeneous (left, c);
1231 ppl_delete_Coefficient (c);
1232 value_clear (v);
1233
1234 code = LE_EXPR;
1235 }
1236 else if (code == GT_EXPR)
1237 {
1238 value_init (v);
1239 value_set_si (v, 1);
1240 ppl_new_Coefficient (&c);
1241 ppl_assign_Coefficient_from_mpz_t (c, v);
1242 ppl_Linear_Expression_add_to_inhomogeneous (right, c);
1243 ppl_delete_Coefficient (c);
1244 value_clear (v);
1245
1246 code = GE_EXPR;
1247 }
1248
1249 type = ppl_constraint_type_from_tree_code (code);
1250
1251 ppl_subtract_Linear_Expression_from_Linear_Expression (left, right);
1252
1253 ppl_new_Constraint (&cstr, left, type);
1254 ppl_Pointset_Powerset_C_Polyhedron_add_constraint (ps, cstr);
1255
1256 ppl_delete_Constraint (cstr);
1257 ppl_delete_Linear_Expression (left);
1258 ppl_delete_Linear_Expression (right);
1259 }
1260
1261 /* Add conditional statement STMT to pbb. CODE is used as the comparision
1262 operator. This allows us to invert the condition or to handle
1263 inequalities. */
1264
1265 static void
1266 add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code)
1267 {
1268 if (code == NE_EXPR)
1269 {
1270 ppl_Pointset_Powerset_C_Polyhedron_t left = PBB_DOMAIN (pbb);
1271 ppl_Pointset_Powerset_C_Polyhedron_t right;
1272 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1273 (&right, left);
1274 add_condition_to_domain (left, stmt, pbb, LT_EXPR);
1275 add_condition_to_domain (right, stmt, pbb, GT_EXPR);
1276 ppl_Pointset_Powerset_C_Polyhedron_upper_bound_assign (left,
1277 right);
1278 ppl_delete_Pointset_Powerset_C_Polyhedron (right);
1279 }
1280 else
1281 add_condition_to_domain (PBB_DOMAIN (pbb), stmt, pbb, code);
1282 }
1283
1284 /* Add conditions to the domain of PBB. */
1285
1286 static void
1287 add_conditions_to_domain (poly_bb_p pbb)
1288 {
1289 unsigned int i;
1290 gimple stmt;
1291 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1292 VEC (gimple, heap) *conditions = GBB_CONDITIONS (gbb);
1293
1294 if (VEC_empty (gimple, conditions))
1295 return;
1296
1297 for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
1298 switch (gimple_code (stmt))
1299 {
1300 case GIMPLE_COND:
1301 {
1302 enum tree_code code = gimple_cond_code (stmt);
1303
1304 /* The conditions for ELSE-branches are inverted. */
1305 if (VEC_index (gimple, gbb->condition_cases, i) == NULL)
1306 code = invert_tree_comparison (code, false);
1307
1308 add_condition_to_pbb (pbb, stmt, code);
1309 break;
1310 }
1311
1312 case GIMPLE_SWITCH:
1313 /* Switch statements are not supported right now - fall throught. */
1314
1315 default:
1316 gcc_unreachable ();
1317 break;
1318 }
1319 }
1320
1321 /* Structure used to pass data to dom_walk. */
1322
1323 struct bsc
1324 {
1325 VEC (gimple, heap) **conditions, **cases;
1326 sese region;
1327 };
1328
1329 /* Returns non NULL when BB has a single predecessor and the last
1330 statement of that predecessor is a COND_EXPR. */
1331
1332 static gimple
1333 single_pred_cond (basic_block bb)
1334 {
1335 if (single_pred_p (bb))
1336 {
1337 edge e = single_pred_edge (bb);
1338 basic_block pred = e->src;
1339 gimple stmt = last_stmt (pred);
1340
1341 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1342 return stmt;
1343 }
1344 return NULL;
1345 }
1346
1347 /* Call-back for dom_walk executed before visiting the dominated
1348 blocks. */
1349
1350 static void
1351 build_sese_conditions_before (struct dom_walk_data *dw_data,
1352 basic_block bb)
1353 {
1354 struct bsc *data = (struct bsc *) dw_data->global_data;
1355 VEC (gimple, heap) **conditions = data->conditions;
1356 VEC (gimple, heap) **cases = data->cases;
1357 gimple_bb_p gbb = gbb_from_bb (bb);
1358 gimple stmt = single_pred_cond (bb);
1359
1360 if (!bb_in_sese_p (bb, data->region))
1361 return;
1362
1363 if (stmt)
1364 {
1365 edge e = single_pred_edge (bb);
1366
1367 VEC_safe_push (gimple, heap, *conditions, stmt);
1368
1369 if (e->flags & EDGE_TRUE_VALUE)
1370 VEC_safe_push (gimple, heap, *cases, stmt);
1371 else
1372 VEC_safe_push (gimple, heap, *cases, NULL);
1373 }
1374
1375 if (gbb)
1376 {
1377 GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
1378 GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
1379 }
1380 }
1381
1382 /* Call-back for dom_walk executed after visiting the dominated
1383 blocks. */
1384
1385 static void
1386 build_sese_conditions_after (struct dom_walk_data *dw_data,
1387 basic_block bb)
1388 {
1389 struct bsc *data = (struct bsc *) dw_data->global_data;
1390 VEC (gimple, heap) **conditions = data->conditions;
1391 VEC (gimple, heap) **cases = data->cases;
1392
1393 if (!bb_in_sese_p (bb, data->region))
1394 return;
1395
1396 if (single_pred_cond (bb))
1397 {
1398 VEC_pop (gimple, *conditions);
1399 VEC_pop (gimple, *cases);
1400 }
1401 }
1402
1403 /* Record all conditions in REGION. */
1404
1405 static void
1406 build_sese_conditions (sese region)
1407 {
1408 struct dom_walk_data walk_data;
1409 VEC (gimple, heap) *conditions = VEC_alloc (gimple, heap, 3);
1410 VEC (gimple, heap) *cases = VEC_alloc (gimple, heap, 3);
1411 struct bsc data;
1412
1413 data.conditions = &conditions;
1414 data.cases = &cases;
1415 data.region = region;
1416
1417 walk_data.dom_direction = CDI_DOMINATORS;
1418 walk_data.initialize_block_local_data = NULL;
1419 walk_data.before_dom_children = build_sese_conditions_before;
1420 walk_data.after_dom_children = build_sese_conditions_after;
1421 walk_data.global_data = &data;
1422 walk_data.block_local_data_size = 0;
1423
1424 init_walk_dominator_tree (&walk_data);
1425 walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region));
1426 fini_walk_dominator_tree (&walk_data);
1427
1428 VEC_free (gimple, heap, conditions);
1429 VEC_free (gimple, heap, cases);
1430 }
1431
1432 /* Traverses all the GBBs of the SCOP and add their constraints to the
1433 iteration domains. */
1434
1435 static void
1436 add_conditions_to_constraints (scop_p scop)
1437 {
1438 int i;
1439 poly_bb_p pbb;
1440
1441 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1442 add_conditions_to_domain (pbb);
1443 }
1444
1445 /* Add constraints on the possible values of parameter P from the type
1446 of P. */
1447
1448 static void
1449 add_param_constraints (scop_p scop, ppl_Polyhedron_t context, graphite_dim_t p)
1450 {
1451 ppl_Constraint_t cstr;
1452 ppl_Linear_Expression_t le;
1453 tree parameter = VEC_index (tree, SESE_PARAMS (SCOP_REGION (scop)), p);
1454 tree type = TREE_TYPE (parameter);
1455 tree lb, ub;
1456
1457 /* Disabled until we fix CPU2006. */
1458 return;
1459
1460 if (!INTEGRAL_TYPE_P (type))
1461 return;
1462
1463 lb = TYPE_MIN_VALUE (type);
1464 ub = TYPE_MAX_VALUE (type);
1465
1466 if (lb)
1467 {
1468 ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1469 ppl_set_coef (le, p, -1);
1470 ppl_set_inhomogeneous_tree (le, lb);
1471 ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL);
1472 ppl_Polyhedron_add_constraint (context, cstr);
1473 ppl_delete_Linear_Expression (le);
1474 ppl_delete_Constraint (cstr);
1475 }
1476
1477 if (ub)
1478 {
1479 ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1480 ppl_set_coef (le, p, -1);
1481 ppl_set_inhomogeneous_tree (le, ub);
1482 ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1483 ppl_Polyhedron_add_constraint (context, cstr);
1484 ppl_delete_Linear_Expression (le);
1485 ppl_delete_Constraint (cstr);
1486 }
1487 }
1488
1489 /* Build the context of the SCOP. The context usually contains extra
1490 constraints that are added to the iteration domains that constrain
1491 some parameters. */
1492
1493 static void
1494 build_scop_context (scop_p scop)
1495 {
1496 ppl_Polyhedron_t context;
1497 graphite_dim_t p, n = scop_nb_params (scop);
1498
1499 ppl_new_C_Polyhedron_from_space_dimension (&context, n, 0);
1500
1501 for (p = 0; p < n; p++)
1502 add_param_constraints (scop, context, p);
1503
1504 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1505 (&SCOP_CONTEXT (scop), context);
1506
1507 ppl_delete_Polyhedron (context);
1508 }
1509
1510 /* Build the iteration domains: the loops belonging to the current
1511 SCOP, and that vary for the execution of the current basic block.
1512 Returns false if there is no loop in SCOP. */
1513
1514 static void
1515 build_scop_iteration_domain (scop_p scop)
1516 {
1517 struct loop *loop;
1518 sese region = SCOP_REGION (scop);
1519 int i;
1520 ppl_Polyhedron_t ph;
1521 poly_bb_p pbb;
1522
1523 ppl_new_C_Polyhedron_from_space_dimension (&ph, scop_nb_params (scop), 0);
1524
1525 for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1526 if (!loop_in_sese_p (loop_outer (loop), region))
1527 build_loop_iteration_domains (scop, loop, ph, 0);
1528
1529 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1530 if (gbb_loop (PBB_BLACK_BOX (pbb))->aux)
1531 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1532 (&PBB_DOMAIN (pbb), (ppl_const_Pointset_Powerset_C_Polyhedron_t)
1533 gbb_loop (PBB_BLACK_BOX (pbb))->aux);
1534 else
1535 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1536 (&PBB_DOMAIN (pbb), ph);
1537
1538 for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1539 if (loop->aux)
1540 {
1541 ppl_delete_Pointset_Powerset_C_Polyhedron
1542 ((ppl_Pointset_Powerset_C_Polyhedron_t) loop->aux);
1543 loop->aux = NULL;
1544 }
1545
1546 ppl_delete_Polyhedron (ph);
1547 }
1548
1549 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1550 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1551 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1552 domain. */
1553
1554 static void
1555 pdr_add_alias_set (ppl_Polyhedron_t accesses, data_reference_p dr,
1556 ppl_dimension_type accessp_nb_dims,
1557 ppl_dimension_type dom_nb_dims)
1558 {
1559 ppl_Linear_Expression_t alias;
1560 ppl_Constraint_t cstr;
1561 int alias_set_num = 0;
1562
1563 if (dr->aux != NULL)
1564 alias_set_num = ((int *)(dr->aux))[ALIAS_SET_INDEX];
1565
1566 ppl_new_Linear_Expression_with_dimension (&alias, accessp_nb_dims);
1567
1568 ppl_set_coef (alias, dom_nb_dims, 1);
1569 ppl_set_inhomogeneous (alias, -alias_set_num);
1570 ppl_new_Constraint (&cstr, alias, PPL_CONSTRAINT_TYPE_EQUAL);
1571 ppl_Polyhedron_add_constraint (accesses, cstr);
1572
1573 ppl_delete_Linear_Expression (alias);
1574 ppl_delete_Constraint (cstr);
1575 }
1576
1577 /* Add to ACCESSES polyhedron equalities defining the access functions
1578 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1579 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1580 PBB is the poly_bb_p that contains the data reference DR. */
1581
1582 static void
1583 pdr_add_memory_accesses (ppl_Polyhedron_t accesses, data_reference_p dr,
1584 ppl_dimension_type accessp_nb_dims,
1585 ppl_dimension_type dom_nb_dims,
1586 poly_bb_p pbb)
1587 {
1588 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1589 Value v;
1590 scop_p scop = PBB_SCOP (pbb);
1591 sese region = SCOP_REGION (scop);
1592
1593 value_init (v);
1594
1595 for (i = 0; i < nb_subscripts; i++)
1596 {
1597 ppl_Linear_Expression_t fn, access;
1598 ppl_Constraint_t cstr;
1599 ppl_dimension_type subscript = dom_nb_dims + 1 + i;
1600 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1601
1602 ppl_new_Linear_Expression_with_dimension (&fn, dom_nb_dims);
1603 ppl_new_Linear_Expression_with_dimension (&access, accessp_nb_dims);
1604
1605 value_set_si (v, 1);
1606 scan_tree_for_params (region, afn, fn, v);
1607 ppl_assign_Linear_Expression_from_Linear_Expression (access, fn);
1608
1609 ppl_set_coef (access, subscript, -1);
1610 ppl_new_Constraint (&cstr, access, PPL_CONSTRAINT_TYPE_EQUAL);
1611 ppl_Polyhedron_add_constraint (accesses, cstr);
1612
1613 ppl_delete_Linear_Expression (fn);
1614 ppl_delete_Linear_Expression (access);
1615 ppl_delete_Constraint (cstr);
1616 }
1617
1618 value_clear (v);
1619 }
1620
1621 /* Add constrains representing the size of the accessed data to the
1622 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1623 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1624 domain. */
1625
1626 static void
1627 pdr_add_data_dimensions (ppl_Polyhedron_t accesses, data_reference_p dr,
1628 ppl_dimension_type accessp_nb_dims,
1629 ppl_dimension_type dom_nb_dims)
1630 {
1631 tree ref = DR_REF (dr);
1632 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1633
1634 for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1635 {
1636 ppl_Linear_Expression_t expr;
1637 ppl_Constraint_t cstr;
1638 ppl_dimension_type subscript = dom_nb_dims + 1 + i;
1639 tree low, high;
1640
1641 if (TREE_CODE (ref) != ARRAY_REF)
1642 break;
1643
1644 low = array_ref_low_bound (ref);
1645
1646 /* subscript - low >= 0 */
1647 if (host_integerp (low, 0))
1648 {
1649 ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1650 ppl_set_coef (expr, subscript, 1);
1651
1652 ppl_set_inhomogeneous (expr, -int_cst_value (low));
1653
1654 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1655 ppl_Polyhedron_add_constraint (accesses, cstr);
1656 ppl_delete_Linear_Expression (expr);
1657 ppl_delete_Constraint (cstr);
1658 }
1659
1660 high = array_ref_up_bound (ref);
1661
1662 /* high - subscript >= 0
1663 XXX: 1-element arrays at end of structures may extend over their
1664 declared size. */
1665 if (high && host_integerp (high, 0))
1666 {
1667 ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1668 ppl_set_coef (expr, subscript, -1);
1669
1670 ppl_set_inhomogeneous (expr, int_cst_value (high));
1671
1672 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1673 ppl_Polyhedron_add_constraint (accesses, cstr);
1674 ppl_delete_Linear_Expression (expr);
1675 ppl_delete_Constraint (cstr);
1676 }
1677 }
1678 }
1679
1680 /* Build data accesses for DR in PBB. */
1681
1682 static void
1683 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1684 {
1685 ppl_Polyhedron_t accesses;
1686 ppl_Pointset_Powerset_C_Polyhedron_t accesses_ps;
1687 ppl_dimension_type dom_nb_dims;
1688 ppl_dimension_type accessp_nb_dims;
1689 int dr_base_object_set;
1690
1691 ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PBB_DOMAIN (pbb),
1692 &dom_nb_dims);
1693 accessp_nb_dims = dom_nb_dims + 1 + DR_NUM_DIMENSIONS (dr);
1694
1695 ppl_new_C_Polyhedron_from_space_dimension (&accesses, accessp_nb_dims, 0);
1696
1697 pdr_add_alias_set (accesses, dr, accessp_nb_dims, dom_nb_dims);
1698 pdr_add_memory_accesses (accesses, dr, accessp_nb_dims, dom_nb_dims, pbb);
1699 pdr_add_data_dimensions (accesses, dr, accessp_nb_dims, dom_nb_dims);
1700
1701 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&accesses_ps,
1702 accesses);
1703 ppl_delete_Polyhedron (accesses);
1704
1705 dr_base_object_set = ((int *)(dr->aux))[BASE_OBJECT_SET_INDEX];
1706
1707 new_poly_dr (pbb, dr_base_object_set, accesses_ps, DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1708 dr, DR_NUM_DIMENSIONS (dr));
1709 }
1710
1711 /* Write to FILE the alias graph of data references with DIMACS format. */
1712
1713 static inline bool
1714 write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
1715 VEC (data_reference_p, heap) *drs)
1716 {
1717 int num_vertex = VEC_length (data_reference_p, drs);
1718 int edge_num = 0;
1719 data_reference_p dr1, dr2;
1720 int i, j;
1721
1722 if (num_vertex == 0)
1723 return true;
1724
1725 for (i = 0; VEC_iterate (data_reference_p, drs, i, dr1); i++)
1726 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1727 if (dr_may_alias_p (dr1, dr2))
1728 edge_num++;
1729
1730 fprintf (file, "$\n");
1731
1732 if (comment)
1733 fprintf (file, "c %s\n", comment);
1734
1735 fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1736
1737 for (i = 0; VEC_iterate (data_reference_p, drs, i, dr1); i++)
1738 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1739 if (dr_may_alias_p (dr1, dr2))
1740 fprintf (file, "e %d %d\n", i + 1, j + 1);
1741
1742 return true;
1743 }
1744
1745 static void
1746 partition_drs_to_sets (VEC (data_reference_p, heap) *drs, int choice,
1747 bool (* edge_exist_p) (const struct data_reference *,
1748 const struct data_reference *))
1749 {
1750 int num_vertex = VEC_length (data_reference_p, drs);
1751 struct graph *g = new_graph (num_vertex);
1752 data_reference_p dr1, dr2;
1753 int i, j;
1754 int num_component;
1755 int *queue;
1756
1757 for (i = 0; VEC_iterate (data_reference_p, drs, i, dr1); i++)
1758 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1759 if ((*edge_exist_p) (dr1, dr2))
1760 {
1761 add_edge (g, i, j);
1762 add_edge (g, j, i);
1763 }
1764
1765 queue = XNEWVEC (int, num_vertex);
1766 for (i = 0; i < num_vertex; i++)
1767 queue[i] = i;
1768
1769 num_component = graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1770
1771 for (i = 0; i < g->n_vertices; i++)
1772 {
1773 data_reference_p dr = VEC_index (data_reference_p, drs, i);
1774 if (!dr->aux)
1775 dr->aux = XNEWVEC (int, 2);
1776 ((int *)(dr->aux))[choice] = g->vertices[i].component + 1;
1777 }
1778
1779 free (queue);
1780 free_graph (g);
1781 }
1782
1783 static bool
1784 dr_same_base_object_p (const struct data_reference *dr1,
1785 const struct data_reference *dr2)
1786 {
1787 return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1788 }
1789
1790 /* Group each data reference in DRS with it's alias set num. */
1791
1792 static void
1793 build_alias_set_for_drs (VEC (data_reference_p, heap) *drs)
1794 {
1795 partition_drs_to_sets (drs, ALIAS_SET_INDEX, dr_may_alias_p);
1796 }
1797
1798 /* Group each data reference in DRS with it's base object set num. */
1799
1800 static void
1801 build_base_obj_set_for_drs (VEC (data_reference_p, heap) *drs)
1802 {
1803 partition_drs_to_sets (drs, BASE_OBJECT_SET_INDEX, dr_same_base_object_p);
1804 }
1805
1806 /* Build the data references for PBB. */
1807
1808 static void
1809 build_pbb_drs (poly_bb_p pbb)
1810 {
1811 int j;
1812 data_reference_p dr;
1813 VEC (data_reference_p, heap) *gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1814
1815 for (j = 0; VEC_iterate (data_reference_p, gbb_drs, j, dr); j++)
1816 build_poly_dr (dr, pbb);
1817 }
1818
1819 /* Build data references in SCOP. */
1820
1821 static void
1822 build_scop_drs (scop_p scop)
1823 {
1824 int i, j;
1825 poly_bb_p pbb;
1826 data_reference_p dr;
1827 VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
1828
1829 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1830 for (j = 0; VEC_iterate (data_reference_p,
1831 GBB_DATA_REFS (PBB_BLACK_BOX (pbb)), j, dr); j++)
1832 VEC_safe_push (data_reference_p, heap, drs, dr);
1833
1834 build_alias_set_for_drs (drs);
1835 build_base_obj_set_for_drs (drs);
1836
1837 /* When debugging, enable the following code. This cannot be used
1838 in production compilers. */
1839 #if 0
1840 {
1841 char comment[100];
1842 FILE *file;
1843
1844 file = fopen ("/tmp/dr_alias_graph", "ab");
1845 if (file)
1846 {
1847 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1848 current_function_name ());
1849 write_alias_graph_to_ascii_dimacs (file, comment, drs);
1850 fclose (file);
1851 }
1852 }
1853 #endif
1854
1855 VEC_free (data_reference_p, heap, drs);
1856
1857 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1858 build_pbb_drs (pbb);
1859 }
1860
1861 /* Return a gsi at the position of the VAR definition. */
1862
1863 static gimple_stmt_iterator
1864 gsi_for_ssa_name_def (tree var)
1865 {
1866 gimple stmt;
1867 basic_block bb;
1868 gimple_stmt_iterator gsi;
1869 gimple_stmt_iterator psi;
1870
1871 gcc_assert (TREE_CODE (var) == SSA_NAME);
1872
1873 stmt = SSA_NAME_DEF_STMT (var);
1874 bb = gimple_bb (stmt);
1875
1876 for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1877 if (stmt == gsi_stmt (psi))
1878 return gsi_after_labels (bb);
1879
1880 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1881 if (stmt == gsi_stmt (gsi))
1882 {
1883 gsi_next (&gsi);
1884 return gsi;
1885 }
1886
1887 gcc_unreachable ();
1888 return gsi;
1889 }
1890
1891 /* Insert the assignment "RES := VAR" just after the definition of VAR. */
1892
1893 static void
1894 insert_out_of_ssa_copy (tree res, tree var)
1895 {
1896 gimple_stmt_iterator gsi = gsi_for_ssa_name_def (var);
1897 gimple stmt;
1898 gimple_seq stmts;
1899 gimple_stmt_iterator si;
1900
1901 var = force_gimple_operand (var, &stmts, true, NULL_TREE);
1902 stmt = gimple_build_assign (res, var);
1903 if (!stmts)
1904 stmts = gimple_seq_alloc ();
1905 si = gsi_last (stmts);
1906 gsi_insert_after (&si, stmt, GSI_NEW_STMT);
1907 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
1908 }
1909
1910 /* Insert on edge E the assignment "RES := EXPR". */
1911
1912 static void
1913 insert_out_of_ssa_copy_on_edge (edge e, tree res, tree expr)
1914 {
1915 gimple_stmt_iterator gsi;
1916 gimple_seq stmts;
1917 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
1918 gimple stmt = gimple_build_assign (res, var);
1919
1920 if (!stmts)
1921 stmts = gimple_seq_alloc ();
1922
1923 gsi = gsi_last (stmts);
1924 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
1925 gsi_insert_seq_on_edge (e, stmts);
1926 gsi_commit_edge_inserts ();
1927 }
1928
1929 /* Creates a zero dimension array of the same type as VAR. */
1930
1931 static tree
1932 create_zero_dim_array (tree var)
1933 {
1934 tree index_type = build_index_type (integer_zero_node);
1935 tree elt_type = TREE_TYPE (var);
1936 tree array_type = build_array_type (elt_type, index_type);
1937 tree base = create_tmp_var (array_type, "Red");
1938
1939 add_referenced_var (base);
1940
1941 return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
1942 NULL_TREE);
1943 }
1944
1945 /* Returns true when PHI is a loop close phi node. */
1946
1947 static bool
1948 scalar_close_phi_node_p (gimple phi)
1949 {
1950 gcc_assert (gimple_code (phi) == GIMPLE_PHI);
1951
1952 if (!is_gimple_reg (gimple_phi_result (phi)))
1953 return false;
1954
1955 return (gimple_phi_num_args (phi) == 1);
1956 }
1957
1958 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
1959 dimension array for it. */
1960
1961 static void
1962 rewrite_close_phi_out_of_ssa (gimple_stmt_iterator *psi)
1963 {
1964 gimple phi = gsi_stmt (*psi);
1965 tree res = gimple_phi_result (phi);
1966 tree var = SSA_NAME_VAR (res);
1967 tree zero_dim_array = create_zero_dim_array (var);
1968 gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (phi));
1969 gimple stmt = gimple_build_assign (res, zero_dim_array);
1970 tree arg = gimple_phi_arg_def (phi, 0);
1971
1972 insert_out_of_ssa_copy (zero_dim_array, arg);
1973
1974 remove_phi_node (psi, false);
1975 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
1976 SSA_NAME_DEF_STMT (res) = stmt;
1977 }
1978
1979 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
1980 dimension array for it. */
1981
1982 static void
1983 rewrite_phi_out_of_ssa (gimple_stmt_iterator *psi)
1984 {
1985 size_t i;
1986 gimple phi = gsi_stmt (*psi);
1987 basic_block bb = gimple_bb (phi);
1988 tree res = gimple_phi_result (phi);
1989 tree var = SSA_NAME_VAR (res);
1990 tree zero_dim_array = create_zero_dim_array (var);
1991 gimple_stmt_iterator gsi;
1992 gimple stmt;
1993 gimple_seq stmts;
1994
1995 for (i = 0; i < gimple_phi_num_args (phi); i++)
1996 {
1997 tree arg = gimple_phi_arg_def (phi, i);
1998
1999 /* Try to avoid the insertion on edges as much as possible: this
2000 would avoid the insertion of code on loop latch edges, making
2001 the pattern matching of the vectorizer happy, or it would
2002 avoid the insertion of useless basic blocks. Note that it is
2003 incorrect to insert out of SSA copies close by their
2004 definition when they are more than two loop levels apart:
2005 for example, starting from a double nested loop
2006
2007 | a = ...
2008 | loop_1
2009 | loop_2
2010 | b = phi (a, c)
2011 | c = ...
2012 | end_2
2013 | end_1
2014
2015 the following transform is incorrect
2016
2017 | a = ...
2018 | Red[0] = a
2019 | loop_1
2020 | loop_2
2021 | b = Red[0]
2022 | c = ...
2023 | Red[0] = c
2024 | end_2
2025 | end_1
2026
2027 whereas inserting the copy on the incomming edge is correct
2028
2029 | a = ...
2030 | loop_1
2031 | Red[0] = a
2032 | loop_2
2033 | b = Red[0]
2034 | c = ...
2035 | Red[0] = c
2036 | end_2
2037 | end_1
2038 */
2039 if (TREE_CODE (arg) == SSA_NAME
2040 && is_gimple_reg (arg)
2041 && gimple_bb (SSA_NAME_DEF_STMT (arg))
2042 && (flow_bb_inside_loop_p (bb->loop_father,
2043 gimple_bb (SSA_NAME_DEF_STMT (arg)))
2044 || flow_bb_inside_loop_p (loop_outer (bb->loop_father),
2045 gimple_bb (SSA_NAME_DEF_STMT (arg)))))
2046 insert_out_of_ssa_copy (zero_dim_array, arg);
2047 else
2048 insert_out_of_ssa_copy_on_edge (gimple_phi_arg_edge (phi, i),
2049 zero_dim_array, arg);
2050 }
2051
2052 var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
2053
2054 if (!stmts)
2055 stmts = gimple_seq_alloc ();
2056
2057 stmt = gimple_build_assign (res, var);
2058 remove_phi_node (psi, false);
2059 SSA_NAME_DEF_STMT (res) = stmt;
2060
2061 gsi = gsi_last (stmts);
2062 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
2063
2064 gsi = gsi_after_labels (bb);
2065 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2066 }
2067
2068 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2069
2070 static void
2071 rewrite_reductions_out_of_ssa (scop_p scop)
2072 {
2073 basic_block bb;
2074 gimple_stmt_iterator psi;
2075 sese region = SCOP_REGION (scop);
2076
2077 FOR_EACH_BB (bb)
2078 if (bb_in_region (bb, SESE_ENTRY_BB (region), SESE_EXIT_BB (region)))
2079 for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2080 {
2081 if (scalar_close_phi_node_p (gsi_stmt (psi)))
2082 rewrite_close_phi_out_of_ssa (&psi);
2083 else if (reduction_phi_p (region, &psi))
2084 rewrite_phi_out_of_ssa (&psi);
2085 }
2086
2087 update_ssa (TODO_update_ssa);
2088 #ifdef ENABLE_CHECKING
2089 verify_ssa (false);
2090 verify_loop_closed_ssa ();
2091 #endif
2092 }
2093
2094 /* Returns the number of pbbs that are in loops contained in SCOP. */
2095
2096 static int
2097 nb_pbbs_in_loops (scop_p scop)
2098 {
2099 int i;
2100 poly_bb_p pbb;
2101 int res = 0;
2102
2103 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
2104 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2105 res++;
2106
2107 return res;
2108 }
2109
2110 /* Builds the polyhedral representation for a SESE region. */
2111
2112 bool
2113 build_poly_scop (scop_p scop)
2114 {
2115 sese region = SCOP_REGION (scop);
2116 rewrite_reductions_out_of_ssa (scop);
2117 build_scop_bbs (scop);
2118
2119 /* FIXME: This restriction is needed to avoid a problem in CLooG.
2120 Once CLooG is fixed, remove this guard. Anyways, it makes no
2121 sense to optimize a scop containing only PBBs that do not belong
2122 to any loops. */
2123 if (nb_pbbs_in_loops (scop) == 0)
2124 return false;
2125
2126 build_sese_loop_nests (region);
2127 build_sese_conditions (region);
2128 find_scop_parameters (scop);
2129
2130 build_scop_iteration_domain (scop);
2131 build_scop_context (scop);
2132
2133 add_conditions_to_constraints (scop);
2134 build_scop_scattering (scop);
2135 build_scop_drs (scop);
2136
2137 return true;
2138 }
2139
2140 /* Always return false. Exercise the scop_to_clast function. */
2141
2142 void
2143 check_poly_representation (scop_p scop ATTRIBUTE_UNUSED)
2144 {
2145 #ifdef ENABLE_CHECKING
2146 cloog_prog_clast pc = scop_to_clast (scop);
2147 cloog_clast_free (pc.stmt);
2148 cloog_program_free (pc.prog);
2149 #endif
2150 }
2151 #endif