OSDN Git Service

2009-09-14 Sebastian Pop <sebastian.pop@amd.com>
[pf3gnuchains/gcc-fork.git] / gcc / graphite-sese-to-poly.c
1 /* Conversion of SESE regions to Polyhedra.
2    Copyright (C) 2009 Free Software Foundation, Inc.
3    Contributed by Sebastian Pop <sebastian.pop@amd.com>.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "ggc.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "basic-block.h"
29 #include "diagnostic.h"
30 #include "tree-flow.h"
31 #include "toplev.h"
32 #include "tree-dump.h"
33 #include "timevar.h"
34 #include "cfgloop.h"
35 #include "tree-chrec.h"
36 #include "tree-data-ref.h"
37 #include "tree-scalar-evolution.h"
38 #include "tree-pass.h"
39 #include "domwalk.h"
40 #include "value-prof.h"
41 #include "pointer-set.h"
42 #include "gimple.h"
43 #include "sese.h"
44
45 #ifdef HAVE_cloog
46 #include "cloog/cloog.h"
47 #include "ppl_c.h"
48 #include "graphite-ppl.h"
49 #include "graphite.h"
50 #include "graphite-poly.h"
51 #include "graphite-scop-detection.h"
52 #include "graphite-clast-to-gimple.h"
53 #include "graphite-sese-to-poly.h"
54
55 /* Check if VAR is used in a phi node, that is no loop header.  */
56
57 static bool
58 var_used_in_not_loop_header_phi_node (tree var)
59 {
60
61   imm_use_iterator imm_iter;
62   gimple stmt;
63   bool result = false;
64
65   FOR_EACH_IMM_USE_STMT (stmt, imm_iter, var)
66     {
67       basic_block bb = gimple_bb (stmt);
68
69       if (gimple_code (stmt) == GIMPLE_PHI
70           && bb->loop_father->header != bb)
71         result = true;
72     }
73
74   return result;
75 }
76
77 /* Returns the index of the phi argument corresponding to the initial
78    value in the loop.  */
79
80 static size_t
81 loop_entry_phi_arg (gimple phi)
82 {
83   loop_p loop = gimple_bb (phi)->loop_father;
84   size_t i;
85
86   for (i = 0; i < gimple_phi_num_args (phi); i++)
87     if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
88       return i;
89
90   gcc_unreachable ();
91   return 0;
92 }
93
94 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
95    PSI by inserting on the loop ENTRY edge assignment "RES = INIT".  */
96
97 static void
98 remove_simple_copy_phi (gimple_stmt_iterator *psi)
99 {
100   gimple phi = gsi_stmt (*psi);
101   tree res = gimple_phi_result (phi);
102   size_t entry = loop_entry_phi_arg (phi);
103   tree init = gimple_phi_arg_def (phi, entry);
104   gimple stmt = gimple_build_assign (res, init);
105   edge e = gimple_phi_arg_edge (phi, entry);
106
107   remove_phi_node (psi, false);
108   gsi_insert_on_edge_immediate (e, stmt);
109   SSA_NAME_DEF_STMT (res) = stmt;
110 }
111
112 /* Removes an invariant phi node at position PSI by inserting on the
113    loop ENTRY edge the assignment RES = INIT.  */
114
115 static void
116 remove_invariant_phi (sese region, gimple_stmt_iterator *psi)
117 {
118   gimple phi = gsi_stmt (*psi);
119   loop_p loop = loop_containing_stmt (phi);
120   tree res = gimple_phi_result (phi);
121   tree scev = scalar_evolution_in_region (region, loop, res);
122   size_t entry = loop_entry_phi_arg (phi);
123   edge e = gimple_phi_arg_edge (phi, entry);
124   tree var;
125   gimple stmt;
126   gimple_seq stmts;
127   gimple_stmt_iterator gsi;
128
129   if (tree_contains_chrecs (scev, NULL))
130     scev = gimple_phi_arg_def (phi, entry);
131
132   var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
133   stmt = gimple_build_assign (res, var);
134   remove_phi_node (psi, false);
135
136   if (!stmts)
137     stmts = gimple_seq_alloc ();
138
139   gsi = gsi_last (stmts);
140   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
141   gsi_insert_seq_on_edge (e, stmts);
142   gsi_commit_edge_inserts ();
143   SSA_NAME_DEF_STMT (res) = stmt;
144 }
145
146 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)".  */
147
148 static inline bool
149 simple_copy_phi_p (gimple phi)
150 {
151   tree res;
152
153   if (gimple_phi_num_args (phi) != 2)
154     return false;
155
156   res = gimple_phi_result (phi);
157   return (res == gimple_phi_arg_def (phi, 0)
158           || res == gimple_phi_arg_def (phi, 1));
159 }
160
161 /* Returns true when the phi node at position PSI is a reduction phi
162    node in REGION.  Otherwise moves the pointer PSI to the next phi to
163    be considered.  */
164
165 static bool
166 reduction_phi_p (sese region, gimple_stmt_iterator *psi)
167 {
168   loop_p loop;
169   tree scev;
170   affine_iv iv;
171   gimple phi = gsi_stmt (*psi);
172   tree res = gimple_phi_result (phi);
173
174   if (!is_gimple_reg (res))
175     {
176       gsi_next (psi);
177       return false;
178     }
179
180   loop = loop_containing_stmt (phi);
181
182   if (simple_copy_phi_p (phi))
183     {
184       /* FIXME: PRE introduces phi nodes like these, for an example,
185          see id-5.f in the fortran graphite testsuite:
186
187          # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
188       */
189       remove_simple_copy_phi (psi);
190       return false;
191     }
192
193   /* Main induction variables with constant strides in LOOP are not
194      reductions.  */
195   if (simple_iv (loop, loop, res, &iv, true))
196     {
197       gsi_next (psi);
198       return false;
199     }
200
201   scev = scalar_evolution_in_region (region, loop, res);
202   if (chrec_contains_undetermined (scev))
203     return true;
204
205   if (evolution_function_is_invariant_p (scev, loop->num))
206     {
207       remove_invariant_phi (region, psi);
208       return false;
209     }
210
211   /* All the other cases are considered reductions.  */
212   return true;
213 }
214
215 /* Returns true when BB will be represented in graphite.  Return false
216    for the basic blocks that contain code eliminated in the code
217    generation pass: i.e. induction variables and exit conditions.  */
218
219 static bool
220 graphite_stmt_p (sese region, basic_block bb,
221                  VEC (data_reference_p, heap) *drs)
222 {
223   gimple_stmt_iterator gsi;
224   loop_p loop = bb->loop_father;
225
226   if (VEC_length (data_reference_p, drs) > 0)
227     return true;
228
229   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
230     {
231       gimple stmt = gsi_stmt (gsi);
232
233       switch (gimple_code (stmt))
234         {
235         case GIMPLE_DEBUG:
236           /* Control flow expressions can be ignored, as they are
237              represented in the iteration domains and will be
238              regenerated by graphite.  */
239         case GIMPLE_COND:
240         case GIMPLE_GOTO:
241         case GIMPLE_SWITCH:
242           break;
243
244         case GIMPLE_ASSIGN:
245           {
246             tree var = gimple_assign_lhs (stmt);
247
248             /* We need these bbs to be able to construct the phi nodes.  */
249             if (var_used_in_not_loop_header_phi_node (var))
250               return true;
251
252             var = scalar_evolution_in_region (region, loop, var);
253             if (chrec_contains_undetermined (var))
254               return true;
255
256             break;
257           }
258
259         default:
260           return true;
261         }
262     }
263
264   return false;
265 }
266
267 /* Store the GRAPHITE representation of BB.  */
268
269 static gimple_bb_p
270 new_gimple_bb (basic_block bb, VEC (data_reference_p, heap) *drs)
271 {
272   struct gimple_bb *gbb;
273
274   gbb = XNEW (struct gimple_bb);
275   bb->aux = gbb;
276   GBB_BB (gbb) = bb;
277   GBB_DATA_REFS (gbb) = drs;
278   GBB_CONDITIONS (gbb) = NULL;
279   GBB_CONDITION_CASES (gbb) = NULL;
280   GBB_CLOOG_IV_TYPES (gbb) = NULL;
281
282   return gbb;
283 }
284
285 /* Frees GBB.  */
286
287 static void
288 free_gimple_bb (struct gimple_bb *gbb)
289 {
290   if (GBB_CLOOG_IV_TYPES (gbb))
291     htab_delete (GBB_CLOOG_IV_TYPES (gbb));
292
293   free_data_refs (GBB_DATA_REFS (gbb));
294
295   VEC_free (gimple, heap, GBB_CONDITIONS (gbb));
296   VEC_free (gimple, heap, GBB_CONDITION_CASES (gbb));
297   GBB_BB (gbb)->aux = 0;
298   XDELETE (gbb);
299 }
300
301 /* Deletes all gimple bbs in SCOP.  */
302
303 static void
304 remove_gbbs_in_scop (scop_p scop)
305 {
306   int i;
307   poly_bb_p pbb;
308
309   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
310     free_gimple_bb (PBB_BLACK_BOX (pbb));
311 }
312
313 /* Deletes all scops in SCOPS.  */
314
315 void
316 free_scops (VEC (scop_p, heap) *scops)
317 {
318   int i;
319   scop_p scop;
320
321   for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++)
322     {
323       remove_gbbs_in_scop (scop);
324       free_sese (SCOP_REGION (scop));
325       free_scop (scop);
326     }
327
328   VEC_free (scop_p, heap, scops);
329 }
330
331 /* Generates a polyhedral black box only if the bb contains interesting
332    information.  */
333
334 static void
335 try_generate_gimple_bb (scop_p scop, basic_block bb)
336 {
337   VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
338   loop_p nest = outermost_loop_in_sese (SCOP_REGION (scop), bb);
339   gimple_stmt_iterator gsi;
340
341   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
342     {
343       gimple stmt = gsi_stmt (gsi);
344       if (!is_gimple_debug (stmt))
345         graphite_find_data_references_in_stmt (nest, stmt, &drs);
346     }
347
348   if (!graphite_stmt_p (SCOP_REGION (scop), bb, drs))
349     free_data_refs (drs);
350   else
351     new_poly_bb (scop, new_gimple_bb (bb, drs));
352 }
353
354 /* Returns true if all predecessors of BB, that are not dominated by BB, are
355    marked in MAP.  The predecessors dominated by BB are loop latches and will
356    be handled after BB.  */
357
358 static bool
359 all_non_dominated_preds_marked_p (basic_block bb, sbitmap map)
360 {
361   edge e;
362   edge_iterator ei;
363
364   FOR_EACH_EDGE (e, ei, bb->preds)
365     if (!TEST_BIT (map, e->src->index)
366         && !dominated_by_p (CDI_DOMINATORS, e->src, bb))
367         return false;
368
369   return true;
370 }
371
372 /* Compare the depth of two basic_block's P1 and P2.  */
373
374 static int
375 compare_bb_depths (const void *p1, const void *p2)
376 {
377   const_basic_block const bb1 = *(const_basic_block const*)p1;
378   const_basic_block const bb2 = *(const_basic_block const*)p2;
379   int d1 = loop_depth (bb1->loop_father);
380   int d2 = loop_depth (bb2->loop_father);
381
382   if (d1 < d2)
383     return 1;
384
385   if (d1 > d2)
386     return -1;
387
388   return 0;
389 }
390
391 /* Sort the basic blocks from DOM such that the first are the ones at
392    a deepest loop level.  */
393
394 static void
395 graphite_sort_dominated_info (VEC (basic_block, heap) *dom)
396 {
397   size_t len = VEC_length (basic_block, dom);
398
399   qsort (VEC_address (basic_block, dom), len, sizeof (basic_block),
400          compare_bb_depths);
401 }
402
403 /* Recursive helper function for build_scops_bbs.  */
404
405 static void
406 build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
407 {
408   sese region = SCOP_REGION (scop);
409   VEC (basic_block, heap) *dom;
410
411   if (TEST_BIT (visited, bb->index)
412       || !bb_in_sese_p (bb, region))
413     return;
414
415   try_generate_gimple_bb (scop, bb);
416   SET_BIT (visited, bb->index);
417
418   dom = get_dominated_by (CDI_DOMINATORS, bb);
419
420   if (dom == NULL)
421     return;
422
423   graphite_sort_dominated_info (dom);
424
425   while (!VEC_empty (basic_block, dom))
426     {
427       int i;
428       basic_block dom_bb;
429
430       for (i = 0; VEC_iterate (basic_block, dom, i, dom_bb); i++)
431         if (all_non_dominated_preds_marked_p (dom_bb, visited))
432           {
433             build_scop_bbs_1 (scop, visited, dom_bb);
434             VEC_unordered_remove (basic_block, dom, i);
435             break;
436           }
437     }
438
439   VEC_free (basic_block, heap, dom);
440 }
441
442 /* Gather the basic blocks belonging to the SCOP.  */
443
444 void
445 build_scop_bbs (scop_p scop)
446 {
447   sbitmap visited = sbitmap_alloc (last_basic_block);
448   sese region = SCOP_REGION (scop);
449
450   sbitmap_zero (visited);
451   build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region));
452
453   sbitmap_free (visited);
454 }
455
456 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
457    We generate SCATTERING_DIMENSIONS scattering dimensions.
458
459    CLooG 0.15.0 and previous versions require, that all
460    scattering functions of one CloogProgram have the same number of
461    scattering dimensions, therefore we allow to specify it.  This
462    should be removed in future versions of CLooG.
463
464    The scattering polyhedron consists of these dimensions: scattering,
465    loop_iterators, parameters.
466
467    Example:
468
469    | scattering_dimensions = 5
470    | used_scattering_dimensions = 3
471    | nb_iterators = 1
472    | scop_nb_params = 2
473    |
474    | Schedule:
475    |   i
476    | 4 5
477    |
478    | Scattering polyhedron:
479    |
480    | scattering: {s1, s2, s3, s4, s5}
481    | loop_iterators: {i}
482    | parameters: {p1, p2}
483    |
484    | s1  s2  s3  s4  s5  i   p1  p2  1
485    | 1   0   0   0   0   0   0   0  -4  = 0
486    | 0   1   0   0   0  -1   0   0   0  = 0
487    | 0   0   1   0   0   0   0   0  -5  = 0  */
488
489 static void
490 build_pbb_scattering_polyhedrons (ppl_Linear_Expression_t static_schedule,
491                                   poly_bb_p pbb, int scattering_dimensions)
492 {
493   int i;
494   scop_p scop = PBB_SCOP (pbb);
495   int nb_iterators = pbb_dim_iter_domain (pbb);
496   int used_scattering_dimensions = nb_iterators * 2 + 1;
497   int nb_params = scop_nb_params (scop);
498   ppl_Coefficient_t c;
499   ppl_dimension_type dim = scattering_dimensions + nb_iterators + nb_params;
500   Value v;
501
502   gcc_assert (scattering_dimensions >= used_scattering_dimensions);
503
504   value_init (v);
505   ppl_new_Coefficient (&c);
506   PBB_TRANSFORMED (pbb) = poly_scattering_new ();
507   ppl_new_C_Polyhedron_from_space_dimension
508     (&PBB_TRANSFORMED_SCATTERING (pbb), dim, 0);
509
510   PBB_NB_SCATTERING_TRANSFORM (pbb) = scattering_dimensions;
511
512   for (i = 0; i < scattering_dimensions; i++)
513     {
514       ppl_Constraint_t cstr;
515       ppl_Linear_Expression_t expr;
516
517       ppl_new_Linear_Expression_with_dimension (&expr, dim);
518       value_set_si (v, 1);
519       ppl_assign_Coefficient_from_mpz_t (c, v);
520       ppl_Linear_Expression_add_to_coefficient (expr, i, c);
521
522       /* Textual order inside this loop.  */
523       if ((i % 2) == 0)
524         {
525           ppl_Linear_Expression_coefficient (static_schedule, i / 2, c);
526           ppl_Coefficient_to_mpz_t (c, v);
527           value_oppose (v, v);
528           ppl_assign_Coefficient_from_mpz_t (c, v);
529           ppl_Linear_Expression_add_to_inhomogeneous (expr, c);
530         }
531
532       /* Iterations of this loop.  */
533       else /* if ((i % 2) == 1) */
534         {
535           int loop = (i - 1) / 2;
536
537           value_set_si (v, -1);
538           ppl_assign_Coefficient_from_mpz_t (c, v);
539           ppl_Linear_Expression_add_to_coefficient
540             (expr, scattering_dimensions + loop, c);
541         }
542
543       ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL);
544       ppl_Polyhedron_add_constraint (PBB_TRANSFORMED_SCATTERING (pbb), cstr);
545       ppl_delete_Linear_Expression (expr);
546       ppl_delete_Constraint (cstr);
547     }
548
549   value_clear (v);
550   ppl_delete_Coefficient (c);
551
552   PBB_ORIGINAL (pbb) = poly_scattering_copy (PBB_TRANSFORMED (pbb));
553 }
554
555 /* Build for BB the static schedule.
556
557    The static schedule is a Dewey numbering of the abstract syntax
558    tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
559
560    The following example informally defines the static schedule:
561
562    A
563    for (i: ...)
564      {
565        for (j: ...)
566          {
567            B
568            C
569          }
570
571        for (k: ...)
572          {
573            D
574            E
575          }
576      }
577    F
578
579    Static schedules for A to F:
580
581      DEPTH
582      0 1 2
583    A 0
584    B 1 0 0
585    C 1 0 1
586    D 1 1 0
587    E 1 1 1
588    F 2
589 */
590
591 static void
592 build_scop_scattering (scop_p scop)
593 {
594   int i;
595   poly_bb_p pbb;
596   gimple_bb_p previous_gbb = NULL;
597   ppl_Linear_Expression_t static_schedule;
598   ppl_Coefficient_t c;
599   Value v;
600
601   value_init (v);
602   ppl_new_Coefficient (&c);
603   ppl_new_Linear_Expression (&static_schedule);
604
605   /* We have to start schedules at 0 on the first component and
606      because we cannot compare_prefix_loops against a previous loop,
607      prefix will be equal to zero, and that index will be
608      incremented before copying.  */
609   value_set_si (v, -1);
610   ppl_assign_Coefficient_from_mpz_t (c, v);
611   ppl_Linear_Expression_add_to_coefficient (static_schedule, 0, c);
612
613   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
614     {
615       gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
616       ppl_Linear_Expression_t common;
617       int prefix;
618       int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1;
619
620       if (previous_gbb)
621         prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
622       else
623         prefix = 0;
624
625       previous_gbb = gbb;
626       ppl_new_Linear_Expression_with_dimension (&common, prefix + 1);
627       ppl_assign_Linear_Expression_from_Linear_Expression (common,
628                                                            static_schedule);
629
630       value_set_si (v, 1);
631       ppl_assign_Coefficient_from_mpz_t (c, v);
632       ppl_Linear_Expression_add_to_coefficient (common, prefix, c);
633       ppl_assign_Linear_Expression_from_Linear_Expression (static_schedule,
634                                                            common);
635
636       build_pbb_scattering_polyhedrons (common, pbb, nb_scat_dims);
637
638       ppl_delete_Linear_Expression (common);
639     }
640
641   value_clear (v);
642   ppl_delete_Coefficient (c);
643   ppl_delete_Linear_Expression (static_schedule);
644 }
645
646 /* Add the value K to the dimension D of the linear expression EXPR.  */
647
648 static void
649 add_value_to_dim (ppl_dimension_type d, ppl_Linear_Expression_t expr,
650                   Value k)
651 {
652   Value val;
653   ppl_Coefficient_t coef;
654
655   ppl_new_Coefficient (&coef);
656   ppl_Linear_Expression_coefficient (expr, d, coef);
657   value_init (val);
658   ppl_Coefficient_to_mpz_t (coef, val);
659
660   value_addto (val, val, k);
661
662   ppl_assign_Coefficient_from_mpz_t (coef, val);
663   ppl_Linear_Expression_add_to_coefficient (expr, d, coef);
664   value_clear (val);
665   ppl_delete_Coefficient (coef);
666 }
667
668 /* In the context of scop S, scan E, the right hand side of a scalar
669    evolution function in loop VAR, and translate it to a linear
670    expression EXPR.  */
671
672 static void
673 scan_tree_for_params_right_scev (sese s, tree e, int var,
674                                  ppl_Linear_Expression_t expr)
675 {
676   if (expr)
677     {
678       loop_p loop = get_loop (var);
679       ppl_dimension_type l = sese_loop_depth (s, loop) - 1;
680       Value val;
681
682       /* Scalar evolutions should happen in the sese region.  */
683       gcc_assert (sese_loop_depth (s, loop) > 0);
684
685       /* We can not deal with parametric strides like:
686
687       | p = parameter;
688       |
689       | for i:
690       |   a [i * p] = ...   */
691       gcc_assert (TREE_CODE (e) == INTEGER_CST);
692
693       value_init (val);
694       value_set_si (val, int_cst_value (e));
695       add_value_to_dim (l, expr, val);
696       value_clear (val);
697     }
698 }
699
700 /* Scan the integer constant CST, and add it to the inhomogeneous part of the
701    linear expression EXPR.  K is the multiplier of the constant.  */
702
703 static void
704 scan_tree_for_params_int (tree cst, ppl_Linear_Expression_t expr, Value k)
705 {
706   Value val;
707   ppl_Coefficient_t coef;
708   int v = int_cst_value (cst);
709
710   value_init (val);
711   value_set_si (val, 0);
712
713   /* Necessary to not get "-1 = 2^n - 1". */
714   if (v < 0)
715     value_sub_int (val, val, -v);
716   else
717     value_add_int (val, val, v);
718
719   value_multiply (val, val, k);
720   ppl_new_Coefficient (&coef);
721   ppl_assign_Coefficient_from_mpz_t (coef, val);
722   ppl_Linear_Expression_add_to_inhomogeneous (expr, coef);
723   value_clear (val);
724   ppl_delete_Coefficient (coef);
725 }
726
727 /* Saves in NV at index I a new name for variable P.  */
728
729 static void
730 save_var_name (char **nv, int i, tree p)
731 {
732   const char *name = get_name (SSA_NAME_VAR (p));
733
734   if (name)
735     {
736       int len = strlen (name) + 16;
737       nv[i] = XNEWVEC (char, len);
738       snprintf (nv[i], len, "%s_%d", name, SSA_NAME_VERSION (p));
739     }
740   else
741     {
742       nv[i] = XNEWVEC (char, 16);
743       snprintf (nv[i], 2 + 16, "T_%d", SSA_NAME_VERSION (p));
744     }
745 }
746
747 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
748    Otherwise returns -1.  */
749
750 static inline int
751 parameter_index_in_region_1 (tree name, sese region)
752 {
753   int i;
754   tree p;
755
756   gcc_assert (TREE_CODE (name) == SSA_NAME);
757
758   for (i = 0; VEC_iterate (tree, SESE_PARAMS (region), i, p); i++)
759     if (p == name)
760       return i;
761
762   return -1;
763 }
764
765 /* When the parameter NAME is in REGION, returns its index in
766    SESE_PARAMS.  Otherwise this function inserts NAME in SESE_PARAMS
767    and returns the index of NAME.  */
768
769 static int
770 parameter_index_in_region (tree name, sese region)
771 {
772   int i;
773
774   gcc_assert (TREE_CODE (name) == SSA_NAME);
775
776   i = parameter_index_in_region_1 (name, region);
777   if (i != -1)
778     return i;
779
780   gcc_assert (SESE_ADD_PARAMS (region));
781
782   i = VEC_length (tree, SESE_PARAMS (region));
783   save_var_name (SESE_PARAMS_NAMES (region), i, name);
784   save_clast_name_index (SESE_PARAMS_INDEX (region),
785                          SESE_PARAMS_NAMES (region)[i], i);
786   VEC_safe_push (tree, heap, SESE_PARAMS (region), name);
787   return i;
788 }
789
790 /* In the context of sese S, scan the expression E and translate it to
791    a linear expression C.  When parsing a symbolic multiplication, K
792    represents the constant multiplier of an expression containing
793    parameters.  */
794
795 static void
796 scan_tree_for_params (sese s, tree e, ppl_Linear_Expression_t c,
797                       Value k)
798 {
799   if (e == chrec_dont_know)
800     return;
801
802   switch (TREE_CODE (e))
803     {
804     case POLYNOMIAL_CHREC:
805       scan_tree_for_params_right_scev (s, CHREC_RIGHT (e),
806                                        CHREC_VARIABLE (e), c);
807       scan_tree_for_params (s, CHREC_LEFT (e), c, k);
808       break;
809
810     case MULT_EXPR:
811       if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
812         {
813           if (c)
814             {
815               Value val;
816               gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0));
817               value_init (val);
818               value_set_si (val, int_cst_value (TREE_OPERAND (e, 1)));
819               value_multiply (val, val, k);
820               scan_tree_for_params (s, TREE_OPERAND (e, 0), c, val);
821               value_clear (val);
822             }
823           else
824             scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
825         }
826       else
827         {
828           if (c)
829             {
830               Value val;
831               gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0));
832               value_init (val);
833               value_set_si (val, int_cst_value (TREE_OPERAND (e, 0)));
834               value_multiply (val, val, k);
835               scan_tree_for_params (s, TREE_OPERAND (e, 1), c, val);
836               value_clear (val);
837             }
838           else
839             scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k);
840         }
841       break;
842
843     case PLUS_EXPR:
844     case POINTER_PLUS_EXPR:
845       scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
846       scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k);
847       break;
848
849     case MINUS_EXPR:
850       {
851         ppl_Linear_Expression_t tmp_expr = NULL;
852
853         if (c)
854           {
855             ppl_dimension_type dim;
856             ppl_Linear_Expression_space_dimension (c, &dim);
857             ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
858           }
859
860         scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
861         scan_tree_for_params (s, TREE_OPERAND (e, 1), tmp_expr, k);
862
863         if (c)
864           {
865             ppl_subtract_Linear_Expression_from_Linear_Expression (c,
866                                                                    tmp_expr);
867             ppl_delete_Linear_Expression (tmp_expr);
868           }
869
870         break;
871       }
872
873     case NEGATE_EXPR:
874       {
875         ppl_Linear_Expression_t tmp_expr = NULL;
876
877         if (c)
878           {
879             ppl_dimension_type dim;
880             ppl_Linear_Expression_space_dimension (c, &dim);
881             ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
882           }
883
884         scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k);
885
886         if (c)
887           {
888             ppl_subtract_Linear_Expression_from_Linear_Expression (c,
889                                                                    tmp_expr);
890             ppl_delete_Linear_Expression (tmp_expr);
891           }
892
893         break;
894       }
895
896     case BIT_NOT_EXPR:
897       {
898         ppl_Linear_Expression_t tmp_expr = NULL;
899
900         if (c)
901           {
902             ppl_dimension_type dim;
903             ppl_Linear_Expression_space_dimension (c, &dim);
904             ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
905           }
906
907         scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k);
908
909         if (c)
910           {
911             ppl_Coefficient_t coef;
912             Value minus_one;
913
914             ppl_subtract_Linear_Expression_from_Linear_Expression (c,
915                                                                    tmp_expr);
916             ppl_delete_Linear_Expression (tmp_expr);
917             value_init (minus_one);
918             value_set_si (minus_one, -1);
919             ppl_new_Coefficient_from_mpz_t (&coef, minus_one);
920             ppl_Linear_Expression_add_to_inhomogeneous (c, coef);
921             value_clear (minus_one);
922             ppl_delete_Coefficient (coef);
923           }
924
925         break;
926       }
927
928     case SSA_NAME:
929       {
930         ppl_dimension_type p = parameter_index_in_region (e, s);
931
932         if (c)
933           {
934             ppl_dimension_type dim;
935             ppl_Linear_Expression_space_dimension (c, &dim);
936             p += dim - sese_nb_params (s);
937             add_value_to_dim (p, c, k);
938           }
939         break;
940       }
941
942     case INTEGER_CST:
943       if (c)
944         scan_tree_for_params_int (e, c, k);
945       break;
946
947     CASE_CONVERT:
948     case NON_LVALUE_EXPR:
949       scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
950       break;
951
952    default:
953       gcc_unreachable ();
954       break;
955     }
956 }
957
958 /* Find parameters with respect to REGION in BB. We are looking in memory
959    access functions, conditions and loop bounds.  */
960
961 static void
962 find_params_in_bb (sese region, gimple_bb_p gbb)
963 {
964   int i;
965   unsigned j;
966   data_reference_p dr;
967   gimple stmt;
968   loop_p loop = GBB_BB (gbb)->loop_father;
969   Value one;
970
971   value_init (one);
972   value_set_si (one, 1);
973
974   /* Find parameters in the access functions of data references.  */
975   for (i = 0; VEC_iterate (data_reference_p, GBB_DATA_REFS (gbb), i, dr); i++)
976     for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
977       scan_tree_for_params (region, DR_ACCESS_FN (dr, j), NULL, one);
978
979   /* Find parameters in conditional statements.  */
980   for (i = 0; VEC_iterate (gimple, GBB_CONDITIONS (gbb), i, stmt); i++)
981     {
982       tree lhs = scalar_evolution_in_region (region, loop,
983                                              gimple_cond_lhs (stmt));
984       tree rhs = scalar_evolution_in_region (region, loop,
985                                              gimple_cond_rhs (stmt));
986
987       scan_tree_for_params (region, lhs, NULL, one);
988       scan_tree_for_params (region, rhs, NULL, one);
989     }
990
991   value_clear (one);
992 }
993
994 /* Record the parameters used in the SCOP.  A variable is a parameter
995    in a scop if it does not vary during the execution of that scop.  */
996
997 static void
998 find_scop_parameters (scop_p scop)
999 {
1000   poly_bb_p pbb;
1001   unsigned i;
1002   sese region = SCOP_REGION (scop);
1003   struct loop *loop;
1004   Value one;
1005
1006   value_init (one);
1007   value_set_si (one, 1);
1008
1009   /* Find the parameters used in the loop bounds.  */
1010   for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1011     {
1012       tree nb_iters = number_of_latch_executions (loop);
1013
1014       if (!chrec_contains_symbols (nb_iters))
1015         continue;
1016
1017       nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1018       scan_tree_for_params (region, nb_iters, NULL, one);
1019     }
1020
1021   value_clear (one);
1022
1023   /* Find the parameters used in data accesses.  */
1024   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1025     find_params_in_bb (region, PBB_BLACK_BOX (pbb));
1026
1027   scop_set_nb_params (scop, sese_nb_params (region));
1028   SESE_ADD_PARAMS (region) = false;
1029 }
1030
1031 /* Returns a gimple_bb from BB.  */
1032
1033 static inline gimple_bb_p
1034 gbb_from_bb (basic_block bb)
1035 {
1036   return (gimple_bb_p) bb->aux;
1037 }
1038
1039 /* Builds the constraint polyhedra for LOOP in SCOP.  OUTER_PH gives
1040    the constraints for the surrounding loops.  */
1041
1042 static void
1043 build_loop_iteration_domains (scop_p scop, struct loop *loop,
1044                               ppl_Polyhedron_t outer_ph, int nb)
1045
1046 {
1047   int i;
1048   ppl_Polyhedron_t ph;
1049   tree nb_iters = number_of_latch_executions (loop);
1050   ppl_dimension_type dim = nb + 1 + scop_nb_params (scop);
1051   sese region = SCOP_REGION (scop);
1052
1053   {
1054     ppl_const_Constraint_System_t pcs;
1055     ppl_dimension_type *map
1056       = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim);
1057
1058     ppl_new_C_Polyhedron_from_space_dimension (&ph, dim, 0);
1059     ppl_Polyhedron_get_constraints (outer_ph, &pcs);
1060     ppl_Polyhedron_add_constraints (ph, pcs);
1061
1062     for (i = 0; i < (int) nb; i++)
1063       map[i] = i;
1064     for (i = (int) nb; i < (int) dim - 1; i++)
1065       map[i] = i + 1;
1066     map[dim - 1] = nb;
1067
1068     ppl_Polyhedron_map_space_dimensions (ph, map, dim);
1069     free (map);
1070   }
1071
1072   /* 0 <= loop_i */
1073   {
1074     ppl_Constraint_t lb;
1075     ppl_Linear_Expression_t lb_expr;
1076
1077     ppl_new_Linear_Expression_with_dimension (&lb_expr, dim);
1078     ppl_set_coef (lb_expr, nb, 1);
1079     ppl_new_Constraint (&lb, lb_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1080     ppl_delete_Linear_Expression (lb_expr);
1081     ppl_Polyhedron_add_constraint (ph, lb);
1082     ppl_delete_Constraint (lb);
1083   }
1084
1085   if (TREE_CODE (nb_iters) == INTEGER_CST)
1086     {
1087       ppl_Constraint_t ub;
1088       ppl_Linear_Expression_t ub_expr;
1089
1090       ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1091
1092       /* loop_i <= cst_nb_iters */
1093       ppl_set_coef (ub_expr, nb, -1);
1094       ppl_set_inhomogeneous_tree (ub_expr, nb_iters);
1095       ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1096       ppl_Polyhedron_add_constraint (ph, ub);
1097       ppl_delete_Linear_Expression (ub_expr);
1098       ppl_delete_Constraint (ub);
1099     }
1100   else if (!chrec_contains_undetermined (nb_iters))
1101     {
1102       Value one;
1103       ppl_Constraint_t ub;
1104       ppl_Linear_Expression_t ub_expr;
1105
1106       value_init (one);
1107       value_set_si (one, 1);
1108       ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1109       nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1110       scan_tree_for_params (SCOP_REGION (scop), nb_iters, ub_expr, one);
1111       value_clear (one);
1112
1113       /* loop_i <= expr_nb_iters */
1114       ppl_set_coef (ub_expr, nb, -1);
1115       ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1116       ppl_Polyhedron_add_constraint (ph, ub);
1117       ppl_delete_Linear_Expression (ub_expr);
1118       ppl_delete_Constraint (ub);
1119     }
1120   else
1121     gcc_unreachable ();
1122
1123   if (loop->inner && loop_in_sese_p (loop->inner, region))
1124     build_loop_iteration_domains (scop, loop->inner, ph, nb + 1);
1125
1126   if (nb != 0
1127       && loop->next
1128       && loop_in_sese_p (loop->next, region))
1129     build_loop_iteration_domains (scop, loop->next, outer_ph, nb);
1130
1131   ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1132     ((ppl_Pointset_Powerset_C_Polyhedron_t *) &loop->aux, ph);
1133
1134   ppl_delete_Polyhedron (ph);
1135 }
1136
1137 /* Returns a linear expression for tree T evaluated in PBB.  */
1138
1139 static ppl_Linear_Expression_t
1140 create_linear_expr_from_tree (poly_bb_p pbb, tree t)
1141 {
1142   Value one;
1143   ppl_Linear_Expression_t res;
1144   ppl_dimension_type dim;
1145   sese region = SCOP_REGION (PBB_SCOP (pbb));
1146   loop_p loop = GBB_BB (PBB_BLACK_BOX (pbb))->loop_father;
1147
1148   dim = pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb);
1149   ppl_new_Linear_Expression_with_dimension (&res, dim);
1150
1151   t = scalar_evolution_in_region (region, loop, t);
1152   gcc_assert (!automatically_generated_chrec_p (t));
1153
1154   value_init (one);
1155   value_set_si (one, 1);
1156   scan_tree_for_params (region, t, res, one);
1157   value_clear (one);
1158
1159   return res;
1160 }
1161
1162 /* Returns the ppl constraint type from the gimple tree code CODE.  */
1163
1164 static enum ppl_enum_Constraint_Type
1165 ppl_constraint_type_from_tree_code (enum tree_code code)
1166 {
1167   switch (code)
1168     {
1169     /* We do not support LT and GT to be able to work with C_Polyhedron.
1170        As we work on integer polyhedron "a < b" can be expressed by
1171        "a + 1 <= b".  */
1172     case LT_EXPR:
1173     case GT_EXPR:
1174       gcc_unreachable ();
1175
1176     case LE_EXPR:
1177       return PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL;
1178
1179     case GE_EXPR:
1180       return PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL;
1181
1182     case EQ_EXPR:
1183       return PPL_CONSTRAINT_TYPE_EQUAL;
1184
1185     default:
1186       gcc_unreachable ();
1187     }
1188 }
1189
1190 /* Add conditional statement STMT to PS.  It is evaluated in PBB and
1191    CODE is used as the comparison operator.  This allows us to invert the
1192    condition or to handle inequalities.  */
1193
1194 static void
1195 add_condition_to_domain (ppl_Pointset_Powerset_C_Polyhedron_t ps, gimple stmt,
1196                          poly_bb_p pbb, enum tree_code code)
1197 {
1198   Value v;
1199   ppl_Coefficient_t c;
1200   ppl_Linear_Expression_t left, right;
1201   ppl_Constraint_t cstr;
1202   enum ppl_enum_Constraint_Type type;
1203
1204   left = create_linear_expr_from_tree (pbb, gimple_cond_lhs (stmt));
1205   right = create_linear_expr_from_tree (pbb, gimple_cond_rhs (stmt));
1206
1207   /* If we have < or > expressions convert them to <= or >= by adding 1 to
1208      the left or the right side of the expression. */
1209   if (code == LT_EXPR)
1210     {
1211       value_init (v);
1212       value_set_si (v, 1);
1213       ppl_new_Coefficient (&c);
1214       ppl_assign_Coefficient_from_mpz_t (c, v);
1215       ppl_Linear_Expression_add_to_inhomogeneous (left, c);
1216       ppl_delete_Coefficient (c);
1217       value_clear (v);
1218
1219       code = LE_EXPR;
1220     }
1221   else if (code == GT_EXPR)
1222     {
1223       value_init (v);
1224       value_set_si (v, 1);
1225       ppl_new_Coefficient (&c);
1226       ppl_assign_Coefficient_from_mpz_t (c, v);
1227       ppl_Linear_Expression_add_to_inhomogeneous (right, c);
1228       ppl_delete_Coefficient (c);
1229       value_clear (v);
1230
1231       code = GE_EXPR;
1232     }
1233
1234   type = ppl_constraint_type_from_tree_code (code);
1235
1236   ppl_subtract_Linear_Expression_from_Linear_Expression (left, right);
1237
1238   ppl_new_Constraint (&cstr, left, type);
1239   ppl_Pointset_Powerset_C_Polyhedron_add_constraint (ps, cstr);
1240
1241   ppl_delete_Constraint (cstr);
1242   ppl_delete_Linear_Expression (left);
1243   ppl_delete_Linear_Expression (right);
1244 }
1245
1246 /* Add conditional statement STMT to pbb.  CODE is used as the comparision
1247    operator.  This allows us to invert the condition or to handle
1248    inequalities.  */
1249
1250 static void
1251 add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code)
1252 {
1253   if (code == NE_EXPR)
1254     {
1255       ppl_Pointset_Powerset_C_Polyhedron_t left = PBB_DOMAIN (pbb);
1256       ppl_Pointset_Powerset_C_Polyhedron_t right;
1257       ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1258         (&right, left);
1259       add_condition_to_domain (left, stmt, pbb, LT_EXPR);
1260       add_condition_to_domain (right, stmt, pbb, GT_EXPR);
1261       ppl_Pointset_Powerset_C_Polyhedron_upper_bound_assign (left,
1262                                                                right);
1263       ppl_delete_Pointset_Powerset_C_Polyhedron (right);
1264     }
1265   else
1266     add_condition_to_domain (PBB_DOMAIN (pbb), stmt, pbb, code);
1267 }
1268
1269 /* Add conditions to the domain of PBB.  */
1270
1271 static void
1272 add_conditions_to_domain (poly_bb_p pbb)
1273 {
1274   unsigned int i;
1275   gimple stmt;
1276   gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1277   VEC (gimple, heap) *conditions = GBB_CONDITIONS (gbb);
1278
1279   if (VEC_empty (gimple, conditions))
1280     return;
1281
1282   for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
1283     switch (gimple_code (stmt))
1284       {
1285       case GIMPLE_COND:
1286           {
1287             enum tree_code code = gimple_cond_code (stmt);
1288
1289             /* The conditions for ELSE-branches are inverted.  */
1290             if (VEC_index (gimple, gbb->condition_cases, i) == NULL)
1291               code = invert_tree_comparison (code, false);
1292
1293             add_condition_to_pbb (pbb, stmt, code);
1294             break;
1295           }
1296
1297       case GIMPLE_SWITCH:
1298         /* Switch statements are not supported right now - fall throught.  */
1299
1300       default:
1301         gcc_unreachable ();
1302         break;
1303       }
1304 }
1305
1306 /* Structure used to pass data to dom_walk.  */
1307
1308 struct bsc
1309 {
1310   VEC (gimple, heap) **conditions, **cases;
1311   sese region;
1312 };
1313
1314 /* Returns non NULL when BB has a single predecessor and the last
1315    statement of that predecessor is a COND_EXPR.  */
1316
1317 static gimple
1318 single_pred_cond (basic_block bb)
1319 {
1320   if (single_pred_p (bb))
1321     {
1322       edge e = single_pred_edge (bb);
1323       basic_block pred = e->src;
1324       gimple stmt = last_stmt (pred);
1325
1326       if (stmt && gimple_code (stmt) == GIMPLE_COND)
1327         return stmt;
1328     }
1329   return NULL;
1330 }
1331
1332 /* Call-back for dom_walk executed before visiting the dominated
1333    blocks.  */
1334
1335 static void
1336 build_sese_conditions_before (struct dom_walk_data *dw_data,
1337                               basic_block bb)
1338 {
1339   struct bsc *data = (struct bsc *) dw_data->global_data;
1340   VEC (gimple, heap) **conditions = data->conditions;
1341   VEC (gimple, heap) **cases = data->cases;
1342   gimple_bb_p gbb = gbb_from_bb (bb);
1343   gimple stmt = single_pred_cond (bb);
1344
1345   if (!bb_in_sese_p (bb, data->region))
1346     return;
1347
1348   if (stmt)
1349     {
1350       edge e = single_pred_edge (bb);
1351
1352       VEC_safe_push (gimple, heap, *conditions, stmt);
1353
1354       if (e->flags & EDGE_TRUE_VALUE)
1355         VEC_safe_push (gimple, heap, *cases, stmt);
1356       else
1357         VEC_safe_push (gimple, heap, *cases, NULL);
1358     }
1359
1360   if (gbb)
1361     {
1362       GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
1363       GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
1364     }
1365 }
1366
1367 /* Call-back for dom_walk executed after visiting the dominated
1368    blocks.  */
1369
1370 static void
1371 build_sese_conditions_after (struct dom_walk_data *dw_data,
1372                              basic_block bb)
1373 {
1374   struct bsc *data = (struct bsc *) dw_data->global_data;
1375   VEC (gimple, heap) **conditions = data->conditions;
1376   VEC (gimple, heap) **cases = data->cases;
1377
1378   if (!bb_in_sese_p (bb, data->region))
1379     return;
1380
1381   if (single_pred_cond (bb))
1382     {
1383       VEC_pop (gimple, *conditions);
1384       VEC_pop (gimple, *cases);
1385     }
1386 }
1387
1388 /* Record all conditions in REGION.  */
1389
1390 static void
1391 build_sese_conditions (sese region)
1392 {
1393   struct dom_walk_data walk_data;
1394   VEC (gimple, heap) *conditions = VEC_alloc (gimple, heap, 3);
1395   VEC (gimple, heap) *cases = VEC_alloc (gimple, heap, 3);
1396   struct bsc data;
1397
1398   data.conditions = &conditions;
1399   data.cases = &cases;
1400   data.region = region;
1401
1402   walk_data.dom_direction = CDI_DOMINATORS;
1403   walk_data.initialize_block_local_data = NULL;
1404   walk_data.before_dom_children = build_sese_conditions_before;
1405   walk_data.after_dom_children = build_sese_conditions_after;
1406   walk_data.global_data = &data;
1407   walk_data.block_local_data_size = 0;
1408
1409   init_walk_dominator_tree (&walk_data);
1410   walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region));
1411   fini_walk_dominator_tree (&walk_data);
1412
1413   VEC_free (gimple, heap, conditions);
1414   VEC_free (gimple, heap, cases);
1415 }
1416
1417 /* Traverses all the GBBs of the SCOP and add their constraints to the
1418    iteration domains.  */
1419
1420 static void
1421 add_conditions_to_constraints (scop_p scop)
1422 {
1423   int i;
1424   poly_bb_p pbb;
1425
1426   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1427     add_conditions_to_domain (pbb);
1428 }
1429
1430 /* Add constraints on the possible values of parameter P from the type
1431    of P.  */
1432
1433 static void
1434 add_param_constraints (scop_p scop, ppl_Polyhedron_t context, graphite_dim_t p)
1435 {
1436   ppl_Constraint_t cstr;
1437   ppl_Linear_Expression_t le;
1438   tree parameter = VEC_index (tree, SESE_PARAMS (SCOP_REGION (scop)), p);
1439   tree type = TREE_TYPE (parameter);
1440   tree lb, ub;
1441
1442   /* Disabled until we fix CPU2006.  */
1443   return;
1444
1445   if (!INTEGRAL_TYPE_P (type))
1446     return;
1447
1448   lb = TYPE_MIN_VALUE (type);
1449   ub = TYPE_MAX_VALUE (type);
1450
1451   if (lb)
1452     {
1453       ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1454       ppl_set_coef (le, p, -1);
1455       ppl_set_inhomogeneous_tree (le, lb);
1456       ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL);
1457       ppl_Polyhedron_add_constraint (context, cstr);
1458       ppl_delete_Linear_Expression (le);
1459       ppl_delete_Constraint (cstr);
1460     }
1461
1462   if (ub)
1463     {
1464       ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1465       ppl_set_coef (le, p, -1);
1466       ppl_set_inhomogeneous_tree (le, ub);
1467       ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1468       ppl_Polyhedron_add_constraint (context, cstr);
1469       ppl_delete_Linear_Expression (le);
1470       ppl_delete_Constraint (cstr);
1471     }
1472 }
1473
1474 /* Build the context of the SCOP.  The context usually contains extra
1475    constraints that are added to the iteration domains that constrain
1476    some parameters.  */
1477
1478 static void
1479 build_scop_context (scop_p scop)
1480 {
1481   ppl_Polyhedron_t context;
1482   graphite_dim_t p, n = scop_nb_params (scop);
1483
1484   ppl_new_C_Polyhedron_from_space_dimension (&context, n, 0);
1485
1486   for (p = 0; p < n; p++)
1487     add_param_constraints (scop, context, p);
1488
1489   ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1490     (&SCOP_CONTEXT (scop), context);
1491
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
1508   ppl_new_C_Polyhedron_from_space_dimension (&ph, scop_nb_params (scop), 0);
1509
1510   for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1511     if (!loop_in_sese_p (loop_outer (loop), region))
1512       build_loop_iteration_domains (scop, loop, ph, 0);
1513
1514   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1515     if (gbb_loop (PBB_BLACK_BOX (pbb))->aux)
1516       ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1517         (&PBB_DOMAIN (pbb), (ppl_const_Pointset_Powerset_C_Polyhedron_t)
1518          gbb_loop (PBB_BLACK_BOX (pbb))->aux);
1519     else
1520       ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1521         (&PBB_DOMAIN (pbb), ph);
1522
1523   for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1524     if (loop->aux)
1525       {
1526         ppl_delete_Pointset_Powerset_C_Polyhedron
1527           ((ppl_Pointset_Powerset_C_Polyhedron_t) loop->aux);
1528         loop->aux = NULL;
1529       }
1530
1531   ppl_delete_Polyhedron (ph);
1532 }
1533
1534 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1535    data reference DR.  ACCESSP_NB_DIMS is the dimension of the
1536    ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1537    domain.  */
1538
1539 static void
1540 pdr_add_alias_set (ppl_Polyhedron_t accesses, data_reference_p dr,
1541                    ppl_dimension_type accessp_nb_dims,
1542                    ppl_dimension_type dom_nb_dims)
1543 {
1544   ppl_Linear_Expression_t alias;
1545   ppl_Constraint_t cstr;
1546   int alias_set_num = 0;
1547
1548   if (dr->aux != NULL)
1549     {
1550       alias_set_num = *((int *)(dr->aux));
1551       free (dr->aux);
1552       dr->aux = NULL;
1553     }
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   Value v;
1579   scop_p scop = PBB_SCOP (pbb);
1580   sese region = SCOP_REGION (scop);
1581
1582   value_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       value_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   value_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           ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1639           ppl_set_coef (expr, subscript, 1);
1640
1641           ppl_set_inhomogeneous (expr, -int_cst_value (low));
1642
1643           ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1644           ppl_Polyhedron_add_constraint (accesses, cstr);
1645           ppl_delete_Linear_Expression (expr);
1646           ppl_delete_Constraint (cstr);
1647         }
1648
1649       high = array_ref_up_bound (ref);
1650
1651       /* high - subscript >= 0
1652          XXX: 1-element arrays at end of structures may extend over their
1653          declared size.  */
1654       if (high && host_integerp (high, 0))
1655         {
1656           ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1657           ppl_set_coef (expr, subscript, -1);
1658
1659           ppl_set_inhomogeneous (expr, int_cst_value (high));
1660
1661           ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1662           ppl_Polyhedron_add_constraint (accesses, cstr);
1663           ppl_delete_Linear_Expression (expr);
1664           ppl_delete_Constraint (cstr);
1665         }
1666     }
1667 }
1668
1669 /* Build data accesses for DR in PBB.  */
1670
1671 static void
1672 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1673 {
1674   ppl_Polyhedron_t accesses;
1675   ppl_Pointset_Powerset_C_Polyhedron_t accesses_ps;
1676   ppl_dimension_type dom_nb_dims;
1677   ppl_dimension_type accessp_nb_dims;
1678
1679   ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PBB_DOMAIN (pbb),
1680                                                       &dom_nb_dims);
1681   accessp_nb_dims = dom_nb_dims + 1 + DR_NUM_DIMENSIONS (dr);
1682
1683   ppl_new_C_Polyhedron_from_space_dimension (&accesses, accessp_nb_dims, 0);
1684
1685   pdr_add_alias_set (accesses, dr, accessp_nb_dims, dom_nb_dims);
1686   pdr_add_memory_accesses (accesses, dr, accessp_nb_dims, dom_nb_dims, pbb);
1687   pdr_add_data_dimensions (accesses, dr, accessp_nb_dims, dom_nb_dims);
1688
1689   ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&accesses_ps,
1690                                                             accesses);
1691   ppl_delete_Polyhedron (accesses);
1692   new_poly_dr (pbb, accesses_ps, DR_IS_READ (dr) ? PDR_READ : PDR_WRITE, dr,
1693                DR_NUM_DIMENSIONS (dr));
1694 }
1695
1696 /* Group each data reference in DRS with it's alias set num.  */
1697
1698 static void
1699 build_alias_set_for_drs (VEC (data_reference_p, heap) **drs)
1700 {
1701   int num_vertex = VEC_length (data_reference_p, *drs);
1702   struct graph *g = new_graph (num_vertex);
1703   data_reference_p dr1, dr2;
1704   int i, j;
1705   int num_component;
1706   int *queue;
1707
1708   for (i = 0; VEC_iterate (data_reference_p, *drs, i, dr1); i++)
1709     for (j = i+1; VEC_iterate (data_reference_p, *drs, j, dr2); j++)
1710       if (dr_may_alias_p (dr1, dr2))
1711         {
1712           add_edge (g, i, j);
1713           add_edge (g, j, i);
1714         }
1715
1716   queue = XNEWVEC (int, num_vertex);
1717   for (i = 0; i < num_vertex; i++)
1718     queue[i] = i;
1719
1720   num_component = graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1721
1722   for (i = 0; i < g->n_vertices; i++)
1723     {
1724       data_reference_p dr = VEC_index (data_reference_p, *drs, i);
1725       dr->aux = XNEW (int);
1726       *((int *)(dr->aux)) = g->vertices[i].component + 1;
1727     }
1728
1729   free (queue);
1730   free_graph (g);
1731 }
1732
1733 /* Build the data references for PBB.  */
1734
1735 static void
1736 build_pbb_drs (poly_bb_p pbb)
1737 {
1738   int j;
1739   data_reference_p dr;
1740   VEC (data_reference_p, heap) *gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1741
1742   for (j = 0; VEC_iterate (data_reference_p, gbb_drs, j, dr); j++)
1743     build_poly_dr (dr, pbb);
1744 }
1745
1746 /* Build data references in SCOP.  */
1747
1748 static void
1749 build_scop_drs (scop_p scop)
1750 {
1751   int i, j;
1752   poly_bb_p pbb;
1753   data_reference_p dr;
1754   VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
1755
1756   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1757     {
1758       VEC (data_reference_p, heap) *gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1759       for (j = 0; VEC_iterate (data_reference_p, gbb_drs, j, dr); j++)
1760        VEC_safe_push (data_reference_p, heap, drs, dr);
1761     }
1762
1763   build_alias_set_for_drs (&drs);
1764   VEC_free (data_reference_p, heap, drs);
1765
1766   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1767     build_pbb_drs (pbb);
1768 }
1769
1770 /* Return a gsi at the position of the VAR definition.  */
1771
1772 static gimple_stmt_iterator
1773 gsi_for_ssa_name_def (tree var)
1774 {
1775   gimple stmt;
1776   basic_block bb;
1777   gimple_stmt_iterator gsi;
1778   gimple_stmt_iterator psi;
1779
1780   gcc_assert (TREE_CODE (var) == SSA_NAME);
1781
1782   stmt = SSA_NAME_DEF_STMT (var);
1783   bb = gimple_bb (stmt);
1784
1785   for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1786     if (stmt == gsi_stmt (psi))
1787       return gsi_after_labels (bb);
1788
1789   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1790     if (stmt == gsi_stmt (gsi))
1791       {
1792         gsi_next (&gsi);
1793         return gsi;
1794       }
1795
1796   gcc_unreachable ();
1797   return gsi;
1798 }
1799
1800 /* Insert the assignment "RES := VAR" just after the definition of VAR.  */
1801
1802 static void
1803 insert_out_of_ssa_copy (tree res, tree var)
1804 {
1805   gimple_stmt_iterator gsi = gsi_for_ssa_name_def (var);
1806   gimple stmt;
1807   gimple_seq stmts;
1808   gimple_stmt_iterator si;
1809
1810   var = force_gimple_operand (var, &stmts, true, NULL_TREE);
1811   stmt = gimple_build_assign (res, var);
1812   if (!stmts)
1813     stmts = gimple_seq_alloc ();
1814   si = gsi_last (stmts);
1815   gsi_insert_after (&si, stmt, GSI_NEW_STMT);
1816   gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
1817 }
1818
1819 /* Insert on edge E the assignment "RES := EXPR".  */
1820
1821 static void
1822 insert_out_of_ssa_copy_on_edge (edge e, tree res, tree expr)
1823 {
1824   gimple_stmt_iterator gsi;
1825   gimple_seq stmts;
1826   tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
1827   gimple stmt = gimple_build_assign (res, var);
1828
1829   if (!stmts)
1830     stmts = gimple_seq_alloc ();
1831
1832   gsi = gsi_last (stmts);
1833   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
1834   gsi_insert_seq_on_edge (e, stmts);
1835   gsi_commit_edge_inserts ();
1836 }
1837
1838 /* Creates a zero dimension array of the same type as VAR.  */
1839
1840 static tree
1841 create_zero_dim_array (tree var)
1842 {
1843   tree index_type = build_index_type (integer_zero_node);
1844   tree elt_type = TREE_TYPE (var);
1845   tree array_type = build_array_type (elt_type, index_type);
1846   tree base = create_tmp_var (array_type, "Red");
1847
1848   add_referenced_var (base);
1849
1850   return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
1851                  NULL_TREE);
1852 }
1853
1854 /* Returns true when PHI is a loop close phi node.  */
1855
1856 static bool
1857 scalar_close_phi_node_p (gimple phi)
1858 {
1859   gcc_assert (gimple_code (phi) == GIMPLE_PHI);
1860
1861   if (!is_gimple_reg (gimple_phi_result (phi)))
1862     return false;
1863
1864   return (gimple_phi_num_args (phi) == 1);
1865 }
1866
1867 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
1868    dimension array for it.  */
1869
1870 static void
1871 rewrite_close_phi_out_of_ssa (gimple_stmt_iterator *psi)
1872 {
1873   gimple phi = gsi_stmt (*psi);
1874   tree res = gimple_phi_result (phi);
1875   tree var = SSA_NAME_VAR (res);
1876   tree zero_dim_array = create_zero_dim_array (var);
1877   gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (phi));
1878   gimple stmt = gimple_build_assign (res, zero_dim_array);
1879   tree arg = gimple_phi_arg_def (phi, 0);
1880
1881   insert_out_of_ssa_copy (zero_dim_array, arg);
1882
1883   remove_phi_node (psi, false);
1884   gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
1885   SSA_NAME_DEF_STMT (res) = stmt;
1886 }
1887
1888 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
1889    dimension array for it.  */
1890
1891 static void
1892 rewrite_phi_out_of_ssa (gimple_stmt_iterator *psi)
1893 {
1894   size_t i;
1895   gimple phi = gsi_stmt (*psi);
1896   basic_block bb = gimple_bb (phi);
1897   tree res = gimple_phi_result (phi);
1898   tree var = SSA_NAME_VAR (res);
1899   tree zero_dim_array = create_zero_dim_array (var);
1900   gimple_stmt_iterator gsi;
1901   gimple stmt;
1902   gimple_seq stmts;
1903
1904   for (i = 0; i < gimple_phi_num_args (phi); i++)
1905     {
1906       tree arg = gimple_phi_arg_def (phi, i);
1907
1908       /* Try to avoid the insertion on edges as much as possible: this
1909          would avoid the insertion of code on loop latch edges, making
1910          the pattern matching of the vectorizer happy, or it would
1911          avoid the insertion of useless basic blocks.  Note that it is
1912          incorrect to insert out of SSA copies close by their
1913          definition when they are more than two loop levels apart:
1914          for example, starting from a double nested loop
1915
1916          | a = ...
1917          | loop_1
1918          |  loop_2
1919          |    b = phi (a, c)
1920          |    c = ...
1921          |  end_2
1922          | end_1
1923
1924          the following transform is incorrect
1925
1926          | a = ...
1927          | Red[0] = a
1928          | loop_1
1929          |  loop_2
1930          |    b = Red[0]
1931          |    c = ...
1932          |    Red[0] = c
1933          |  end_2
1934          | end_1
1935
1936          whereas inserting the copy on the incomming edge is correct
1937
1938          | a = ...
1939          | loop_1
1940          |  Red[0] = a
1941          |  loop_2
1942          |    b = Red[0]
1943          |    c = ...
1944          |    Red[0] = c
1945          |  end_2
1946          | end_1
1947       */
1948       if (TREE_CODE (arg) == SSA_NAME
1949           && is_gimple_reg (arg)
1950           && gimple_bb (SSA_NAME_DEF_STMT (arg))
1951           && (flow_bb_inside_loop_p (bb->loop_father,
1952                                      gimple_bb (SSA_NAME_DEF_STMT (arg)))
1953               || flow_bb_inside_loop_p (loop_outer (bb->loop_father),
1954                                         gimple_bb (SSA_NAME_DEF_STMT (arg)))))
1955         insert_out_of_ssa_copy (zero_dim_array, arg);
1956       else
1957         insert_out_of_ssa_copy_on_edge (gimple_phi_arg_edge (phi, i),
1958                                         zero_dim_array, arg);
1959     }
1960
1961   var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
1962
1963   if (!stmts)
1964     stmts = gimple_seq_alloc ();
1965
1966   stmt = gimple_build_assign (res, var);
1967   remove_phi_node (psi, false);
1968   SSA_NAME_DEF_STMT (res) = stmt;
1969
1970   gsi = gsi_last (stmts);
1971   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
1972
1973   gsi = gsi_after_labels (bb);
1974   gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
1975 }
1976
1977 /* Rewrite out of SSA all the reduction phi nodes of SCOP.  */
1978
1979 static void
1980 rewrite_reductions_out_of_ssa (scop_p scop)
1981 {
1982   basic_block bb;
1983   gimple_stmt_iterator psi;
1984   sese region = SCOP_REGION (scop);
1985
1986   FOR_EACH_BB (bb)
1987     if (bb_in_region (bb, SESE_ENTRY_BB (region), SESE_EXIT_BB (region)))
1988       for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
1989         {
1990           if (scalar_close_phi_node_p (gsi_stmt (psi)))
1991             rewrite_close_phi_out_of_ssa (&psi);
1992           else if (reduction_phi_p (region, &psi))
1993             rewrite_phi_out_of_ssa (&psi);
1994         }
1995
1996   update_ssa (TODO_update_ssa);
1997 #ifdef ENABLE_CHECKING
1998   verify_ssa (false);
1999   verify_loop_closed_ssa ();
2000 #endif
2001 }
2002
2003 /* Returns the number of pbbs that are in loops contained in SCOP.  */
2004
2005 static int
2006 nb_pbbs_in_loops (scop_p scop)
2007 {
2008   int i;
2009   poly_bb_p pbb;
2010   int res = 0;
2011
2012   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
2013     if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2014       res++;
2015
2016   return res;
2017 }
2018
2019 /* Builds the polyhedral representation for a SESE region.  */
2020
2021 bool
2022 build_poly_scop (scop_p scop)
2023 {
2024   sese region = SCOP_REGION (scop);
2025   rewrite_reductions_out_of_ssa (scop);
2026   build_scop_bbs (scop);
2027
2028   /* FIXME: This restriction is needed to avoid a problem in CLooG.
2029      Once CLooG is fixed, remove this guard.  Anyways, it makes no
2030      sense to optimize a scop containing only PBBs that do not belong
2031      to any loops.  */
2032   if (nb_pbbs_in_loops (scop) == 0)
2033     return false;
2034
2035   build_sese_loop_nests (region);
2036   build_sese_conditions (region);
2037   find_scop_parameters (scop);
2038
2039   build_scop_iteration_domain (scop);
2040   build_scop_context (scop);
2041
2042   add_conditions_to_constraints (scop);
2043   build_scop_scattering (scop);
2044   build_scop_drs (scop);
2045
2046   return true;
2047 }
2048
2049 /* Always return false.  Exercise the scop_to_clast function.  */
2050
2051 void
2052 check_poly_representation (scop_p scop ATTRIBUTE_UNUSED)
2053 {
2054 #ifdef ENABLE_CHECKING
2055   cloog_prog_clast pc = scop_to_clast (scop);
2056   cloog_clast_free (pc.stmt);
2057   cloog_program_free (pc.prog);
2058 #endif
2059 }
2060 #endif