OSDN Git Service

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