OSDN Git Service

Do not use a data ref with indices invalid in the loop of the close_phi.
[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   if (PBB_DOMAIN (pbb))
2156     ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
2157       (&PBB_DOMAIN (pbb1), PBB_DOMAIN (pbb));
2158
2159   GBB_PBB (gbb1) = pbb1;
2160   GBB_CONDITIONS (gbb1) = VEC_copy (gimple, heap, GBB_CONDITIONS (gbb));
2161   GBB_CONDITION_CASES (gbb1) = VEC_copy (gimple, heap, GBB_CONDITION_CASES (gbb));
2162   VEC_safe_insert (poly_bb_p, heap, SCOP_BBS (scop), index + 1, pbb1);
2163 }
2164
2165 /* Insert on edge E the assignment "RES := EXPR".  */
2166
2167 static void
2168 insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
2169 {
2170   gimple_stmt_iterator gsi;
2171   gimple_seq stmts;
2172   tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2173   gimple stmt = gimple_build_assign (res, var);
2174   basic_block bb;
2175   VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
2176
2177   if (!stmts)
2178     stmts = gimple_seq_alloc ();
2179
2180   gsi = gsi_last (stmts);
2181   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
2182   for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2183     VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
2184
2185   gsi_insert_seq_on_edge (e, stmts);
2186   gsi_commit_edge_inserts ();
2187   bb = gimple_bb (stmt);
2188
2189   if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2190     return;
2191
2192   if (!gbb_from_bb (bb))
2193     new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
2194
2195   analyze_drs_in_stmts (scop, bb, x);
2196   VEC_free (gimple, heap, x);
2197 }
2198
2199 /* Creates a zero dimension array of the same type as VAR.  */
2200
2201 static tree
2202 create_zero_dim_array (tree var, const char *base_name)
2203 {
2204   tree index_type = build_index_type (integer_zero_node);
2205   tree elt_type = TREE_TYPE (var);
2206   tree array_type = build_array_type (elt_type, index_type);
2207   tree base = create_tmp_var (array_type, base_name);
2208
2209   add_referenced_var (base);
2210
2211   return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
2212                  NULL_TREE);
2213 }
2214
2215 /* Returns true when PHI is a loop close phi node.  */
2216
2217 static bool
2218 scalar_close_phi_node_p (gimple phi)
2219 {
2220   if (gimple_code (phi) != GIMPLE_PHI
2221       || !is_gimple_reg (gimple_phi_result (phi)))
2222     return false;
2223
2224   /* Note that loop close phi nodes should have a single argument
2225      because we translated the representation into a canonical form
2226      before Graphite: see canonicalize_loop_closed_ssa_form.  */
2227   return (gimple_phi_num_args (phi) == 1);
2228 }
2229
2230 /* For a definition DEF in REGION, propagates the expression EXPR in
2231    all the uses of DEF outside REGION.  */
2232
2233 static void
2234 propagate_expr_outside_region (tree def, tree expr, sese region)
2235 {
2236   imm_use_iterator imm_iter;
2237   gimple use_stmt;
2238   gimple_seq stmts;
2239   bool replaced_once = false;
2240
2241   gcc_assert (TREE_CODE (def) == SSA_NAME);
2242
2243   expr = force_gimple_operand (unshare_expr (expr), &stmts, true,
2244                                NULL_TREE);
2245
2246   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2247     if (!is_gimple_debug (use_stmt)
2248         && !bb_in_sese_p (gimple_bb (use_stmt), region))
2249       {
2250         ssa_op_iter iter;
2251         use_operand_p use_p;
2252
2253         FOR_EACH_PHI_OR_STMT_USE (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2254           if (operand_equal_p (def, USE_FROM_PTR (use_p), 0)
2255               && (replaced_once = true))
2256             replace_exp (use_p, expr);
2257
2258         update_stmt (use_stmt);
2259       }
2260
2261   if (replaced_once)
2262     {
2263       gsi_insert_seq_on_edge (SESE_ENTRY (region), stmts);
2264       gsi_commit_edge_inserts ();
2265     }
2266 }
2267
2268 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2269    dimension array for it.  */
2270
2271 static void
2272 rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2273 {
2274   sese region = SCOP_REGION (scop);
2275   gimple phi = gsi_stmt (*psi);
2276   tree res = gimple_phi_result (phi);
2277   tree var = SSA_NAME_VAR (res);
2278   basic_block bb = gimple_bb (phi);
2279   gimple_stmt_iterator gsi = gsi_after_labels (bb);
2280   tree arg = gimple_phi_arg_def (phi, 0);
2281   gimple stmt;
2282
2283   /* Note that loop close phi nodes should have a single argument
2284      because we translated the representation into a canonical form
2285      before Graphite: see canonicalize_loop_closed_ssa_form.  */
2286   gcc_assert (gimple_phi_num_args (phi) == 1);
2287
2288   /* The phi node can be a non close phi node, when its argument is
2289      invariant, or a default definition.  */
2290   if (is_gimple_min_invariant (arg)
2291       || SSA_NAME_IS_DEFAULT_DEF (arg))
2292     {
2293       propagate_expr_outside_region (res, arg, region);
2294       gsi_next (psi);
2295       return;
2296     }
2297
2298   else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
2299     {
2300       propagate_expr_outside_region (res, arg, region);
2301       stmt = gimple_build_assign (res, arg);
2302       remove_phi_node (psi, false);
2303       gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2304       SSA_NAME_DEF_STMT (res) = stmt;
2305       return;
2306     }
2307
2308   /* If res is scev analyzable and is not a scalar value, it is safe
2309      to ignore the close phi node: it will be code generated in the
2310      out of Graphite pass.  */
2311   else if (scev_analyzable_p (res, region))
2312     {
2313       loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2314       tree scev;
2315
2316       if (!loop_in_sese_p (loop, region))
2317         {
2318           loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2319           scev = scalar_evolution_in_region (region, loop, arg);
2320           scev = compute_overall_effect_of_inner_loop (loop, scev);
2321         }
2322       else
2323         scev = scalar_evolution_in_region (region, loop, res);
2324
2325       if (tree_does_not_contain_chrecs (scev))
2326         propagate_expr_outside_region (res, scev, region);
2327
2328       gsi_next (psi);
2329       return;
2330     }
2331   else
2332     {
2333       tree zero_dim_array = create_zero_dim_array (var, "Close_Phi");
2334
2335       stmt = gimple_build_assign (res, zero_dim_array);
2336
2337       if (TREE_CODE (arg) == SSA_NAME)
2338         insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2339                                 SSA_NAME_DEF_STMT (arg));
2340       else
2341         insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
2342                                         zero_dim_array, arg);
2343     }
2344
2345   remove_phi_node (psi, false);
2346   SSA_NAME_DEF_STMT (res) = stmt;
2347
2348   insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2349 }
2350
2351 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2352    dimension array for it.  */
2353
2354 static void
2355 rewrite_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2356 {
2357   size_t i;
2358   gimple phi = gsi_stmt (*psi);
2359   basic_block bb = gimple_bb (phi);
2360   tree res = gimple_phi_result (phi);
2361   tree var = SSA_NAME_VAR (res);
2362   tree zero_dim_array = create_zero_dim_array (var, "phi_out_of_ssa");
2363   gimple stmt;
2364   gimple_seq stmts;
2365
2366   for (i = 0; i < gimple_phi_num_args (phi); i++)
2367     {
2368       tree arg = gimple_phi_arg_def (phi, i);
2369       edge e = gimple_phi_arg_edge (phi, i);
2370
2371       /* Avoid the insertion of code in the loop latch to please the
2372          pattern matching of the vectorizer.  */
2373       if (TREE_CODE (arg) == SSA_NAME
2374           && e->src == bb->loop_father->latch)
2375         insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2376                                 SSA_NAME_DEF_STMT (arg));
2377       else
2378         insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
2379     }
2380
2381   var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
2382
2383   stmt = gimple_build_assign (res, var);
2384   remove_phi_node (psi, false);
2385   SSA_NAME_DEF_STMT (res) = stmt;
2386
2387   insert_stmts (scop, stmt, stmts, gsi_after_labels (bb));
2388 }
2389
2390 /* Rewrite the degenerate phi node at position PSI from the degenerate
2391    form "x = phi (y, y, ..., y)" to "x = y".  */
2392
2393 static void
2394 rewrite_degenerate_phi (gimple_stmt_iterator *psi)
2395 {
2396   tree rhs;
2397   gimple stmt;
2398   gimple_stmt_iterator gsi;
2399   gimple phi = gsi_stmt (*psi);
2400   tree res = gimple_phi_result (phi);
2401   basic_block bb;
2402
2403   bb = gimple_bb (phi);
2404   rhs = degenerate_phi_result (phi);
2405   gcc_assert (rhs);
2406
2407   stmt = gimple_build_assign (res, rhs);
2408   remove_phi_node (psi, false);
2409   SSA_NAME_DEF_STMT (res) = stmt;
2410
2411   gsi = gsi_after_labels (bb);
2412   gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2413 }
2414
2415 /* Rewrite out of SSA all the reduction phi nodes of SCOP.  */
2416
2417 static void
2418 rewrite_reductions_out_of_ssa (scop_p scop)
2419 {
2420   basic_block bb;
2421   gimple_stmt_iterator psi;
2422   sese region = SCOP_REGION (scop);
2423
2424   FOR_EACH_BB (bb)
2425     if (bb_in_sese_p (bb, region))
2426       for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2427         {
2428           gimple phi = gsi_stmt (psi);
2429
2430           if (!is_gimple_reg (gimple_phi_result (phi)))
2431             {
2432               gsi_next (&psi);
2433               continue;
2434             }
2435
2436           if (gimple_phi_num_args (phi) > 1
2437               && degenerate_phi_result (phi))
2438             rewrite_degenerate_phi (&psi);
2439
2440           else if (scalar_close_phi_node_p (phi))
2441             rewrite_close_phi_out_of_ssa (scop, &psi);
2442
2443           else if (reduction_phi_p (region, &psi))
2444             rewrite_phi_out_of_ssa (scop, &psi);
2445         }
2446
2447   update_ssa (TODO_update_ssa);
2448 #ifdef ENABLE_CHECKING
2449   verify_loop_closed_ssa (true);
2450 #endif
2451 }
2452
2453 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2454    read from ZERO_DIM_ARRAY.  */
2455
2456 static void
2457 rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
2458                                     tree def, gimple use_stmt)
2459 {
2460   tree var = SSA_NAME_VAR (def);
2461   gimple name_stmt = gimple_build_assign (var, zero_dim_array);
2462   tree name = make_ssa_name (var, name_stmt);
2463   ssa_op_iter iter;
2464   use_operand_p use_p;
2465
2466   gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2467
2468   gimple_assign_set_lhs (name_stmt, name);
2469   insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
2470
2471   FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2472     if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2473       replace_exp (use_p, name);
2474
2475   update_stmt (use_stmt);
2476 }
2477
2478 /* For every definition DEF in the SCOP that is used outside the scop,
2479    insert a closing-scop definition in the basic block just after this
2480    SCOP.  */
2481
2482 static void
2483 handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple stmt)
2484 {
2485   tree var = create_tmp_reg (TREE_TYPE (def), NULL);
2486   tree new_name = make_ssa_name (var, stmt);
2487   bool needs_copy = false;
2488   use_operand_p use_p;
2489   imm_use_iterator imm_iter;
2490   gimple use_stmt;
2491   sese region = SCOP_REGION (scop);
2492
2493   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2494     {
2495       if (!bb_in_sese_p (gimple_bb (use_stmt), region))
2496         {
2497           FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2498             {
2499               SET_USE (use_p, new_name);
2500             }
2501           update_stmt (use_stmt);
2502           needs_copy = true;
2503         }
2504     }
2505
2506   /* Insert in the empty BB just after the scop a use of DEF such
2507      that the rewrite of cross_bb_scalar_dependences won't insert
2508      arrays everywhere else.  */
2509   if (needs_copy)
2510     {
2511       gimple assign = gimple_build_assign (new_name, def);
2512       gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
2513
2514       add_referenced_var (var);
2515       SSA_NAME_DEF_STMT (new_name) = assign;
2516       update_stmt (assign);
2517       gsi_insert_before (&psi, assign, GSI_SAME_STMT);
2518     }
2519 }
2520
2521 /* Rewrite the scalar dependences crossing the boundary of the BB
2522    containing STMT with an array.  Return true when something has been
2523    changed.  */
2524
2525 static bool
2526 rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
2527 {
2528   sese region = SCOP_REGION (scop);
2529   gimple stmt = gsi_stmt (*gsi);
2530   imm_use_iterator imm_iter;
2531   tree def;
2532   basic_block def_bb;
2533   tree zero_dim_array = NULL_TREE;
2534   gimple use_stmt;
2535   bool res = false;
2536
2537   switch (gimple_code (stmt))
2538     {
2539     case GIMPLE_ASSIGN:
2540       def = gimple_assign_lhs (stmt);
2541       break;
2542
2543     case GIMPLE_CALL:
2544       def = gimple_call_lhs (stmt);
2545       break;
2546
2547     default:
2548       return false;
2549     }
2550
2551   if (!def
2552       || !is_gimple_reg (def))
2553     return false;
2554
2555   if (scev_analyzable_p (def, region))
2556     {
2557       loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
2558       tree scev = scalar_evolution_in_region (region, loop, def);
2559
2560       if (tree_contains_chrecs (scev, NULL))
2561         return false;
2562
2563       propagate_expr_outside_region (def, scev, region);
2564       return true;
2565     }
2566
2567   def_bb = gimple_bb (stmt);
2568
2569   handle_scalar_deps_crossing_scop_limits (scop, def, stmt);
2570
2571   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2572     if (gimple_code (use_stmt) == GIMPLE_PHI
2573         && (res = true))
2574       {
2575         gimple_stmt_iterator psi = gsi_for_stmt (use_stmt);
2576
2577         if (scalar_close_phi_node_p (gsi_stmt (psi)))
2578           rewrite_close_phi_out_of_ssa (scop, &psi);
2579         else
2580           rewrite_phi_out_of_ssa (scop, &psi);
2581       }
2582
2583   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2584     if (gimple_code (use_stmt) != GIMPLE_PHI
2585         && def_bb != gimple_bb (use_stmt)
2586         && !is_gimple_debug (use_stmt)
2587         && (res = true))
2588       {
2589         if (!zero_dim_array)
2590           {
2591             zero_dim_array = create_zero_dim_array
2592               (SSA_NAME_VAR (def), "Cross_BB_scalar_dependence");
2593             insert_out_of_ssa_copy (scop, zero_dim_array, def,
2594                                     SSA_NAME_DEF_STMT (def));
2595             gsi_next (gsi);
2596           }
2597
2598         rewrite_cross_bb_scalar_dependence (scop, zero_dim_array,
2599                                             def, use_stmt);
2600       }
2601
2602   return res;
2603 }
2604
2605 /* Rewrite out of SSA all the reduction phi nodes of SCOP.  */
2606
2607 static void
2608 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
2609 {
2610   basic_block bb;
2611   gimple_stmt_iterator psi;
2612   sese region = SCOP_REGION (scop);
2613   bool changed = false;
2614
2615   /* Create an extra empty BB after the scop.  */
2616   split_edge (SESE_EXIT (region));
2617
2618   FOR_EACH_BB (bb)
2619     if (bb_in_sese_p (bb, region))
2620       for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2621         changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
2622
2623   if (changed)
2624     {
2625       scev_reset_htab ();
2626       update_ssa (TODO_update_ssa);
2627 #ifdef ENABLE_CHECKING
2628       verify_loop_closed_ssa (true);
2629 #endif
2630     }
2631 }
2632
2633 /* Returns the number of pbbs that are in loops contained in SCOP.  */
2634
2635 static int
2636 nb_pbbs_in_loops (scop_p scop)
2637 {
2638   int i;
2639   poly_bb_p pbb;
2640   int res = 0;
2641
2642   FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
2643     if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2644       res++;
2645
2646   return res;
2647 }
2648
2649 /* Return the number of data references in BB that write in
2650    memory.  */
2651
2652 static int
2653 nb_data_writes_in_bb (basic_block bb)
2654 {
2655   int res = 0;
2656   gimple_stmt_iterator gsi;
2657
2658   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2659     if (gimple_vdef (gsi_stmt (gsi)))
2660       res++;
2661
2662   return res;
2663 }
2664
2665 /* Splits at STMT the basic block BB represented as PBB in the
2666    polyhedral form.  */
2667
2668 static edge
2669 split_pbb (scop_p scop, poly_bb_p pbb, basic_block bb, gimple stmt)
2670 {
2671   edge e1 = split_block (bb, stmt);
2672   new_pbb_from_pbb (scop, pbb, e1->dest);
2673   return e1;
2674 }
2675
2676 /* Splits STMT out of its current BB.  This is done for reduction
2677    statements for which we want to ignore data dependences.  */
2678
2679 static basic_block
2680 split_reduction_stmt (scop_p scop, gimple stmt)
2681 {
2682   basic_block bb = gimple_bb (stmt);
2683   poly_bb_p pbb = pbb_from_bb (bb);
2684   gimple_bb_p gbb = gbb_from_bb (bb);
2685   edge e1;
2686   int i;
2687   data_reference_p dr;
2688
2689   /* Do not split basic blocks with no writes to memory: the reduction
2690      will be the only write to memory.  */
2691   if (nb_data_writes_in_bb (bb) == 0
2692       /* Or if we have already marked BB as a reduction.  */
2693       || PBB_IS_REDUCTION (pbb_from_bb (bb)))
2694     return bb;
2695
2696   e1 = split_pbb (scop, pbb, bb, stmt);
2697
2698   /* Split once more only when the reduction stmt is not the only one
2699      left in the original BB.  */
2700   if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
2701     {
2702       gimple_stmt_iterator gsi = gsi_last_bb (bb);
2703       gsi_prev (&gsi);
2704       e1 = split_pbb (scop, pbb, bb, gsi_stmt (gsi));
2705     }
2706
2707   /* A part of the data references will end in a different basic block
2708      after the split: move the DRs from the original GBB to the newly
2709      created GBB1.  */
2710   FOR_EACH_VEC_ELT (data_reference_p, GBB_DATA_REFS (gbb), i, dr)
2711     {
2712       basic_block bb1 = gimple_bb (DR_STMT (dr));
2713
2714       if (bb1 != bb)
2715         {
2716           gimple_bb_p gbb1 = gbb_from_bb (bb1);
2717           VEC_safe_push (data_reference_p, heap, GBB_DATA_REFS (gbb1), dr);
2718           VEC_ordered_remove (data_reference_p, GBB_DATA_REFS (gbb), i);
2719           i--;
2720         }
2721     }
2722
2723   return e1->dest;
2724 }
2725
2726 /* Return true when stmt is a reduction operation.  */
2727
2728 static inline bool
2729 is_reduction_operation_p (gimple stmt)
2730 {
2731   enum tree_code code;
2732
2733   gcc_assert (is_gimple_assign (stmt));
2734   code = gimple_assign_rhs_code (stmt);
2735
2736   return flag_associative_math
2737     && commutative_tree_code (code)
2738     && associative_tree_code (code);
2739 }
2740
2741 /* Returns true when PHI contains an argument ARG.  */
2742
2743 static bool
2744 phi_contains_arg (gimple phi, tree arg)
2745 {
2746   size_t i;
2747
2748   for (i = 0; i < gimple_phi_num_args (phi); i++)
2749     if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2750       return true;
2751
2752   return false;
2753 }
2754
2755 /* Return a loop phi node that corresponds to a reduction containing LHS.  */
2756
2757 static gimple
2758 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2759 {
2760   gimple stmt;
2761
2762   if (TREE_CODE (arg) != SSA_NAME)
2763     return NULL;
2764
2765   stmt = SSA_NAME_DEF_STMT (arg);
2766
2767   if (gimple_code (stmt) == GIMPLE_NOP
2768       || gimple_code (stmt) == GIMPLE_CALL)
2769     return NULL;
2770
2771   if (gimple_code (stmt) == GIMPLE_PHI)
2772     {
2773       if (phi_contains_arg (stmt, lhs))
2774         return stmt;
2775       return NULL;
2776     }
2777
2778   if (!is_gimple_assign (stmt))
2779     return NULL;
2780
2781   if (gimple_num_ops (stmt) == 2)
2782     return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2783
2784   if (is_reduction_operation_p (stmt))
2785     {
2786       gimple res = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2787
2788       return res ? res :
2789         follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2790     }
2791
2792   return NULL;
2793 }
2794
2795 /* Detect commutative and associative scalar reductions starting at
2796    the STMT.  Return the phi node of the reduction cycle, or NULL.  */
2797
2798 static gimple
2799 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2800                                   VEC (gimple, heap) **in,
2801                                   VEC (gimple, heap) **out)
2802 {
2803   gimple phi = follow_ssa_with_commutative_ops (arg, lhs);
2804
2805   if (!phi)
2806     return NULL;
2807
2808   VEC_safe_push (gimple, heap, *in, stmt);
2809   VEC_safe_push (gimple, heap, *out, stmt);
2810   return phi;
2811 }
2812
2813 /* Detect commutative and associative scalar reductions starting at
2814    STMT.  Return the phi node of the reduction cycle, or NULL.  */
2815
2816 static gimple
2817 detect_commutative_reduction_assign (gimple stmt, VEC (gimple, heap) **in,
2818                                      VEC (gimple, heap) **out)
2819 {
2820   tree lhs = gimple_assign_lhs (stmt);
2821
2822   if (gimple_num_ops (stmt) == 2)
2823     return detect_commutative_reduction_arg (lhs, stmt,
2824                                              gimple_assign_rhs1 (stmt),
2825                                              in, out);
2826
2827   if (is_reduction_operation_p (stmt))
2828     {
2829       gimple res = detect_commutative_reduction_arg (lhs, stmt,
2830                                                      gimple_assign_rhs1 (stmt),
2831                                                      in, out);
2832       return res ? res
2833         : detect_commutative_reduction_arg (lhs, stmt,
2834                                             gimple_assign_rhs2 (stmt),
2835                                             in, out);
2836     }
2837
2838   return NULL;
2839 }
2840
2841 /* Return a loop phi node that corresponds to a reduction containing LHS.  */
2842
2843 static gimple
2844 follow_inital_value_to_phi (tree arg, tree lhs)
2845 {
2846   gimple stmt;
2847
2848   if (!arg || TREE_CODE (arg) != SSA_NAME)
2849     return NULL;
2850
2851   stmt = SSA_NAME_DEF_STMT (arg);
2852
2853   if (gimple_code (stmt) == GIMPLE_PHI
2854       && phi_contains_arg (stmt, lhs))
2855     return stmt;
2856
2857   return NULL;
2858 }
2859
2860
2861 /* Return the argument of the loop PHI that is the inital value coming
2862    from outside the loop.  */
2863
2864 static edge
2865 edge_initial_value_for_loop_phi (gimple phi)
2866 {
2867   size_t i;
2868
2869   for (i = 0; i < gimple_phi_num_args (phi); i++)
2870     {
2871       edge e = gimple_phi_arg_edge (phi, i);
2872
2873       if (loop_depth (e->src->loop_father)
2874           < loop_depth (e->dest->loop_father))
2875         return e;
2876     }
2877
2878   return NULL;
2879 }
2880
2881 /* Return the argument of the loop PHI that is the inital value coming
2882    from outside the loop.  */
2883
2884 static tree
2885 initial_value_for_loop_phi (gimple phi)
2886 {
2887   size_t i;
2888
2889   for (i = 0; i < gimple_phi_num_args (phi); i++)
2890     {
2891       edge e = gimple_phi_arg_edge (phi, i);
2892
2893       if (loop_depth (e->src->loop_father)
2894           < loop_depth (e->dest->loop_father))
2895         return gimple_phi_arg_def (phi, i);
2896     }
2897
2898   return NULL_TREE;
2899 }
2900
2901 /* Detect commutative and associative scalar reductions belonging to
2902    the SCOP starting at the loop closed phi node STMT.  Return the phi
2903    node of the reduction cycle, or NULL.  */
2904
2905 static gimple
2906 detect_commutative_reduction (scop_p scop, gimple stmt, VEC (gimple, heap) **in,
2907                               VEC (gimple, heap) **out)
2908 {
2909   if (scalar_close_phi_node_p (stmt))
2910     {
2911       tree arg = gimple_phi_arg_def (stmt, 0);
2912       gimple def, loop_phi;
2913
2914       if (TREE_CODE (arg) != SSA_NAME)
2915         return NULL;
2916
2917       /* Note that loop close phi nodes should have a single argument
2918          because we translated the representation into a canonical form
2919          before Graphite: see canonicalize_loop_closed_ssa_form.  */
2920       gcc_assert (gimple_phi_num_args (stmt) == 1);
2921
2922       def = SSA_NAME_DEF_STMT (arg);
2923       if (!stmt_in_sese_p (def, SCOP_REGION (scop)))
2924         return NULL;
2925
2926       loop_phi = detect_commutative_reduction (scop, def, in, out);
2927
2928       if (loop_phi)
2929         {
2930           tree lhs = gimple_phi_result (stmt);
2931           tree init = initial_value_for_loop_phi (loop_phi);
2932           gimple phi = follow_inital_value_to_phi (init, lhs);
2933
2934           VEC_safe_push (gimple, heap, *in, loop_phi);
2935           VEC_safe_push (gimple, heap, *out, stmt);
2936           return phi;
2937         }
2938       else
2939         return NULL;
2940     }
2941
2942   if (gimple_code (stmt) == GIMPLE_ASSIGN)
2943     return detect_commutative_reduction_assign (stmt, in, out);
2944
2945   return NULL;
2946 }
2947
2948 /* Translate the scalar reduction statement STMT to an array RED
2949    knowing that its recursive phi node is LOOP_PHI.  */
2950
2951 static void
2952 translate_scalar_reduction_to_array_for_stmt (scop_p scop, tree red,
2953                                               gimple stmt, gimple loop_phi)
2954 {
2955   tree res = gimple_phi_result (loop_phi);
2956   gimple assign = gimple_build_assign (res, unshare_expr (red));
2957   gimple_stmt_iterator gsi;
2958
2959   insert_stmts (scop, assign, NULL, gsi_after_labels (gimple_bb (loop_phi)));
2960
2961   assign = gimple_build_assign (unshare_expr (red), gimple_assign_lhs (stmt));
2962   gsi = gsi_for_stmt (stmt);
2963   gsi_next (&gsi);
2964   insert_stmts (scop, assign, NULL, gsi);
2965 }
2966
2967 /* Removes the PHI node and resets all the debug stmts that are using
2968    the PHI_RESULT.  */
2969
2970 static void
2971 remove_phi (gimple phi)
2972 {
2973   imm_use_iterator imm_iter;
2974   tree def;
2975   use_operand_p use_p;
2976   gimple_stmt_iterator gsi;
2977   VEC (gimple, heap) *update = VEC_alloc (gimple, heap, 3);
2978   unsigned int i;
2979   gimple stmt;
2980
2981   def = PHI_RESULT (phi);
2982   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2983     {
2984       stmt = USE_STMT (use_p);
2985
2986       if (is_gimple_debug (stmt))
2987         {
2988           gimple_debug_bind_reset_value (stmt);
2989           VEC_safe_push (gimple, heap, update, stmt);
2990         }
2991     }
2992
2993   FOR_EACH_VEC_ELT (gimple, update, i, stmt)
2994     update_stmt (stmt);
2995
2996   VEC_free (gimple, heap, update);
2997
2998   gsi = gsi_for_phi_node (phi);
2999   remove_phi_node (&gsi, false);
3000 }
3001
3002 /* Helper function for for_each_index.  For each INDEX of the data
3003    reference REF, returns true when its indices are valid in the loop
3004    nest LOOP passed in as DATA.  */
3005
3006 static bool
3007 dr_indices_valid_in_loop (tree ref ATTRIBUTE_UNUSED, tree *index, void *data)
3008 {
3009   loop_p loop;
3010   basic_block header, def_bb;
3011   gimple stmt;
3012
3013   if (TREE_CODE (*index) != SSA_NAME)
3014     return true;
3015
3016   loop = *((loop_p *) data);
3017   header = loop->header;
3018   stmt = SSA_NAME_DEF_STMT (*index);
3019
3020   if (!stmt)
3021     return true;
3022
3023   def_bb = gimple_bb (stmt);
3024
3025   if (!def_bb)
3026     return true;
3027
3028   return dominated_by_p (CDI_DOMINATORS, header, def_bb);
3029 }
3030
3031 /* When the result of a CLOSE_PHI is written to a memory location,
3032    return a pointer to that memory reference, otherwise return
3033    NULL_TREE.  */
3034
3035 static tree
3036 close_phi_written_to_memory (gimple close_phi)
3037 {
3038   imm_use_iterator imm_iter;
3039   use_operand_p use_p;
3040   gimple stmt;
3041   tree res, def = gimple_phi_result (close_phi);
3042
3043   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
3044     if ((stmt = USE_STMT (use_p))
3045         && gimple_code (stmt) == GIMPLE_ASSIGN
3046         && (res = gimple_assign_lhs (stmt)))
3047       {
3048         switch (TREE_CODE (res))
3049           {
3050           case VAR_DECL:
3051           case PARM_DECL:
3052           case RESULT_DECL:
3053             return res;
3054
3055           case ARRAY_REF:
3056           case MEM_REF:
3057             {
3058               tree arg = gimple_phi_arg_def (close_phi, 0);
3059               loop_p nest = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
3060
3061               /* FIXME: this restriction is for id-{24,25}.f and
3062                  could be handled by duplicating the computation of
3063                  array indices before the loop of the close_phi.  */
3064               if (for_each_index (&res, dr_indices_valid_in_loop, &nest))
3065                 return res;
3066             }
3067             /* Fallthru.  */
3068
3069           default:
3070             continue;
3071           }
3072       }
3073   return NULL_TREE;
3074 }
3075
3076 /* Rewrite out of SSA the reduction described by the loop phi nodes
3077    IN, and the close phi nodes OUT.  IN and OUT are structured by loop
3078    levels like this:
3079
3080    IN: stmt, loop_n, ..., loop_0
3081    OUT: stmt, close_n, ..., close_0
3082
3083    the first element is the reduction statement, and the next elements
3084    are the loop and close phi nodes of each of the outer loops.  */
3085
3086 static void
3087 translate_scalar_reduction_to_array (scop_p scop,
3088                                      VEC (gimple, heap) *in,
3089                                      VEC (gimple, heap) *out)
3090 {
3091   gimple loop_phi;
3092   unsigned int i = VEC_length (gimple, out) - 1;
3093   tree red = close_phi_written_to_memory (VEC_index (gimple, out, i));
3094
3095   FOR_EACH_VEC_ELT (gimple, in, i, loop_phi)
3096     {
3097       gimple close_phi = VEC_index (gimple, out, i);
3098
3099       if (i == 0)
3100         {
3101           gimple stmt = loop_phi;
3102           basic_block bb = split_reduction_stmt (scop, stmt);
3103           poly_bb_p pbb = pbb_from_bb (bb);
3104           PBB_IS_REDUCTION (pbb) = true;
3105           gcc_assert (close_phi == loop_phi);
3106
3107           if (!red)
3108             red = create_zero_dim_array
3109               (gimple_assign_lhs (stmt), "Commutative_Associative_Reduction");
3110
3111           translate_scalar_reduction_to_array_for_stmt
3112             (scop, red, stmt, VEC_index (gimple, in, 1));
3113           continue;
3114         }
3115
3116       if (i == VEC_length (gimple, in) - 1)
3117         {
3118           insert_out_of_ssa_copy (scop, gimple_phi_result (close_phi),
3119                                   unshare_expr (red), close_phi);
3120           insert_out_of_ssa_copy_on_edge
3121             (scop, edge_initial_value_for_loop_phi (loop_phi),
3122              unshare_expr (red), initial_value_for_loop_phi (loop_phi));
3123         }
3124
3125       remove_phi (loop_phi);
3126       remove_phi (close_phi);
3127     }
3128 }
3129
3130 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI.  Returns
3131    true when something has been changed.  */
3132
3133 static bool
3134 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop,
3135                                                      gimple close_phi)
3136 {
3137   bool res;
3138   VEC (gimple, heap) *in = VEC_alloc (gimple, heap, 10);
3139   VEC (gimple, heap) *out = VEC_alloc (gimple, heap, 10);
3140
3141   detect_commutative_reduction (scop, close_phi, &in, &out);
3142   res = VEC_length (gimple, in) > 0;
3143   if (res)
3144     translate_scalar_reduction_to_array (scop, in, out);
3145
3146   VEC_free (gimple, heap, in);
3147   VEC_free (gimple, heap, out);
3148   return res;
3149 }
3150
3151 /* Rewrites all the commutative reductions from LOOP out of SSA.
3152    Returns true when something has been changed.  */
3153
3154 static bool
3155 rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop,
3156                                                 loop_p loop)
3157 {
3158   gimple_stmt_iterator gsi;
3159   edge exit = single_exit (loop);
3160   tree res;
3161   bool changed = false;
3162
3163   if (!exit)
3164     return false;
3165
3166   for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
3167     if ((res = gimple_phi_result (gsi_stmt (gsi)))
3168         && is_gimple_reg (res)
3169         && !scev_analyzable_p (res, SCOP_REGION (scop)))
3170       changed |= rewrite_commutative_reductions_out_of_ssa_close_phi
3171         (scop, gsi_stmt (gsi));
3172
3173   return changed;
3174 }
3175
3176 /* Rewrites all the commutative reductions from SCOP out of SSA.  */
3177
3178 static void
3179 rewrite_commutative_reductions_out_of_ssa (scop_p scop)
3180 {
3181   loop_iterator li;
3182   loop_p loop;
3183   bool changed = false;
3184   sese region = SCOP_REGION (scop);
3185
3186   FOR_EACH_LOOP (li, loop, 0)
3187     if (loop_in_sese_p (loop, region))
3188       changed |= rewrite_commutative_reductions_out_of_ssa_loop (scop, loop);
3189
3190   if (changed)
3191     {
3192       scev_reset_htab ();
3193       gsi_commit_edge_inserts ();
3194       update_ssa (TODO_update_ssa);
3195 #ifdef ENABLE_CHECKING
3196       verify_loop_closed_ssa (true);
3197 #endif
3198     }
3199 }
3200
3201 /* Java does not initialize long_long_integer_type_node.  */
3202 #define my_long_long (long_long_integer_type_node ? long_long_integer_type_node : ssizetype)
3203
3204 /* Can all ivs be represented by a signed integer?
3205    As CLooG might generate negative values in its expressions, signed loop ivs
3206    are required in the backend. */
3207
3208 static bool
3209 scop_ivs_can_be_represented (scop_p scop)
3210 {
3211   loop_iterator li;
3212   loop_p loop;
3213   gimple_stmt_iterator psi;
3214
3215   FOR_EACH_LOOP (li, loop, 0)
3216     {
3217       if (!loop_in_sese_p (loop, SCOP_REGION (scop)))
3218         continue;
3219
3220       for (psi = gsi_start_phis (loop->header);
3221            !gsi_end_p (psi); gsi_next (&psi))
3222         {
3223           gimple phi = gsi_stmt (psi);
3224           tree res = PHI_RESULT (phi);
3225           tree type = TREE_TYPE (res);
3226
3227           if (TYPE_UNSIGNED (type)
3228               && TYPE_PRECISION (type) >= TYPE_PRECISION (my_long_long))
3229             return false;
3230         }
3231     }
3232
3233   return true;
3234 }
3235
3236 #undef my_long_long
3237
3238 /* Builds the polyhedral representation for a SESE region.  */
3239
3240 void
3241 build_poly_scop (scop_p scop)
3242 {
3243   sese region = SCOP_REGION (scop);
3244   graphite_dim_t max_dim;
3245
3246   build_scop_bbs (scop);
3247
3248   /* FIXME: This restriction is needed to avoid a problem in CLooG.
3249      Once CLooG is fixed, remove this guard.  Anyways, it makes no
3250      sense to optimize a scop containing only PBBs that do not belong
3251      to any loops.  */
3252   if (nb_pbbs_in_loops (scop) == 0)
3253     return;
3254
3255   if (!scop_ivs_can_be_represented (scop))
3256     return;
3257
3258   if (flag_associative_math)
3259     rewrite_commutative_reductions_out_of_ssa (scop);
3260
3261   build_sese_loop_nests (region);
3262   build_sese_conditions (region);
3263   find_scop_parameters (scop);
3264
3265   max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
3266   if (scop_nb_params (scop) > max_dim)
3267     return;
3268
3269   build_scop_iteration_domain (scop);
3270   build_scop_context (scop);
3271   add_conditions_to_constraints (scop);
3272
3273   /* Rewrite out of SSA only after having translated the
3274      representation to the polyhedral representation to avoid scev
3275      analysis failures.  That means that these functions will insert
3276      new data references that they create in the right place.  */
3277   rewrite_reductions_out_of_ssa (scop);
3278   rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
3279
3280   build_scop_drs (scop);
3281   scop_to_lst (scop);
3282   build_scop_scattering (scop);
3283
3284   /* This SCoP has been translated to the polyhedral
3285      representation.  */
3286   POLY_SCOP_P (scop) = true;
3287 }
3288 #endif