OSDN Git Service

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