graphite-dependences.c (reduction_ddr): New.
[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 imm_use_iterator imm_iter;
61 gimple stmt;
62 bool result = false;
63
64 FOR_EACH_IMM_USE_STMT (stmt, imm_iter, var)
65 {
66 basic_block bb = gimple_bb (stmt);
67
68 if (gimple_code (stmt) == GIMPLE_PHI
69 && bb->loop_father->header != bb)
70 result = true;
71 }
72
73 return result;
74 }
75
76 /* Returns the index of the phi argument corresponding to the initial
77 value in the loop. */
78
79 static size_t
80 loop_entry_phi_arg (gimple phi)
81 {
82 loop_p loop = gimple_bb (phi)->loop_father;
83 size_t i;
84
85 for (i = 0; i < gimple_phi_num_args (phi); i++)
86 if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
87 return i;
88
89 gcc_unreachable ();
90 return 0;
91 }
92
93 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
94 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
95
96 static void
97 remove_simple_copy_phi (gimple_stmt_iterator *psi)
98 {
99 gimple phi = gsi_stmt (*psi);
100 tree res = gimple_phi_result (phi);
101 size_t entry = loop_entry_phi_arg (phi);
102 tree init = gimple_phi_arg_def (phi, entry);
103 gimple stmt = gimple_build_assign (res, init);
104 edge e = gimple_phi_arg_edge (phi, entry);
105
106 remove_phi_node (psi, false);
107 gsi_insert_on_edge_immediate (e, stmt);
108 SSA_NAME_DEF_STMT (res) = stmt;
109 }
110
111 /* Removes an invariant phi node at position PSI by inserting on the
112 loop ENTRY edge the assignment RES = INIT. */
113
114 static void
115 remove_invariant_phi (sese region, gimple_stmt_iterator *psi)
116 {
117 gimple phi = gsi_stmt (*psi);
118 loop_p loop = loop_containing_stmt (phi);
119 tree res = gimple_phi_result (phi);
120 tree scev = scalar_evolution_in_region (region, loop, res);
121 size_t entry = loop_entry_phi_arg (phi);
122 edge e = gimple_phi_arg_edge (phi, entry);
123 tree var;
124 gimple stmt;
125 gimple_seq stmts;
126 gimple_stmt_iterator gsi;
127
128 if (tree_contains_chrecs (scev, NULL))
129 scev = gimple_phi_arg_def (phi, entry);
130
131 var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
132 stmt = gimple_build_assign (res, var);
133 remove_phi_node (psi, false);
134
135 if (!stmts)
136 stmts = gimple_seq_alloc ();
137
138 gsi = gsi_last (stmts);
139 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
140 gsi_insert_seq_on_edge (e, stmts);
141 gsi_commit_edge_inserts ();
142 SSA_NAME_DEF_STMT (res) = stmt;
143 }
144
145 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
146
147 static inline bool
148 simple_copy_phi_p (gimple phi)
149 {
150 tree res;
151
152 if (gimple_phi_num_args (phi) != 2)
153 return false;
154
155 res = gimple_phi_result (phi);
156 return (res == gimple_phi_arg_def (phi, 0)
157 || res == gimple_phi_arg_def (phi, 1));
158 }
159
160 /* Returns true when the phi node at position PSI is a reduction phi
161 node in REGION. Otherwise moves the pointer PSI to the next phi to
162 be considered. */
163
164 static bool
165 reduction_phi_p (sese region, gimple_stmt_iterator *psi)
166 {
167 loop_p loop;
168 tree scev;
169 affine_iv iv;
170 gimple phi = gsi_stmt (*psi);
171 tree res = gimple_phi_result (phi);
172
173 if (!is_gimple_reg (res))
174 {
175 gsi_next (psi);
176 return false;
177 }
178
179 loop = loop_containing_stmt (phi);
180
181 if (simple_copy_phi_p (phi))
182 {
183 /* FIXME: PRE introduces phi nodes like these, for an example,
184 see id-5.f in the fortran graphite testsuite:
185
186 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
187 */
188 remove_simple_copy_phi (psi);
189 return false;
190 }
191
192 /* Main induction variables with constant strides in LOOP are not
193 reductions. */
194 if (simple_iv (loop, loop, res, &iv, true))
195 {
196 gsi_next (psi);
197 return false;
198 }
199
200 scev = scalar_evolution_in_region (region, loop, res);
201 if (chrec_contains_undetermined (scev))
202 return true;
203
204 if (evolution_function_is_invariant_p (scev, loop->num))
205 {
206 remove_invariant_phi (region, psi);
207 return false;
208 }
209
210 /* All the other cases are considered reductions. */
211 return true;
212 }
213
214 /* Returns true when BB will be represented in graphite. Return false
215 for the basic blocks that contain code eliminated in the code
216 generation pass: i.e. induction variables and exit conditions. */
217
218 static bool
219 graphite_stmt_p (sese region, basic_block bb,
220 VEC (data_reference_p, heap) *drs)
221 {
222 gimple_stmt_iterator gsi;
223 loop_p loop = bb->loop_father;
224
225 if (VEC_length (data_reference_p, drs) > 0)
226 return true;
227
228 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
229 {
230 gimple stmt = gsi_stmt (gsi);
231
232 switch (gimple_code (stmt))
233 {
234 case GIMPLE_DEBUG:
235 /* Control flow expressions can be ignored, as they are
236 represented in the iteration domains and will be
237 regenerated by graphite. */
238 case GIMPLE_COND:
239 case GIMPLE_GOTO:
240 case GIMPLE_SWITCH:
241 break;
242
243 case GIMPLE_ASSIGN:
244 {
245 tree var = gimple_assign_lhs (stmt);
246
247 /* We need these bbs to be able to construct the phi nodes. */
248 if (var_used_in_not_loop_header_phi_node (var))
249 return true;
250
251 var = scalar_evolution_in_region (region, loop, var);
252 if (chrec_contains_undetermined (var))
253 return true;
254
255 break;
256 }
257
258 default:
259 return true;
260 }
261 }
262
263 return false;
264 }
265
266 /* Store the GRAPHITE representation of BB. */
267
268 static gimple_bb_p
269 new_gimple_bb (basic_block bb, VEC (data_reference_p, heap) *drs)
270 {
271 struct gimple_bb *gbb;
272
273 gbb = XNEW (struct gimple_bb);
274 bb->aux = gbb;
275 GBB_BB (gbb) = bb;
276 GBB_DATA_REFS (gbb) = drs;
277 GBB_CONDITIONS (gbb) = NULL;
278 GBB_CONDITION_CASES (gbb) = NULL;
279 GBB_CLOOG_IV_TYPES (gbb) = NULL;
280
281 return gbb;
282 }
283
284 static void
285 free_data_refs_aux (VEC (data_reference_p, heap) *datarefs)
286 {
287 unsigned int i;
288 struct data_reference *dr;
289
290 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
291 if (!dr->aux)
292 {
293 free (dr->aux);
294 dr->aux = NULL;
295 }
296 }
297
298 /* Frees GBB. */
299
300 static void
301 free_gimple_bb (struct gimple_bb *gbb)
302 {
303 if (GBB_CLOOG_IV_TYPES (gbb))
304 htab_delete (GBB_CLOOG_IV_TYPES (gbb));
305
306 free_data_refs_aux (GBB_DATA_REFS (gbb));
307 free_data_refs (GBB_DATA_REFS (gbb));
308
309 VEC_free (gimple, heap, GBB_CONDITIONS (gbb));
310 VEC_free (gimple, heap, GBB_CONDITION_CASES (gbb));
311 GBB_BB (gbb)->aux = 0;
312 XDELETE (gbb);
313 }
314
315 /* Deletes all gimple bbs in SCOP. */
316
317 static void
318 remove_gbbs_in_scop (scop_p scop)
319 {
320 int i;
321 poly_bb_p pbb;
322
323 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
324 free_gimple_bb (PBB_BLACK_BOX (pbb));
325 }
326
327 /* Deletes all scops in SCOPS. */
328
329 void
330 free_scops (VEC (scop_p, heap) *scops)
331 {
332 int i;
333 scop_p scop;
334
335 for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++)
336 {
337 remove_gbbs_in_scop (scop);
338 free_sese (SCOP_REGION (scop));
339 free_scop (scop);
340 }
341
342 VEC_free (scop_p, heap, scops);
343 }
344
345 /* Generates a polyhedral black box only if the bb contains interesting
346 information. */
347
348 static void
349 try_generate_gimple_bb (scop_p scop, basic_block bb, sbitmap reductions)
350 {
351 VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
352 loop_p nest = outermost_loop_in_sese (SCOP_REGION (scop), bb);
353 gimple_stmt_iterator gsi;
354
355 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
356 {
357 gimple stmt = gsi_stmt (gsi);
358 if (!is_gimple_debug (stmt))
359 graphite_find_data_references_in_stmt (nest, stmt, &drs);
360 }
361
362 if (!graphite_stmt_p (SCOP_REGION (scop), bb, drs))
363 free_data_refs (drs);
364 else
365 new_poly_bb (scop, new_gimple_bb (bb, drs), TEST_BIT (reductions,
366 bb->index));
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, sbitmap reductions)
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, reductions);
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, reductions);
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 static void
460 build_scop_bbs (scop_p scop, sbitmap reductions)
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), reductions);
467 sbitmap_free (visited);
468 }
469
470 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
471 We generate SCATTERING_DIMENSIONS scattering dimensions.
472
473 CLooG 0.15.0 and previous versions require, that all
474 scattering functions of one CloogProgram have the same number of
475 scattering dimensions, therefore we allow to specify it. This
476 should be removed in future versions of CLooG.
477
478 The scattering polyhedron consists of these dimensions: scattering,
479 loop_iterators, parameters.
480
481 Example:
482
483 | scattering_dimensions = 5
484 | used_scattering_dimensions = 3
485 | nb_iterators = 1
486 | scop_nb_params = 2
487 |
488 | Schedule:
489 | i
490 | 4 5
491 |
492 | Scattering polyhedron:
493 |
494 | scattering: {s1, s2, s3, s4, s5}
495 | loop_iterators: {i}
496 | parameters: {p1, p2}
497 |
498 | s1 s2 s3 s4 s5 i p1 p2 1
499 | 1 0 0 0 0 0 0 0 -4 = 0
500 | 0 1 0 0 0 -1 0 0 0 = 0
501 | 0 0 1 0 0 0 0 0 -5 = 0 */
502
503 static void
504 build_pbb_scattering_polyhedrons (ppl_Linear_Expression_t static_schedule,
505 poly_bb_p pbb, int scattering_dimensions)
506 {
507 int i;
508 scop_p scop = PBB_SCOP (pbb);
509 int nb_iterators = pbb_dim_iter_domain (pbb);
510 int used_scattering_dimensions = nb_iterators * 2 + 1;
511 int nb_params = scop_nb_params (scop);
512 ppl_Coefficient_t c;
513 ppl_dimension_type dim = scattering_dimensions + nb_iterators + nb_params;
514 Value v;
515
516 gcc_assert (scattering_dimensions >= used_scattering_dimensions);
517
518 value_init (v);
519 ppl_new_Coefficient (&c);
520 PBB_TRANSFORMED (pbb) = poly_scattering_new ();
521 ppl_new_C_Polyhedron_from_space_dimension
522 (&PBB_TRANSFORMED_SCATTERING (pbb), dim, 0);
523
524 PBB_NB_SCATTERING_TRANSFORM (pbb) = scattering_dimensions;
525
526 for (i = 0; i < scattering_dimensions; i++)
527 {
528 ppl_Constraint_t cstr;
529 ppl_Linear_Expression_t expr;
530
531 ppl_new_Linear_Expression_with_dimension (&expr, dim);
532 value_set_si (v, 1);
533 ppl_assign_Coefficient_from_mpz_t (c, v);
534 ppl_Linear_Expression_add_to_coefficient (expr, i, c);
535
536 /* Textual order inside this loop. */
537 if ((i % 2) == 0)
538 {
539 ppl_Linear_Expression_coefficient (static_schedule, i / 2, c);
540 ppl_Coefficient_to_mpz_t (c, v);
541 value_oppose (v, v);
542 ppl_assign_Coefficient_from_mpz_t (c, v);
543 ppl_Linear_Expression_add_to_inhomogeneous (expr, c);
544 }
545
546 /* Iterations of this loop. */
547 else /* if ((i % 2) == 1) */
548 {
549 int loop = (i - 1) / 2;
550
551 value_set_si (v, -1);
552 ppl_assign_Coefficient_from_mpz_t (c, v);
553 ppl_Linear_Expression_add_to_coefficient
554 (expr, scattering_dimensions + loop, c);
555 }
556
557 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL);
558 ppl_Polyhedron_add_constraint (PBB_TRANSFORMED_SCATTERING (pbb), cstr);
559 ppl_delete_Linear_Expression (expr);
560 ppl_delete_Constraint (cstr);
561 }
562
563 value_clear (v);
564 ppl_delete_Coefficient (c);
565
566 PBB_ORIGINAL (pbb) = poly_scattering_copy (PBB_TRANSFORMED (pbb));
567 }
568
569 /* Build for BB the static schedule.
570
571 The static schedule is a Dewey numbering of the abstract syntax
572 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
573
574 The following example informally defines the static schedule:
575
576 A
577 for (i: ...)
578 {
579 for (j: ...)
580 {
581 B
582 C
583 }
584
585 for (k: ...)
586 {
587 D
588 E
589 }
590 }
591 F
592
593 Static schedules for A to F:
594
595 DEPTH
596 0 1 2
597 A 0
598 B 1 0 0
599 C 1 0 1
600 D 1 1 0
601 E 1 1 1
602 F 2
603 */
604
605 static void
606 build_scop_scattering (scop_p scop)
607 {
608 int i;
609 poly_bb_p pbb;
610 gimple_bb_p previous_gbb = NULL;
611 ppl_Linear_Expression_t static_schedule;
612 ppl_Coefficient_t c;
613 Value v;
614
615 value_init (v);
616 ppl_new_Coefficient (&c);
617 ppl_new_Linear_Expression (&static_schedule);
618
619 /* We have to start schedules at 0 on the first component and
620 because we cannot compare_prefix_loops against a previous loop,
621 prefix will be equal to zero, and that index will be
622 incremented before copying. */
623 value_set_si (v, -1);
624 ppl_assign_Coefficient_from_mpz_t (c, v);
625 ppl_Linear_Expression_add_to_coefficient (static_schedule, 0, c);
626
627 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
628 {
629 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
630 ppl_Linear_Expression_t common;
631 int prefix;
632 int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1;
633
634 if (previous_gbb)
635 prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
636 else
637 prefix = 0;
638
639 previous_gbb = gbb;
640 ppl_new_Linear_Expression_with_dimension (&common, prefix + 1);
641 ppl_assign_Linear_Expression_from_Linear_Expression (common,
642 static_schedule);
643
644 value_set_si (v, 1);
645 ppl_assign_Coefficient_from_mpz_t (c, v);
646 ppl_Linear_Expression_add_to_coefficient (common, prefix, c);
647 ppl_assign_Linear_Expression_from_Linear_Expression (static_schedule,
648 common);
649
650 build_pbb_scattering_polyhedrons (common, pbb, nb_scat_dims);
651
652 ppl_delete_Linear_Expression (common);
653 }
654
655 value_clear (v);
656 ppl_delete_Coefficient (c);
657 ppl_delete_Linear_Expression (static_schedule);
658 }
659
660 /* Add the value K to the dimension D of the linear expression EXPR. */
661
662 static void
663 add_value_to_dim (ppl_dimension_type d, ppl_Linear_Expression_t expr,
664 Value k)
665 {
666 Value val;
667 ppl_Coefficient_t coef;
668
669 ppl_new_Coefficient (&coef);
670 ppl_Linear_Expression_coefficient (expr, d, coef);
671 value_init (val);
672 ppl_Coefficient_to_mpz_t (coef, val);
673
674 value_addto (val, val, k);
675
676 ppl_assign_Coefficient_from_mpz_t (coef, val);
677 ppl_Linear_Expression_add_to_coefficient (expr, d, coef);
678 value_clear (val);
679 ppl_delete_Coefficient (coef);
680 }
681
682 /* In the context of scop S, scan E, the right hand side of a scalar
683 evolution function in loop VAR, and translate it to a linear
684 expression EXPR. */
685
686 static void
687 scan_tree_for_params_right_scev (sese s, tree e, int var,
688 ppl_Linear_Expression_t expr)
689 {
690 if (expr)
691 {
692 loop_p loop = get_loop (var);
693 ppl_dimension_type l = sese_loop_depth (s, loop) - 1;
694 Value val;
695
696 /* Scalar evolutions should happen in the sese region. */
697 gcc_assert (sese_loop_depth (s, loop) > 0);
698
699 /* We can not deal with parametric strides like:
700
701 | p = parameter;
702 |
703 | for i:
704 | a [i * p] = ... */
705 gcc_assert (TREE_CODE (e) == INTEGER_CST);
706
707 value_init (val);
708 value_set_si (val, int_cst_value (e));
709 add_value_to_dim (l, expr, val);
710 value_clear (val);
711 }
712 }
713
714 /* Scan the integer constant CST, and add it to the inhomogeneous part of the
715 linear expression EXPR. K is the multiplier of the constant. */
716
717 static void
718 scan_tree_for_params_int (tree cst, ppl_Linear_Expression_t expr, Value k)
719 {
720 Value val;
721 ppl_Coefficient_t coef;
722 int v = int_cst_value (cst);
723
724 value_init (val);
725 value_set_si (val, 0);
726
727 /* Necessary to not get "-1 = 2^n - 1". */
728 if (v < 0)
729 value_sub_int (val, val, -v);
730 else
731 value_add_int (val, val, v);
732
733 value_multiply (val, val, k);
734 ppl_new_Coefficient (&coef);
735 ppl_assign_Coefficient_from_mpz_t (coef, val);
736 ppl_Linear_Expression_add_to_inhomogeneous (expr, coef);
737 value_clear (val);
738 ppl_delete_Coefficient (coef);
739 }
740
741 /* Saves in NV at index I a new name for variable P. */
742
743 static void
744 save_var_name (char **nv, int i, tree p)
745 {
746 const char *name = get_name (SSA_NAME_VAR (p));
747
748 if (name)
749 {
750 int len = strlen (name) + 16;
751 nv[i] = XNEWVEC (char, len);
752 snprintf (nv[i], len, "%s_%d", name, SSA_NAME_VERSION (p));
753 }
754 else
755 {
756 nv[i] = XNEWVEC (char, 16);
757 snprintf (nv[i], 2 + 16, "T_%d", SSA_NAME_VERSION (p));
758 }
759 }
760
761 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
762 Otherwise returns -1. */
763
764 static inline int
765 parameter_index_in_region_1 (tree name, sese region)
766 {
767 int i;
768 tree p;
769
770 gcc_assert (TREE_CODE (name) == SSA_NAME);
771
772 for (i = 0; VEC_iterate (tree, SESE_PARAMS (region), i, p); i++)
773 if (p == name)
774 return i;
775
776 return -1;
777 }
778
779 /* When the parameter NAME is in REGION, returns its index in
780 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
781 and returns the index of NAME. */
782
783 static int
784 parameter_index_in_region (tree name, sese region)
785 {
786 int i;
787
788 gcc_assert (TREE_CODE (name) == SSA_NAME);
789
790 i = parameter_index_in_region_1 (name, region);
791 if (i != -1)
792 return i;
793
794 gcc_assert (SESE_ADD_PARAMS (region));
795
796 i = VEC_length (tree, SESE_PARAMS (region));
797 save_var_name (SESE_PARAMS_NAMES (region), i, name);
798 save_clast_name_index (SESE_PARAMS_INDEX (region),
799 SESE_PARAMS_NAMES (region)[i], i);
800 VEC_safe_push (tree, heap, SESE_PARAMS (region), name);
801 return i;
802 }
803
804 /* In the context of sese S, scan the expression E and translate it to
805 a linear expression C. When parsing a symbolic multiplication, K
806 represents the constant multiplier of an expression containing
807 parameters. */
808
809 static void
810 scan_tree_for_params (sese s, tree e, ppl_Linear_Expression_t c,
811 Value k)
812 {
813 if (e == chrec_dont_know)
814 return;
815
816 switch (TREE_CODE (e))
817 {
818 case POLYNOMIAL_CHREC:
819 scan_tree_for_params_right_scev (s, CHREC_RIGHT (e),
820 CHREC_VARIABLE (e), c);
821 scan_tree_for_params (s, CHREC_LEFT (e), c, k);
822 break;
823
824 case MULT_EXPR:
825 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
826 {
827 if (c)
828 {
829 Value val;
830 gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0));
831 value_init (val);
832 value_set_si (val, int_cst_value (TREE_OPERAND (e, 1)));
833 value_multiply (val, val, k);
834 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, val);
835 value_clear (val);
836 }
837 else
838 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
839 }
840 else
841 {
842 if (c)
843 {
844 Value val;
845 gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0));
846 value_init (val);
847 value_set_si (val, int_cst_value (TREE_OPERAND (e, 0)));
848 value_multiply (val, val, k);
849 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, val);
850 value_clear (val);
851 }
852 else
853 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k);
854 }
855 break;
856
857 case PLUS_EXPR:
858 case POINTER_PLUS_EXPR:
859 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
860 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k);
861 break;
862
863 case MINUS_EXPR:
864 {
865 ppl_Linear_Expression_t tmp_expr = NULL;
866
867 if (c)
868 {
869 ppl_dimension_type dim;
870 ppl_Linear_Expression_space_dimension (c, &dim);
871 ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
872 }
873
874 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
875 scan_tree_for_params (s, TREE_OPERAND (e, 1), tmp_expr, k);
876
877 if (c)
878 {
879 ppl_subtract_Linear_Expression_from_Linear_Expression (c,
880 tmp_expr);
881 ppl_delete_Linear_Expression (tmp_expr);
882 }
883
884 break;
885 }
886
887 case NEGATE_EXPR:
888 {
889 ppl_Linear_Expression_t tmp_expr = NULL;
890
891 if (c)
892 {
893 ppl_dimension_type dim;
894 ppl_Linear_Expression_space_dimension (c, &dim);
895 ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
896 }
897
898 scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k);
899
900 if (c)
901 {
902 ppl_subtract_Linear_Expression_from_Linear_Expression (c,
903 tmp_expr);
904 ppl_delete_Linear_Expression (tmp_expr);
905 }
906
907 break;
908 }
909
910 case BIT_NOT_EXPR:
911 {
912 ppl_Linear_Expression_t tmp_expr = NULL;
913
914 if (c)
915 {
916 ppl_dimension_type dim;
917 ppl_Linear_Expression_space_dimension (c, &dim);
918 ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
919 }
920
921 scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k);
922
923 if (c)
924 {
925 ppl_Coefficient_t coef;
926 Value minus_one;
927
928 ppl_subtract_Linear_Expression_from_Linear_Expression (c,
929 tmp_expr);
930 ppl_delete_Linear_Expression (tmp_expr);
931 value_init (minus_one);
932 value_set_si (minus_one, -1);
933 ppl_new_Coefficient_from_mpz_t (&coef, minus_one);
934 ppl_Linear_Expression_add_to_inhomogeneous (c, coef);
935 value_clear (minus_one);
936 ppl_delete_Coefficient (coef);
937 }
938
939 break;
940 }
941
942 case SSA_NAME:
943 {
944 ppl_dimension_type p = parameter_index_in_region (e, s);
945
946 if (c)
947 {
948 ppl_dimension_type dim;
949 ppl_Linear_Expression_space_dimension (c, &dim);
950 p += dim - sese_nb_params (s);
951 add_value_to_dim (p, c, k);
952 }
953 break;
954 }
955
956 case INTEGER_CST:
957 if (c)
958 scan_tree_for_params_int (e, c, k);
959 break;
960
961 CASE_CONVERT:
962 case NON_LVALUE_EXPR:
963 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
964 break;
965
966 default:
967 gcc_unreachable ();
968 break;
969 }
970 }
971
972 /* Find parameters with respect to REGION in BB. We are looking in memory
973 access functions, conditions and loop bounds. */
974
975 static void
976 find_params_in_bb (sese region, gimple_bb_p gbb)
977 {
978 int i;
979 unsigned j;
980 data_reference_p dr;
981 gimple stmt;
982 loop_p loop = GBB_BB (gbb)->loop_father;
983 Value one;
984
985 value_init (one);
986 value_set_si (one, 1);
987
988 /* Find parameters in the access functions of data references. */
989 for (i = 0; VEC_iterate (data_reference_p, GBB_DATA_REFS (gbb), i, dr); i++)
990 for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
991 scan_tree_for_params (region, DR_ACCESS_FN (dr, j), NULL, one);
992
993 /* Find parameters in conditional statements. */
994 for (i = 0; VEC_iterate (gimple, GBB_CONDITIONS (gbb), i, stmt); i++)
995 {
996 tree lhs = scalar_evolution_in_region (region, loop,
997 gimple_cond_lhs (stmt));
998 tree rhs = scalar_evolution_in_region (region, loop,
999 gimple_cond_rhs (stmt));
1000
1001 scan_tree_for_params (region, lhs, NULL, one);
1002 scan_tree_for_params (region, rhs, NULL, one);
1003 }
1004
1005 value_clear (one);
1006 }
1007
1008 /* Record the parameters used in the SCOP. A variable is a parameter
1009 in a scop if it does not vary during the execution of that scop. */
1010
1011 static void
1012 find_scop_parameters (scop_p scop)
1013 {
1014 poly_bb_p pbb;
1015 unsigned i;
1016 sese region = SCOP_REGION (scop);
1017 struct loop *loop;
1018 Value one;
1019
1020 value_init (one);
1021 value_set_si (one, 1);
1022
1023 /* Find the parameters used in the loop bounds. */
1024 for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1025 {
1026 tree nb_iters = number_of_latch_executions (loop);
1027
1028 if (!chrec_contains_symbols (nb_iters))
1029 continue;
1030
1031 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1032 scan_tree_for_params (region, nb_iters, NULL, one);
1033 }
1034
1035 value_clear (one);
1036
1037 /* Find the parameters used in data accesses. */
1038 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1039 find_params_in_bb (region, PBB_BLACK_BOX (pbb));
1040
1041 scop_set_nb_params (scop, sese_nb_params (region));
1042 SESE_ADD_PARAMS (region) = false;
1043 }
1044
1045 /* Returns a gimple_bb from BB. */
1046
1047 static inline gimple_bb_p
1048 gbb_from_bb (basic_block bb)
1049 {
1050 return (gimple_bb_p) bb->aux;
1051 }
1052
1053 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
1054 the constraints for the surrounding loops. */
1055
1056 static void
1057 build_loop_iteration_domains (scop_p scop, struct loop *loop,
1058 ppl_Polyhedron_t outer_ph, int nb)
1059
1060 {
1061 int i;
1062 ppl_Polyhedron_t ph;
1063 tree nb_iters = number_of_latch_executions (loop);
1064 ppl_dimension_type dim = nb + 1 + scop_nb_params (scop);
1065 sese region = SCOP_REGION (scop);
1066
1067 {
1068 ppl_const_Constraint_System_t pcs;
1069 ppl_dimension_type *map
1070 = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim);
1071
1072 ppl_new_C_Polyhedron_from_space_dimension (&ph, dim, 0);
1073 ppl_Polyhedron_get_constraints (outer_ph, &pcs);
1074 ppl_Polyhedron_add_constraints (ph, pcs);
1075
1076 for (i = 0; i < (int) nb; i++)
1077 map[i] = i;
1078 for (i = (int) nb; i < (int) dim - 1; i++)
1079 map[i] = i + 1;
1080 map[dim - 1] = nb;
1081
1082 ppl_Polyhedron_map_space_dimensions (ph, map, dim);
1083 free (map);
1084 }
1085
1086 /* 0 <= loop_i */
1087 {
1088 ppl_Constraint_t lb;
1089 ppl_Linear_Expression_t lb_expr;
1090
1091 ppl_new_Linear_Expression_with_dimension (&lb_expr, dim);
1092 ppl_set_coef (lb_expr, nb, 1);
1093 ppl_new_Constraint (&lb, lb_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1094 ppl_delete_Linear_Expression (lb_expr);
1095 ppl_Polyhedron_add_constraint (ph, lb);
1096 ppl_delete_Constraint (lb);
1097 }
1098
1099 if (TREE_CODE (nb_iters) == INTEGER_CST)
1100 {
1101 ppl_Constraint_t ub;
1102 ppl_Linear_Expression_t ub_expr;
1103
1104 ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1105
1106 /* loop_i <= cst_nb_iters */
1107 ppl_set_coef (ub_expr, nb, -1);
1108 ppl_set_inhomogeneous_tree (ub_expr, nb_iters);
1109 ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1110 ppl_Polyhedron_add_constraint (ph, ub);
1111 ppl_delete_Linear_Expression (ub_expr);
1112 ppl_delete_Constraint (ub);
1113 }
1114 else if (!chrec_contains_undetermined (nb_iters))
1115 {
1116 Value one;
1117 ppl_Constraint_t ub;
1118 ppl_Linear_Expression_t ub_expr;
1119
1120 value_init (one);
1121 value_set_si (one, 1);
1122 ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1123 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1124 scan_tree_for_params (SCOP_REGION (scop), nb_iters, ub_expr, one);
1125 value_clear (one);
1126
1127 /* loop_i <= expr_nb_iters */
1128 ppl_set_coef (ub_expr, nb, -1);
1129 ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1130 ppl_Polyhedron_add_constraint (ph, ub);
1131 ppl_delete_Linear_Expression (ub_expr);
1132 ppl_delete_Constraint (ub);
1133 }
1134 else
1135 gcc_unreachable ();
1136
1137 if (loop->inner && loop_in_sese_p (loop->inner, region))
1138 build_loop_iteration_domains (scop, loop->inner, ph, nb + 1);
1139
1140 if (nb != 0
1141 && loop->next
1142 && loop_in_sese_p (loop->next, region))
1143 build_loop_iteration_domains (scop, loop->next, outer_ph, nb);
1144
1145 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1146 ((ppl_Pointset_Powerset_C_Polyhedron_t *) &loop->aux, ph);
1147
1148 ppl_delete_Polyhedron (ph);
1149 }
1150
1151 /* Returns a linear expression for tree T evaluated in PBB. */
1152
1153 static ppl_Linear_Expression_t
1154 create_linear_expr_from_tree (poly_bb_p pbb, tree t)
1155 {
1156 Value one;
1157 ppl_Linear_Expression_t res;
1158 ppl_dimension_type dim;
1159 sese region = SCOP_REGION (PBB_SCOP (pbb));
1160 loop_p loop = pbb_loop (pbb);
1161
1162 dim = pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb);
1163 ppl_new_Linear_Expression_with_dimension (&res, dim);
1164
1165 t = scalar_evolution_in_region (region, loop, t);
1166 gcc_assert (!automatically_generated_chrec_p (t));
1167
1168 value_init (one);
1169 value_set_si (one, 1);
1170 scan_tree_for_params (region, t, res, one);
1171 value_clear (one);
1172
1173 return res;
1174 }
1175
1176 /* Returns the ppl constraint type from the gimple tree code CODE. */
1177
1178 static enum ppl_enum_Constraint_Type
1179 ppl_constraint_type_from_tree_code (enum tree_code code)
1180 {
1181 switch (code)
1182 {
1183 /* We do not support LT and GT to be able to work with C_Polyhedron.
1184 As we work on integer polyhedron "a < b" can be expressed by
1185 "a + 1 <= b". */
1186 case LT_EXPR:
1187 case GT_EXPR:
1188 gcc_unreachable ();
1189
1190 case LE_EXPR:
1191 return PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL;
1192
1193 case GE_EXPR:
1194 return PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL;
1195
1196 case EQ_EXPR:
1197 return PPL_CONSTRAINT_TYPE_EQUAL;
1198
1199 default:
1200 gcc_unreachable ();
1201 }
1202 }
1203
1204 /* Add conditional statement STMT to PS. It is evaluated in PBB and
1205 CODE is used as the comparison operator. This allows us to invert the
1206 condition or to handle inequalities. */
1207
1208 static void
1209 add_condition_to_domain (ppl_Pointset_Powerset_C_Polyhedron_t ps, gimple stmt,
1210 poly_bb_p pbb, enum tree_code code)
1211 {
1212 Value v;
1213 ppl_Coefficient_t c;
1214 ppl_Linear_Expression_t left, right;
1215 ppl_Constraint_t cstr;
1216 enum ppl_enum_Constraint_Type type;
1217
1218 left = create_linear_expr_from_tree (pbb, gimple_cond_lhs (stmt));
1219 right = create_linear_expr_from_tree (pbb, gimple_cond_rhs (stmt));
1220
1221 /* If we have < or > expressions convert them to <= or >= by adding 1 to
1222 the left or the right side of the expression. */
1223 if (code == LT_EXPR)
1224 {
1225 value_init (v);
1226 value_set_si (v, 1);
1227 ppl_new_Coefficient (&c);
1228 ppl_assign_Coefficient_from_mpz_t (c, v);
1229 ppl_Linear_Expression_add_to_inhomogeneous (left, c);
1230 ppl_delete_Coefficient (c);
1231 value_clear (v);
1232
1233 code = LE_EXPR;
1234 }
1235 else if (code == GT_EXPR)
1236 {
1237 value_init (v);
1238 value_set_si (v, 1);
1239 ppl_new_Coefficient (&c);
1240 ppl_assign_Coefficient_from_mpz_t (c, v);
1241 ppl_Linear_Expression_add_to_inhomogeneous (right, c);
1242 ppl_delete_Coefficient (c);
1243 value_clear (v);
1244
1245 code = GE_EXPR;
1246 }
1247
1248 type = ppl_constraint_type_from_tree_code (code);
1249
1250 ppl_subtract_Linear_Expression_from_Linear_Expression (left, right);
1251
1252 ppl_new_Constraint (&cstr, left, type);
1253 ppl_Pointset_Powerset_C_Polyhedron_add_constraint (ps, cstr);
1254
1255 ppl_delete_Constraint (cstr);
1256 ppl_delete_Linear_Expression (left);
1257 ppl_delete_Linear_Expression (right);
1258 }
1259
1260 /* Add conditional statement STMT to pbb. CODE is used as the comparision
1261 operator. This allows us to invert the condition or to handle
1262 inequalities. */
1263
1264 static void
1265 add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code)
1266 {
1267 if (code == NE_EXPR)
1268 {
1269 ppl_Pointset_Powerset_C_Polyhedron_t left = PBB_DOMAIN (pbb);
1270 ppl_Pointset_Powerset_C_Polyhedron_t right;
1271 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1272 (&right, left);
1273 add_condition_to_domain (left, stmt, pbb, LT_EXPR);
1274 add_condition_to_domain (right, stmt, pbb, GT_EXPR);
1275 ppl_Pointset_Powerset_C_Polyhedron_upper_bound_assign (left,
1276 right);
1277 ppl_delete_Pointset_Powerset_C_Polyhedron (right);
1278 }
1279 else
1280 add_condition_to_domain (PBB_DOMAIN (pbb), stmt, pbb, code);
1281 }
1282
1283 /* Add conditions to the domain of PBB. */
1284
1285 static void
1286 add_conditions_to_domain (poly_bb_p pbb)
1287 {
1288 unsigned int i;
1289 gimple stmt;
1290 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1291 VEC (gimple, heap) *conditions = GBB_CONDITIONS (gbb);
1292
1293 if (VEC_empty (gimple, conditions))
1294 return;
1295
1296 for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
1297 switch (gimple_code (stmt))
1298 {
1299 case GIMPLE_COND:
1300 {
1301 enum tree_code code = gimple_cond_code (stmt);
1302
1303 /* The conditions for ELSE-branches are inverted. */
1304 if (VEC_index (gimple, gbb->condition_cases, i) == NULL)
1305 code = invert_tree_comparison (code, false);
1306
1307 add_condition_to_pbb (pbb, stmt, code);
1308 break;
1309 }
1310
1311 case GIMPLE_SWITCH:
1312 /* Switch statements are not supported right now - fall throught. */
1313
1314 default:
1315 gcc_unreachable ();
1316 break;
1317 }
1318 }
1319
1320 /* Structure used to pass data to dom_walk. */
1321
1322 struct bsc
1323 {
1324 VEC (gimple, heap) **conditions, **cases;
1325 sese region;
1326 };
1327
1328 /* Returns non NULL when BB has a single predecessor and the last
1329 statement of that predecessor is a COND_EXPR. */
1330
1331 static gimple
1332 single_pred_cond (basic_block bb)
1333 {
1334 if (single_pred_p (bb))
1335 {
1336 edge e = single_pred_edge (bb);
1337 basic_block pred = e->src;
1338 gimple stmt = last_stmt (pred);
1339
1340 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1341 return stmt;
1342 }
1343 return NULL;
1344 }
1345
1346 /* Call-back for dom_walk executed before visiting the dominated
1347 blocks. */
1348
1349 static void
1350 build_sese_conditions_before (struct dom_walk_data *dw_data,
1351 basic_block bb)
1352 {
1353 struct bsc *data = (struct bsc *) dw_data->global_data;
1354 VEC (gimple, heap) **conditions = data->conditions;
1355 VEC (gimple, heap) **cases = data->cases;
1356 gimple_bb_p gbb = gbb_from_bb (bb);
1357 gimple stmt = single_pred_cond (bb);
1358
1359 if (!bb_in_sese_p (bb, data->region))
1360 return;
1361
1362 if (stmt)
1363 {
1364 edge e = single_pred_edge (bb);
1365
1366 VEC_safe_push (gimple, heap, *conditions, stmt);
1367
1368 if (e->flags & EDGE_TRUE_VALUE)
1369 VEC_safe_push (gimple, heap, *cases, stmt);
1370 else
1371 VEC_safe_push (gimple, heap, *cases, NULL);
1372 }
1373
1374 if (gbb)
1375 {
1376 GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
1377 GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
1378 }
1379 }
1380
1381 /* Call-back for dom_walk executed after visiting the dominated
1382 blocks. */
1383
1384 static void
1385 build_sese_conditions_after (struct dom_walk_data *dw_data,
1386 basic_block bb)
1387 {
1388 struct bsc *data = (struct bsc *) dw_data->global_data;
1389 VEC (gimple, heap) **conditions = data->conditions;
1390 VEC (gimple, heap) **cases = data->cases;
1391
1392 if (!bb_in_sese_p (bb, data->region))
1393 return;
1394
1395 if (single_pred_cond (bb))
1396 {
1397 VEC_pop (gimple, *conditions);
1398 VEC_pop (gimple, *cases);
1399 }
1400 }
1401
1402 /* Record all conditions in REGION. */
1403
1404 static void
1405 build_sese_conditions (sese region)
1406 {
1407 struct dom_walk_data walk_data;
1408 VEC (gimple, heap) *conditions = VEC_alloc (gimple, heap, 3);
1409 VEC (gimple, heap) *cases = VEC_alloc (gimple, heap, 3);
1410 struct bsc data;
1411
1412 data.conditions = &conditions;
1413 data.cases = &cases;
1414 data.region = region;
1415
1416 walk_data.dom_direction = CDI_DOMINATORS;
1417 walk_data.initialize_block_local_data = NULL;
1418 walk_data.before_dom_children = build_sese_conditions_before;
1419 walk_data.after_dom_children = build_sese_conditions_after;
1420 walk_data.global_data = &data;
1421 walk_data.block_local_data_size = 0;
1422
1423 init_walk_dominator_tree (&walk_data);
1424 walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region));
1425 fini_walk_dominator_tree (&walk_data);
1426
1427 VEC_free (gimple, heap, conditions);
1428 VEC_free (gimple, heap, cases);
1429 }
1430
1431 /* Traverses all the GBBs of the SCOP and add their constraints to the
1432 iteration domains. */
1433
1434 static void
1435 add_conditions_to_constraints (scop_p scop)
1436 {
1437 int i;
1438 poly_bb_p pbb;
1439
1440 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1441 add_conditions_to_domain (pbb);
1442 }
1443
1444 /* Add constraints on the possible values of parameter P from the type
1445 of P. */
1446
1447 static void
1448 add_param_constraints (scop_p scop, ppl_Polyhedron_t context, graphite_dim_t p)
1449 {
1450 ppl_Constraint_t cstr;
1451 ppl_Linear_Expression_t le;
1452 tree parameter = VEC_index (tree, SESE_PARAMS (SCOP_REGION (scop)), p);
1453 tree type = TREE_TYPE (parameter);
1454 tree lb, ub;
1455
1456 /* Disabled until we fix CPU2006. */
1457 return;
1458
1459 if (!INTEGRAL_TYPE_P (type))
1460 return;
1461
1462 lb = TYPE_MIN_VALUE (type);
1463 ub = TYPE_MAX_VALUE (type);
1464
1465 if (lb)
1466 {
1467 ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1468 ppl_set_coef (le, p, -1);
1469 ppl_set_inhomogeneous_tree (le, lb);
1470 ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL);
1471 ppl_Polyhedron_add_constraint (context, cstr);
1472 ppl_delete_Linear_Expression (le);
1473 ppl_delete_Constraint (cstr);
1474 }
1475
1476 if (ub)
1477 {
1478 ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1479 ppl_set_coef (le, p, -1);
1480 ppl_set_inhomogeneous_tree (le, ub);
1481 ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1482 ppl_Polyhedron_add_constraint (context, cstr);
1483 ppl_delete_Linear_Expression (le);
1484 ppl_delete_Constraint (cstr);
1485 }
1486 }
1487
1488 /* Build the context of the SCOP. The context usually contains extra
1489 constraints that are added to the iteration domains that constrain
1490 some parameters. */
1491
1492 static void
1493 build_scop_context (scop_p scop)
1494 {
1495 ppl_Polyhedron_t context;
1496 graphite_dim_t p, n = scop_nb_params (scop);
1497
1498 ppl_new_C_Polyhedron_from_space_dimension (&context, n, 0);
1499
1500 for (p = 0; p < n; p++)
1501 add_param_constraints (scop, context, p);
1502
1503 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1504 (&SCOP_CONTEXT (scop), context);
1505
1506 ppl_delete_Polyhedron (context);
1507 }
1508
1509 /* Build the iteration domains: the loops belonging to the current
1510 SCOP, and that vary for the execution of the current basic block.
1511 Returns false if there is no loop in SCOP. */
1512
1513 static void
1514 build_scop_iteration_domain (scop_p scop)
1515 {
1516 struct loop *loop;
1517 sese region = SCOP_REGION (scop);
1518 int i;
1519 ppl_Polyhedron_t ph;
1520 poly_bb_p pbb;
1521
1522 ppl_new_C_Polyhedron_from_space_dimension (&ph, scop_nb_params (scop), 0);
1523
1524 for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1525 if (!loop_in_sese_p (loop_outer (loop), region))
1526 build_loop_iteration_domains (scop, loop, ph, 0);
1527
1528 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1529 if (gbb_loop (PBB_BLACK_BOX (pbb))->aux)
1530 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1531 (&PBB_DOMAIN (pbb), (ppl_const_Pointset_Powerset_C_Polyhedron_t)
1532 gbb_loop (PBB_BLACK_BOX (pbb))->aux);
1533 else
1534 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1535 (&PBB_DOMAIN (pbb), ph);
1536
1537 for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1538 if (loop->aux)
1539 {
1540 ppl_delete_Pointset_Powerset_C_Polyhedron
1541 ((ppl_Pointset_Powerset_C_Polyhedron_t) loop->aux);
1542 loop->aux = NULL;
1543 }
1544
1545 ppl_delete_Polyhedron (ph);
1546 }
1547
1548 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1549 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1550 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1551 domain. */
1552
1553 static void
1554 pdr_add_alias_set (ppl_Polyhedron_t accesses, data_reference_p dr,
1555 ppl_dimension_type accessp_nb_dims,
1556 ppl_dimension_type dom_nb_dims)
1557 {
1558 ppl_Linear_Expression_t alias;
1559 ppl_Constraint_t cstr;
1560 int alias_set_num = 0;
1561
1562 if (dr->aux != NULL)
1563 alias_set_num = ((int *)(dr->aux))[ALIAS_SET_INDEX];
1564
1565 ppl_new_Linear_Expression_with_dimension (&alias, accessp_nb_dims);
1566
1567 ppl_set_coef (alias, dom_nb_dims, 1);
1568 ppl_set_inhomogeneous (alias, -alias_set_num);
1569 ppl_new_Constraint (&cstr, alias, PPL_CONSTRAINT_TYPE_EQUAL);
1570 ppl_Polyhedron_add_constraint (accesses, cstr);
1571
1572 ppl_delete_Linear_Expression (alias);
1573 ppl_delete_Constraint (cstr);
1574 }
1575
1576 /* Add to ACCESSES polyhedron equalities defining the access functions
1577 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1578 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1579 PBB is the poly_bb_p that contains the data reference DR. */
1580
1581 static void
1582 pdr_add_memory_accesses (ppl_Polyhedron_t accesses, data_reference_p dr,
1583 ppl_dimension_type accessp_nb_dims,
1584 ppl_dimension_type dom_nb_dims,
1585 poly_bb_p pbb)
1586 {
1587 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1588 Value v;
1589 scop_p scop = PBB_SCOP (pbb);
1590 sese region = SCOP_REGION (scop);
1591
1592 value_init (v);
1593
1594 for (i = 0; i < nb_subscripts; i++)
1595 {
1596 ppl_Linear_Expression_t fn, access;
1597 ppl_Constraint_t cstr;
1598 ppl_dimension_type subscript = dom_nb_dims + 1 + i;
1599 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1600
1601 ppl_new_Linear_Expression_with_dimension (&fn, dom_nb_dims);
1602 ppl_new_Linear_Expression_with_dimension (&access, accessp_nb_dims);
1603
1604 value_set_si (v, 1);
1605 scan_tree_for_params (region, afn, fn, v);
1606 ppl_assign_Linear_Expression_from_Linear_Expression (access, fn);
1607
1608 ppl_set_coef (access, subscript, -1);
1609 ppl_new_Constraint (&cstr, access, PPL_CONSTRAINT_TYPE_EQUAL);
1610 ppl_Polyhedron_add_constraint (accesses, cstr);
1611
1612 ppl_delete_Linear_Expression (fn);
1613 ppl_delete_Linear_Expression (access);
1614 ppl_delete_Constraint (cstr);
1615 }
1616
1617 value_clear (v);
1618 }
1619
1620 /* Add constrains representing the size of the accessed data to the
1621 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1622 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1623 domain. */
1624
1625 static void
1626 pdr_add_data_dimensions (ppl_Polyhedron_t accesses, data_reference_p dr,
1627 ppl_dimension_type accessp_nb_dims,
1628 ppl_dimension_type dom_nb_dims)
1629 {
1630 tree ref = DR_REF (dr);
1631 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1632
1633 for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1634 {
1635 ppl_Linear_Expression_t expr;
1636 ppl_Constraint_t cstr;
1637 ppl_dimension_type subscript = dom_nb_dims + 1 + i;
1638 tree low, high;
1639
1640 if (TREE_CODE (ref) != ARRAY_REF)
1641 break;
1642
1643 low = array_ref_low_bound (ref);
1644
1645 /* subscript - low >= 0 */
1646 if (host_integerp (low, 0))
1647 {
1648 ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1649 ppl_set_coef (expr, subscript, 1);
1650
1651 ppl_set_inhomogeneous (expr, -int_cst_value (low));
1652
1653 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1654 ppl_Polyhedron_add_constraint (accesses, cstr);
1655 ppl_delete_Linear_Expression (expr);
1656 ppl_delete_Constraint (cstr);
1657 }
1658
1659 high = array_ref_up_bound (ref);
1660
1661 /* high - subscript >= 0
1662 XXX: 1-element arrays at end of structures may extend over their
1663 declared size. */
1664 if (high && host_integerp (high, 0))
1665 {
1666 ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1667 ppl_set_coef (expr, subscript, -1);
1668
1669 ppl_set_inhomogeneous (expr, int_cst_value (high));
1670
1671 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1672 ppl_Polyhedron_add_constraint (accesses, cstr);
1673 ppl_delete_Linear_Expression (expr);
1674 ppl_delete_Constraint (cstr);
1675 }
1676 }
1677 }
1678
1679 /* Build data accesses for DR in PBB. */
1680
1681 static void
1682 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1683 {
1684 ppl_Polyhedron_t accesses;
1685 ppl_Pointset_Powerset_C_Polyhedron_t accesses_ps;
1686 ppl_dimension_type dom_nb_dims;
1687 ppl_dimension_type accessp_nb_dims;
1688 int dr_base_object_set;
1689
1690 ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PBB_DOMAIN (pbb),
1691 &dom_nb_dims);
1692 accessp_nb_dims = dom_nb_dims + 1 + DR_NUM_DIMENSIONS (dr);
1693
1694 ppl_new_C_Polyhedron_from_space_dimension (&accesses, accessp_nb_dims, 0);
1695
1696 pdr_add_alias_set (accesses, dr, accessp_nb_dims, dom_nb_dims);
1697 pdr_add_memory_accesses (accesses, dr, accessp_nb_dims, dom_nb_dims, pbb);
1698 pdr_add_data_dimensions (accesses, dr, accessp_nb_dims, dom_nb_dims);
1699
1700 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&accesses_ps,
1701 accesses);
1702 ppl_delete_Polyhedron (accesses);
1703
1704 dr_base_object_set = ((int *)(dr->aux))[BASE_OBJECT_SET_INDEX];
1705
1706 new_poly_dr (pbb, dr_base_object_set, accesses_ps, DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1707 dr, DR_NUM_DIMENSIONS (dr));
1708 }
1709
1710 /* Write to FILE the alias graph of data references with DIMACS format. */
1711
1712 static inline bool
1713 write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
1714 VEC (data_reference_p, heap) *drs)
1715 {
1716 int num_vertex = VEC_length (data_reference_p, drs);
1717 int edge_num = 0;
1718 data_reference_p dr1, dr2;
1719 int i, j;
1720
1721 if (num_vertex == 0)
1722 return true;
1723
1724 for (i = 0; VEC_iterate (data_reference_p, drs, i, dr1); i++)
1725 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1726 if (dr_may_alias_p (dr1, dr2))
1727 edge_num++;
1728
1729 fprintf (file, "$\n");
1730
1731 if (comment)
1732 fprintf (file, "c %s\n", comment);
1733
1734 fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1735
1736 for (i = 0; VEC_iterate (data_reference_p, drs, i, dr1); i++)
1737 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1738 if (dr_may_alias_p (dr1, dr2))
1739 fprintf (file, "e %d %d\n", i + 1, j + 1);
1740
1741 return true;
1742 }
1743
1744 static void
1745 partition_drs_to_sets (VEC (data_reference_p, heap) *drs, int choice,
1746 bool (* edge_exist_p) (const struct data_reference *,
1747 const struct data_reference *))
1748 {
1749 int num_vertex = VEC_length (data_reference_p, drs);
1750 struct graph *g = new_graph (num_vertex);
1751 data_reference_p dr1, dr2;
1752 int i, j;
1753 int num_component;
1754 int *queue;
1755
1756 for (i = 0; VEC_iterate (data_reference_p, drs, i, dr1); i++)
1757 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1758 if ((*edge_exist_p) (dr1, dr2))
1759 {
1760 add_edge (g, i, j);
1761 add_edge (g, j, i);
1762 }
1763
1764 queue = XNEWVEC (int, num_vertex);
1765 for (i = 0; i < num_vertex; i++)
1766 queue[i] = i;
1767
1768 num_component = graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1769
1770 for (i = 0; i < g->n_vertices; i++)
1771 {
1772 data_reference_p dr = VEC_index (data_reference_p, drs, i);
1773 if (!dr->aux)
1774 dr->aux = XNEWVEC (int, 2);
1775 ((int *)(dr->aux))[choice] = g->vertices[i].component + 1;
1776 }
1777
1778 free (queue);
1779 free_graph (g);
1780 }
1781
1782 static bool
1783 dr_same_base_object_p (const struct data_reference *dr1,
1784 const struct data_reference *dr2)
1785 {
1786 return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1787 }
1788
1789 /* Group each data reference in DRS with it's alias set num. */
1790
1791 static void
1792 build_alias_set_for_drs (VEC (data_reference_p, heap) *drs)
1793 {
1794 partition_drs_to_sets (drs, ALIAS_SET_INDEX, dr_may_alias_p);
1795 }
1796
1797 /* Group each data reference in DRS with it's base object set num. */
1798
1799 static void
1800 build_base_obj_set_for_drs (VEC (data_reference_p, heap) *drs)
1801 {
1802 partition_drs_to_sets (drs, BASE_OBJECT_SET_INDEX, dr_same_base_object_p);
1803 }
1804
1805 /* Build the data references for PBB. */
1806
1807 static void
1808 build_pbb_drs (poly_bb_p pbb)
1809 {
1810 int j;
1811 data_reference_p dr;
1812 VEC (data_reference_p, heap) *gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1813
1814 for (j = 0; VEC_iterate (data_reference_p, gbb_drs, j, dr); j++)
1815 build_poly_dr (dr, pbb);
1816 }
1817
1818 /* Build data references in SCOP. */
1819
1820 static void
1821 build_scop_drs (scop_p scop)
1822 {
1823 int i, j;
1824 poly_bb_p pbb;
1825 data_reference_p dr;
1826 VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
1827
1828 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1829 for (j = 0; VEC_iterate (data_reference_p,
1830 GBB_DATA_REFS (PBB_BLACK_BOX (pbb)), j, dr); j++)
1831 VEC_safe_push (data_reference_p, heap, drs, dr);
1832
1833 build_alias_set_for_drs (drs);
1834 build_base_obj_set_for_drs (drs);
1835
1836 /* When debugging, enable the following code. This cannot be used
1837 in production compilers. */
1838 #if 0
1839 {
1840 char comment[100];
1841 FILE *file;
1842
1843 file = fopen ("/tmp/dr_alias_graph", "ab");
1844 if (file)
1845 {
1846 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1847 current_function_name ());
1848 write_alias_graph_to_ascii_dimacs (file, comment, drs);
1849 fclose (file);
1850 }
1851 }
1852 #endif
1853
1854 VEC_free (data_reference_p, heap, drs);
1855
1856 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1857 build_pbb_drs (pbb);
1858 }
1859
1860 /* Return a gsi at the position of the phi node STMT. */
1861
1862 static gimple_stmt_iterator
1863 gsi_for_phi_node (gimple stmt)
1864 {
1865 gimple_stmt_iterator psi;
1866 basic_block bb = gimple_bb (stmt);
1867
1868 for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1869 if (stmt == gsi_stmt (psi))
1870 return psi;
1871
1872 gcc_unreachable ();
1873 return psi;
1874 }
1875
1876 /* Insert the assignment "RES := VAR" just after the definition of VAR. */
1877
1878 static void
1879 insert_out_of_ssa_copy (tree res, tree var)
1880 {
1881 gimple stmt;
1882 gimple_seq stmts;
1883 gimple_stmt_iterator si;
1884 gimple_stmt_iterator gsi;
1885
1886 var = force_gimple_operand (var, &stmts, true, NULL_TREE);
1887 stmt = gimple_build_assign (res, var);
1888 if (!stmts)
1889 stmts = gimple_seq_alloc ();
1890 si = gsi_last (stmts);
1891 gsi_insert_after (&si, stmt, GSI_NEW_STMT);
1892
1893 stmt = SSA_NAME_DEF_STMT (var);
1894 if (gimple_code (stmt) == GIMPLE_PHI)
1895 {
1896 gsi = gsi_after_labels (gimple_bb (stmt));
1897 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
1898 }
1899 else
1900 {
1901 gsi = gsi_for_stmt (stmt);
1902 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
1903 }
1904 }
1905
1906 /* Insert on edge E the assignment "RES := EXPR". */
1907
1908 static void
1909 insert_out_of_ssa_copy_on_edge (edge e, tree res, tree expr)
1910 {
1911 gimple_stmt_iterator gsi;
1912 gimple_seq stmts;
1913 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
1914 gimple stmt = gimple_build_assign (res, var);
1915
1916 if (!stmts)
1917 stmts = gimple_seq_alloc ();
1918
1919 gsi = gsi_last (stmts);
1920 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
1921 gsi_insert_seq_on_edge (e, stmts);
1922 gsi_commit_edge_inserts ();
1923 }
1924
1925 /* Creates a zero dimension array of the same type as VAR. */
1926
1927 static tree
1928 create_zero_dim_array (tree var)
1929 {
1930 tree index_type = build_index_type (integer_zero_node);
1931 tree elt_type = TREE_TYPE (var);
1932 tree array_type = build_array_type (elt_type, index_type);
1933 tree base = create_tmp_var (array_type, "Red");
1934
1935 add_referenced_var (base);
1936
1937 return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
1938 NULL_TREE);
1939 }
1940
1941 /* Returns true when PHI is a loop close phi node. */
1942
1943 static bool
1944 scalar_close_phi_node_p (gimple phi)
1945 {
1946 if (gimple_code (phi) != GIMPLE_PHI
1947 || !is_gimple_reg (gimple_phi_result (phi)))
1948 return false;
1949
1950 return (gimple_phi_num_args (phi) == 1);
1951 }
1952
1953 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
1954 dimension array for it. */
1955
1956 static void
1957 rewrite_close_phi_out_of_ssa (gimple_stmt_iterator *psi)
1958 {
1959 gimple phi = gsi_stmt (*psi);
1960 tree res = gimple_phi_result (phi);
1961 tree var = SSA_NAME_VAR (res);
1962 tree zero_dim_array = create_zero_dim_array (var);
1963 gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (phi));
1964 gimple stmt = gimple_build_assign (res, zero_dim_array);
1965 tree arg = gimple_phi_arg_def (phi, 0);
1966
1967 insert_out_of_ssa_copy (zero_dim_array, arg);
1968
1969 remove_phi_node (psi, false);
1970 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
1971 SSA_NAME_DEF_STMT (res) = stmt;
1972 }
1973
1974 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
1975 dimension array for it. */
1976
1977 static void
1978 rewrite_phi_out_of_ssa (gimple_stmt_iterator *psi)
1979 {
1980 size_t i;
1981 gimple phi = gsi_stmt (*psi);
1982 basic_block bb = gimple_bb (phi);
1983 tree res = gimple_phi_result (phi);
1984 tree var = SSA_NAME_VAR (res);
1985 tree zero_dim_array = create_zero_dim_array (var);
1986 gimple_stmt_iterator gsi;
1987 gimple stmt;
1988 gimple_seq stmts;
1989
1990 for (i = 0; i < gimple_phi_num_args (phi); i++)
1991 {
1992 tree arg = gimple_phi_arg_def (phi, i);
1993
1994 /* Try to avoid the insertion on edges as much as possible: this
1995 would avoid the insertion of code on loop latch edges, making
1996 the pattern matching of the vectorizer happy, or it would
1997 avoid the insertion of useless basic blocks. Note that it is
1998 incorrect to insert out of SSA copies close by their
1999 definition when they are more than two loop levels apart:
2000 for example, starting from a double nested loop
2001
2002 | a = ...
2003 | loop_1
2004 | loop_2
2005 | b = phi (a, c)
2006 | c = ...
2007 | end_2
2008 | end_1
2009
2010 the following transform is incorrect
2011
2012 | a = ...
2013 | Red[0] = a
2014 | loop_1
2015 | loop_2
2016 | b = Red[0]
2017 | c = ...
2018 | Red[0] = c
2019 | end_2
2020 | end_1
2021
2022 whereas inserting the copy on the incomming edge is correct
2023
2024 | a = ...
2025 | loop_1
2026 | Red[0] = a
2027 | loop_2
2028 | b = Red[0]
2029 | c = ...
2030 | Red[0] = c
2031 | end_2
2032 | end_1
2033 */
2034 if (TREE_CODE (arg) == SSA_NAME
2035 && is_gimple_reg (arg)
2036 && gimple_bb (SSA_NAME_DEF_STMT (arg))
2037 && (flow_bb_inside_loop_p (bb->loop_father,
2038 gimple_bb (SSA_NAME_DEF_STMT (arg)))
2039 || flow_bb_inside_loop_p (loop_outer (bb->loop_father),
2040 gimple_bb (SSA_NAME_DEF_STMT (arg)))))
2041 insert_out_of_ssa_copy (zero_dim_array, arg);
2042 else
2043 insert_out_of_ssa_copy_on_edge (gimple_phi_arg_edge (phi, i),
2044 zero_dim_array, arg);
2045 }
2046
2047 var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
2048
2049 if (!stmts)
2050 stmts = gimple_seq_alloc ();
2051
2052 stmt = gimple_build_assign (res, var);
2053 remove_phi_node (psi, false);
2054 SSA_NAME_DEF_STMT (res) = stmt;
2055
2056 gsi = gsi_last (stmts);
2057 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
2058
2059 gsi = gsi_after_labels (bb);
2060 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2061 }
2062
2063 /* Return true when DEF can be analyzed in REGION by the scalar
2064 evolution analyzer. */
2065
2066 static bool
2067 scev_analyzable_p (tree def, sese region)
2068 {
2069 gimple stmt = SSA_NAME_DEF_STMT (def);
2070 loop_p loop = loop_containing_stmt (stmt);
2071 tree scev = scalar_evolution_in_region (region, loop, def);
2072
2073 return !chrec_contains_undetermined (scev);
2074 }
2075
2076 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2077 read from ZERO_DIM_ARRAY. */
2078
2079 static void
2080 rewrite_cross_bb_scalar_dependence (tree zero_dim_array, tree def, gimple use_stmt)
2081 {
2082 tree var = SSA_NAME_VAR (def);
2083 gimple name_stmt = gimple_build_assign (var, zero_dim_array);
2084 tree name = make_ssa_name (var, name_stmt);
2085 ssa_op_iter iter;
2086 use_operand_p use_p;
2087 gimple_stmt_iterator gsi;
2088
2089 gimple_assign_set_lhs (name_stmt, name);
2090
2091 if (gimple_code (use_stmt) == GIMPLE_PHI)
2092 {
2093 gimple phi = use_stmt;
2094 edge entry;
2095 unsigned i;
2096
2097 for (i = 0; i < gimple_phi_num_args (phi); i++)
2098 if (operand_equal_p (def, gimple_phi_arg_def (phi, i), 0))
2099 {
2100 entry = gimple_phi_arg_edge (phi, i);
2101 break;
2102 }
2103
2104 FOR_EACH_PHI_ARG (use_p, phi, iter, SSA_OP_USE)
2105 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2106 {
2107 gsi = gsi_last_bb (entry->src);
2108 gsi_insert_after (&gsi, name_stmt, GSI_NEW_STMT);
2109 SET_USE (use_p, name);
2110 break;
2111 }
2112 }
2113 else
2114 {
2115 gsi = gsi_for_stmt (use_stmt);
2116 gsi_insert_before (&gsi, name_stmt, GSI_NEW_STMT);
2117
2118 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2119 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2120 replace_exp (use_p, name);
2121 }
2122
2123 update_stmt (use_stmt);
2124 }
2125
2126 /* Rewrite the scalar dependences crossing the boundary of the BB
2127 containing STMT with an array. */
2128
2129 static void
2130 rewrite_cross_bb_scalar_deps (sese region, gimple_stmt_iterator *gsi)
2131 {
2132 gimple stmt = gsi_stmt (*gsi);
2133 imm_use_iterator imm_iter;
2134 tree def;
2135 basic_block def_bb;
2136 tree zero_dim_array = NULL_TREE;
2137 gimple use_stmt;
2138
2139 if (gimple_code (stmt) != GIMPLE_ASSIGN)
2140 return;
2141
2142 def = gimple_assign_lhs (stmt);
2143 if (!is_gimple_reg (def)
2144 || scev_analyzable_p (def, region))
2145 return;
2146
2147 def_bb = gimple_bb (stmt);
2148
2149 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2150 if (def_bb != gimple_bb (use_stmt))
2151 {
2152 if (!zero_dim_array)
2153 {
2154 zero_dim_array = create_zero_dim_array (SSA_NAME_VAR (def));
2155 insert_out_of_ssa_copy (zero_dim_array, def);
2156 gsi_next (gsi);
2157 }
2158
2159 rewrite_cross_bb_scalar_dependence (zero_dim_array, def, use_stmt);
2160 }
2161 }
2162
2163 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2164
2165 static void
2166 rewrite_reductions_out_of_ssa (scop_p scop)
2167 {
2168 basic_block bb;
2169 gimple_stmt_iterator psi;
2170 sese region = SCOP_REGION (scop);
2171
2172 FOR_EACH_BB (bb)
2173 if (bb_in_sese_p (bb, region))
2174 for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2175 {
2176 if (scalar_close_phi_node_p (gsi_stmt (psi)))
2177 rewrite_close_phi_out_of_ssa (&psi);
2178 else if (reduction_phi_p (region, &psi))
2179 rewrite_phi_out_of_ssa (&psi);
2180 }
2181
2182 update_ssa (TODO_update_ssa);
2183 #ifdef ENABLE_CHECKING
2184 verify_ssa (false);
2185 verify_loop_closed_ssa ();
2186 #endif
2187
2188 FOR_EACH_BB (bb)
2189 if (bb_in_sese_p (bb, region))
2190 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2191 rewrite_cross_bb_scalar_deps (region, &psi);
2192
2193 update_ssa (TODO_update_ssa);
2194 #ifdef ENABLE_CHECKING
2195 verify_ssa (false);
2196 verify_loop_closed_ssa ();
2197 #endif
2198 }
2199
2200 /* Returns the number of pbbs that are in loops contained in SCOP. */
2201
2202 static int
2203 nb_pbbs_in_loops (scop_p scop)
2204 {
2205 int i;
2206 poly_bb_p pbb;
2207 int res = 0;
2208
2209 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
2210 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2211 res++;
2212
2213 return res;
2214 }
2215
2216 /* Splits STMT out of its current BB. */
2217
2218 static basic_block
2219 split_reduction_stmt (gimple stmt)
2220 {
2221 gimple_stmt_iterator gsi;
2222 basic_block bb = gimple_bb (stmt);
2223 edge e;
2224
2225 split_block (bb, stmt);
2226
2227 gsi = gsi_last_bb (bb);
2228 gsi_prev (&gsi);
2229 e = split_block (bb, gsi_stmt (gsi));
2230
2231 return e->dest;
2232 }
2233
2234 /* Return true when stmt is a reduction operation. */
2235
2236 static inline bool
2237 is_reduction_operation_p (gimple stmt)
2238 {
2239 return flag_associative_math
2240 && commutative_tree_code (gimple_assign_rhs_code (stmt))
2241 && associative_tree_code (gimple_assign_rhs_code (stmt));
2242 }
2243
2244 /* Returns true when PHI contains an argument ARG. */
2245
2246 static bool
2247 phi_contains_arg (gimple phi, tree arg)
2248 {
2249 size_t i;
2250
2251 for (i = 0; i < gimple_phi_num_args (phi); i++)
2252 if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2253 return true;
2254
2255 return false;
2256 }
2257
2258 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2259
2260 static gimple
2261 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2262 {
2263 gimple stmt;
2264
2265 if (TREE_CODE (arg) != SSA_NAME)
2266 return NULL;
2267
2268 stmt = SSA_NAME_DEF_STMT (arg);
2269
2270 if (gimple_code (stmt) == GIMPLE_PHI)
2271 {
2272 if (phi_contains_arg (stmt, lhs))
2273 return stmt;
2274 return NULL;
2275 }
2276
2277 if (gimple_num_ops (stmt) == 2)
2278 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2279
2280 if (is_reduction_operation_p (stmt))
2281 {
2282 gimple res = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2283
2284 return res ? res :
2285 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2286 }
2287
2288 return NULL;
2289 }
2290
2291 /* Detect commutative and associative scalar reductions starting at
2292 the STMT. */
2293
2294 static gimple
2295 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2296 VEC (gimple, heap) **in,
2297 VEC (gimple, heap) **out)
2298 {
2299 gimple phi = follow_ssa_with_commutative_ops (arg, lhs);
2300
2301 if (phi)
2302 {
2303 VEC_safe_push (gimple, heap, *in, stmt);
2304 VEC_safe_push (gimple, heap, *out, stmt);
2305 return phi;
2306 }
2307
2308 return NULL;
2309 }
2310
2311 /* Detect commutative and associative scalar reductions starting at
2312 the STMT. */
2313
2314 static gimple
2315 detect_commutative_reduction_assign (gimple stmt, VEC (gimple, heap) **in,
2316 VEC (gimple, heap) **out)
2317 {
2318 tree lhs = gimple_assign_lhs (stmt);
2319
2320 if (gimple_num_ops (stmt) == 2)
2321 return detect_commutative_reduction_arg (lhs, stmt,
2322 gimple_assign_rhs1 (stmt),
2323 in, out);
2324
2325 if (is_reduction_operation_p (stmt))
2326 {
2327 gimple res = detect_commutative_reduction_arg (lhs, stmt,
2328 gimple_assign_rhs1 (stmt),
2329 in, out);
2330 return res ? res
2331 : detect_commutative_reduction_arg (lhs, stmt,
2332 gimple_assign_rhs2 (stmt),
2333 in, out);
2334 }
2335
2336 return NULL;
2337 }
2338
2339 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2340
2341 static gimple
2342 follow_inital_value_to_phi (tree arg, tree lhs)
2343 {
2344 gimple stmt;
2345
2346 if (!arg || TREE_CODE (arg) != SSA_NAME)
2347 return NULL;
2348
2349 stmt = SSA_NAME_DEF_STMT (arg);
2350
2351 if (gimple_code (stmt) == GIMPLE_PHI
2352 && phi_contains_arg (stmt, lhs))
2353 return stmt;
2354
2355 return NULL;
2356 }
2357
2358
2359 /* Return the argument of the loop PHI that is the inital value coming
2360 from outside the loop. */
2361
2362 static edge
2363 edge_initial_value_for_loop_phi (gimple phi)
2364 {
2365 size_t i;
2366
2367 for (i = 0; i < gimple_phi_num_args (phi); i++)
2368 {
2369 edge e = gimple_phi_arg_edge (phi, i);
2370
2371 if (loop_depth (e->src->loop_father)
2372 < loop_depth (e->dest->loop_father))
2373 return e;
2374 }
2375
2376 return NULL;
2377 }
2378
2379 /* Return the argument of the loop PHI that is the inital value coming
2380 from outside the loop. */
2381
2382 static tree
2383 initial_value_for_loop_phi (gimple phi)
2384 {
2385 size_t i;
2386
2387 for (i = 0; i < gimple_phi_num_args (phi); i++)
2388 {
2389 edge e = gimple_phi_arg_edge (phi, i);
2390
2391 if (loop_depth (e->src->loop_father)
2392 < loop_depth (e->dest->loop_father))
2393 return gimple_phi_arg_def (phi, i);
2394 }
2395
2396 return NULL_TREE;
2397 }
2398
2399 /* Detect commutative and associative scalar reductions starting at
2400 the loop closed phi node CLOSE_PHI. */
2401
2402 static gimple
2403 detect_commutative_reduction (gimple stmt, VEC (gimple, heap) **in,
2404 VEC (gimple, heap) **out)
2405 {
2406 if (scalar_close_phi_node_p (stmt))
2407 {
2408 tree arg = gimple_phi_arg_def (stmt, 0);
2409 gimple def = SSA_NAME_DEF_STMT (arg);
2410 gimple loop_phi = detect_commutative_reduction (def, in, out);
2411
2412 if (loop_phi)
2413 {
2414 tree lhs = gimple_phi_result (stmt);
2415 tree init = initial_value_for_loop_phi (loop_phi);
2416 gimple phi = follow_inital_value_to_phi (init, lhs);
2417
2418 VEC_safe_push (gimple, heap, *in, loop_phi);
2419 VEC_safe_push (gimple, heap, *out, stmt);
2420 return phi;
2421 }
2422 else
2423 return NULL;
2424 }
2425
2426 if (gimple_code (stmt) == GIMPLE_ASSIGN)
2427 return detect_commutative_reduction_assign (stmt, in, out);
2428
2429 return NULL;
2430 }
2431
2432 /* Translate the scalar reduction statement STMT to an array RED
2433 knowing that its recursive phi node is LOOP_PHI. */
2434
2435 static void
2436 translate_scalar_reduction_to_array_for_stmt (tree red, gimple stmt,
2437 gimple loop_phi)
2438 {
2439 basic_block bb = gimple_bb (stmt);
2440 gimple_stmt_iterator insert_gsi = gsi_after_labels (bb);
2441 tree res = gimple_phi_result (loop_phi);
2442 gimple assign = gimple_build_assign (res, red);
2443
2444 gsi_insert_before (&insert_gsi, assign, GSI_SAME_STMT);
2445
2446 assign = gimple_build_assign (red, gimple_assign_lhs (stmt));
2447 insert_gsi = gsi_last_bb (bb);
2448 gsi_insert_after (&insert_gsi, assign, GSI_SAME_STMT);
2449 }
2450
2451 /* Insert the assignment "result (CLOSE_PHI) = RED". */
2452
2453 static void
2454 insert_copyout (tree red, gimple close_phi)
2455 {
2456 tree res = gimple_phi_result (close_phi);
2457 basic_block bb = gimple_bb (close_phi);
2458 gimple_stmt_iterator insert_gsi = gsi_after_labels (bb);
2459 gimple assign = gimple_build_assign (res, red);
2460
2461 gsi_insert_before (&insert_gsi, assign, GSI_SAME_STMT);
2462 }
2463
2464 /* Insert the assignment "RED = initial_value (LOOP_PHI)". */
2465
2466 static void
2467 insert_copyin (tree red, gimple loop_phi)
2468 {
2469 gimple_seq stmts;
2470 tree init = initial_value_for_loop_phi (loop_phi);
2471 edge e = edge_initial_value_for_loop_phi (loop_phi);
2472 basic_block bb = e->src;
2473 gimple_stmt_iterator insert_gsi = gsi_last_bb (bb);
2474 tree expr = build2 (MODIFY_EXPR, TREE_TYPE (init), red, init);
2475
2476 force_gimple_operand (expr, &stmts, true, NULL);
2477 gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
2478 }
2479
2480 /* Rewrite out of SSA the reduction described by the loop phi nodes
2481 IN, and the close phi nodes OUT. IN and OUT are structured by loop
2482 levels like this:
2483
2484 IN: stmt, loop_n, ..., loop_0
2485 OUT: stmt, close_n, ..., close_0
2486
2487 the first element is the reduction statement, and the next elements
2488 are the loop and close phi nodes of each of the outer loops. */
2489
2490 static void
2491 translate_scalar_reduction_to_array (VEC (gimple, heap) *in,
2492 VEC (gimple, heap) *out,
2493 sbitmap reductions)
2494 {
2495 unsigned int i;
2496 gimple loop_phi;
2497 tree red;
2498 gimple_stmt_iterator gsi;
2499
2500 for (i = 0; VEC_iterate (gimple, in, i, loop_phi); i++)
2501 {
2502 gimple close_phi = VEC_index (gimple, out, i);
2503
2504 if (i == 0)
2505 {
2506 gimple stmt = loop_phi;
2507 basic_block bb = split_reduction_stmt (stmt);
2508
2509 SET_BIT (reductions, bb->index);
2510 gcc_assert (close_phi == loop_phi);
2511
2512 red = create_zero_dim_array (gimple_assign_lhs (stmt));
2513 translate_scalar_reduction_to_array_for_stmt
2514 (red, stmt, VEC_index (gimple, in, 1));
2515 continue;
2516 }
2517
2518 if (i == VEC_length (gimple, in) - 1)
2519 {
2520 insert_copyout (red, close_phi);
2521 insert_copyin (red, loop_phi);
2522 }
2523
2524 gsi = gsi_for_phi_node (loop_phi);
2525 remove_phi_node (&gsi, false);
2526
2527 gsi = gsi_for_phi_node (close_phi);
2528 remove_phi_node (&gsi, false);
2529 }
2530 }
2531
2532 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI. */
2533
2534 static void
2535 rewrite_commutative_reductions_out_of_ssa_close_phi (gimple close_phi,
2536 sbitmap reductions)
2537 {
2538 VEC (gimple, heap) *in = VEC_alloc (gimple, heap, 10);
2539 VEC (gimple, heap) *out = VEC_alloc (gimple, heap, 10);
2540
2541 detect_commutative_reduction (close_phi, &in, &out);
2542 if (VEC_length (gimple, in) > 0)
2543 translate_scalar_reduction_to_array (in, out, reductions);
2544
2545 VEC_free (gimple, heap, in);
2546 VEC_free (gimple, heap, out);
2547 }
2548
2549 /* Rewrites all the commutative reductions from LOOP out of SSA. */
2550
2551 static void
2552 rewrite_commutative_reductions_out_of_ssa_loop (loop_p loop,
2553 sbitmap reductions)
2554 {
2555 gimple_stmt_iterator gsi;
2556 edge exit = single_exit (loop);
2557
2558 if (!exit)
2559 return;
2560
2561 for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
2562 rewrite_commutative_reductions_out_of_ssa_close_phi (gsi_stmt (gsi),
2563 reductions);
2564 }
2565
2566 /* Rewrites all the commutative reductions from SCOP out of SSA. */
2567
2568 static void
2569 rewrite_commutative_reductions_out_of_ssa (sese region, sbitmap reductions)
2570 {
2571 loop_iterator li;
2572 loop_p loop;
2573
2574 FOR_EACH_LOOP (li, loop, 0)
2575 if (loop_in_sese_p (loop, region))
2576 rewrite_commutative_reductions_out_of_ssa_loop (loop, reductions);
2577 }
2578
2579 /* Builds the polyhedral representation for a SESE region. */
2580
2581 bool
2582 build_poly_scop (scop_p scop)
2583 {
2584 sese region = SCOP_REGION (scop);
2585 sbitmap reductions = sbitmap_alloc (last_basic_block * 2);
2586
2587 sbitmap_zero (reductions);
2588 rewrite_commutative_reductions_out_of_ssa (region, reductions);
2589 rewrite_reductions_out_of_ssa (scop);
2590 build_scop_bbs (scop, reductions);
2591 sbitmap_free (reductions);
2592
2593 /* FIXME: This restriction is needed to avoid a problem in CLooG.
2594 Once CLooG is fixed, remove this guard. Anyways, it makes no
2595 sense to optimize a scop containing only PBBs that do not belong
2596 to any loops. */
2597 if (nb_pbbs_in_loops (scop) == 0)
2598 return false;
2599
2600 build_sese_loop_nests (region);
2601 build_sese_conditions (region);
2602 find_scop_parameters (scop);
2603
2604 build_scop_iteration_domain (scop);
2605 build_scop_context (scop);
2606
2607 add_conditions_to_constraints (scop);
2608 build_scop_scattering (scop);
2609 build_scop_drs (scop);
2610
2611 return true;
2612 }
2613
2614 /* Always return false. Exercise the scop_to_clast function. */
2615
2616 void
2617 check_poly_representation (scop_p scop ATTRIBUTE_UNUSED)
2618 {
2619 #ifdef ENABLE_CHECKING
2620 cloog_prog_clast pc = scop_to_clast (scop);
2621 cloog_clast_free (pc.stmt);
2622 cloog_program_free (pc.prog);
2623 #endif
2624 }
2625 #endif