]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/graphite-sese-to-poly.c
coretypes.h (gimple_seq, [...]): Typedef as gimple.
[thirdparty/gcc.git] / gcc / graphite-sese-to-poly.c
1 /* Conversion of SESE regions to Polyhedra.
2 Copyright (C) 2009, 2010, 2011 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 "tree-flow.h"
25 #include "tree-dump.h"
26 #include "cfgloop.h"
27 #include "tree-chrec.h"
28 #include "tree-data-ref.h"
29 #include "tree-scalar-evolution.h"
30 #include "domwalk.h"
31 #include "sese.h"
32
33 #ifdef HAVE_cloog
34 #include "ppl_c.h"
35 #include "graphite-ppl.h"
36 #include "graphite-poly.h"
37 #include "graphite-sese-to-poly.h"
38
39 /* Returns the index of the PHI argument defined in the outermost
40 loop. */
41
42 static size_t
43 phi_arg_in_outermost_loop (gimple phi)
44 {
45 loop_p loop = gimple_bb (phi)->loop_father;
46 size_t i, res = 0;
47
48 for (i = 0; i < gimple_phi_num_args (phi); i++)
49 if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
50 {
51 loop = gimple_phi_arg_edge (phi, i)->src->loop_father;
52 res = i;
53 }
54
55 return res;
56 }
57
58 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
59 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
60
61 static void
62 remove_simple_copy_phi (gimple_stmt_iterator *psi)
63 {
64 gimple phi = gsi_stmt (*psi);
65 tree res = gimple_phi_result (phi);
66 size_t entry = phi_arg_in_outermost_loop (phi);
67 tree init = gimple_phi_arg_def (phi, entry);
68 gimple stmt = gimple_build_assign (res, init);
69 edge e = gimple_phi_arg_edge (phi, entry);
70
71 remove_phi_node (psi, false);
72 gsi_insert_on_edge_immediate (e, stmt);
73 SSA_NAME_DEF_STMT (res) = stmt;
74 }
75
76 /* Removes an invariant phi node at position PSI by inserting on the
77 loop ENTRY edge the assignment RES = INIT. */
78
79 static void
80 remove_invariant_phi (sese region, gimple_stmt_iterator *psi)
81 {
82 gimple phi = gsi_stmt (*psi);
83 loop_p loop = loop_containing_stmt (phi);
84 tree res = gimple_phi_result (phi);
85 tree scev = scalar_evolution_in_region (region, loop, res);
86 size_t entry = phi_arg_in_outermost_loop (phi);
87 edge e = gimple_phi_arg_edge (phi, entry);
88 tree var;
89 gimple stmt;
90 gimple_seq stmts = NULL;
91
92 if (tree_contains_chrecs (scev, NULL))
93 scev = gimple_phi_arg_def (phi, entry);
94
95 var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
96 stmt = gimple_build_assign (res, var);
97 remove_phi_node (psi, false);
98
99 gimple_seq_add_stmt (&stmts, stmt);
100 gsi_insert_seq_on_edge (e, stmts);
101 gsi_commit_edge_inserts ();
102 SSA_NAME_DEF_STMT (res) = stmt;
103 }
104
105 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
106
107 static inline bool
108 simple_copy_phi_p (gimple phi)
109 {
110 tree res;
111
112 if (gimple_phi_num_args (phi) != 2)
113 return false;
114
115 res = gimple_phi_result (phi);
116 return (res == gimple_phi_arg_def (phi, 0)
117 || res == gimple_phi_arg_def (phi, 1));
118 }
119
120 /* Returns true when the phi node at position PSI is a reduction phi
121 node in REGION. Otherwise moves the pointer PSI to the next phi to
122 be considered. */
123
124 static bool
125 reduction_phi_p (sese region, gimple_stmt_iterator *psi)
126 {
127 loop_p loop;
128 gimple phi = gsi_stmt (*psi);
129 tree res = gimple_phi_result (phi);
130
131 loop = loop_containing_stmt (phi);
132
133 if (simple_copy_phi_p (phi))
134 {
135 /* PRE introduces phi nodes like these, for an example,
136 see id-5.f in the fortran graphite testsuite:
137
138 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
139 */
140 remove_simple_copy_phi (psi);
141 return false;
142 }
143
144 if (scev_analyzable_p (res, region))
145 {
146 tree scev = scalar_evolution_in_region (region, loop, res);
147
148 if (evolution_function_is_invariant_p (scev, loop->num))
149 remove_invariant_phi (region, psi);
150 else
151 gsi_next (psi);
152
153 return false;
154 }
155
156 /* All the other cases are considered reductions. */
157 return true;
158 }
159
160 /* Store the GRAPHITE representation of BB. */
161
162 static gimple_bb_p
163 new_gimple_bb (basic_block bb, VEC (data_reference_p, heap) *drs)
164 {
165 struct gimple_bb *gbb;
166
167 gbb = XNEW (struct gimple_bb);
168 bb->aux = gbb;
169 GBB_BB (gbb) = bb;
170 GBB_DATA_REFS (gbb) = drs;
171 GBB_CONDITIONS (gbb) = NULL;
172 GBB_CONDITION_CASES (gbb) = NULL;
173
174 return gbb;
175 }
176
177 static void
178 free_data_refs_aux (VEC (data_reference_p, heap) *datarefs)
179 {
180 unsigned int i;
181 struct data_reference *dr;
182
183 FOR_EACH_VEC_ELT (data_reference_p, datarefs, i, dr)
184 if (dr->aux)
185 {
186 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
187
188 free (bap->alias_set);
189
190 free (bap);
191 dr->aux = NULL;
192 }
193 }
194 /* Frees GBB. */
195
196 static void
197 free_gimple_bb (struct gimple_bb *gbb)
198 {
199 free_data_refs_aux (GBB_DATA_REFS (gbb));
200 free_data_refs (GBB_DATA_REFS (gbb));
201
202 VEC_free (gimple, heap, GBB_CONDITIONS (gbb));
203 VEC_free (gimple, heap, GBB_CONDITION_CASES (gbb));
204 GBB_BB (gbb)->aux = 0;
205 XDELETE (gbb);
206 }
207
208 /* Deletes all gimple bbs in SCOP. */
209
210 static void
211 remove_gbbs_in_scop (scop_p scop)
212 {
213 int i;
214 poly_bb_p pbb;
215
216 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
217 free_gimple_bb (PBB_BLACK_BOX (pbb));
218 }
219
220 /* Deletes all scops in SCOPS. */
221
222 void
223 free_scops (VEC (scop_p, heap) *scops)
224 {
225 int i;
226 scop_p scop;
227
228 FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
229 {
230 remove_gbbs_in_scop (scop);
231 free_sese (SCOP_REGION (scop));
232 free_scop (scop);
233 }
234
235 VEC_free (scop_p, heap, scops);
236 }
237
238 /* Same as outermost_loop_in_sese, returns the outermost loop
239 containing BB in REGION, but makes sure that the returned loop
240 belongs to the REGION, and so this returns the first loop in the
241 REGION when the loop containing BB does not belong to REGION. */
242
243 static loop_p
244 outermost_loop_in_sese_1 (sese region, basic_block bb)
245 {
246 loop_p nest = outermost_loop_in_sese (region, bb);
247
248 if (loop_in_sese_p (nest, region))
249 return nest;
250
251 /* When the basic block BB does not belong to a loop in the region,
252 return the first loop in the region. */
253 nest = nest->inner;
254 while (nest)
255 if (loop_in_sese_p (nest, region))
256 break;
257 else
258 nest = nest->next;
259
260 gcc_assert (nest);
261 return nest;
262 }
263
264 /* Generates a polyhedral black box only if the bb contains interesting
265 information. */
266
267 static gimple_bb_p
268 try_generate_gimple_bb (scop_p scop, basic_block bb)
269 {
270 VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
271 sese region = SCOP_REGION (scop);
272 loop_p nest = outermost_loop_in_sese_1 (region, bb);
273 gimple_stmt_iterator gsi;
274
275 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
276 {
277 gimple stmt = gsi_stmt (gsi);
278 loop_p loop;
279
280 if (is_gimple_debug (stmt))
281 continue;
282
283 loop = loop_containing_stmt (stmt);
284 if (!loop_in_sese_p (loop, region))
285 loop = nest;
286
287 graphite_find_data_references_in_stmt (nest, loop, stmt, &drs);
288 }
289
290 return new_gimple_bb (bb, drs);
291 }
292
293 /* Returns true if all predecessors of BB, that are not dominated by BB, are
294 marked in MAP. The predecessors dominated by BB are loop latches and will
295 be handled after BB. */
296
297 static bool
298 all_non_dominated_preds_marked_p (basic_block bb, sbitmap map)
299 {
300 edge e;
301 edge_iterator ei;
302
303 FOR_EACH_EDGE (e, ei, bb->preds)
304 if (!TEST_BIT (map, e->src->index)
305 && !dominated_by_p (CDI_DOMINATORS, e->src, bb))
306 return false;
307
308 return true;
309 }
310
311 /* Compare the depth of two basic_block's P1 and P2. */
312
313 static int
314 compare_bb_depths (const void *p1, const void *p2)
315 {
316 const_basic_block const bb1 = *(const_basic_block const*)p1;
317 const_basic_block const bb2 = *(const_basic_block const*)p2;
318 int d1 = loop_depth (bb1->loop_father);
319 int d2 = loop_depth (bb2->loop_father);
320
321 if (d1 < d2)
322 return 1;
323
324 if (d1 > d2)
325 return -1;
326
327 return 0;
328 }
329
330 /* Sort the basic blocks from DOM such that the first are the ones at
331 a deepest loop level. */
332
333 static void
334 graphite_sort_dominated_info (VEC (basic_block, heap) *dom)
335 {
336 VEC_qsort (basic_block, dom, compare_bb_depths);
337 }
338
339 /* Recursive helper function for build_scops_bbs. */
340
341 static void
342 build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
343 {
344 sese region = SCOP_REGION (scop);
345 VEC (basic_block, heap) *dom;
346 poly_bb_p pbb;
347
348 if (TEST_BIT (visited, bb->index)
349 || !bb_in_sese_p (bb, region))
350 return;
351
352 pbb = new_poly_bb (scop, try_generate_gimple_bb (scop, bb));
353 VEC_safe_push (poly_bb_p, heap, SCOP_BBS (scop), pbb);
354 SET_BIT (visited, bb->index);
355
356 dom = get_dominated_by (CDI_DOMINATORS, bb);
357
358 if (dom == NULL)
359 return;
360
361 graphite_sort_dominated_info (dom);
362
363 while (!VEC_empty (basic_block, dom))
364 {
365 int i;
366 basic_block dom_bb;
367
368 FOR_EACH_VEC_ELT (basic_block, dom, i, dom_bb)
369 if (all_non_dominated_preds_marked_p (dom_bb, visited))
370 {
371 build_scop_bbs_1 (scop, visited, dom_bb);
372 VEC_unordered_remove (basic_block, dom, i);
373 break;
374 }
375 }
376
377 VEC_free (basic_block, heap, dom);
378 }
379
380 /* Gather the basic blocks belonging to the SCOP. */
381
382 static void
383 build_scop_bbs (scop_p scop)
384 {
385 sbitmap visited = sbitmap_alloc (last_basic_block);
386 sese region = SCOP_REGION (scop);
387
388 sbitmap_zero (visited);
389 build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region));
390 sbitmap_free (visited);
391 }
392
393 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
394 We generate SCATTERING_DIMENSIONS scattering dimensions.
395
396 CLooG 0.15.0 and previous versions require, that all
397 scattering functions of one CloogProgram have the same number of
398 scattering dimensions, therefore we allow to specify it. This
399 should be removed in future versions of CLooG.
400
401 The scattering polyhedron consists of these dimensions: scattering,
402 loop_iterators, parameters.
403
404 Example:
405
406 | scattering_dimensions = 5
407 | used_scattering_dimensions = 3
408 | nb_iterators = 1
409 | scop_nb_params = 2
410 |
411 | Schedule:
412 | i
413 | 4 5
414 |
415 | Scattering polyhedron:
416 |
417 | scattering: {s1, s2, s3, s4, s5}
418 | loop_iterators: {i}
419 | parameters: {p1, p2}
420 |
421 | s1 s2 s3 s4 s5 i p1 p2 1
422 | 1 0 0 0 0 0 0 0 -4 = 0
423 | 0 1 0 0 0 -1 0 0 0 = 0
424 | 0 0 1 0 0 0 0 0 -5 = 0 */
425
426 static void
427 build_pbb_scattering_polyhedrons (ppl_Linear_Expression_t static_schedule,
428 poly_bb_p pbb, int scattering_dimensions)
429 {
430 int i;
431 scop_p scop = PBB_SCOP (pbb);
432 int nb_iterators = pbb_dim_iter_domain (pbb);
433 int used_scattering_dimensions = nb_iterators * 2 + 1;
434 int nb_params = scop_nb_params (scop);
435 ppl_Coefficient_t c;
436 ppl_dimension_type dim = scattering_dimensions + nb_iterators + nb_params;
437 mpz_t v;
438
439 gcc_assert (scattering_dimensions >= used_scattering_dimensions);
440
441 mpz_init (v);
442 ppl_new_Coefficient (&c);
443 PBB_TRANSFORMED (pbb) = poly_scattering_new ();
444 ppl_new_C_Polyhedron_from_space_dimension
445 (&PBB_TRANSFORMED_SCATTERING (pbb), dim, 0);
446
447 PBB_NB_SCATTERING_TRANSFORM (pbb) = scattering_dimensions;
448
449 for (i = 0; i < scattering_dimensions; i++)
450 {
451 ppl_Constraint_t cstr;
452 ppl_Linear_Expression_t expr;
453
454 ppl_new_Linear_Expression_with_dimension (&expr, dim);
455 mpz_set_si (v, 1);
456 ppl_assign_Coefficient_from_mpz_t (c, v);
457 ppl_Linear_Expression_add_to_coefficient (expr, i, c);
458
459 /* Textual order inside this loop. */
460 if ((i % 2) == 0)
461 {
462 ppl_Linear_Expression_coefficient (static_schedule, i / 2, c);
463 ppl_Coefficient_to_mpz_t (c, v);
464 mpz_neg (v, v);
465 ppl_assign_Coefficient_from_mpz_t (c, v);
466 ppl_Linear_Expression_add_to_inhomogeneous (expr, c);
467 }
468
469 /* Iterations of this loop. */
470 else /* if ((i % 2) == 1) */
471 {
472 int loop = (i - 1) / 2;
473
474 mpz_set_si (v, -1);
475 ppl_assign_Coefficient_from_mpz_t (c, v);
476 ppl_Linear_Expression_add_to_coefficient
477 (expr, scattering_dimensions + loop, c);
478 }
479
480 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL);
481 ppl_Polyhedron_add_constraint (PBB_TRANSFORMED_SCATTERING (pbb), cstr);
482 ppl_delete_Linear_Expression (expr);
483 ppl_delete_Constraint (cstr);
484 }
485
486 mpz_clear (v);
487 ppl_delete_Coefficient (c);
488
489 PBB_ORIGINAL (pbb) = poly_scattering_copy (PBB_TRANSFORMED (pbb));
490 }
491
492 /* Build for BB the static schedule.
493
494 The static schedule is a Dewey numbering of the abstract syntax
495 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
496
497 The following example informally defines the static schedule:
498
499 A
500 for (i: ...)
501 {
502 for (j: ...)
503 {
504 B
505 C
506 }
507
508 for (k: ...)
509 {
510 D
511 E
512 }
513 }
514 F
515
516 Static schedules for A to F:
517
518 DEPTH
519 0 1 2
520 A 0
521 B 1 0 0
522 C 1 0 1
523 D 1 1 0
524 E 1 1 1
525 F 2
526 */
527
528 static void
529 build_scop_scattering (scop_p scop)
530 {
531 int i;
532 poly_bb_p pbb;
533 gimple_bb_p previous_gbb = NULL;
534 ppl_Linear_Expression_t static_schedule;
535 ppl_Coefficient_t c;
536 mpz_t v;
537
538 mpz_init (v);
539 ppl_new_Coefficient (&c);
540 ppl_new_Linear_Expression (&static_schedule);
541
542 /* We have to start schedules at 0 on the first component and
543 because we cannot compare_prefix_loops against a previous loop,
544 prefix will be equal to zero, and that index will be
545 incremented before copying. */
546 mpz_set_si (v, -1);
547 ppl_assign_Coefficient_from_mpz_t (c, v);
548 ppl_Linear_Expression_add_to_coefficient (static_schedule, 0, c);
549
550 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
551 {
552 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
553 ppl_Linear_Expression_t common;
554 int prefix;
555 int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1;
556
557 if (previous_gbb)
558 prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
559 else
560 prefix = 0;
561
562 previous_gbb = gbb;
563 ppl_new_Linear_Expression_with_dimension (&common, prefix + 1);
564 ppl_assign_Linear_Expression_from_Linear_Expression (common,
565 static_schedule);
566
567 mpz_set_si (v, 1);
568 ppl_assign_Coefficient_from_mpz_t (c, v);
569 ppl_Linear_Expression_add_to_coefficient (common, prefix, c);
570 ppl_assign_Linear_Expression_from_Linear_Expression (static_schedule,
571 common);
572
573 build_pbb_scattering_polyhedrons (common, pbb, nb_scat_dims);
574
575 ppl_delete_Linear_Expression (common);
576 }
577
578 mpz_clear (v);
579 ppl_delete_Coefficient (c);
580 ppl_delete_Linear_Expression (static_schedule);
581 }
582
583 /* Add the value K to the dimension D of the linear expression EXPR. */
584
585 static void
586 add_value_to_dim (ppl_dimension_type d, ppl_Linear_Expression_t expr,
587 mpz_t k)
588 {
589 mpz_t val;
590 ppl_Coefficient_t coef;
591
592 ppl_new_Coefficient (&coef);
593 ppl_Linear_Expression_coefficient (expr, d, coef);
594 mpz_init (val);
595 ppl_Coefficient_to_mpz_t (coef, val);
596
597 mpz_add (val, val, k);
598
599 ppl_assign_Coefficient_from_mpz_t (coef, val);
600 ppl_Linear_Expression_add_to_coefficient (expr, d, coef);
601 mpz_clear (val);
602 ppl_delete_Coefficient (coef);
603 }
604
605 /* In the context of scop S, scan E, the right hand side of a scalar
606 evolution function in loop VAR, and translate it to a linear
607 expression EXPR. */
608
609 static void
610 scan_tree_for_params_right_scev (sese s, tree e, int var,
611 ppl_Linear_Expression_t expr)
612 {
613 if (expr)
614 {
615 loop_p loop = get_loop (var);
616 ppl_dimension_type l = sese_loop_depth (s, loop) - 1;
617 mpz_t val;
618
619 /* Scalar evolutions should happen in the sese region. */
620 gcc_assert (sese_loop_depth (s, loop) > 0);
621
622 /* We can not deal with parametric strides like:
623
624 | p = parameter;
625 |
626 | for i:
627 | a [i * p] = ... */
628 gcc_assert (TREE_CODE (e) == INTEGER_CST);
629
630 mpz_init (val);
631 tree_int_to_gmp (e, val);
632 add_value_to_dim (l, expr, val);
633 mpz_clear (val);
634 }
635 }
636
637 /* Scan the integer constant CST, and add it to the inhomogeneous part of the
638 linear expression EXPR. K is the multiplier of the constant. */
639
640 static void
641 scan_tree_for_params_int (tree cst, ppl_Linear_Expression_t expr, mpz_t k)
642 {
643 mpz_t val;
644 ppl_Coefficient_t coef;
645 tree type = TREE_TYPE (cst);
646
647 mpz_init (val);
648
649 /* Necessary to not get "-1 = 2^n - 1". */
650 mpz_set_double_int (val, double_int_sext (tree_to_double_int (cst),
651 TYPE_PRECISION (type)), false);
652
653 mpz_mul (val, val, k);
654 ppl_new_Coefficient (&coef);
655 ppl_assign_Coefficient_from_mpz_t (coef, val);
656 ppl_Linear_Expression_add_to_inhomogeneous (expr, coef);
657 mpz_clear (val);
658 ppl_delete_Coefficient (coef);
659 }
660
661 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
662 Otherwise returns -1. */
663
664 static inline int
665 parameter_index_in_region_1 (tree name, sese region)
666 {
667 int i;
668 tree p;
669
670 gcc_assert (TREE_CODE (name) == SSA_NAME);
671
672 FOR_EACH_VEC_ELT (tree, SESE_PARAMS (region), i, p)
673 if (p == name)
674 return i;
675
676 return -1;
677 }
678
679 /* When the parameter NAME is in REGION, returns its index in
680 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
681 and returns the index of NAME. */
682
683 static int
684 parameter_index_in_region (tree name, sese region)
685 {
686 int i;
687
688 gcc_assert (TREE_CODE (name) == SSA_NAME);
689
690 i = parameter_index_in_region_1 (name, region);
691 if (i != -1)
692 return i;
693
694 gcc_assert (SESE_ADD_PARAMS (region));
695
696 i = VEC_length (tree, SESE_PARAMS (region));
697 VEC_safe_push (tree, heap, SESE_PARAMS (region), name);
698 return i;
699 }
700
701 /* In the context of sese S, scan the expression E and translate it to
702 a linear expression C. When parsing a symbolic multiplication, K
703 represents the constant multiplier of an expression containing
704 parameters. */
705
706 static void
707 scan_tree_for_params (sese s, tree e, ppl_Linear_Expression_t c,
708 mpz_t k)
709 {
710 if (e == chrec_dont_know)
711 return;
712
713 switch (TREE_CODE (e))
714 {
715 case POLYNOMIAL_CHREC:
716 scan_tree_for_params_right_scev (s, CHREC_RIGHT (e),
717 CHREC_VARIABLE (e), c);
718 scan_tree_for_params (s, CHREC_LEFT (e), c, k);
719 break;
720
721 case MULT_EXPR:
722 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
723 {
724 if (c)
725 {
726 mpz_t val;
727 gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0));
728 mpz_init (val);
729 tree_int_to_gmp (TREE_OPERAND (e, 1), val);
730 mpz_mul (val, val, k);
731 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, val);
732 mpz_clear (val);
733 }
734 else
735 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
736 }
737 else
738 {
739 if (c)
740 {
741 mpz_t val;
742 gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0));
743 mpz_init (val);
744 tree_int_to_gmp (TREE_OPERAND (e, 0), val);
745 mpz_mul (val, val, k);
746 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, val);
747 mpz_clear (val);
748 }
749 else
750 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k);
751 }
752 break;
753
754 case PLUS_EXPR:
755 case POINTER_PLUS_EXPR:
756 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
757 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k);
758 break;
759
760 case MINUS_EXPR:
761 {
762 ppl_Linear_Expression_t tmp_expr = NULL;
763
764 if (c)
765 {
766 ppl_dimension_type dim;
767 ppl_Linear_Expression_space_dimension (c, &dim);
768 ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
769 }
770
771 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
772 scan_tree_for_params (s, TREE_OPERAND (e, 1), tmp_expr, k);
773
774 if (c)
775 {
776 ppl_subtract_Linear_Expression_from_Linear_Expression (c,
777 tmp_expr);
778 ppl_delete_Linear_Expression (tmp_expr);
779 }
780
781 break;
782 }
783
784 case NEGATE_EXPR:
785 {
786 ppl_Linear_Expression_t tmp_expr = NULL;
787
788 if (c)
789 {
790 ppl_dimension_type dim;
791 ppl_Linear_Expression_space_dimension (c, &dim);
792 ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
793 }
794
795 scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k);
796
797 if (c)
798 {
799 ppl_subtract_Linear_Expression_from_Linear_Expression (c,
800 tmp_expr);
801 ppl_delete_Linear_Expression (tmp_expr);
802 }
803
804 break;
805 }
806
807 case BIT_NOT_EXPR:
808 {
809 ppl_Linear_Expression_t tmp_expr = NULL;
810
811 if (c)
812 {
813 ppl_dimension_type dim;
814 ppl_Linear_Expression_space_dimension (c, &dim);
815 ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
816 }
817
818 scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k);
819
820 if (c)
821 {
822 ppl_Coefficient_t coef;
823 mpz_t minus_one;
824
825 ppl_subtract_Linear_Expression_from_Linear_Expression (c,
826 tmp_expr);
827 ppl_delete_Linear_Expression (tmp_expr);
828 mpz_init (minus_one);
829 mpz_set_si (minus_one, -1);
830 ppl_new_Coefficient_from_mpz_t (&coef, minus_one);
831 ppl_Linear_Expression_add_to_inhomogeneous (c, coef);
832 mpz_clear (minus_one);
833 ppl_delete_Coefficient (coef);
834 }
835
836 break;
837 }
838
839 case SSA_NAME:
840 {
841 ppl_dimension_type p = parameter_index_in_region (e, s);
842
843 if (c)
844 {
845 ppl_dimension_type dim;
846 ppl_Linear_Expression_space_dimension (c, &dim);
847 p += dim - sese_nb_params (s);
848 add_value_to_dim (p, c, k);
849 }
850 break;
851 }
852
853 case INTEGER_CST:
854 if (c)
855 scan_tree_for_params_int (e, c, k);
856 break;
857
858 CASE_CONVERT:
859 case NON_LVALUE_EXPR:
860 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
861 break;
862
863 case ADDR_EXPR:
864 break;
865
866 default:
867 gcc_unreachable ();
868 break;
869 }
870 }
871
872 /* Find parameters with respect to REGION in BB. We are looking in memory
873 access functions, conditions and loop bounds. */
874
875 static void
876 find_params_in_bb (sese region, gimple_bb_p gbb)
877 {
878 int i;
879 unsigned j;
880 data_reference_p dr;
881 gimple stmt;
882 loop_p loop = GBB_BB (gbb)->loop_father;
883 mpz_t one;
884
885 mpz_init (one);
886 mpz_set_si (one, 1);
887
888 /* Find parameters in the access functions of data references. */
889 FOR_EACH_VEC_ELT (data_reference_p, GBB_DATA_REFS (gbb), i, dr)
890 for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
891 scan_tree_for_params (region, DR_ACCESS_FN (dr, j), NULL, one);
892
893 /* Find parameters in conditional statements. */
894 FOR_EACH_VEC_ELT (gimple, GBB_CONDITIONS (gbb), i, stmt)
895 {
896 tree lhs = scalar_evolution_in_region (region, loop,
897 gimple_cond_lhs (stmt));
898 tree rhs = scalar_evolution_in_region (region, loop,
899 gimple_cond_rhs (stmt));
900
901 scan_tree_for_params (region, lhs, NULL, one);
902 scan_tree_for_params (region, rhs, NULL, one);
903 }
904
905 mpz_clear (one);
906 }
907
908 /* Record the parameters used in the SCOP. A variable is a parameter
909 in a scop if it does not vary during the execution of that scop. */
910
911 static void
912 find_scop_parameters (scop_p scop)
913 {
914 poly_bb_p pbb;
915 unsigned i;
916 sese region = SCOP_REGION (scop);
917 struct loop *loop;
918 mpz_t one;
919
920 mpz_init (one);
921 mpz_set_si (one, 1);
922
923 /* Find the parameters used in the loop bounds. */
924 FOR_EACH_VEC_ELT (loop_p, SESE_LOOP_NEST (region), i, loop)
925 {
926 tree nb_iters = number_of_latch_executions (loop);
927
928 if (!chrec_contains_symbols (nb_iters))
929 continue;
930
931 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
932 scan_tree_for_params (region, nb_iters, NULL, one);
933 }
934
935 mpz_clear (one);
936
937 /* Find the parameters used in data accesses. */
938 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
939 find_params_in_bb (region, PBB_BLACK_BOX (pbb));
940
941 scop_set_nb_params (scop, sese_nb_params (region));
942 SESE_ADD_PARAMS (region) = false;
943
944 ppl_new_Pointset_Powerset_C_Polyhedron_from_space_dimension
945 (&SCOP_CONTEXT (scop), scop_nb_params (scop), 0);
946 }
947
948 /* Insert in the SCOP context constraints from the estimation of the
949 number of iterations. UB_EXPR is a linear expression describing
950 the number of iterations in a loop. This expression is bounded by
951 the estimation NIT. */
952
953 static void
954 add_upper_bounds_from_estimated_nit (scop_p scop, double_int nit,
955 ppl_dimension_type dim,
956 ppl_Linear_Expression_t ub_expr)
957 {
958 mpz_t val;
959 ppl_Linear_Expression_t nb_iters_le;
960 ppl_Polyhedron_t pol;
961 ppl_Coefficient_t coef;
962 ppl_Constraint_t ub;
963
964 ppl_new_C_Polyhedron_from_space_dimension (&pol, dim, 0);
965 ppl_new_Linear_Expression_from_Linear_Expression (&nb_iters_le,
966 ub_expr);
967
968 /* Construct the negated number of last iteration in VAL. */
969 mpz_init (val);
970 mpz_set_double_int (val, nit, false);
971 mpz_sub_ui (val, val, 1);
972 mpz_neg (val, val);
973
974 /* NB_ITERS_LE holds the number of last iteration in
975 parametrical form. Subtract estimated number of last
976 iteration and assert that result is not positive. */
977 ppl_new_Coefficient_from_mpz_t (&coef, val);
978 ppl_Linear_Expression_add_to_inhomogeneous (nb_iters_le, coef);
979 ppl_delete_Coefficient (coef);
980 ppl_new_Constraint (&ub, nb_iters_le,
981 PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL);
982 ppl_Polyhedron_add_constraint (pol, ub);
983
984 /* Remove all but last GDIM dimensions from POL to obtain
985 only the constraints on the parameters. */
986 {
987 graphite_dim_t gdim = scop_nb_params (scop);
988 ppl_dimension_type *dims = XNEWVEC (ppl_dimension_type, dim - gdim);
989 graphite_dim_t i;
990
991 for (i = 0; i < dim - gdim; i++)
992 dims[i] = i;
993
994 ppl_Polyhedron_remove_space_dimensions (pol, dims, dim - gdim);
995 XDELETEVEC (dims);
996 }
997
998 /* Add the constraints on the parameters to the SCoP context. */
999 {
1000 ppl_Pointset_Powerset_C_Polyhedron_t constraints_ps;
1001
1002 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1003 (&constraints_ps, pol);
1004 ppl_Pointset_Powerset_C_Polyhedron_intersection_assign
1005 (SCOP_CONTEXT (scop), constraints_ps);
1006 ppl_delete_Pointset_Powerset_C_Polyhedron (constraints_ps);
1007 }
1008
1009 ppl_delete_Polyhedron (pol);
1010 ppl_delete_Linear_Expression (nb_iters_le);
1011 ppl_delete_Constraint (ub);
1012 mpz_clear (val);
1013 }
1014
1015 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
1016 the constraints for the surrounding loops. */
1017
1018 static void
1019 build_loop_iteration_domains (scop_p scop, struct loop *loop,
1020 ppl_Polyhedron_t outer_ph, int nb,
1021 ppl_Pointset_Powerset_C_Polyhedron_t *domains)
1022 {
1023 int i;
1024 ppl_Polyhedron_t ph;
1025 tree nb_iters = number_of_latch_executions (loop);
1026 ppl_dimension_type dim = nb + 1 + scop_nb_params (scop);
1027 sese region = SCOP_REGION (scop);
1028
1029 {
1030 ppl_const_Constraint_System_t pcs;
1031 ppl_dimension_type *map
1032 = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim);
1033
1034 ppl_new_C_Polyhedron_from_space_dimension (&ph, dim, 0);
1035 ppl_Polyhedron_get_constraints (outer_ph, &pcs);
1036 ppl_Polyhedron_add_constraints (ph, pcs);
1037
1038 for (i = 0; i < (int) nb; i++)
1039 map[i] = i;
1040 for (i = (int) nb; i < (int) dim - 1; i++)
1041 map[i] = i + 1;
1042 map[dim - 1] = nb;
1043
1044 ppl_Polyhedron_map_space_dimensions (ph, map, dim);
1045 free (map);
1046 }
1047
1048 /* 0 <= loop_i */
1049 {
1050 ppl_Constraint_t lb;
1051 ppl_Linear_Expression_t lb_expr;
1052
1053 ppl_new_Linear_Expression_with_dimension (&lb_expr, dim);
1054 ppl_set_coef (lb_expr, nb, 1);
1055 ppl_new_Constraint (&lb, lb_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1056 ppl_delete_Linear_Expression (lb_expr);
1057 ppl_Polyhedron_add_constraint (ph, lb);
1058 ppl_delete_Constraint (lb);
1059 }
1060
1061 if (TREE_CODE (nb_iters) == INTEGER_CST)
1062 {
1063 ppl_Constraint_t ub;
1064 ppl_Linear_Expression_t ub_expr;
1065
1066 ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1067
1068 /* loop_i <= cst_nb_iters */
1069 ppl_set_coef (ub_expr, nb, -1);
1070 ppl_set_inhomogeneous_tree (ub_expr, nb_iters);
1071 ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1072 ppl_Polyhedron_add_constraint (ph, ub);
1073 ppl_delete_Linear_Expression (ub_expr);
1074 ppl_delete_Constraint (ub);
1075 }
1076 else if (!chrec_contains_undetermined (nb_iters))
1077 {
1078 mpz_t one;
1079 ppl_Constraint_t ub;
1080 ppl_Linear_Expression_t ub_expr;
1081 double_int nit;
1082
1083 mpz_init (one);
1084 mpz_set_si (one, 1);
1085 ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1086 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1087 scan_tree_for_params (SCOP_REGION (scop), nb_iters, ub_expr, one);
1088 mpz_clear (one);
1089
1090 if (max_stmt_executions (loop, &nit))
1091 add_upper_bounds_from_estimated_nit (scop, nit, dim, ub_expr);
1092
1093 /* loop_i <= expr_nb_iters */
1094 ppl_set_coef (ub_expr, nb, -1);
1095 ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1096 ppl_Polyhedron_add_constraint (ph, ub);
1097 ppl_delete_Linear_Expression (ub_expr);
1098 ppl_delete_Constraint (ub);
1099 }
1100 else
1101 gcc_unreachable ();
1102
1103 if (loop->inner && loop_in_sese_p (loop->inner, region))
1104 build_loop_iteration_domains (scop, loop->inner, ph, nb + 1, domains);
1105
1106 if (nb != 0
1107 && loop->next
1108 && loop_in_sese_p (loop->next, region))
1109 build_loop_iteration_domains (scop, loop->next, outer_ph, nb, domains);
1110
1111 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1112 (&domains[loop->num], ph);
1113
1114 ppl_delete_Polyhedron (ph);
1115 }
1116
1117 /* Returns a linear expression for tree T evaluated in PBB. */
1118
1119 static ppl_Linear_Expression_t
1120 create_linear_expr_from_tree (poly_bb_p pbb, tree t)
1121 {
1122 mpz_t one;
1123 ppl_Linear_Expression_t res;
1124 ppl_dimension_type dim;
1125 sese region = SCOP_REGION (PBB_SCOP (pbb));
1126 loop_p loop = pbb_loop (pbb);
1127
1128 dim = pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb);
1129 ppl_new_Linear_Expression_with_dimension (&res, dim);
1130
1131 t = scalar_evolution_in_region (region, loop, t);
1132 gcc_assert (!automatically_generated_chrec_p (t));
1133
1134 mpz_init (one);
1135 mpz_set_si (one, 1);
1136 scan_tree_for_params (region, t, res, one);
1137 mpz_clear (one);
1138
1139 return res;
1140 }
1141
1142 /* Returns the ppl constraint type from the gimple tree code CODE. */
1143
1144 static enum ppl_enum_Constraint_Type
1145 ppl_constraint_type_from_tree_code (enum tree_code code)
1146 {
1147 switch (code)
1148 {
1149 /* We do not support LT and GT to be able to work with C_Polyhedron.
1150 As we work on integer polyhedron "a < b" can be expressed by
1151 "a + 1 <= b". */
1152 case LT_EXPR:
1153 case GT_EXPR:
1154 gcc_unreachable ();
1155
1156 case LE_EXPR:
1157 return PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL;
1158
1159 case GE_EXPR:
1160 return PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL;
1161
1162 case EQ_EXPR:
1163 return PPL_CONSTRAINT_TYPE_EQUAL;
1164
1165 default:
1166 gcc_unreachable ();
1167 }
1168 }
1169
1170 /* Add conditional statement STMT to PS. It is evaluated in PBB and
1171 CODE is used as the comparison operator. This allows us to invert the
1172 condition or to handle inequalities. */
1173
1174 static void
1175 add_condition_to_domain (ppl_Pointset_Powerset_C_Polyhedron_t ps, gimple stmt,
1176 poly_bb_p pbb, enum tree_code code)
1177 {
1178 mpz_t v;
1179 ppl_Coefficient_t c;
1180 ppl_Linear_Expression_t left, right;
1181 ppl_Constraint_t cstr;
1182 enum ppl_enum_Constraint_Type type;
1183
1184 left = create_linear_expr_from_tree (pbb, gimple_cond_lhs (stmt));
1185 right = create_linear_expr_from_tree (pbb, gimple_cond_rhs (stmt));
1186
1187 /* If we have < or > expressions convert them to <= or >= by adding 1 to
1188 the left or the right side of the expression. */
1189 if (code == LT_EXPR)
1190 {
1191 mpz_init (v);
1192 mpz_set_si (v, 1);
1193 ppl_new_Coefficient (&c);
1194 ppl_assign_Coefficient_from_mpz_t (c, v);
1195 ppl_Linear_Expression_add_to_inhomogeneous (left, c);
1196 ppl_delete_Coefficient (c);
1197 mpz_clear (v);
1198
1199 code = LE_EXPR;
1200 }
1201 else if (code == GT_EXPR)
1202 {
1203 mpz_init (v);
1204 mpz_set_si (v, 1);
1205 ppl_new_Coefficient (&c);
1206 ppl_assign_Coefficient_from_mpz_t (c, v);
1207 ppl_Linear_Expression_add_to_inhomogeneous (right, c);
1208 ppl_delete_Coefficient (c);
1209 mpz_clear (v);
1210
1211 code = GE_EXPR;
1212 }
1213
1214 type = ppl_constraint_type_from_tree_code (code);
1215
1216 ppl_subtract_Linear_Expression_from_Linear_Expression (left, right);
1217
1218 ppl_new_Constraint (&cstr, left, type);
1219 ppl_Pointset_Powerset_C_Polyhedron_add_constraint (ps, cstr);
1220
1221 ppl_delete_Constraint (cstr);
1222 ppl_delete_Linear_Expression (left);
1223 ppl_delete_Linear_Expression (right);
1224 }
1225
1226 /* Add conditional statement STMT to pbb. CODE is used as the comparision
1227 operator. This allows us to invert the condition or to handle
1228 inequalities. */
1229
1230 static void
1231 add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code)
1232 {
1233 if (code == NE_EXPR)
1234 {
1235 ppl_Pointset_Powerset_C_Polyhedron_t left = PBB_DOMAIN (pbb);
1236 ppl_Pointset_Powerset_C_Polyhedron_t right;
1237 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1238 (&right, left);
1239 add_condition_to_domain (left, stmt, pbb, LT_EXPR);
1240 add_condition_to_domain (right, stmt, pbb, GT_EXPR);
1241 ppl_Pointset_Powerset_C_Polyhedron_upper_bound_assign (left, right);
1242 ppl_delete_Pointset_Powerset_C_Polyhedron (right);
1243 }
1244 else
1245 add_condition_to_domain (PBB_DOMAIN (pbb), stmt, pbb, code);
1246 }
1247
1248 /* Add conditions to the domain of PBB. */
1249
1250 static void
1251 add_conditions_to_domain (poly_bb_p pbb)
1252 {
1253 unsigned int i;
1254 gimple stmt;
1255 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1256
1257 if (VEC_empty (gimple, GBB_CONDITIONS (gbb)))
1258 return;
1259
1260 FOR_EACH_VEC_ELT (gimple, GBB_CONDITIONS (gbb), i, stmt)
1261 switch (gimple_code (stmt))
1262 {
1263 case GIMPLE_COND:
1264 {
1265 enum tree_code code = gimple_cond_code (stmt);
1266
1267 /* The conditions for ELSE-branches are inverted. */
1268 if (!VEC_index (gimple, GBB_CONDITION_CASES (gbb), i))
1269 code = invert_tree_comparison (code, false);
1270
1271 add_condition_to_pbb (pbb, stmt, code);
1272 break;
1273 }
1274
1275 case GIMPLE_SWITCH:
1276 /* Switch statements are not supported right now - fall throught. */
1277
1278 default:
1279 gcc_unreachable ();
1280 break;
1281 }
1282 }
1283
1284 /* Traverses all the GBBs of the SCOP and add their constraints to the
1285 iteration domains. */
1286
1287 static void
1288 add_conditions_to_constraints (scop_p scop)
1289 {
1290 int i;
1291 poly_bb_p pbb;
1292
1293 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
1294 add_conditions_to_domain (pbb);
1295 }
1296
1297 /* Structure used to pass data to dom_walk. */
1298
1299 struct bsc
1300 {
1301 VEC (gimple, heap) **conditions, **cases;
1302 sese region;
1303 };
1304
1305 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1306 edge between BB and its predecessor is not a loop exit edge, and
1307 the last statement of the single predecessor is a COND_EXPR. */
1308
1309 static gimple
1310 single_pred_cond_non_loop_exit (basic_block bb)
1311 {
1312 if (single_pred_p (bb))
1313 {
1314 edge e = single_pred_edge (bb);
1315 basic_block pred = e->src;
1316 gimple stmt;
1317
1318 if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
1319 return NULL;
1320
1321 stmt = last_stmt (pred);
1322
1323 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1324 return stmt;
1325 }
1326
1327 return NULL;
1328 }
1329
1330 /* Call-back for dom_walk executed before visiting the dominated
1331 blocks. */
1332
1333 static void
1334 build_sese_conditions_before (struct dom_walk_data *dw_data,
1335 basic_block bb)
1336 {
1337 struct bsc *data = (struct bsc *) dw_data->global_data;
1338 VEC (gimple, heap) **conditions = data->conditions;
1339 VEC (gimple, heap) **cases = data->cases;
1340 gimple_bb_p gbb;
1341 gimple stmt;
1342
1343 if (!bb_in_sese_p (bb, data->region))
1344 return;
1345
1346 stmt = single_pred_cond_non_loop_exit (bb);
1347
1348 if (stmt)
1349 {
1350 edge e = single_pred_edge (bb);
1351
1352 VEC_safe_push (gimple, heap, *conditions, stmt);
1353
1354 if (e->flags & EDGE_TRUE_VALUE)
1355 VEC_safe_push (gimple, heap, *cases, stmt);
1356 else
1357 VEC_safe_push (gimple, heap, *cases, NULL);
1358 }
1359
1360 gbb = gbb_from_bb (bb);
1361
1362 if (gbb)
1363 {
1364 GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
1365 GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
1366 }
1367 }
1368
1369 /* Call-back for dom_walk executed after visiting the dominated
1370 blocks. */
1371
1372 static void
1373 build_sese_conditions_after (struct dom_walk_data *dw_data,
1374 basic_block bb)
1375 {
1376 struct bsc *data = (struct bsc *) dw_data->global_data;
1377 VEC (gimple, heap) **conditions = data->conditions;
1378 VEC (gimple, heap) **cases = data->cases;
1379
1380 if (!bb_in_sese_p (bb, data->region))
1381 return;
1382
1383 if (single_pred_cond_non_loop_exit (bb))
1384 {
1385 VEC_pop (gimple, *conditions);
1386 VEC_pop (gimple, *cases);
1387 }
1388 }
1389
1390 /* Record all conditions in REGION. */
1391
1392 static void
1393 build_sese_conditions (sese region)
1394 {
1395 struct dom_walk_data walk_data;
1396 VEC (gimple, heap) *conditions = VEC_alloc (gimple, heap, 3);
1397 VEC (gimple, heap) *cases = VEC_alloc (gimple, heap, 3);
1398 struct bsc data;
1399
1400 data.conditions = &conditions;
1401 data.cases = &cases;
1402 data.region = region;
1403
1404 walk_data.dom_direction = CDI_DOMINATORS;
1405 walk_data.initialize_block_local_data = NULL;
1406 walk_data.before_dom_children = build_sese_conditions_before;
1407 walk_data.after_dom_children = build_sese_conditions_after;
1408 walk_data.global_data = &data;
1409 walk_data.block_local_data_size = 0;
1410
1411 init_walk_dominator_tree (&walk_data);
1412 walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region));
1413 fini_walk_dominator_tree (&walk_data);
1414
1415 VEC_free (gimple, heap, conditions);
1416 VEC_free (gimple, heap, cases);
1417 }
1418
1419 /* Add constraints on the possible values of parameter P from the type
1420 of P. */
1421
1422 static void
1423 add_param_constraints (scop_p scop, ppl_Polyhedron_t context, graphite_dim_t p)
1424 {
1425 ppl_Constraint_t cstr;
1426 ppl_Linear_Expression_t le;
1427 tree parameter = VEC_index (tree, SESE_PARAMS (SCOP_REGION (scop)), p);
1428 tree type = TREE_TYPE (parameter);
1429 tree lb = NULL_TREE;
1430 tree ub = NULL_TREE;
1431
1432 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
1433 lb = lower_bound_in_type (type, type);
1434 else
1435 lb = TYPE_MIN_VALUE (type);
1436
1437 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
1438 ub = upper_bound_in_type (type, type);
1439 else
1440 ub = TYPE_MAX_VALUE (type);
1441
1442 if (lb)
1443 {
1444 ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1445 ppl_set_coef (le, p, -1);
1446 ppl_set_inhomogeneous_tree (le, lb);
1447 ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL);
1448 ppl_Polyhedron_add_constraint (context, cstr);
1449 ppl_delete_Linear_Expression (le);
1450 ppl_delete_Constraint (cstr);
1451 }
1452
1453 if (ub)
1454 {
1455 ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1456 ppl_set_coef (le, p, -1);
1457 ppl_set_inhomogeneous_tree (le, ub);
1458 ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1459 ppl_Polyhedron_add_constraint (context, cstr);
1460 ppl_delete_Linear_Expression (le);
1461 ppl_delete_Constraint (cstr);
1462 }
1463 }
1464
1465 /* Build the context of the SCOP. The context usually contains extra
1466 constraints that are added to the iteration domains that constrain
1467 some parameters. */
1468
1469 static void
1470 build_scop_context (scop_p scop)
1471 {
1472 ppl_Polyhedron_t context;
1473 ppl_Pointset_Powerset_C_Polyhedron_t ps;
1474 graphite_dim_t p, n = scop_nb_params (scop);
1475
1476 ppl_new_C_Polyhedron_from_space_dimension (&context, n, 0);
1477
1478 for (p = 0; p < n; p++)
1479 add_param_constraints (scop, context, p);
1480
1481 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1482 (&ps, context);
1483 ppl_Pointset_Powerset_C_Polyhedron_intersection_assign
1484 (SCOP_CONTEXT (scop), ps);
1485
1486 ppl_delete_Pointset_Powerset_C_Polyhedron (ps);
1487 ppl_delete_Polyhedron (context);
1488 }
1489
1490 /* Build the iteration domains: the loops belonging to the current
1491 SCOP, and that vary for the execution of the current basic block.
1492 Returns false if there is no loop in SCOP. */
1493
1494 static void
1495 build_scop_iteration_domain (scop_p scop)
1496 {
1497 struct loop *loop;
1498 sese region = SCOP_REGION (scop);
1499 int i;
1500 ppl_Polyhedron_t ph;
1501 poly_bb_p pbb;
1502 int nb_loops = number_of_loops ();
1503 ppl_Pointset_Powerset_C_Polyhedron_t *domains
1504 = XNEWVEC (ppl_Pointset_Powerset_C_Polyhedron_t, nb_loops);
1505
1506 for (i = 0; i < nb_loops; i++)
1507 domains[i] = NULL;
1508
1509 ppl_new_C_Polyhedron_from_space_dimension (&ph, scop_nb_params (scop), 0);
1510
1511 FOR_EACH_VEC_ELT (loop_p, SESE_LOOP_NEST (region), i, loop)
1512 if (!loop_in_sese_p (loop_outer (loop), region))
1513 build_loop_iteration_domains (scop, loop, ph, 0, domains);
1514
1515 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
1516 if (domains[gbb_loop (PBB_BLACK_BOX (pbb))->num])
1517 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1518 (&PBB_DOMAIN (pbb), (ppl_const_Pointset_Powerset_C_Polyhedron_t)
1519 domains[gbb_loop (PBB_BLACK_BOX (pbb))->num]);
1520 else
1521 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1522 (&PBB_DOMAIN (pbb), ph);
1523
1524 for (i = 0; i < nb_loops; i++)
1525 if (domains[i])
1526 ppl_delete_Pointset_Powerset_C_Polyhedron (domains[i]);
1527
1528 ppl_delete_Polyhedron (ph);
1529 free (domains);
1530 }
1531
1532 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1533 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1534 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1535 domain. */
1536
1537 static void
1538 pdr_add_alias_set (ppl_Polyhedron_t accesses, data_reference_p dr,
1539 ppl_dimension_type accessp_nb_dims,
1540 ppl_dimension_type dom_nb_dims)
1541 {
1542 ppl_Linear_Expression_t alias;
1543 ppl_Constraint_t cstr;
1544 int alias_set_num = 0;
1545 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1546
1547 if (bap && bap->alias_set)
1548 alias_set_num = *(bap->alias_set);
1549
1550 ppl_new_Linear_Expression_with_dimension (&alias, accessp_nb_dims);
1551
1552 ppl_set_coef (alias, dom_nb_dims, 1);
1553 ppl_set_inhomogeneous (alias, -alias_set_num);
1554 ppl_new_Constraint (&cstr, alias, PPL_CONSTRAINT_TYPE_EQUAL);
1555 ppl_Polyhedron_add_constraint (accesses, cstr);
1556
1557 ppl_delete_Linear_Expression (alias);
1558 ppl_delete_Constraint (cstr);
1559 }
1560
1561 /* Add to ACCESSES polyhedron equalities defining the access functions
1562 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1563 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1564 PBB is the poly_bb_p that contains the data reference DR. */
1565
1566 static void
1567 pdr_add_memory_accesses (ppl_Polyhedron_t accesses, data_reference_p dr,
1568 ppl_dimension_type accessp_nb_dims,
1569 ppl_dimension_type dom_nb_dims,
1570 poly_bb_p pbb)
1571 {
1572 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1573 mpz_t v;
1574 scop_p scop = PBB_SCOP (pbb);
1575 sese region = SCOP_REGION (scop);
1576
1577 mpz_init (v);
1578
1579 for (i = 0; i < nb_subscripts; i++)
1580 {
1581 ppl_Linear_Expression_t fn, access;
1582 ppl_Constraint_t cstr;
1583 ppl_dimension_type subscript = dom_nb_dims + 1 + i;
1584 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1585
1586 ppl_new_Linear_Expression_with_dimension (&fn, dom_nb_dims);
1587 ppl_new_Linear_Expression_with_dimension (&access, accessp_nb_dims);
1588
1589 mpz_set_si (v, 1);
1590 scan_tree_for_params (region, afn, fn, v);
1591 ppl_assign_Linear_Expression_from_Linear_Expression (access, fn);
1592
1593 ppl_set_coef (access, subscript, -1);
1594 ppl_new_Constraint (&cstr, access, PPL_CONSTRAINT_TYPE_EQUAL);
1595 ppl_Polyhedron_add_constraint (accesses, cstr);
1596
1597 ppl_delete_Linear_Expression (fn);
1598 ppl_delete_Linear_Expression (access);
1599 ppl_delete_Constraint (cstr);
1600 }
1601
1602 mpz_clear (v);
1603 }
1604
1605 /* Add constrains representing the size of the accessed data to the
1606 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1607 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1608 domain. */
1609
1610 static void
1611 pdr_add_data_dimensions (ppl_Polyhedron_t accesses, data_reference_p dr,
1612 ppl_dimension_type accessp_nb_dims,
1613 ppl_dimension_type dom_nb_dims)
1614 {
1615 tree ref = DR_REF (dr);
1616 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1617
1618 for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1619 {
1620 ppl_Linear_Expression_t expr;
1621 ppl_Constraint_t cstr;
1622 ppl_dimension_type subscript = dom_nb_dims + 1 + i;
1623 tree low, high;
1624
1625 if (TREE_CODE (ref) != ARRAY_REF)
1626 break;
1627
1628 low = array_ref_low_bound (ref);
1629
1630 /* subscript - low >= 0 */
1631 if (host_integerp (low, 0))
1632 {
1633 tree minus_low;
1634
1635 ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1636 ppl_set_coef (expr, subscript, 1);
1637
1638 minus_low = fold_build1 (NEGATE_EXPR, TREE_TYPE (low), low);
1639 ppl_set_inhomogeneous_tree (expr, minus_low);
1640
1641 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1642 ppl_Polyhedron_add_constraint (accesses, cstr);
1643 ppl_delete_Linear_Expression (expr);
1644 ppl_delete_Constraint (cstr);
1645 }
1646
1647 high = array_ref_up_bound (ref);
1648
1649 /* high - subscript >= 0 */
1650 if (high && host_integerp (high, 0)
1651 /* 1-element arrays at end of structures may extend over
1652 their declared size. */
1653 && !(array_at_struct_end_p (ref)
1654 && operand_equal_p (low, high, 0)))
1655 {
1656 ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1657 ppl_set_coef (expr, subscript, -1);
1658
1659 ppl_set_inhomogeneous_tree (expr, high);
1660
1661 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1662 ppl_Polyhedron_add_constraint (accesses, cstr);
1663 ppl_delete_Linear_Expression (expr);
1664 ppl_delete_Constraint (cstr);
1665 }
1666 }
1667 }
1668
1669 /* Build data accesses for DR in PBB. */
1670
1671 static void
1672 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1673 {
1674 ppl_Polyhedron_t accesses;
1675 ppl_Pointset_Powerset_C_Polyhedron_t accesses_ps;
1676 ppl_dimension_type dom_nb_dims;
1677 ppl_dimension_type accessp_nb_dims;
1678 int dr_base_object_set;
1679
1680 ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PBB_DOMAIN (pbb),
1681 &dom_nb_dims);
1682 accessp_nb_dims = dom_nb_dims + 1 + DR_NUM_DIMENSIONS (dr);
1683
1684 ppl_new_C_Polyhedron_from_space_dimension (&accesses, accessp_nb_dims, 0);
1685
1686 pdr_add_alias_set (accesses, dr, accessp_nb_dims, dom_nb_dims);
1687 pdr_add_memory_accesses (accesses, dr, accessp_nb_dims, dom_nb_dims, pbb);
1688 pdr_add_data_dimensions (accesses, dr, accessp_nb_dims, dom_nb_dims);
1689
1690 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&accesses_ps,
1691 accesses);
1692 ppl_delete_Polyhedron (accesses);
1693
1694 gcc_assert (dr->aux);
1695 dr_base_object_set = ((base_alias_pair *)(dr->aux))->base_obj_set;
1696
1697 new_poly_dr (pbb, dr_base_object_set, accesses_ps,
1698 DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1699 dr, DR_NUM_DIMENSIONS (dr));
1700 }
1701
1702 /* Write to FILE the alias graph of data references in DIMACS format. */
1703
1704 static inline bool
1705 write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
1706 VEC (data_reference_p, heap) *drs)
1707 {
1708 int num_vertex = VEC_length (data_reference_p, drs);
1709 int edge_num = 0;
1710 data_reference_p dr1, dr2;
1711 int i, j;
1712
1713 if (num_vertex == 0)
1714 return true;
1715
1716 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1717 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1718 if (dr_may_alias_p (dr1, dr2, true))
1719 edge_num++;
1720
1721 fprintf (file, "$\n");
1722
1723 if (comment)
1724 fprintf (file, "c %s\n", comment);
1725
1726 fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1727
1728 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1729 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1730 if (dr_may_alias_p (dr1, dr2, true))
1731 fprintf (file, "e %d %d\n", i + 1, j + 1);
1732
1733 return true;
1734 }
1735
1736 /* Write to FILE the alias graph of data references in DOT format. */
1737
1738 static inline bool
1739 write_alias_graph_to_ascii_dot (FILE *file, char *comment,
1740 VEC (data_reference_p, heap) *drs)
1741 {
1742 int num_vertex = VEC_length (data_reference_p, drs);
1743 data_reference_p dr1, dr2;
1744 int i, j;
1745
1746 if (num_vertex == 0)
1747 return true;
1748
1749 fprintf (file, "$\n");
1750
1751 if (comment)
1752 fprintf (file, "c %s\n", comment);
1753
1754 /* First print all the vertices. */
1755 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1756 fprintf (file, "n%d;\n", i);
1757
1758 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1759 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1760 if (dr_may_alias_p (dr1, dr2, true))
1761 fprintf (file, "n%d n%d\n", i, j);
1762
1763 return true;
1764 }
1765
1766 /* Write to FILE the alias graph of data references in ECC format. */
1767
1768 static inline bool
1769 write_alias_graph_to_ascii_ecc (FILE *file, char *comment,
1770 VEC (data_reference_p, heap) *drs)
1771 {
1772 int num_vertex = VEC_length (data_reference_p, drs);
1773 data_reference_p dr1, dr2;
1774 int i, j;
1775
1776 if (num_vertex == 0)
1777 return true;
1778
1779 fprintf (file, "$\n");
1780
1781 if (comment)
1782 fprintf (file, "c %s\n", comment);
1783
1784 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1785 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1786 if (dr_may_alias_p (dr1, dr2, true))
1787 fprintf (file, "%d %d\n", i, j);
1788
1789 return true;
1790 }
1791
1792 /* Check if DR1 and DR2 are in the same object set. */
1793
1794 static bool
1795 dr_same_base_object_p (const struct data_reference *dr1,
1796 const struct data_reference *dr2)
1797 {
1798 return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1799 }
1800
1801 /* Uses DFS component number as representative of alias-sets. Also tests for
1802 optimality by verifying if every connected component is a clique. Returns
1803 true (1) if the above test is true, and false (0) otherwise. */
1804
1805 static int
1806 build_alias_set_optimal_p (VEC (data_reference_p, heap) *drs)
1807 {
1808 int num_vertices = VEC_length (data_reference_p, drs);
1809 struct graph *g = new_graph (num_vertices);
1810 data_reference_p dr1, dr2;
1811 int i, j;
1812 int num_connected_components;
1813 int v_indx1, v_indx2, num_vertices_in_component;
1814 int *all_vertices;
1815 int *vertices;
1816 struct graph_edge *e;
1817 int this_component_is_clique;
1818 int all_components_are_cliques = 1;
1819
1820 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1821 for (j = i+1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1822 if (dr_may_alias_p (dr1, dr2, true))
1823 {
1824 add_edge (g, i, j);
1825 add_edge (g, j, i);
1826 }
1827
1828 all_vertices = XNEWVEC (int, num_vertices);
1829 vertices = XNEWVEC (int, num_vertices);
1830 for (i = 0; i < num_vertices; i++)
1831 all_vertices[i] = i;
1832
1833 num_connected_components = graphds_dfs (g, all_vertices, num_vertices,
1834 NULL, true, NULL);
1835 for (i = 0; i < g->n_vertices; i++)
1836 {
1837 data_reference_p dr = VEC_index (data_reference_p, drs, i);
1838 base_alias_pair *bap;
1839
1840 gcc_assert (dr->aux);
1841 bap = (base_alias_pair *)(dr->aux);
1842
1843 bap->alias_set = XNEW (int);
1844 *(bap->alias_set) = g->vertices[i].component + 1;
1845 }
1846
1847 /* Verify if the DFS numbering results in optimal solution. */
1848 for (i = 0; i < num_connected_components; i++)
1849 {
1850 num_vertices_in_component = 0;
1851 /* Get all vertices whose DFS component number is the same as i. */
1852 for (j = 0; j < num_vertices; j++)
1853 if (g->vertices[j].component == i)
1854 vertices[num_vertices_in_component++] = j;
1855
1856 /* Now test if the vertices in 'vertices' form a clique, by testing
1857 for edges among each pair. */
1858 this_component_is_clique = 1;
1859 for (v_indx1 = 0; v_indx1 < num_vertices_in_component; v_indx1++)
1860 {
1861 for (v_indx2 = v_indx1+1; v_indx2 < num_vertices_in_component; v_indx2++)
1862 {
1863 /* Check if the two vertices are connected by iterating
1864 through all the edges which have one of these are source. */
1865 e = g->vertices[vertices[v_indx2]].pred;
1866 while (e)
1867 {
1868 if (e->src == vertices[v_indx1])
1869 break;
1870 e = e->pred_next;
1871 }
1872 if (!e)
1873 {
1874 this_component_is_clique = 0;
1875 break;
1876 }
1877 }
1878 if (!this_component_is_clique)
1879 all_components_are_cliques = 0;
1880 }
1881 }
1882
1883 free (all_vertices);
1884 free (vertices);
1885 free_graph (g);
1886 return all_components_are_cliques;
1887 }
1888
1889 /* Group each data reference in DRS with its base object set num. */
1890
1891 static void
1892 build_base_obj_set_for_drs (VEC (data_reference_p, heap) *drs)
1893 {
1894 int num_vertex = VEC_length (data_reference_p, drs);
1895 struct graph *g = new_graph (num_vertex);
1896 data_reference_p dr1, dr2;
1897 int i, j;
1898 int *queue;
1899
1900 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1901 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1902 if (dr_same_base_object_p (dr1, dr2))
1903 {
1904 add_edge (g, i, j);
1905 add_edge (g, j, i);
1906 }
1907
1908 queue = XNEWVEC (int, num_vertex);
1909 for (i = 0; i < num_vertex; i++)
1910 queue[i] = i;
1911
1912 graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1913
1914 for (i = 0; i < g->n_vertices; i++)
1915 {
1916 data_reference_p dr = VEC_index (data_reference_p, drs, i);
1917 base_alias_pair *bap;
1918
1919 gcc_assert (dr->aux);
1920 bap = (base_alias_pair *)(dr->aux);
1921
1922 bap->base_obj_set = g->vertices[i].component + 1;
1923 }
1924
1925 free (queue);
1926 free_graph (g);
1927 }
1928
1929 /* Build the data references for PBB. */
1930
1931 static void
1932 build_pbb_drs (poly_bb_p pbb)
1933 {
1934 int j;
1935 data_reference_p dr;
1936 VEC (data_reference_p, heap) *gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1937
1938 FOR_EACH_VEC_ELT (data_reference_p, gbb_drs, j, dr)
1939 build_poly_dr (dr, pbb);
1940 }
1941
1942 /* Dump to file the alias graphs for the data references in DRS. */
1943
1944 static void
1945 dump_alias_graphs (VEC (data_reference_p, heap) *drs)
1946 {
1947 char comment[100];
1948 FILE *file_dimacs, *file_ecc, *file_dot;
1949
1950 file_dimacs = fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1951 if (file_dimacs)
1952 {
1953 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1954 current_function_name ());
1955 write_alias_graph_to_ascii_dimacs (file_dimacs, comment, drs);
1956 fclose (file_dimacs);
1957 }
1958
1959 file_ecc = fopen ("/tmp/dr_alias_graph_ecc", "ab");
1960 if (file_ecc)
1961 {
1962 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1963 current_function_name ());
1964 write_alias_graph_to_ascii_ecc (file_ecc, comment, drs);
1965 fclose (file_ecc);
1966 }
1967
1968 file_dot = fopen ("/tmp/dr_alias_graph_dot", "ab");
1969 if (file_dot)
1970 {
1971 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1972 current_function_name ());
1973 write_alias_graph_to_ascii_dot (file_dot, comment, drs);
1974 fclose (file_dot);
1975 }
1976 }
1977
1978 /* Build data references in SCOP. */
1979
1980 static void
1981 build_scop_drs (scop_p scop)
1982 {
1983 int i, j;
1984 poly_bb_p pbb;
1985 data_reference_p dr;
1986 VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
1987
1988 /* Remove all the PBBs that do not have data references: these basic
1989 blocks are not handled in the polyhedral representation. */
1990 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1991 if (VEC_empty (data_reference_p, GBB_DATA_REFS (PBB_BLACK_BOX (pbb))))
1992 {
1993 free_gimple_bb (PBB_BLACK_BOX (pbb));
1994 VEC_ordered_remove (poly_bb_p, SCOP_BBS (scop), i);
1995 i--;
1996 }
1997
1998 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
1999 for (j = 0; VEC_iterate (data_reference_p,
2000 GBB_DATA_REFS (PBB_BLACK_BOX (pbb)), j, dr); j++)
2001 VEC_safe_push (data_reference_p, heap, drs, dr);
2002
2003 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr)
2004 dr->aux = XNEW (base_alias_pair);
2005
2006 if (!build_alias_set_optimal_p (drs))
2007 {
2008 /* TODO: Add support when building alias set is not optimal. */
2009 ;
2010 }
2011
2012 build_base_obj_set_for_drs (drs);
2013
2014 /* When debugging, enable the following code. This cannot be used
2015 in production compilers. */
2016 if (0)
2017 dump_alias_graphs (drs);
2018
2019 VEC_free (data_reference_p, heap, drs);
2020
2021 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
2022 build_pbb_drs (pbb);
2023 }
2024
2025 /* Return a gsi at the position of the phi node STMT. */
2026
2027 static gimple_stmt_iterator
2028 gsi_for_phi_node (gimple stmt)
2029 {
2030 gimple_stmt_iterator psi;
2031 basic_block bb = gimple_bb (stmt);
2032
2033 for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
2034 if (stmt == gsi_stmt (psi))
2035 return psi;
2036
2037 gcc_unreachable ();
2038 return psi;
2039 }
2040
2041 /* Analyze all the data references of STMTS and add them to the
2042 GBB_DATA_REFS vector of BB. */
2043
2044 static void
2045 analyze_drs_in_stmts (scop_p scop, basic_block bb, VEC (gimple, heap) *stmts)
2046 {
2047 loop_p nest;
2048 gimple_bb_p gbb;
2049 gimple stmt;
2050 int i;
2051 sese region = SCOP_REGION (scop);
2052
2053 if (!bb_in_sese_p (bb, region))
2054 return;
2055
2056 nest = outermost_loop_in_sese_1 (region, bb);
2057 gbb = gbb_from_bb (bb);
2058
2059 FOR_EACH_VEC_ELT (gimple, stmts, i, stmt)
2060 {
2061 loop_p loop;
2062
2063 if (is_gimple_debug (stmt))
2064 continue;
2065
2066 loop = loop_containing_stmt (stmt);
2067 if (!loop_in_sese_p (loop, region))
2068 loop = nest;
2069
2070 graphite_find_data_references_in_stmt (nest, loop, stmt,
2071 &GBB_DATA_REFS (gbb));
2072 }
2073 }
2074
2075 /* Insert STMT at the end of the STMTS sequence and then insert the
2076 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
2077 on STMTS. */
2078
2079 static void
2080 insert_stmts (scop_p scop, gimple stmt, gimple_seq stmts,
2081 gimple_stmt_iterator insert_gsi)
2082 {
2083 gimple_stmt_iterator gsi;
2084 VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
2085
2086 gimple_seq_add_stmt (&stmts, stmt);
2087 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2088 VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
2089
2090 gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
2091 analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
2092 VEC_free (gimple, heap, x);
2093 }
2094
2095 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
2096
2097 static void
2098 insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple after_stmt)
2099 {
2100 gimple_seq stmts;
2101 gimple_stmt_iterator gsi;
2102 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2103 gimple stmt = gimple_build_assign (res, var);
2104 VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
2105
2106 gimple_seq_add_stmt (&stmts, stmt);
2107 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2108 VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
2109
2110 if (gimple_code (after_stmt) == GIMPLE_PHI)
2111 {
2112 gsi = gsi_after_labels (gimple_bb (after_stmt));
2113 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2114 }
2115 else
2116 {
2117 gsi = gsi_for_stmt (after_stmt);
2118 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
2119 }
2120
2121 analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
2122 VEC_free (gimple, heap, x);
2123 }
2124
2125 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
2126
2127 static void
2128 new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
2129 {
2130 VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
2131 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
2132 gimple_bb_p gbb1 = new_gimple_bb (bb, drs);
2133 poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
2134 int index, n = VEC_length (poly_bb_p, SCOP_BBS (scop));
2135
2136 /* The INDEX of PBB in SCOP_BBS. */
2137 for (index = 0; index < n; index++)
2138 if (VEC_index (poly_bb_p, SCOP_BBS (scop), index) == pbb)
2139 break;
2140
2141 if (PBB_DOMAIN (pbb))
2142 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
2143 (&PBB_DOMAIN (pbb1), PBB_DOMAIN (pbb));
2144
2145 GBB_PBB (gbb1) = pbb1;
2146 GBB_CONDITIONS (gbb1) = VEC_copy (gimple, heap, GBB_CONDITIONS (gbb));
2147 GBB_CONDITION_CASES (gbb1) = VEC_copy (gimple, heap, GBB_CONDITION_CASES (gbb));
2148 VEC_safe_insert (poly_bb_p, heap, SCOP_BBS (scop), index + 1, pbb1);
2149 }
2150
2151 /* Insert on edge E the assignment "RES := EXPR". */
2152
2153 static void
2154 insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
2155 {
2156 gimple_stmt_iterator gsi;
2157 gimple_seq stmts = NULL;
2158 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2159 gimple stmt = gimple_build_assign (res, var);
2160 basic_block bb;
2161 VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
2162
2163 gimple_seq_add_stmt (&stmts, stmt);
2164 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2165 VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
2166
2167 gsi_insert_seq_on_edge (e, stmts);
2168 gsi_commit_edge_inserts ();
2169 bb = gimple_bb (stmt);
2170
2171 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2172 return;
2173
2174 if (!gbb_from_bb (bb))
2175 new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
2176
2177 analyze_drs_in_stmts (scop, bb, x);
2178 VEC_free (gimple, heap, x);
2179 }
2180
2181 /* Creates a zero dimension array of the same type as VAR. */
2182
2183 static tree
2184 create_zero_dim_array (tree var, const char *base_name)
2185 {
2186 tree index_type = build_index_type (integer_zero_node);
2187 tree elt_type = TREE_TYPE (var);
2188 tree array_type = build_array_type (elt_type, index_type);
2189 tree base = create_tmp_var (array_type, base_name);
2190
2191 add_referenced_var (base);
2192
2193 return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
2194 NULL_TREE);
2195 }
2196
2197 /* Returns true when PHI is a loop close phi node. */
2198
2199 static bool
2200 scalar_close_phi_node_p (gimple phi)
2201 {
2202 if (gimple_code (phi) != GIMPLE_PHI
2203 || !is_gimple_reg (gimple_phi_result (phi)))
2204 return false;
2205
2206 /* Note that loop close phi nodes should have a single argument
2207 because we translated the representation into a canonical form
2208 before Graphite: see canonicalize_loop_closed_ssa_form. */
2209 return (gimple_phi_num_args (phi) == 1);
2210 }
2211
2212 /* For a definition DEF in REGION, propagates the expression EXPR in
2213 all the uses of DEF outside REGION. */
2214
2215 static void
2216 propagate_expr_outside_region (tree def, tree expr, sese region)
2217 {
2218 imm_use_iterator imm_iter;
2219 gimple use_stmt;
2220 gimple_seq stmts;
2221 bool replaced_once = false;
2222
2223 gcc_assert (TREE_CODE (def) == SSA_NAME);
2224
2225 expr = force_gimple_operand (unshare_expr (expr), &stmts, true,
2226 NULL_TREE);
2227
2228 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2229 if (!is_gimple_debug (use_stmt)
2230 && !bb_in_sese_p (gimple_bb (use_stmt), region))
2231 {
2232 ssa_op_iter iter;
2233 use_operand_p use_p;
2234
2235 FOR_EACH_PHI_OR_STMT_USE (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2236 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0)
2237 && (replaced_once = true))
2238 replace_exp (use_p, expr);
2239
2240 update_stmt (use_stmt);
2241 }
2242
2243 if (replaced_once)
2244 {
2245 gsi_insert_seq_on_edge (SESE_ENTRY (region), stmts);
2246 gsi_commit_edge_inserts ();
2247 }
2248 }
2249
2250 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2251 dimension array for it. */
2252
2253 static void
2254 rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2255 {
2256 sese region = SCOP_REGION (scop);
2257 gimple phi = gsi_stmt (*psi);
2258 tree res = gimple_phi_result (phi);
2259 tree var = SSA_NAME_VAR (res);
2260 basic_block bb = gimple_bb (phi);
2261 gimple_stmt_iterator gsi = gsi_after_labels (bb);
2262 tree arg = gimple_phi_arg_def (phi, 0);
2263 gimple stmt;
2264
2265 /* Note that loop close phi nodes should have a single argument
2266 because we translated the representation into a canonical form
2267 before Graphite: see canonicalize_loop_closed_ssa_form. */
2268 gcc_assert (gimple_phi_num_args (phi) == 1);
2269
2270 /* The phi node can be a non close phi node, when its argument is
2271 invariant, or a default definition. */
2272 if (is_gimple_min_invariant (arg)
2273 || SSA_NAME_IS_DEFAULT_DEF (arg))
2274 {
2275 propagate_expr_outside_region (res, arg, region);
2276 gsi_next (psi);
2277 return;
2278 }
2279
2280 else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
2281 {
2282 propagate_expr_outside_region (res, arg, region);
2283 stmt = gimple_build_assign (res, arg);
2284 remove_phi_node (psi, false);
2285 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2286 SSA_NAME_DEF_STMT (res) = stmt;
2287 return;
2288 }
2289
2290 /* If res is scev analyzable and is not a scalar value, it is safe
2291 to ignore the close phi node: it will be code generated in the
2292 out of Graphite pass. */
2293 else if (scev_analyzable_p (res, region))
2294 {
2295 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2296 tree scev;
2297
2298 if (!loop_in_sese_p (loop, region))
2299 {
2300 loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2301 scev = scalar_evolution_in_region (region, loop, arg);
2302 scev = compute_overall_effect_of_inner_loop (loop, scev);
2303 }
2304 else
2305 scev = scalar_evolution_in_region (region, loop, res);
2306
2307 if (tree_does_not_contain_chrecs (scev))
2308 propagate_expr_outside_region (res, scev, region);
2309
2310 gsi_next (psi);
2311 return;
2312 }
2313 else
2314 {
2315 tree zero_dim_array = create_zero_dim_array (var, "Close_Phi");
2316
2317 stmt = gimple_build_assign (res, zero_dim_array);
2318
2319 if (TREE_CODE (arg) == SSA_NAME)
2320 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2321 SSA_NAME_DEF_STMT (arg));
2322 else
2323 insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
2324 zero_dim_array, arg);
2325 }
2326
2327 remove_phi_node (psi, false);
2328 SSA_NAME_DEF_STMT (res) = stmt;
2329
2330 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2331 }
2332
2333 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2334 dimension array for it. */
2335
2336 static void
2337 rewrite_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2338 {
2339 size_t i;
2340 gimple phi = gsi_stmt (*psi);
2341 basic_block bb = gimple_bb (phi);
2342 tree res = gimple_phi_result (phi);
2343 tree var = SSA_NAME_VAR (res);
2344 tree zero_dim_array = create_zero_dim_array (var, "phi_out_of_ssa");
2345 gimple stmt;
2346 gimple_seq stmts;
2347
2348 for (i = 0; i < gimple_phi_num_args (phi); i++)
2349 {
2350 tree arg = gimple_phi_arg_def (phi, i);
2351 edge e = gimple_phi_arg_edge (phi, i);
2352
2353 /* Avoid the insertion of code in the loop latch to please the
2354 pattern matching of the vectorizer. */
2355 if (TREE_CODE (arg) == SSA_NAME
2356 && e->src == bb->loop_father->latch)
2357 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2358 SSA_NAME_DEF_STMT (arg));
2359 else
2360 insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
2361 }
2362
2363 var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
2364
2365 stmt = gimple_build_assign (res, var);
2366 remove_phi_node (psi, false);
2367 SSA_NAME_DEF_STMT (res) = stmt;
2368
2369 insert_stmts (scop, stmt, stmts, gsi_after_labels (bb));
2370 }
2371
2372 /* Rewrite the degenerate phi node at position PSI from the degenerate
2373 form "x = phi (y, y, ..., y)" to "x = y". */
2374
2375 static void
2376 rewrite_degenerate_phi (gimple_stmt_iterator *psi)
2377 {
2378 tree rhs;
2379 gimple stmt;
2380 gimple_stmt_iterator gsi;
2381 gimple phi = gsi_stmt (*psi);
2382 tree res = gimple_phi_result (phi);
2383 basic_block bb;
2384
2385 bb = gimple_bb (phi);
2386 rhs = degenerate_phi_result (phi);
2387 gcc_assert (rhs);
2388
2389 stmt = gimple_build_assign (res, rhs);
2390 remove_phi_node (psi, false);
2391 SSA_NAME_DEF_STMT (res) = stmt;
2392
2393 gsi = gsi_after_labels (bb);
2394 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2395 }
2396
2397 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2398
2399 static void
2400 rewrite_reductions_out_of_ssa (scop_p scop)
2401 {
2402 basic_block bb;
2403 gimple_stmt_iterator psi;
2404 sese region = SCOP_REGION (scop);
2405
2406 FOR_EACH_BB (bb)
2407 if (bb_in_sese_p (bb, region))
2408 for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2409 {
2410 gimple phi = gsi_stmt (psi);
2411
2412 if (!is_gimple_reg (gimple_phi_result (phi)))
2413 {
2414 gsi_next (&psi);
2415 continue;
2416 }
2417
2418 if (gimple_phi_num_args (phi) > 1
2419 && degenerate_phi_result (phi))
2420 rewrite_degenerate_phi (&psi);
2421
2422 else if (scalar_close_phi_node_p (phi))
2423 rewrite_close_phi_out_of_ssa (scop, &psi);
2424
2425 else if (reduction_phi_p (region, &psi))
2426 rewrite_phi_out_of_ssa (scop, &psi);
2427 }
2428
2429 update_ssa (TODO_update_ssa);
2430 #ifdef ENABLE_CHECKING
2431 verify_loop_closed_ssa (true);
2432 #endif
2433 }
2434
2435 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2436 read from ZERO_DIM_ARRAY. */
2437
2438 static void
2439 rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
2440 tree def, gimple use_stmt)
2441 {
2442 tree var = SSA_NAME_VAR (def);
2443 gimple name_stmt = gimple_build_assign (var, zero_dim_array);
2444 tree name = make_ssa_name (var, name_stmt);
2445 ssa_op_iter iter;
2446 use_operand_p use_p;
2447
2448 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2449
2450 gimple_assign_set_lhs (name_stmt, name);
2451 insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
2452
2453 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2454 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2455 replace_exp (use_p, name);
2456
2457 update_stmt (use_stmt);
2458 }
2459
2460 /* For every definition DEF in the SCOP that is used outside the scop,
2461 insert a closing-scop definition in the basic block just after this
2462 SCOP. */
2463
2464 static void
2465 handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple stmt)
2466 {
2467 tree var = create_tmp_reg (TREE_TYPE (def), NULL);
2468 tree new_name = make_ssa_name (var, stmt);
2469 bool needs_copy = false;
2470 use_operand_p use_p;
2471 imm_use_iterator imm_iter;
2472 gimple use_stmt;
2473 sese region = SCOP_REGION (scop);
2474
2475 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2476 {
2477 if (!bb_in_sese_p (gimple_bb (use_stmt), region))
2478 {
2479 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2480 {
2481 SET_USE (use_p, new_name);
2482 }
2483 update_stmt (use_stmt);
2484 needs_copy = true;
2485 }
2486 }
2487
2488 /* Insert in the empty BB just after the scop a use of DEF such
2489 that the rewrite of cross_bb_scalar_dependences won't insert
2490 arrays everywhere else. */
2491 if (needs_copy)
2492 {
2493 gimple assign = gimple_build_assign (new_name, def);
2494 gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
2495
2496 add_referenced_var (var);
2497 SSA_NAME_DEF_STMT (new_name) = assign;
2498 update_stmt (assign);
2499 gsi_insert_before (&psi, assign, GSI_SAME_STMT);
2500 }
2501 }
2502
2503 /* Rewrite the scalar dependences crossing the boundary of the BB
2504 containing STMT with an array. Return true when something has been
2505 changed. */
2506
2507 static bool
2508 rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
2509 {
2510 sese region = SCOP_REGION (scop);
2511 gimple stmt = gsi_stmt (*gsi);
2512 imm_use_iterator imm_iter;
2513 tree def;
2514 basic_block def_bb;
2515 tree zero_dim_array = NULL_TREE;
2516 gimple use_stmt;
2517 bool res = false;
2518
2519 switch (gimple_code (stmt))
2520 {
2521 case GIMPLE_ASSIGN:
2522 def = gimple_assign_lhs (stmt);
2523 break;
2524
2525 case GIMPLE_CALL:
2526 def = gimple_call_lhs (stmt);
2527 break;
2528
2529 default:
2530 return false;
2531 }
2532
2533 if (!def
2534 || !is_gimple_reg (def))
2535 return false;
2536
2537 if (scev_analyzable_p (def, region))
2538 {
2539 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
2540 tree scev = scalar_evolution_in_region (region, loop, def);
2541
2542 if (tree_contains_chrecs (scev, NULL))
2543 return false;
2544
2545 propagate_expr_outside_region (def, scev, region);
2546 return true;
2547 }
2548
2549 def_bb = gimple_bb (stmt);
2550
2551 handle_scalar_deps_crossing_scop_limits (scop, def, stmt);
2552
2553 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2554 if (gimple_code (use_stmt) == GIMPLE_PHI
2555 && (res = true))
2556 {
2557 gimple_stmt_iterator psi = gsi_for_stmt (use_stmt);
2558
2559 if (scalar_close_phi_node_p (gsi_stmt (psi)))
2560 rewrite_close_phi_out_of_ssa (scop, &psi);
2561 else
2562 rewrite_phi_out_of_ssa (scop, &psi);
2563 }
2564
2565 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2566 if (gimple_code (use_stmt) != GIMPLE_PHI
2567 && def_bb != gimple_bb (use_stmt)
2568 && !is_gimple_debug (use_stmt)
2569 && (res = true))
2570 {
2571 if (!zero_dim_array)
2572 {
2573 zero_dim_array = create_zero_dim_array
2574 (SSA_NAME_VAR (def), "Cross_BB_scalar_dependence");
2575 insert_out_of_ssa_copy (scop, zero_dim_array, def,
2576 SSA_NAME_DEF_STMT (def));
2577 gsi_next (gsi);
2578 }
2579
2580 rewrite_cross_bb_scalar_dependence (scop, zero_dim_array,
2581 def, use_stmt);
2582 }
2583
2584 return res;
2585 }
2586
2587 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2588
2589 static void
2590 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
2591 {
2592 basic_block bb;
2593 gimple_stmt_iterator psi;
2594 sese region = SCOP_REGION (scop);
2595 bool changed = false;
2596
2597 /* Create an extra empty BB after the scop. */
2598 split_edge (SESE_EXIT (region));
2599
2600 FOR_EACH_BB (bb)
2601 if (bb_in_sese_p (bb, region))
2602 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2603 changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
2604
2605 if (changed)
2606 {
2607 scev_reset_htab ();
2608 update_ssa (TODO_update_ssa);
2609 #ifdef ENABLE_CHECKING
2610 verify_loop_closed_ssa (true);
2611 #endif
2612 }
2613 }
2614
2615 /* Returns the number of pbbs that are in loops contained in SCOP. */
2616
2617 static int
2618 nb_pbbs_in_loops (scop_p scop)
2619 {
2620 int i;
2621 poly_bb_p pbb;
2622 int res = 0;
2623
2624 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
2625 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2626 res++;
2627
2628 return res;
2629 }
2630
2631 /* Return the number of data references in BB that write in
2632 memory. */
2633
2634 static int
2635 nb_data_writes_in_bb (basic_block bb)
2636 {
2637 int res = 0;
2638 gimple_stmt_iterator gsi;
2639
2640 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2641 if (gimple_vdef (gsi_stmt (gsi)))
2642 res++;
2643
2644 return res;
2645 }
2646
2647 /* Splits at STMT the basic block BB represented as PBB in the
2648 polyhedral form. */
2649
2650 static edge
2651 split_pbb (scop_p scop, poly_bb_p pbb, basic_block bb, gimple stmt)
2652 {
2653 edge e1 = split_block (bb, stmt);
2654 new_pbb_from_pbb (scop, pbb, e1->dest);
2655 return e1;
2656 }
2657
2658 /* Splits STMT out of its current BB. This is done for reduction
2659 statements for which we want to ignore data dependences. */
2660
2661 static basic_block
2662 split_reduction_stmt (scop_p scop, gimple stmt)
2663 {
2664 basic_block bb = gimple_bb (stmt);
2665 poly_bb_p pbb = pbb_from_bb (bb);
2666 gimple_bb_p gbb = gbb_from_bb (bb);
2667 edge e1;
2668 int i;
2669 data_reference_p dr;
2670
2671 /* Do not split basic blocks with no writes to memory: the reduction
2672 will be the only write to memory. */
2673 if (nb_data_writes_in_bb (bb) == 0
2674 /* Or if we have already marked BB as a reduction. */
2675 || PBB_IS_REDUCTION (pbb_from_bb (bb)))
2676 return bb;
2677
2678 e1 = split_pbb (scop, pbb, bb, stmt);
2679
2680 /* Split once more only when the reduction stmt is not the only one
2681 left in the original BB. */
2682 if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
2683 {
2684 gimple_stmt_iterator gsi = gsi_last_bb (bb);
2685 gsi_prev (&gsi);
2686 e1 = split_pbb (scop, pbb, bb, gsi_stmt (gsi));
2687 }
2688
2689 /* A part of the data references will end in a different basic block
2690 after the split: move the DRs from the original GBB to the newly
2691 created GBB1. */
2692 FOR_EACH_VEC_ELT (data_reference_p, GBB_DATA_REFS (gbb), i, dr)
2693 {
2694 basic_block bb1 = gimple_bb (DR_STMT (dr));
2695
2696 if (bb1 != bb)
2697 {
2698 gimple_bb_p gbb1 = gbb_from_bb (bb1);
2699 VEC_safe_push (data_reference_p, heap, GBB_DATA_REFS (gbb1), dr);
2700 VEC_ordered_remove (data_reference_p, GBB_DATA_REFS (gbb), i);
2701 i--;
2702 }
2703 }
2704
2705 return e1->dest;
2706 }
2707
2708 /* Return true when stmt is a reduction operation. */
2709
2710 static inline bool
2711 is_reduction_operation_p (gimple stmt)
2712 {
2713 enum tree_code code;
2714
2715 gcc_assert (is_gimple_assign (stmt));
2716 code = gimple_assign_rhs_code (stmt);
2717
2718 return flag_associative_math
2719 && commutative_tree_code (code)
2720 && associative_tree_code (code);
2721 }
2722
2723 /* Returns true when PHI contains an argument ARG. */
2724
2725 static bool
2726 phi_contains_arg (gimple phi, tree arg)
2727 {
2728 size_t i;
2729
2730 for (i = 0; i < gimple_phi_num_args (phi); i++)
2731 if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2732 return true;
2733
2734 return false;
2735 }
2736
2737 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2738
2739 static gimple
2740 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2741 {
2742 gimple stmt;
2743
2744 if (TREE_CODE (arg) != SSA_NAME)
2745 return NULL;
2746
2747 stmt = SSA_NAME_DEF_STMT (arg);
2748
2749 if (gimple_code (stmt) == GIMPLE_NOP
2750 || gimple_code (stmt) == GIMPLE_CALL)
2751 return NULL;
2752
2753 if (gimple_code (stmt) == GIMPLE_PHI)
2754 {
2755 if (phi_contains_arg (stmt, lhs))
2756 return stmt;
2757 return NULL;
2758 }
2759
2760 if (!is_gimple_assign (stmt))
2761 return NULL;
2762
2763 if (gimple_num_ops (stmt) == 2)
2764 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2765
2766 if (is_reduction_operation_p (stmt))
2767 {
2768 gimple res = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2769
2770 return res ? res :
2771 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2772 }
2773
2774 return NULL;
2775 }
2776
2777 /* Detect commutative and associative scalar reductions starting at
2778 the STMT. Return the phi node of the reduction cycle, or NULL. */
2779
2780 static gimple
2781 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2782 VEC (gimple, heap) **in,
2783 VEC (gimple, heap) **out)
2784 {
2785 gimple phi = follow_ssa_with_commutative_ops (arg, lhs);
2786
2787 if (!phi)
2788 return NULL;
2789
2790 VEC_safe_push (gimple, heap, *in, stmt);
2791 VEC_safe_push (gimple, heap, *out, stmt);
2792 return phi;
2793 }
2794
2795 /* Detect commutative and associative scalar reductions starting at
2796 STMT. Return the phi node of the reduction cycle, or NULL. */
2797
2798 static gimple
2799 detect_commutative_reduction_assign (gimple stmt, VEC (gimple, heap) **in,
2800 VEC (gimple, heap) **out)
2801 {
2802 tree lhs = gimple_assign_lhs (stmt);
2803
2804 if (gimple_num_ops (stmt) == 2)
2805 return detect_commutative_reduction_arg (lhs, stmt,
2806 gimple_assign_rhs1 (stmt),
2807 in, out);
2808
2809 if (is_reduction_operation_p (stmt))
2810 {
2811 gimple res = detect_commutative_reduction_arg (lhs, stmt,
2812 gimple_assign_rhs1 (stmt),
2813 in, out);
2814 return res ? res
2815 : detect_commutative_reduction_arg (lhs, stmt,
2816 gimple_assign_rhs2 (stmt),
2817 in, out);
2818 }
2819
2820 return NULL;
2821 }
2822
2823 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2824
2825 static gimple
2826 follow_inital_value_to_phi (tree arg, tree lhs)
2827 {
2828 gimple stmt;
2829
2830 if (!arg || TREE_CODE (arg) != SSA_NAME)
2831 return NULL;
2832
2833 stmt = SSA_NAME_DEF_STMT (arg);
2834
2835 if (gimple_code (stmt) == GIMPLE_PHI
2836 && phi_contains_arg (stmt, lhs))
2837 return stmt;
2838
2839 return NULL;
2840 }
2841
2842
2843 /* Return the argument of the loop PHI that is the inital value coming
2844 from outside the loop. */
2845
2846 static edge
2847 edge_initial_value_for_loop_phi (gimple phi)
2848 {
2849 size_t i;
2850
2851 for (i = 0; i < gimple_phi_num_args (phi); i++)
2852 {
2853 edge e = gimple_phi_arg_edge (phi, i);
2854
2855 if (loop_depth (e->src->loop_father)
2856 < loop_depth (e->dest->loop_father))
2857 return e;
2858 }
2859
2860 return NULL;
2861 }
2862
2863 /* Return the argument of the loop PHI that is the inital value coming
2864 from outside the loop. */
2865
2866 static tree
2867 initial_value_for_loop_phi (gimple phi)
2868 {
2869 size_t i;
2870
2871 for (i = 0; i < gimple_phi_num_args (phi); i++)
2872 {
2873 edge e = gimple_phi_arg_edge (phi, i);
2874
2875 if (loop_depth (e->src->loop_father)
2876 < loop_depth (e->dest->loop_father))
2877 return gimple_phi_arg_def (phi, i);
2878 }
2879
2880 return NULL_TREE;
2881 }
2882
2883 /* Returns true when DEF is used outside the reduction cycle of
2884 LOOP_PHI. */
2885
2886 static bool
2887 used_outside_reduction (tree def, gimple loop_phi)
2888 {
2889 use_operand_p use_p;
2890 imm_use_iterator imm_iter;
2891 loop_p loop = loop_containing_stmt (loop_phi);
2892
2893 /* In LOOP, DEF should be used only in LOOP_PHI. */
2894 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2895 {
2896 gimple stmt = USE_STMT (use_p);
2897
2898 if (stmt != loop_phi
2899 && !is_gimple_debug (stmt)
2900 && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
2901 return true;
2902 }
2903
2904 return false;
2905 }
2906
2907 /* Detect commutative and associative scalar reductions belonging to
2908 the SCOP starting at the loop closed phi node STMT. Return the phi
2909 node of the reduction cycle, or NULL. */
2910
2911 static gimple
2912 detect_commutative_reduction (scop_p scop, gimple stmt, VEC (gimple, heap) **in,
2913 VEC (gimple, heap) **out)
2914 {
2915 if (scalar_close_phi_node_p (stmt))
2916 {
2917 gimple def, loop_phi, phi, close_phi = stmt;
2918 tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
2919
2920 if (TREE_CODE (arg) != SSA_NAME)
2921 return NULL;
2922
2923 /* Note that loop close phi nodes should have a single argument
2924 because we translated the representation into a canonical form
2925 before Graphite: see canonicalize_loop_closed_ssa_form. */
2926 gcc_assert (gimple_phi_num_args (close_phi) == 1);
2927
2928 def = SSA_NAME_DEF_STMT (arg);
2929 if (!stmt_in_sese_p (def, SCOP_REGION (scop))
2930 || !(loop_phi = detect_commutative_reduction (scop, def, in, out)))
2931 return NULL;
2932
2933 lhs = gimple_phi_result (close_phi);
2934 init = initial_value_for_loop_phi (loop_phi);
2935 phi = follow_inital_value_to_phi (init, lhs);
2936
2937 if (phi && (used_outside_reduction (lhs, phi)
2938 || !has_single_use (gimple_phi_result (phi))))
2939 return NULL;
2940
2941 VEC_safe_push (gimple, heap, *in, loop_phi);
2942 VEC_safe_push (gimple, heap, *out, close_phi);
2943 return phi;
2944 }
2945
2946 if (gimple_code (stmt) == GIMPLE_ASSIGN)
2947 return detect_commutative_reduction_assign (stmt, in, out);
2948
2949 return NULL;
2950 }
2951
2952 /* Translate the scalar reduction statement STMT to an array RED
2953 knowing that its recursive phi node is LOOP_PHI. */
2954
2955 static void
2956 translate_scalar_reduction_to_array_for_stmt (scop_p scop, tree red,
2957 gimple stmt, gimple loop_phi)
2958 {
2959 tree res = gimple_phi_result (loop_phi);
2960 gimple assign = gimple_build_assign (res, unshare_expr (red));
2961 gimple_stmt_iterator gsi;
2962
2963 insert_stmts (scop, assign, NULL, gsi_after_labels (gimple_bb (loop_phi)));
2964
2965 assign = gimple_build_assign (unshare_expr (red), gimple_assign_lhs (stmt));
2966 gsi = gsi_for_stmt (stmt);
2967 gsi_next (&gsi);
2968 insert_stmts (scop, assign, NULL, gsi);
2969 }
2970
2971 /* Removes the PHI node and resets all the debug stmts that are using
2972 the PHI_RESULT. */
2973
2974 static void
2975 remove_phi (gimple phi)
2976 {
2977 imm_use_iterator imm_iter;
2978 tree def;
2979 use_operand_p use_p;
2980 gimple_stmt_iterator gsi;
2981 VEC (gimple, heap) *update = VEC_alloc (gimple, heap, 3);
2982 unsigned int i;
2983 gimple stmt;
2984
2985 def = PHI_RESULT (phi);
2986 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2987 {
2988 stmt = USE_STMT (use_p);
2989
2990 if (is_gimple_debug (stmt))
2991 {
2992 gimple_debug_bind_reset_value (stmt);
2993 VEC_safe_push (gimple, heap, update, stmt);
2994 }
2995 }
2996
2997 FOR_EACH_VEC_ELT (gimple, update, i, stmt)
2998 update_stmt (stmt);
2999
3000 VEC_free (gimple, heap, update);
3001
3002 gsi = gsi_for_phi_node (phi);
3003 remove_phi_node (&gsi, false);
3004 }
3005
3006 /* Helper function for for_each_index. For each INDEX of the data
3007 reference REF, returns true when its indices are valid in the loop
3008 nest LOOP passed in as DATA. */
3009
3010 static bool
3011 dr_indices_valid_in_loop (tree ref ATTRIBUTE_UNUSED, tree *index, void *data)
3012 {
3013 loop_p loop;
3014 basic_block header, def_bb;
3015 gimple stmt;
3016
3017 if (TREE_CODE (*index) != SSA_NAME)
3018 return true;
3019
3020 loop = *((loop_p *) data);
3021 header = loop->header;
3022 stmt = SSA_NAME_DEF_STMT (*index);
3023
3024 if (!stmt)
3025 return true;
3026
3027 def_bb = gimple_bb (stmt);
3028
3029 if (!def_bb)
3030 return true;
3031
3032 return dominated_by_p (CDI_DOMINATORS, header, def_bb);
3033 }
3034
3035 /* When the result of a CLOSE_PHI is written to a memory location,
3036 return a pointer to that memory reference, otherwise return
3037 NULL_TREE. */
3038
3039 static tree
3040 close_phi_written_to_memory (gimple close_phi)
3041 {
3042 imm_use_iterator imm_iter;
3043 use_operand_p use_p;
3044 gimple stmt;
3045 tree res, def = gimple_phi_result (close_phi);
3046
3047 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
3048 if ((stmt = USE_STMT (use_p))
3049 && gimple_code (stmt) == GIMPLE_ASSIGN
3050 && (res = gimple_assign_lhs (stmt)))
3051 {
3052 switch (TREE_CODE (res))
3053 {
3054 case VAR_DECL:
3055 case PARM_DECL:
3056 case RESULT_DECL:
3057 return res;
3058
3059 case ARRAY_REF:
3060 case MEM_REF:
3061 {
3062 tree arg = gimple_phi_arg_def (close_phi, 0);
3063 loop_p nest = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
3064
3065 /* FIXME: this restriction is for id-{24,25}.f and
3066 could be handled by duplicating the computation of
3067 array indices before the loop of the close_phi. */
3068 if (for_each_index (&res, dr_indices_valid_in_loop, &nest))
3069 return res;
3070 }
3071 /* Fallthru. */
3072
3073 default:
3074 continue;
3075 }
3076 }
3077 return NULL_TREE;
3078 }
3079
3080 /* Rewrite out of SSA the reduction described by the loop phi nodes
3081 IN, and the close phi nodes OUT. IN and OUT are structured by loop
3082 levels like this:
3083
3084 IN: stmt, loop_n, ..., loop_0
3085 OUT: stmt, close_n, ..., close_0
3086
3087 the first element is the reduction statement, and the next elements
3088 are the loop and close phi nodes of each of the outer loops. */
3089
3090 static void
3091 translate_scalar_reduction_to_array (scop_p scop,
3092 VEC (gimple, heap) *in,
3093 VEC (gimple, heap) *out)
3094 {
3095 gimple loop_phi;
3096 unsigned int i = VEC_length (gimple, out) - 1;
3097 tree red = close_phi_written_to_memory (VEC_index (gimple, out, i));
3098
3099 FOR_EACH_VEC_ELT (gimple, in, i, loop_phi)
3100 {
3101 gimple close_phi = VEC_index (gimple, out, i);
3102
3103 if (i == 0)
3104 {
3105 gimple stmt = loop_phi;
3106 basic_block bb = split_reduction_stmt (scop, stmt);
3107 poly_bb_p pbb = pbb_from_bb (bb);
3108 PBB_IS_REDUCTION (pbb) = true;
3109 gcc_assert (close_phi == loop_phi);
3110
3111 if (!red)
3112 red = create_zero_dim_array
3113 (gimple_assign_lhs (stmt), "Commutative_Associative_Reduction");
3114
3115 translate_scalar_reduction_to_array_for_stmt
3116 (scop, red, stmt, VEC_index (gimple, in, 1));
3117 continue;
3118 }
3119
3120 if (i == VEC_length (gimple, in) - 1)
3121 {
3122 insert_out_of_ssa_copy (scop, gimple_phi_result (close_phi),
3123 unshare_expr (red), close_phi);
3124 insert_out_of_ssa_copy_on_edge
3125 (scop, edge_initial_value_for_loop_phi (loop_phi),
3126 unshare_expr (red), initial_value_for_loop_phi (loop_phi));
3127 }
3128
3129 remove_phi (loop_phi);
3130 remove_phi (close_phi);
3131 }
3132 }
3133
3134 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI. Returns
3135 true when something has been changed. */
3136
3137 static bool
3138 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop,
3139 gimple close_phi)
3140 {
3141 bool res;
3142 VEC (gimple, heap) *in = VEC_alloc (gimple, heap, 10);
3143 VEC (gimple, heap) *out = VEC_alloc (gimple, heap, 10);
3144
3145 detect_commutative_reduction (scop, close_phi, &in, &out);
3146 res = VEC_length (gimple, in) > 1;
3147 if (res)
3148 translate_scalar_reduction_to_array (scop, in, out);
3149
3150 VEC_free (gimple, heap, in);
3151 VEC_free (gimple, heap, out);
3152 return res;
3153 }
3154
3155 /* Rewrites all the commutative reductions from LOOP out of SSA.
3156 Returns true when something has been changed. */
3157
3158 static bool
3159 rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop,
3160 loop_p loop)
3161 {
3162 gimple_stmt_iterator gsi;
3163 edge exit = single_exit (loop);
3164 tree res;
3165 bool changed = false;
3166
3167 if (!exit)
3168 return false;
3169
3170 for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
3171 if ((res = gimple_phi_result (gsi_stmt (gsi)))
3172 && is_gimple_reg (res)
3173 && !scev_analyzable_p (res, SCOP_REGION (scop)))
3174 changed |= rewrite_commutative_reductions_out_of_ssa_close_phi
3175 (scop, gsi_stmt (gsi));
3176
3177 return changed;
3178 }
3179
3180 /* Rewrites all the commutative reductions from SCOP out of SSA. */
3181
3182 static void
3183 rewrite_commutative_reductions_out_of_ssa (scop_p scop)
3184 {
3185 loop_iterator li;
3186 loop_p loop;
3187 bool changed = false;
3188 sese region = SCOP_REGION (scop);
3189
3190 FOR_EACH_LOOP (li, loop, 0)
3191 if (loop_in_sese_p (loop, region))
3192 changed |= rewrite_commutative_reductions_out_of_ssa_loop (scop, loop);
3193
3194 if (changed)
3195 {
3196 scev_reset_htab ();
3197 gsi_commit_edge_inserts ();
3198 update_ssa (TODO_update_ssa);
3199 #ifdef ENABLE_CHECKING
3200 verify_loop_closed_ssa (true);
3201 #endif
3202 }
3203 }
3204
3205 /* Can all ivs be represented by a signed integer?
3206 As CLooG might generate negative values in its expressions, signed loop ivs
3207 are required in the backend. */
3208
3209 static bool
3210 scop_ivs_can_be_represented (scop_p scop)
3211 {
3212 loop_iterator li;
3213 loop_p loop;
3214 gimple_stmt_iterator psi;
3215
3216 FOR_EACH_LOOP (li, loop, 0)
3217 {
3218 if (!loop_in_sese_p (loop, SCOP_REGION (scop)))
3219 continue;
3220
3221 for (psi = gsi_start_phis (loop->header);
3222 !gsi_end_p (psi); gsi_next (&psi))
3223 {
3224 gimple phi = gsi_stmt (psi);
3225 tree res = PHI_RESULT (phi);
3226 tree type = TREE_TYPE (res);
3227
3228 if (TYPE_UNSIGNED (type)
3229 && TYPE_PRECISION (type) >= TYPE_PRECISION (long_long_integer_type_node))
3230 return false;
3231 }
3232 }
3233
3234 return true;
3235 }
3236
3237 /* Builds the polyhedral representation for a SESE region. */
3238
3239 void
3240 build_poly_scop (scop_p scop)
3241 {
3242 sese region = SCOP_REGION (scop);
3243 graphite_dim_t max_dim;
3244
3245 build_scop_bbs (scop);
3246
3247 /* FIXME: This restriction is needed to avoid a problem in CLooG.
3248 Once CLooG is fixed, remove this guard. Anyways, it makes no
3249 sense to optimize a scop containing only PBBs that do not belong
3250 to any loops. */
3251 if (nb_pbbs_in_loops (scop) == 0)
3252 return;
3253
3254 if (!scop_ivs_can_be_represented (scop))
3255 return;
3256
3257 if (flag_associative_math)
3258 rewrite_commutative_reductions_out_of_ssa (scop);
3259
3260 build_sese_loop_nests (region);
3261 build_sese_conditions (region);
3262 find_scop_parameters (scop);
3263
3264 max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
3265 if (scop_nb_params (scop) > max_dim)
3266 return;
3267
3268 build_scop_iteration_domain (scop);
3269 build_scop_context (scop);
3270 add_conditions_to_constraints (scop);
3271
3272 /* Rewrite out of SSA only after having translated the
3273 representation to the polyhedral representation to avoid scev
3274 analysis failures. That means that these functions will insert
3275 new data references that they create in the right place. */
3276 rewrite_reductions_out_of_ssa (scop);
3277 rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
3278
3279 build_scop_drs (scop);
3280 scop_to_lst (scop);
3281 build_scop_scattering (scop);
3282
3283 /* This SCoP has been translated to the polyhedral
3284 representation. */
3285 POLY_SCOP_P (scop) = true;
3286 }
3287 #endif