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