OSDN Git Service

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