OSDN Git Service

PR debug/41888
[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 /* Data structure for idx_record_params.  */
959
960 struct irp_data
961 {
962   struct loop *loop;
963   sese region;
964 };
965
966 /* For a data reference with an ARRAY_REF as its BASE, record the
967    parameters occurring in IDX.  DTA is passed in as complementary
968    information, and is used by the automatic walker function.  This
969    function is a callback for for_each_index.  */
970
971 static bool
972 idx_record_params (tree base, tree *idx, void *dta)
973 {
974   struct irp_data *data = (struct irp_data *) dta;
975
976   if (TREE_CODE (base) != ARRAY_REF)
977     return true;
978
979   if (TREE_CODE (*idx) == SSA_NAME)
980     {
981       tree scev;
982       sese region = data->region;
983       struct loop *loop = data->loop;
984       Value one;
985
986       scev = scalar_evolution_in_region (region, loop, *idx);
987
988       value_init (one);
989       value_set_si (one, 1);
990       scan_tree_for_params (region, scev, NULL, one);
991       value_clear (one);
992     }
993
994   return true;
995 }
996
997 /* Find parameters with respect to REGION in BB. We are looking in memory
998    access functions, conditions and loop bounds.  */
999
1000 static void
1001 find_params_in_bb (sese region, gimple_bb_p gbb)
1002 {
1003   int i;
1004   data_reference_p dr;
1005   gimple stmt;
1006   loop_p loop = GBB_BB (gbb)->loop_father;
1007
1008   for (i = 0; VEC_iterate (data_reference_p, GBB_DATA_REFS (gbb), i, dr); i++)
1009     {
1010       struct irp_data irp;
1011
1012       irp.loop = loop;
1013       irp.region = region;
1014       for_each_index (&dr->ref, idx_record_params, &irp);
1015     }
1016
1017   /* Find parameters in conditional statements.  */
1018   for (i = 0; VEC_iterate (gimple, GBB_CONDITIONS (gbb), i, stmt); i++)
1019     {
1020       Value one;
1021       tree lhs = scalar_evolution_in_region (region, loop,
1022                                              gimple_cond_lhs (stmt));
1023       tree rhs = scalar_evolution_in_region (region, loop,
1024                                              gimple_cond_rhs (stmt));
1025
1026       value_init (one);
1027       value_set_si (one, 1);
1028       scan_tree_for_params (region, lhs, NULL, one);
1029       scan_tree_for_params (region, rhs, NULL, one);
1030       value_clear (one);
1031     }
1032 }
1033
1034 /* Record the parameters used in the SCOP.  A variable is a parameter
1035    in a scop if it does not vary during the execution of that scop.  */
1036
1037 static void
1038 find_scop_parameters (scop_p scop)
1039 {
1040   poly_bb_p pbb;
1041   unsigned i;
1042   sese region = SCOP_REGION (scop);
1043   struct loop *loop;
1044   Value one;
1045
1046   value_init (one);
1047   value_set_si (one, 1);
1048
1049   /* Find the parameters used in the loop bounds.  */
1050   for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1051     {
1052       tree nb_iters = number_of_latch_executions (loop);
1053
1054       if (!chrec_contains_symbols (nb_iters))
1055         continue;
1056
1057       nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1058       scan_tree_for_params (region, nb_iters, NULL, one);
1059     }
1060
1061   value_clear (one);
1062
1063   /* Find the parameters used in data accesses.  */
1064   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1065     find_params_in_bb (region, PBB_BLACK_BOX (pbb));
1066
1067   scop_set_nb_params (scop, sese_nb_params (region));
1068   SESE_ADD_PARAMS (region) = false;
1069 }
1070
1071 /* Returns a gimple_bb from BB.  */
1072
1073 static inline gimple_bb_p
1074 gbb_from_bb (basic_block bb)
1075 {
1076   return (gimple_bb_p) bb->aux;
1077 }
1078
1079 /* Builds the constraint polyhedra for LOOP in SCOP.  OUTER_PH gives
1080    the constraints for the surrounding loops.  */
1081
1082 static void
1083 build_loop_iteration_domains (scop_p scop, struct loop *loop,
1084                               ppl_Polyhedron_t outer_ph, int nb)
1085
1086 {
1087   int i;
1088   ppl_Polyhedron_t ph;
1089   tree nb_iters = number_of_latch_executions (loop);
1090   ppl_dimension_type dim = nb + 1 + scop_nb_params (scop);
1091   sese region = SCOP_REGION (scop);
1092
1093   {
1094     ppl_const_Constraint_System_t pcs;
1095     ppl_dimension_type *map
1096       = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim);
1097
1098     ppl_new_C_Polyhedron_from_space_dimension (&ph, dim, 0);
1099     ppl_Polyhedron_get_constraints (outer_ph, &pcs);
1100     ppl_Polyhedron_add_constraints (ph, pcs);
1101
1102     for (i = 0; i < (int) nb; i++)
1103       map[i] = i;
1104     for (i = (int) nb; i < (int) dim - 1; i++)
1105       map[i] = i + 1;
1106     map[dim - 1] = nb;
1107
1108     ppl_Polyhedron_map_space_dimensions (ph, map, dim);
1109     free (map);
1110   }
1111
1112   /* 0 <= loop_i */
1113   {
1114     ppl_Constraint_t lb;
1115     ppl_Linear_Expression_t lb_expr;
1116
1117     ppl_new_Linear_Expression_with_dimension (&lb_expr, dim);
1118     ppl_set_coef (lb_expr, nb, 1);
1119     ppl_new_Constraint (&lb, lb_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1120     ppl_delete_Linear_Expression (lb_expr);
1121     ppl_Polyhedron_add_constraint (ph, lb);
1122     ppl_delete_Constraint (lb);
1123   }
1124
1125   if (TREE_CODE (nb_iters) == INTEGER_CST)
1126     {
1127       ppl_Constraint_t ub;
1128       ppl_Linear_Expression_t ub_expr;
1129
1130       ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1131
1132       /* loop_i <= cst_nb_iters */
1133       ppl_set_coef (ub_expr, nb, -1);
1134       ppl_set_inhomogeneous_tree (ub_expr, nb_iters);
1135       ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1136       ppl_Polyhedron_add_constraint (ph, ub);
1137       ppl_delete_Linear_Expression (ub_expr);
1138       ppl_delete_Constraint (ub);
1139     }
1140   else if (!chrec_contains_undetermined (nb_iters))
1141     {
1142       Value one;
1143       ppl_Constraint_t ub;
1144       ppl_Linear_Expression_t ub_expr;
1145
1146       value_init (one);
1147       value_set_si (one, 1);
1148       ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1149       nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1150       scan_tree_for_params (SCOP_REGION (scop), nb_iters, ub_expr, one);
1151       value_clear (one);
1152
1153       /* loop_i <= expr_nb_iters */
1154       ppl_set_coef (ub_expr, nb, -1);
1155       ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1156       ppl_Polyhedron_add_constraint (ph, ub);
1157       ppl_delete_Linear_Expression (ub_expr);
1158       ppl_delete_Constraint (ub);
1159     }
1160   else
1161     gcc_unreachable ();
1162
1163   if (loop->inner && loop_in_sese_p (loop->inner, region))
1164     build_loop_iteration_domains (scop, loop->inner, ph, nb + 1);
1165
1166   if (nb != 0
1167       && loop->next
1168       && loop_in_sese_p (loop->next, region))
1169     build_loop_iteration_domains (scop, loop->next, outer_ph, nb);
1170
1171   ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1172     ((ppl_Pointset_Powerset_C_Polyhedron_t *) &loop->aux, ph);
1173
1174   ppl_delete_Polyhedron (ph);
1175 }
1176
1177 /* Returns a linear expression for tree T evaluated in PBB.  */
1178
1179 static ppl_Linear_Expression_t
1180 create_linear_expr_from_tree (poly_bb_p pbb, tree t)
1181 {
1182   Value one;
1183   ppl_Linear_Expression_t res;
1184   ppl_dimension_type dim;
1185   sese region = SCOP_REGION (PBB_SCOP (pbb));
1186   loop_p loop = GBB_BB (PBB_BLACK_BOX (pbb))->loop_father;
1187
1188   dim = pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb);
1189   ppl_new_Linear_Expression_with_dimension (&res, dim);
1190
1191   t = scalar_evolution_in_region (region, loop, t);
1192   gcc_assert (!automatically_generated_chrec_p (t));
1193
1194   value_init (one);
1195   value_set_si (one, 1);
1196   scan_tree_for_params (region, t, res, one);
1197   value_clear (one);
1198
1199   return res;
1200 }
1201
1202 /* Returns the ppl constraint type from the gimple tree code CODE.  */
1203
1204 static enum ppl_enum_Constraint_Type
1205 ppl_constraint_type_from_tree_code (enum tree_code code)
1206 {
1207   switch (code)
1208     {
1209     /* We do not support LT and GT to be able to work with C_Polyhedron.
1210        As we work on integer polyhedron "a < b" can be expressed by
1211        "a + 1 <= b".  */
1212     case LT_EXPR:
1213     case GT_EXPR:
1214       gcc_unreachable ();
1215
1216     case LE_EXPR:
1217       return PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL;
1218
1219     case GE_EXPR:
1220       return PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL;
1221
1222     case EQ_EXPR:
1223       return PPL_CONSTRAINT_TYPE_EQUAL;
1224
1225     default:
1226       gcc_unreachable ();
1227     }
1228 }
1229
1230 /* Add conditional statement STMT to PS.  It is evaluated in PBB and
1231    CODE is used as the comparison operator.  This allows us to invert the
1232    condition or to handle inequalities.  */
1233
1234 static void
1235 add_condition_to_domain (ppl_Pointset_Powerset_C_Polyhedron_t ps, gimple stmt,
1236                          poly_bb_p pbb, enum tree_code code)
1237 {
1238   Value v;
1239   ppl_Coefficient_t c;
1240   ppl_Linear_Expression_t left, right;
1241   ppl_Constraint_t cstr;
1242   enum ppl_enum_Constraint_Type type;
1243
1244   left = create_linear_expr_from_tree (pbb, gimple_cond_lhs (stmt));
1245   right = create_linear_expr_from_tree (pbb, gimple_cond_rhs (stmt));
1246
1247   /* If we have < or > expressions convert them to <= or >= by adding 1 to
1248      the left or the right side of the expression. */
1249   if (code == LT_EXPR)
1250     {
1251       value_init (v);
1252       value_set_si (v, 1);
1253       ppl_new_Coefficient (&c);
1254       ppl_assign_Coefficient_from_mpz_t (c, v);
1255       ppl_Linear_Expression_add_to_inhomogeneous (left, c);
1256       ppl_delete_Coefficient (c);
1257       value_clear (v);
1258
1259       code = LE_EXPR;
1260     }
1261   else if (code == GT_EXPR)
1262     {
1263       value_init (v);
1264       value_set_si (v, 1);
1265       ppl_new_Coefficient (&c);
1266       ppl_assign_Coefficient_from_mpz_t (c, v);
1267       ppl_Linear_Expression_add_to_inhomogeneous (right, c);
1268       ppl_delete_Coefficient (c);
1269       value_clear (v);
1270
1271       code = GE_EXPR;
1272     }
1273
1274   type = ppl_constraint_type_from_tree_code (code);
1275
1276   ppl_subtract_Linear_Expression_from_Linear_Expression (left, right);
1277
1278   ppl_new_Constraint (&cstr, left, type);
1279   ppl_Pointset_Powerset_C_Polyhedron_add_constraint (ps, cstr);
1280
1281   ppl_delete_Constraint (cstr);
1282   ppl_delete_Linear_Expression (left);
1283   ppl_delete_Linear_Expression (right);
1284 }
1285
1286 /* Add conditional statement STMT to pbb.  CODE is used as the comparision
1287    operator.  This allows us to invert the condition or to handle
1288    inequalities.  */
1289
1290 static void
1291 add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code)
1292 {
1293   if (code == NE_EXPR)
1294     {
1295       ppl_Pointset_Powerset_C_Polyhedron_t left = PBB_DOMAIN (pbb);
1296       ppl_Pointset_Powerset_C_Polyhedron_t right;
1297       ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1298         (&right, left);
1299       add_condition_to_domain (left, stmt, pbb, LT_EXPR);
1300       add_condition_to_domain (right, stmt, pbb, GT_EXPR);
1301       ppl_Pointset_Powerset_C_Polyhedron_upper_bound_assign (left,
1302                                                                right);
1303       ppl_delete_Pointset_Powerset_C_Polyhedron (right);
1304     }
1305   else
1306     add_condition_to_domain (PBB_DOMAIN (pbb), stmt, pbb, code);
1307 }
1308
1309 /* Add conditions to the domain of PBB.  */
1310
1311 static void
1312 add_conditions_to_domain (poly_bb_p pbb)
1313 {
1314   unsigned int i;
1315   gimple stmt;
1316   gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1317   VEC (gimple, heap) *conditions = GBB_CONDITIONS (gbb);
1318
1319   if (VEC_empty (gimple, conditions))
1320     return;
1321
1322   for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
1323     switch (gimple_code (stmt))
1324       {
1325       case GIMPLE_COND:
1326           {
1327             enum tree_code code = gimple_cond_code (stmt);
1328
1329             /* The conditions for ELSE-branches are inverted.  */
1330             if (VEC_index (gimple, gbb->condition_cases, i) == NULL)
1331               code = invert_tree_comparison (code, false);
1332
1333             add_condition_to_pbb (pbb, stmt, code);
1334             break;
1335           }
1336
1337       case GIMPLE_SWITCH:
1338         /* Switch statements are not supported right now - fall throught.  */
1339
1340       default:
1341         gcc_unreachable ();
1342         break;
1343       }
1344 }
1345
1346 /* Structure used to pass data to dom_walk.  */
1347
1348 struct bsc
1349 {
1350   VEC (gimple, heap) **conditions, **cases;
1351   sese region;
1352 };
1353
1354 /* Returns non NULL when BB has a single predecessor and the last
1355    statement of that predecessor is a COND_EXPR.  */
1356
1357 static gimple
1358 single_pred_cond (basic_block bb)
1359 {
1360   if (single_pred_p (bb))
1361     {
1362       edge e = single_pred_edge (bb);
1363       basic_block pred = e->src;
1364       gimple stmt = last_stmt (pred);
1365
1366       if (stmt && gimple_code (stmt) == GIMPLE_COND)
1367         return stmt;
1368     }
1369   return NULL;
1370 }
1371
1372 /* Call-back for dom_walk executed before visiting the dominated
1373    blocks.  */
1374
1375 static void
1376 build_sese_conditions_before (struct dom_walk_data *dw_data,
1377                               basic_block bb)
1378 {
1379   struct bsc *data = (struct bsc *) dw_data->global_data;
1380   VEC (gimple, heap) **conditions = data->conditions;
1381   VEC (gimple, heap) **cases = data->cases;
1382   gimple_bb_p gbb = gbb_from_bb (bb);
1383   gimple stmt = single_pred_cond (bb);
1384
1385   if (!bb_in_sese_p (bb, data->region))
1386     return;
1387
1388   if (stmt)
1389     {
1390       edge e = single_pred_edge (bb);
1391
1392       VEC_safe_push (gimple, heap, *conditions, stmt);
1393
1394       if (e->flags & EDGE_TRUE_VALUE)
1395         VEC_safe_push (gimple, heap, *cases, stmt);
1396       else
1397         VEC_safe_push (gimple, heap, *cases, NULL);
1398     }
1399
1400   if (gbb)
1401     {
1402       GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
1403       GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
1404     }
1405 }
1406
1407 /* Call-back for dom_walk executed after visiting the dominated
1408    blocks.  */
1409
1410 static void
1411 build_sese_conditions_after (struct dom_walk_data *dw_data,
1412                              basic_block bb)
1413 {
1414   struct bsc *data = (struct bsc *) dw_data->global_data;
1415   VEC (gimple, heap) **conditions = data->conditions;
1416   VEC (gimple, heap) **cases = data->cases;
1417
1418   if (!bb_in_sese_p (bb, data->region))
1419     return;
1420
1421   if (single_pred_cond (bb))
1422     {
1423       VEC_pop (gimple, *conditions);
1424       VEC_pop (gimple, *cases);
1425     }
1426 }
1427
1428 /* Record all conditions in REGION.  */
1429
1430 static void
1431 build_sese_conditions (sese region)
1432 {
1433   struct dom_walk_data walk_data;
1434   VEC (gimple, heap) *conditions = VEC_alloc (gimple, heap, 3);
1435   VEC (gimple, heap) *cases = VEC_alloc (gimple, heap, 3);
1436   struct bsc data;
1437
1438   data.conditions = &conditions;
1439   data.cases = &cases;
1440   data.region = region;
1441
1442   walk_data.dom_direction = CDI_DOMINATORS;
1443   walk_data.initialize_block_local_data = NULL;
1444   walk_data.before_dom_children = build_sese_conditions_before;
1445   walk_data.after_dom_children = build_sese_conditions_after;
1446   walk_data.global_data = &data;
1447   walk_data.block_local_data_size = 0;
1448
1449   init_walk_dominator_tree (&walk_data);
1450   walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region));
1451   fini_walk_dominator_tree (&walk_data);
1452
1453   VEC_free (gimple, heap, conditions);
1454   VEC_free (gimple, heap, cases);
1455 }
1456
1457 /* Traverses all the GBBs of the SCOP and add their constraints to the
1458    iteration domains.  */
1459
1460 static void
1461 add_conditions_to_constraints (scop_p scop)
1462 {
1463   int i;
1464   poly_bb_p pbb;
1465
1466   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1467     add_conditions_to_domain (pbb);
1468 }
1469
1470 /* Add constraints on the possible values of parameter P from the type
1471    of P.  */
1472
1473 static void
1474 add_param_constraints (scop_p scop, ppl_Polyhedron_t context, graphite_dim_t p)
1475 {
1476   ppl_Constraint_t cstr;
1477   ppl_Linear_Expression_t le;
1478   tree parameter = VEC_index (tree, SESE_PARAMS (SCOP_REGION (scop)), p);
1479   tree type = TREE_TYPE (parameter);
1480   tree lb, ub;
1481
1482   /* Disabled until we fix CPU2006.  */
1483   return;
1484
1485   if (!INTEGRAL_TYPE_P (type))
1486     return;
1487
1488   lb = TYPE_MIN_VALUE (type);
1489   ub = TYPE_MAX_VALUE (type);
1490
1491   if (lb)
1492     {
1493       ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1494       ppl_set_coef (le, p, -1);
1495       ppl_set_inhomogeneous_tree (le, lb);
1496       ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL);
1497       ppl_Polyhedron_add_constraint (context, cstr);
1498       ppl_delete_Linear_Expression (le);
1499       ppl_delete_Constraint (cstr);
1500     }
1501
1502   if (ub)
1503     {
1504       ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1505       ppl_set_coef (le, p, -1);
1506       ppl_set_inhomogeneous_tree (le, ub);
1507       ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1508       ppl_Polyhedron_add_constraint (context, cstr);
1509       ppl_delete_Linear_Expression (le);
1510       ppl_delete_Constraint (cstr);
1511     }
1512 }
1513
1514 /* Build the context of the SCOP.  The context usually contains extra
1515    constraints that are added to the iteration domains that constrain
1516    some parameters.  */
1517
1518 static void
1519 build_scop_context (scop_p scop)
1520 {
1521   ppl_Polyhedron_t context;
1522   graphite_dim_t p, n = scop_nb_params (scop);
1523
1524   ppl_new_C_Polyhedron_from_space_dimension (&context, n, 0);
1525
1526   for (p = 0; p < n; p++)
1527     add_param_constraints (scop, context, p);
1528
1529   ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1530     (&SCOP_CONTEXT (scop), context);
1531
1532   ppl_delete_Polyhedron (context);
1533 }
1534
1535 /* Build the iteration domains: the loops belonging to the current
1536    SCOP, and that vary for the execution of the current basic block.
1537    Returns false if there is no loop in SCOP.  */
1538
1539 static void
1540 build_scop_iteration_domain (scop_p scop)
1541 {
1542   struct loop *loop;
1543   sese region = SCOP_REGION (scop);
1544   int i;
1545   ppl_Polyhedron_t ph;
1546   poly_bb_p pbb;
1547
1548   ppl_new_C_Polyhedron_from_space_dimension (&ph, scop_nb_params (scop), 0);
1549
1550   for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1551     if (!loop_in_sese_p (loop_outer (loop), region))
1552       build_loop_iteration_domains (scop, loop, ph, 0);
1553
1554   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1555     if (gbb_loop (PBB_BLACK_BOX (pbb))->aux)
1556       ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1557         (&PBB_DOMAIN (pbb), (ppl_const_Pointset_Powerset_C_Polyhedron_t)
1558          gbb_loop (PBB_BLACK_BOX (pbb))->aux);
1559     else
1560       ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1561         (&PBB_DOMAIN (pbb), ph);
1562
1563   for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1564     if (loop->aux)
1565       {
1566         ppl_delete_Pointset_Powerset_C_Polyhedron
1567           ((ppl_Pointset_Powerset_C_Polyhedron_t) loop->aux);
1568         loop->aux = NULL;
1569       }
1570
1571   ppl_delete_Polyhedron (ph);
1572 }
1573
1574 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1575    data reference DR.  ACCESSP_NB_DIMS is the dimension of the
1576    ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1577    domain.  */
1578
1579 static void
1580 pdr_add_alias_set (ppl_Polyhedron_t accesses, data_reference_p dr,
1581                    ppl_dimension_type accessp_nb_dims,
1582                    ppl_dimension_type dom_nb_dims)
1583 {
1584   ppl_Linear_Expression_t alias;
1585   ppl_Constraint_t cstr;
1586   int alias_set_num = 0;
1587
1588   if (dr->aux != NULL)
1589     {
1590       alias_set_num = *((int *)(dr->aux));
1591       free (dr->aux);
1592       dr->aux = NULL;
1593     }
1594
1595   ppl_new_Linear_Expression_with_dimension (&alias, accessp_nb_dims);
1596
1597   ppl_set_coef (alias, dom_nb_dims, 1);
1598   ppl_set_inhomogeneous (alias, -alias_set_num);
1599   ppl_new_Constraint (&cstr, alias, PPL_CONSTRAINT_TYPE_EQUAL);
1600   ppl_Polyhedron_add_constraint (accesses, cstr);
1601
1602   ppl_delete_Linear_Expression (alias);
1603   ppl_delete_Constraint (cstr);
1604 }
1605
1606 /* Add to ACCESSES polyhedron equalities defining the access functions
1607    to the memory.  ACCESSP_NB_DIMS is the dimension of the ACCESSES
1608    polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1609    PBB is the poly_bb_p that contains the data reference DR.  */
1610
1611 static void
1612 pdr_add_memory_accesses (ppl_Polyhedron_t accesses, data_reference_p dr,
1613                          ppl_dimension_type accessp_nb_dims,
1614                          ppl_dimension_type dom_nb_dims,
1615                          poly_bb_p pbb)
1616 {
1617   int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1618   Value v;
1619   scop_p scop = PBB_SCOP (pbb);
1620   sese region = SCOP_REGION (scop);
1621
1622   value_init (v);
1623
1624   for (i = 0; i < nb_subscripts; i++)
1625     {
1626       ppl_Linear_Expression_t fn, access;
1627       ppl_Constraint_t cstr;
1628       ppl_dimension_type subscript = dom_nb_dims + 1 + i;
1629       tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1630
1631       ppl_new_Linear_Expression_with_dimension (&fn, dom_nb_dims);
1632       ppl_new_Linear_Expression_with_dimension (&access, accessp_nb_dims);
1633
1634       value_set_si (v, 1);
1635       scan_tree_for_params (region, afn, fn, v);
1636       ppl_assign_Linear_Expression_from_Linear_Expression (access, fn);
1637
1638       ppl_set_coef (access, subscript, -1);
1639       ppl_new_Constraint (&cstr, access, PPL_CONSTRAINT_TYPE_EQUAL);
1640       ppl_Polyhedron_add_constraint (accesses, cstr);
1641
1642       ppl_delete_Linear_Expression (fn);
1643       ppl_delete_Linear_Expression (access);
1644       ppl_delete_Constraint (cstr);
1645     }
1646
1647   value_clear (v);
1648 }
1649
1650 /* Add constrains representing the size of the accessed data to the
1651    ACCESSES polyhedron.  ACCESSP_NB_DIMS is the dimension of the
1652    ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1653    domain.  */
1654
1655 static void
1656 pdr_add_data_dimensions (ppl_Polyhedron_t accesses, data_reference_p dr,
1657                          ppl_dimension_type accessp_nb_dims,
1658                          ppl_dimension_type dom_nb_dims)
1659 {
1660   tree ref = DR_REF (dr);
1661   int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1662
1663   for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1664     {
1665       ppl_Linear_Expression_t expr;
1666       ppl_Constraint_t cstr;
1667       ppl_dimension_type subscript = dom_nb_dims + 1 + i;
1668       tree low, high;
1669
1670       if (TREE_CODE (ref) != ARRAY_REF)
1671         break;
1672
1673       low = array_ref_low_bound (ref);
1674
1675       /* subscript - low >= 0 */
1676       if (host_integerp (low, 0))
1677         {
1678           ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1679           ppl_set_coef (expr, subscript, 1);
1680
1681           ppl_set_inhomogeneous (expr, -int_cst_value (low));
1682
1683           ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1684           ppl_Polyhedron_add_constraint (accesses, cstr);
1685           ppl_delete_Linear_Expression (expr);
1686           ppl_delete_Constraint (cstr);
1687         }
1688
1689       high = array_ref_up_bound (ref);
1690
1691       /* high - subscript >= 0
1692          XXX: 1-element arrays at end of structures may extend over their
1693          declared size.  */
1694       if (high && host_integerp (high, 0))
1695         {
1696           ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1697           ppl_set_coef (expr, subscript, -1);
1698
1699           ppl_set_inhomogeneous (expr, int_cst_value (high));
1700
1701           ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1702           ppl_Polyhedron_add_constraint (accesses, cstr);
1703           ppl_delete_Linear_Expression (expr);
1704           ppl_delete_Constraint (cstr);
1705         }
1706     }
1707 }
1708
1709 /* Build data accesses for DR in PBB.  */
1710
1711 static void
1712 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1713 {
1714   ppl_Polyhedron_t accesses;
1715   ppl_Pointset_Powerset_C_Polyhedron_t accesses_ps;
1716   ppl_dimension_type dom_nb_dims;
1717   ppl_dimension_type accessp_nb_dims;
1718
1719   ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PBB_DOMAIN (pbb),
1720                                                       &dom_nb_dims);
1721   accessp_nb_dims = dom_nb_dims + 1 + DR_NUM_DIMENSIONS (dr);
1722
1723   ppl_new_C_Polyhedron_from_space_dimension (&accesses, accessp_nb_dims, 0);
1724
1725   pdr_add_alias_set (accesses, dr, accessp_nb_dims, dom_nb_dims);
1726   pdr_add_memory_accesses (accesses, dr, accessp_nb_dims, dom_nb_dims, pbb);
1727   pdr_add_data_dimensions (accesses, dr, accessp_nb_dims, dom_nb_dims);
1728
1729   ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&accesses_ps,
1730                                                             accesses);
1731   ppl_delete_Polyhedron (accesses);
1732   new_poly_dr (pbb, accesses_ps, DR_IS_READ (dr) ? PDR_READ : PDR_WRITE, dr,
1733                DR_NUM_DIMENSIONS (dr));
1734 }
1735
1736 /* Group each data reference in DRS with it's alias set num.  */
1737
1738 static void
1739 build_alias_set_for_drs (VEC (data_reference_p, heap) **drs)
1740 {
1741   int num_vertex = VEC_length (data_reference_p, *drs);
1742   struct graph *g = new_graph (num_vertex);
1743   data_reference_p dr1, dr2;
1744   int i, j;
1745   int num_component;
1746   int *queue;
1747
1748   for (i = 0; VEC_iterate (data_reference_p, *drs, i, dr1); i++)
1749     for (j = i+1; VEC_iterate (data_reference_p, *drs, j, dr2); j++)
1750       if (dr_may_alias_p (dr1, dr2))
1751         {
1752           add_edge (g, i, j);
1753           add_edge (g, j, i);
1754         }
1755
1756   queue = XNEWVEC (int, num_vertex);
1757   for (i = 0; i < num_vertex; i++)
1758     queue[i] = i;
1759
1760   num_component = graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1761
1762   for (i = 0; i < g->n_vertices; i++)
1763     {
1764       data_reference_p dr = VEC_index (data_reference_p, *drs, i);
1765       dr->aux = XNEW (int);
1766       *((int *)(dr->aux)) = g->vertices[i].component + 1;
1767     }
1768
1769   free (queue);
1770   free_graph (g);
1771 }
1772
1773 /* Build the data references for PBB.  */
1774
1775 static void
1776 build_pbb_drs (poly_bb_p pbb)
1777 {
1778   int j;
1779   data_reference_p dr;
1780   VEC (data_reference_p, heap) *gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1781
1782   for (j = 0; VEC_iterate (data_reference_p, gbb_drs, j, dr); j++)
1783     build_poly_dr (dr, pbb);
1784 }
1785
1786 /* Build data references in SCOP.  */
1787
1788 static void
1789 build_scop_drs (scop_p scop)
1790 {
1791   int i, j;
1792   poly_bb_p pbb;
1793   data_reference_p dr;
1794   VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
1795
1796   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1797     {
1798       VEC (data_reference_p, heap) *gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1799       for (j = 0; VEC_iterate (data_reference_p, gbb_drs, j, dr); j++)
1800        VEC_safe_push (data_reference_p, heap, drs, dr);
1801     }
1802
1803   build_alias_set_for_drs (&drs);
1804   VEC_free (data_reference_p, heap, drs);
1805
1806   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1807     build_pbb_drs (pbb);
1808 }
1809
1810 /* Return a gsi at the position of the VAR definition.  */
1811
1812 static gimple_stmt_iterator
1813 gsi_for_ssa_name_def (tree var)
1814 {
1815   gimple stmt;
1816   basic_block bb;
1817   gimple_stmt_iterator gsi;
1818   gimple_stmt_iterator psi;
1819
1820   gcc_assert (TREE_CODE (var) == SSA_NAME);
1821
1822   stmt = SSA_NAME_DEF_STMT (var);
1823   bb = gimple_bb (stmt);
1824
1825   for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1826     if (stmt == gsi_stmt (psi))
1827       return gsi_after_labels (bb);
1828
1829   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1830     if (stmt == gsi_stmt (gsi))
1831       {
1832         gsi_next (&gsi);
1833         return gsi;
1834       }
1835
1836   gcc_unreachable ();
1837   return gsi;
1838 }
1839
1840 /* Insert the assignment "RES := VAR" just after the definition of VAR.  */
1841
1842 static void
1843 insert_out_of_ssa_copy (tree res, tree var)
1844 {
1845   gimple_stmt_iterator gsi = gsi_for_ssa_name_def (var);
1846   gimple stmt;
1847   gimple_seq stmts;
1848   gimple_stmt_iterator si;
1849
1850   var = force_gimple_operand (var, &stmts, true, NULL_TREE);
1851   stmt = gimple_build_assign (res, var);
1852   if (!stmts)
1853     stmts = gimple_seq_alloc ();
1854   si = gsi_last (stmts);
1855   gsi_insert_after (&si, stmt, GSI_NEW_STMT);
1856   gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
1857 }
1858
1859 /* Insert on edge E the assignment "RES := EXPR".  */
1860
1861 static void
1862 insert_out_of_ssa_copy_on_edge (edge e, tree res, tree expr)
1863 {
1864   gimple_stmt_iterator gsi;
1865   gimple_seq stmts;
1866   tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
1867   gimple stmt = gimple_build_assign (res, var);
1868
1869   if (!stmts)
1870     stmts = gimple_seq_alloc ();
1871
1872   gsi = gsi_last (stmts);
1873   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
1874   gsi_insert_seq_on_edge (e, stmts);
1875   gsi_commit_edge_inserts ();
1876 }
1877
1878 /* Creates a zero dimension array of the same type as VAR.  */
1879
1880 static tree
1881 create_zero_dim_array (tree var)
1882 {
1883   tree index_type = build_index_type (integer_zero_node);
1884   tree elt_type = TREE_TYPE (var);
1885   tree array_type = build_array_type (elt_type, index_type);
1886   tree base = create_tmp_var (array_type, "Red");
1887
1888   add_referenced_var (base);
1889
1890   return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
1891                  NULL_TREE);
1892 }
1893
1894 /* Returns true when PHI is a loop close phi node.  */
1895
1896 static bool
1897 scalar_close_phi_node_p (gimple phi)
1898 {
1899   gcc_assert (gimple_code (phi) == GIMPLE_PHI);
1900
1901   if (!is_gimple_reg (gimple_phi_result (phi)))
1902     return false;
1903
1904   return (gimple_phi_num_args (phi) == 1);
1905 }
1906
1907 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
1908    dimension array for it.  */
1909
1910 static void
1911 rewrite_close_phi_out_of_ssa (gimple_stmt_iterator *psi)
1912 {
1913   gimple phi = gsi_stmt (*psi);
1914   tree res = gimple_phi_result (phi);
1915   tree var = SSA_NAME_VAR (res);
1916   tree zero_dim_array = create_zero_dim_array (var);
1917   gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (phi));
1918   gimple stmt = gimple_build_assign (res, zero_dim_array);
1919   tree arg = gimple_phi_arg_def (phi, 0);
1920
1921   insert_out_of_ssa_copy (zero_dim_array, arg);
1922
1923   remove_phi_node (psi, false);
1924   gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
1925   SSA_NAME_DEF_STMT (res) = stmt;
1926 }
1927
1928 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
1929    dimension array for it.  */
1930
1931 static void
1932 rewrite_phi_out_of_ssa (gimple_stmt_iterator *psi)
1933 {
1934   size_t i;
1935   gimple phi = gsi_stmt (*psi);
1936   basic_block bb = gimple_bb (phi);
1937   tree res = gimple_phi_result (phi);
1938   tree var = SSA_NAME_VAR (res);
1939   tree zero_dim_array = create_zero_dim_array (var);
1940   gimple_stmt_iterator gsi;
1941   gimple stmt;
1942   gimple_seq stmts;
1943
1944   for (i = 0; i < gimple_phi_num_args (phi); i++)
1945     {
1946       tree arg = gimple_phi_arg_def (phi, i);
1947
1948       /* Try to avoid the insertion on edges as much as possible: this
1949          would avoid the insertion of code on loop latch edges, making
1950          the pattern matching of the vectorizer happy, or it would
1951          avoid the insertion of useless basic blocks.  Note that it is
1952          incorrect to insert out of SSA copies close by their
1953          definition when they are more than two loop levels apart:
1954          for example, starting from a double nested loop
1955
1956          | a = ...
1957          | loop_1
1958          |  loop_2
1959          |    b = phi (a, c)
1960          |    c = ...
1961          |  end_2
1962          | end_1
1963
1964          the following transform is incorrect
1965
1966          | a = ...
1967          | Red[0] = a
1968          | loop_1
1969          |  loop_2
1970          |    b = Red[0]
1971          |    c = ...
1972          |    Red[0] = c
1973          |  end_2
1974          | end_1
1975
1976          whereas inserting the copy on the incomming edge is correct
1977
1978          | a = ...
1979          | loop_1
1980          |  Red[0] = a
1981          |  loop_2
1982          |    b = Red[0]
1983          |    c = ...
1984          |    Red[0] = c
1985          |  end_2
1986          | end_1
1987       */
1988       if (TREE_CODE (arg) == SSA_NAME
1989           && is_gimple_reg (arg)
1990           && gimple_bb (SSA_NAME_DEF_STMT (arg))
1991           && (flow_bb_inside_loop_p (bb->loop_father,
1992                                      gimple_bb (SSA_NAME_DEF_STMT (arg)))
1993               || flow_bb_inside_loop_p (loop_outer (bb->loop_father),
1994                                         gimple_bb (SSA_NAME_DEF_STMT (arg)))))
1995         insert_out_of_ssa_copy (zero_dim_array, arg);
1996       else
1997         insert_out_of_ssa_copy_on_edge (gimple_phi_arg_edge (phi, i),
1998                                         zero_dim_array, arg);
1999     }
2000
2001   var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
2002
2003   if (!stmts)
2004     stmts = gimple_seq_alloc ();
2005
2006   stmt = gimple_build_assign (res, var);
2007   remove_phi_node (psi, false);
2008   SSA_NAME_DEF_STMT (res) = stmt;
2009
2010   gsi = gsi_last (stmts);
2011   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
2012
2013   gsi = gsi_after_labels (bb);
2014   gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2015 }
2016
2017 /* Rewrite out of SSA all the reduction phi nodes of SCOP.  */
2018
2019 static void
2020 rewrite_reductions_out_of_ssa (scop_p scop)
2021 {
2022   basic_block bb;
2023   gimple_stmt_iterator psi;
2024   sese region = SCOP_REGION (scop);
2025
2026   FOR_EACH_BB (bb)
2027     if (bb_in_region (bb, SESE_ENTRY_BB (region), SESE_EXIT_BB (region)))
2028       for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2029         {
2030           if (scalar_close_phi_node_p (gsi_stmt (psi)))
2031             rewrite_close_phi_out_of_ssa (&psi);
2032           else if (reduction_phi_p (region, &psi))
2033             rewrite_phi_out_of_ssa (&psi);
2034         }
2035
2036   update_ssa (TODO_update_ssa);
2037 #ifdef ENABLE_CHECKING
2038   verify_ssa (false);
2039   verify_loop_closed_ssa ();
2040 #endif
2041 }
2042
2043 /* Returns the number of pbbs that are in loops contained in SCOP.  */
2044
2045 static int
2046 nb_pbbs_in_loops (scop_p scop)
2047 {
2048   int i;
2049   poly_bb_p pbb;
2050   int res = 0;
2051
2052   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
2053     if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2054       res++;
2055
2056   return res;
2057 }
2058
2059 /* Builds the polyhedral representation for a SESE region.  */
2060
2061 bool
2062 build_poly_scop (scop_p scop)
2063 {
2064   sese region = SCOP_REGION (scop);
2065   rewrite_reductions_out_of_ssa (scop);
2066   build_scop_bbs (scop);
2067
2068   /* FIXME: This restriction is needed to avoid a problem in CLooG.
2069      Once CLooG is fixed, remove this guard.  Anyways, it makes no
2070      sense to optimize a scop containing only PBBs that do not belong
2071      to any loops.  */
2072   if (nb_pbbs_in_loops (scop) == 0)
2073     return false;
2074
2075   build_sese_loop_nests (region);
2076   build_sese_conditions (region);
2077   find_scop_parameters (scop);
2078
2079   build_scop_iteration_domain (scop);
2080   build_scop_context (scop);
2081
2082   add_conditions_to_constraints (scop);
2083   build_scop_scattering (scop);
2084   build_scop_drs (scop);
2085
2086   return true;
2087 }
2088
2089 /* Always return false.  Exercise the scop_to_clast function.  */
2090
2091 void
2092 check_poly_representation (scop_p scop ATTRIBUTE_UNUSED)
2093 {
2094 #ifdef ENABLE_CHECKING
2095   cloog_prog_clast pc = scop_to_clast (scop);
2096   cloog_clast_free (pc.stmt);
2097   cloog_program_free (pc.prog);
2098 #endif
2099 }
2100 #endif