OSDN Git Service

507ab2452639bae0567856882d5b83158791667d
[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   imm_use_iterator imm_iter;
61   gimple stmt;
62   bool result = false;
63
64   FOR_EACH_IMM_USE_STMT (stmt, imm_iter, var)
65     {
66       basic_block bb = gimple_bb (stmt);
67
68       if (gimple_code (stmt) == GIMPLE_PHI
69           && bb->loop_father->header != bb)
70         result = true;
71     }
72
73   return result;
74 }
75
76 /* Returns the index of the phi argument corresponding to the initial
77    value in the loop.  */
78
79 static size_t
80 loop_entry_phi_arg (gimple phi)
81 {
82   loop_p loop = gimple_bb (phi)->loop_father;
83   size_t i;
84
85   for (i = 0; i < gimple_phi_num_args (phi); i++)
86     if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
87       return i;
88
89   gcc_unreachable ();
90   return 0;
91 }
92
93 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
94    PSI by inserting on the loop ENTRY edge assignment "RES = INIT".  */
95
96 static void
97 remove_simple_copy_phi (gimple_stmt_iterator *psi)
98 {
99   gimple phi = gsi_stmt (*psi);
100   tree res = gimple_phi_result (phi);
101   size_t entry = loop_entry_phi_arg (phi);
102   tree init = gimple_phi_arg_def (phi, entry);
103   gimple stmt = gimple_build_assign (res, init);
104   edge e = gimple_phi_arg_edge (phi, entry);
105
106   remove_phi_node (psi, false);
107   gsi_insert_on_edge_immediate (e, stmt);
108   SSA_NAME_DEF_STMT (res) = stmt;
109 }
110
111 /* Removes an invariant phi node at position PSI by inserting on the
112    loop ENTRY edge the assignment RES = INIT.  */
113
114 static void
115 remove_invariant_phi (sese region, gimple_stmt_iterator *psi)
116 {
117   gimple phi = gsi_stmt (*psi);
118   loop_p loop = loop_containing_stmt (phi);
119   tree res = gimple_phi_result (phi);
120   tree scev = scalar_evolution_in_region (region, loop, res);
121   size_t entry = loop_entry_phi_arg (phi);
122   edge e = gimple_phi_arg_edge (phi, entry);
123   tree var;
124   gimple stmt;
125   gimple_seq stmts;
126   gimple_stmt_iterator gsi;
127
128   if (tree_contains_chrecs (scev, NULL))
129     scev = gimple_phi_arg_def (phi, entry);
130
131   var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
132   stmt = gimple_build_assign (res, var);
133   remove_phi_node (psi, false);
134
135   if (!stmts)
136     stmts = gimple_seq_alloc ();
137
138   gsi = gsi_last (stmts);
139   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
140   gsi_insert_seq_on_edge (e, stmts);
141   gsi_commit_edge_inserts ();
142   SSA_NAME_DEF_STMT (res) = stmt;
143 }
144
145 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)".  */
146
147 static inline bool
148 simple_copy_phi_p (gimple phi)
149 {
150   tree res;
151
152   if (gimple_phi_num_args (phi) != 2)
153     return false;
154
155   res = gimple_phi_result (phi);
156   return (res == gimple_phi_arg_def (phi, 0)
157           || res == gimple_phi_arg_def (phi, 1));
158 }
159
160 /* Returns true when the phi node at position PSI is a reduction phi
161    node in REGION.  Otherwise moves the pointer PSI to the next phi to
162    be considered.  */
163
164 static bool
165 reduction_phi_p (sese region, gimple_stmt_iterator *psi)
166 {
167   loop_p loop;
168   tree scev;
169   affine_iv iv;
170   gimple phi = gsi_stmt (*psi);
171   tree res = gimple_phi_result (phi);
172
173   if (!is_gimple_reg (res))
174     {
175       gsi_next (psi);
176       return false;
177     }
178
179   loop = loop_containing_stmt (phi);
180
181   if (simple_copy_phi_p (phi))
182     {
183       /* FIXME: PRE introduces phi nodes like these, for an example,
184          see id-5.f in the fortran graphite testsuite:
185
186          # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
187       */
188       remove_simple_copy_phi (psi);
189       return false;
190     }
191
192   /* Main induction variables with constant strides in LOOP are not
193      reductions.  */
194   if (simple_iv (loop, loop, res, &iv, true))
195     {
196       if (integer_zerop (iv.step))
197         remove_invariant_phi (region, psi);
198       else
199         gsi_next (psi);
200
201       return false;
202     }
203
204   scev = scalar_evolution_in_region (region, loop, res);
205   if (chrec_contains_undetermined (scev))
206     return true;
207
208   if (evolution_function_is_invariant_p (scev, loop->num))
209     {
210       remove_invariant_phi (region, psi);
211       return false;
212     }
213
214   /* All the other cases are considered reductions.  */
215   return true;
216 }
217
218 /* Returns true when BB will be represented in graphite.  Return false
219    for the basic blocks that contain code eliminated in the code
220    generation pass: i.e. induction variables and exit conditions.  */
221
222 static bool
223 graphite_stmt_p (sese region, basic_block bb,
224                  VEC (data_reference_p, heap) *drs)
225 {
226   gimple_stmt_iterator gsi;
227   loop_p loop = bb->loop_father;
228
229   if (VEC_length (data_reference_p, drs) > 0)
230     return true;
231
232   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
233     {
234       gimple stmt = gsi_stmt (gsi);
235
236       switch (gimple_code (stmt))
237         {
238         case GIMPLE_DEBUG:
239           /* Control flow expressions can be ignored, as they are
240              represented in the iteration domains and will be
241              regenerated by graphite.  */
242         case GIMPLE_COND:
243         case GIMPLE_GOTO:
244         case GIMPLE_SWITCH:
245           break;
246
247         case GIMPLE_ASSIGN:
248           {
249             tree var = gimple_assign_lhs (stmt);
250
251             /* We need these bbs to be able to construct the phi nodes.  */
252             if (var_used_in_not_loop_header_phi_node (var))
253               return true;
254
255             var = scalar_evolution_in_region (region, loop, var);
256             if (chrec_contains_undetermined (var))
257               return true;
258
259             break;
260           }
261
262         default:
263           return true;
264         }
265     }
266
267   return false;
268 }
269
270 /* Store the GRAPHITE representation of BB.  */
271
272 static gimple_bb_p
273 new_gimple_bb (basic_block bb, VEC (data_reference_p, heap) *drs)
274 {
275   struct gimple_bb *gbb;
276
277   gbb = XNEW (struct gimple_bb);
278   bb->aux = gbb;
279   GBB_BB (gbb) = bb;
280   GBB_DATA_REFS (gbb) = drs;
281   GBB_CONDITIONS (gbb) = NULL;
282   GBB_CONDITION_CASES (gbb) = NULL;
283   GBB_CLOOG_IV_TYPES (gbb) = NULL;
284
285   return gbb;
286 }
287
288 static void
289 free_data_refs_aux (VEC (data_reference_p, heap) *datarefs)
290 {
291   unsigned int i;
292   struct data_reference *dr;
293
294   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
295     if (!dr->aux)
296       {
297         free (dr->aux);
298         dr->aux = NULL;
299       }
300 }
301
302 /* Frees GBB.  */
303
304 static void
305 free_gimple_bb (struct gimple_bb *gbb)
306 {
307   if (GBB_CLOOG_IV_TYPES (gbb))
308     htab_delete (GBB_CLOOG_IV_TYPES (gbb));
309
310   free_data_refs_aux (GBB_DATA_REFS (gbb));
311   free_data_refs (GBB_DATA_REFS (gbb));
312
313   VEC_free (gimple, heap, GBB_CONDITIONS (gbb));
314   VEC_free (gimple, heap, GBB_CONDITION_CASES (gbb));
315   GBB_BB (gbb)->aux = 0;
316   XDELETE (gbb);
317 }
318
319 /* Deletes all gimple bbs in SCOP.  */
320
321 static void
322 remove_gbbs_in_scop (scop_p scop)
323 {
324   int i;
325   poly_bb_p pbb;
326
327   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
328     free_gimple_bb (PBB_BLACK_BOX (pbb));
329 }
330
331 /* Deletes all scops in SCOPS.  */
332
333 void
334 free_scops (VEC (scop_p, heap) *scops)
335 {
336   int i;
337   scop_p scop;
338
339   for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++)
340     {
341       remove_gbbs_in_scop (scop);
342       free_sese (SCOP_REGION (scop));
343       free_scop (scop);
344     }
345
346   VEC_free (scop_p, heap, scops);
347 }
348
349 /* Generates a polyhedral black box only if the bb contains interesting
350    information.  */
351
352 static void
353 try_generate_gimple_bb (scop_p scop, basic_block bb, sbitmap reductions)
354 {
355   VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
356   loop_p nest = outermost_loop_in_sese (SCOP_REGION (scop), bb);
357   gimple_stmt_iterator gsi;
358
359   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
360     {
361       gimple stmt = gsi_stmt (gsi);
362       if (!is_gimple_debug (stmt))
363         graphite_find_data_references_in_stmt (nest, stmt, &drs);
364     }
365
366   if (!graphite_stmt_p (SCOP_REGION (scop), bb, drs))
367     free_data_refs (drs);
368   else
369     new_poly_bb (scop, new_gimple_bb (bb, drs), TEST_BIT (reductions,
370                                                           bb->index));
371 }
372
373 /* Returns true if all predecessors of BB, that are not dominated by BB, are
374    marked in MAP.  The predecessors dominated by BB are loop latches and will
375    be handled after BB.  */
376
377 static bool
378 all_non_dominated_preds_marked_p (basic_block bb, sbitmap map)
379 {
380   edge e;
381   edge_iterator ei;
382
383   FOR_EACH_EDGE (e, ei, bb->preds)
384     if (!TEST_BIT (map, e->src->index)
385         && !dominated_by_p (CDI_DOMINATORS, e->src, bb))
386         return false;
387
388   return true;
389 }
390
391 /* Compare the depth of two basic_block's P1 and P2.  */
392
393 static int
394 compare_bb_depths (const void *p1, const void *p2)
395 {
396   const_basic_block const bb1 = *(const_basic_block const*)p1;
397   const_basic_block const bb2 = *(const_basic_block const*)p2;
398   int d1 = loop_depth (bb1->loop_father);
399   int d2 = loop_depth (bb2->loop_father);
400
401   if (d1 < d2)
402     return 1;
403
404   if (d1 > d2)
405     return -1;
406
407   return 0;
408 }
409
410 /* Sort the basic blocks from DOM such that the first are the ones at
411    a deepest loop level.  */
412
413 static void
414 graphite_sort_dominated_info (VEC (basic_block, heap) *dom)
415 {
416   size_t len = VEC_length (basic_block, dom);
417
418   qsort (VEC_address (basic_block, dom), len, sizeof (basic_block),
419          compare_bb_depths);
420 }
421
422 /* Recursive helper function for build_scops_bbs.  */
423
424 static void
425 build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb, sbitmap reductions)
426 {
427   sese region = SCOP_REGION (scop);
428   VEC (basic_block, heap) *dom;
429
430   if (TEST_BIT (visited, bb->index)
431       || !bb_in_sese_p (bb, region))
432     return;
433
434   try_generate_gimple_bb (scop, bb, reductions);
435   SET_BIT (visited, bb->index);
436
437   dom = get_dominated_by (CDI_DOMINATORS, bb);
438
439   if (dom == NULL)
440     return;
441
442   graphite_sort_dominated_info (dom);
443
444   while (!VEC_empty (basic_block, dom))
445     {
446       int i;
447       basic_block dom_bb;
448
449       for (i = 0; VEC_iterate (basic_block, dom, i, dom_bb); i++)
450         if (all_non_dominated_preds_marked_p (dom_bb, visited))
451           {
452             build_scop_bbs_1 (scop, visited, dom_bb, reductions);
453             VEC_unordered_remove (basic_block, dom, i);
454             break;
455           }
456     }
457
458   VEC_free (basic_block, heap, dom);
459 }
460
461 /* Gather the basic blocks belonging to the SCOP.  */
462
463 static void
464 build_scop_bbs (scop_p scop, sbitmap reductions)
465 {
466   sbitmap visited = sbitmap_alloc (last_basic_block);
467   sese region = SCOP_REGION (scop);
468
469   sbitmap_zero (visited);
470   build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region), reductions);
471   sbitmap_free (visited);
472 }
473
474 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
475    We generate SCATTERING_DIMENSIONS scattering dimensions.
476
477    CLooG 0.15.0 and previous versions require, that all
478    scattering functions of one CloogProgram have the same number of
479    scattering dimensions, therefore we allow to specify it.  This
480    should be removed in future versions of CLooG.
481
482    The scattering polyhedron consists of these dimensions: scattering,
483    loop_iterators, parameters.
484
485    Example:
486
487    | scattering_dimensions = 5
488    | used_scattering_dimensions = 3
489    | nb_iterators = 1
490    | scop_nb_params = 2
491    |
492    | Schedule:
493    |   i
494    | 4 5
495    |
496    | Scattering polyhedron:
497    |
498    | scattering: {s1, s2, s3, s4, s5}
499    | loop_iterators: {i}
500    | parameters: {p1, p2}
501    |
502    | s1  s2  s3  s4  s5  i   p1  p2  1
503    | 1   0   0   0   0   0   0   0  -4  = 0
504    | 0   1   0   0   0  -1   0   0   0  = 0
505    | 0   0   1   0   0   0   0   0  -5  = 0  */
506
507 static void
508 build_pbb_scattering_polyhedrons (ppl_Linear_Expression_t static_schedule,
509                                   poly_bb_p pbb, int scattering_dimensions)
510 {
511   int i;
512   scop_p scop = PBB_SCOP (pbb);
513   int nb_iterators = pbb_dim_iter_domain (pbb);
514   int used_scattering_dimensions = nb_iterators * 2 + 1;
515   int nb_params = scop_nb_params (scop);
516   ppl_Coefficient_t c;
517   ppl_dimension_type dim = scattering_dimensions + nb_iterators + nb_params;
518   Value v;
519
520   gcc_assert (scattering_dimensions >= used_scattering_dimensions);
521
522   value_init (v);
523   ppl_new_Coefficient (&c);
524   PBB_TRANSFORMED (pbb) = poly_scattering_new ();
525   ppl_new_C_Polyhedron_from_space_dimension
526     (&PBB_TRANSFORMED_SCATTERING (pbb), dim, 0);
527
528   PBB_NB_SCATTERING_TRANSFORM (pbb) = scattering_dimensions;
529
530   for (i = 0; i < scattering_dimensions; i++)
531     {
532       ppl_Constraint_t cstr;
533       ppl_Linear_Expression_t expr;
534
535       ppl_new_Linear_Expression_with_dimension (&expr, dim);
536       value_set_si (v, 1);
537       ppl_assign_Coefficient_from_mpz_t (c, v);
538       ppl_Linear_Expression_add_to_coefficient (expr, i, c);
539
540       /* Textual order inside this loop.  */
541       if ((i % 2) == 0)
542         {
543           ppl_Linear_Expression_coefficient (static_schedule, i / 2, c);
544           ppl_Coefficient_to_mpz_t (c, v);
545           value_oppose (v, v);
546           ppl_assign_Coefficient_from_mpz_t (c, v);
547           ppl_Linear_Expression_add_to_inhomogeneous (expr, c);
548         }
549
550       /* Iterations of this loop.  */
551       else /* if ((i % 2) == 1) */
552         {
553           int loop = (i - 1) / 2;
554
555           value_set_si (v, -1);
556           ppl_assign_Coefficient_from_mpz_t (c, v);
557           ppl_Linear_Expression_add_to_coefficient
558             (expr, scattering_dimensions + loop, c);
559         }
560
561       ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL);
562       ppl_Polyhedron_add_constraint (PBB_TRANSFORMED_SCATTERING (pbb), cstr);
563       ppl_delete_Linear_Expression (expr);
564       ppl_delete_Constraint (cstr);
565     }
566
567   value_clear (v);
568   ppl_delete_Coefficient (c);
569
570   PBB_ORIGINAL (pbb) = poly_scattering_copy (PBB_TRANSFORMED (pbb));
571 }
572
573 /* Build for BB the static schedule.
574
575    The static schedule is a Dewey numbering of the abstract syntax
576    tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
577
578    The following example informally defines the static schedule:
579
580    A
581    for (i: ...)
582      {
583        for (j: ...)
584          {
585            B
586            C
587          }
588
589        for (k: ...)
590          {
591            D
592            E
593          }
594      }
595    F
596
597    Static schedules for A to F:
598
599      DEPTH
600      0 1 2
601    A 0
602    B 1 0 0
603    C 1 0 1
604    D 1 1 0
605    E 1 1 1
606    F 2
607 */
608
609 static void
610 build_scop_scattering (scop_p scop)
611 {
612   int i;
613   poly_bb_p pbb;
614   gimple_bb_p previous_gbb = NULL;
615   ppl_Linear_Expression_t static_schedule;
616   ppl_Coefficient_t c;
617   Value v;
618
619   value_init (v);
620   ppl_new_Coefficient (&c);
621   ppl_new_Linear_Expression (&static_schedule);
622
623   /* We have to start schedules at 0 on the first component and
624      because we cannot compare_prefix_loops against a previous loop,
625      prefix will be equal to zero, and that index will be
626      incremented before copying.  */
627   value_set_si (v, -1);
628   ppl_assign_Coefficient_from_mpz_t (c, v);
629   ppl_Linear_Expression_add_to_coefficient (static_schedule, 0, c);
630
631   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
632     {
633       gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
634       ppl_Linear_Expression_t common;
635       int prefix;
636       int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1;
637
638       if (previous_gbb)
639         prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
640       else
641         prefix = 0;
642
643       previous_gbb = gbb;
644       ppl_new_Linear_Expression_with_dimension (&common, prefix + 1);
645       ppl_assign_Linear_Expression_from_Linear_Expression (common,
646                                                            static_schedule);
647
648       value_set_si (v, 1);
649       ppl_assign_Coefficient_from_mpz_t (c, v);
650       ppl_Linear_Expression_add_to_coefficient (common, prefix, c);
651       ppl_assign_Linear_Expression_from_Linear_Expression (static_schedule,
652                                                            common);
653
654       build_pbb_scattering_polyhedrons (common, pbb, nb_scat_dims);
655
656       ppl_delete_Linear_Expression (common);
657     }
658
659   value_clear (v);
660   ppl_delete_Coefficient (c);
661   ppl_delete_Linear_Expression (static_schedule);
662 }
663
664 /* Add the value K to the dimension D of the linear expression EXPR.  */
665
666 static void
667 add_value_to_dim (ppl_dimension_type d, ppl_Linear_Expression_t expr,
668                   Value k)
669 {
670   Value val;
671   ppl_Coefficient_t coef;
672
673   ppl_new_Coefficient (&coef);
674   ppl_Linear_Expression_coefficient (expr, d, coef);
675   value_init (val);
676   ppl_Coefficient_to_mpz_t (coef, val);
677
678   value_addto (val, val, k);
679
680   ppl_assign_Coefficient_from_mpz_t (coef, val);
681   ppl_Linear_Expression_add_to_coefficient (expr, d, coef);
682   value_clear (val);
683   ppl_delete_Coefficient (coef);
684 }
685
686 /* In the context of scop S, scan E, the right hand side of a scalar
687    evolution function in loop VAR, and translate it to a linear
688    expression EXPR.  */
689
690 static void
691 scan_tree_for_params_right_scev (sese s, tree e, int var,
692                                  ppl_Linear_Expression_t expr)
693 {
694   if (expr)
695     {
696       loop_p loop = get_loop (var);
697       ppl_dimension_type l = sese_loop_depth (s, loop) - 1;
698       Value val;
699
700       /* Scalar evolutions should happen in the sese region.  */
701       gcc_assert (sese_loop_depth (s, loop) > 0);
702
703       /* We can not deal with parametric strides like:
704
705       | p = parameter;
706       |
707       | for i:
708       |   a [i * p] = ...   */
709       gcc_assert (TREE_CODE (e) == INTEGER_CST);
710
711       value_init (val);
712       value_set_si (val, int_cst_value (e));
713       add_value_to_dim (l, expr, val);
714       value_clear (val);
715     }
716 }
717
718 /* Scan the integer constant CST, and add it to the inhomogeneous part of the
719    linear expression EXPR.  K is the multiplier of the constant.  */
720
721 static void
722 scan_tree_for_params_int (tree cst, ppl_Linear_Expression_t expr, Value k)
723 {
724   Value val;
725   ppl_Coefficient_t coef;
726   int v = int_cst_value (cst);
727
728   value_init (val);
729   value_set_si (val, 0);
730
731   /* Necessary to not get "-1 = 2^n - 1". */
732   if (v < 0)
733     value_sub_int (val, val, -v);
734   else
735     value_add_int (val, val, v);
736
737   value_multiply (val, val, k);
738   ppl_new_Coefficient (&coef);
739   ppl_assign_Coefficient_from_mpz_t (coef, val);
740   ppl_Linear_Expression_add_to_inhomogeneous (expr, coef);
741   value_clear (val);
742   ppl_delete_Coefficient (coef);
743 }
744
745 /* Saves in NV at index I a new name for variable P.  */
746
747 static void
748 save_var_name (char **nv, int i, tree p)
749 {
750   const char *name = get_name (SSA_NAME_VAR (p));
751
752   if (name)
753     {
754       int len = strlen (name) + 16;
755       nv[i] = XNEWVEC (char, len);
756       snprintf (nv[i], len, "%s_%d", name, SSA_NAME_VERSION (p));
757     }
758   else
759     {
760       nv[i] = XNEWVEC (char, 16);
761       snprintf (nv[i], 2 + 16, "T_%d", SSA_NAME_VERSION (p));
762     }
763 }
764
765 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
766    Otherwise returns -1.  */
767
768 static inline int
769 parameter_index_in_region_1 (tree name, sese region)
770 {
771   int i;
772   tree p;
773
774   gcc_assert (TREE_CODE (name) == SSA_NAME);
775
776   for (i = 0; VEC_iterate (tree, SESE_PARAMS (region), i, p); i++)
777     if (p == name)
778       return i;
779
780   return -1;
781 }
782
783 /* When the parameter NAME is in REGION, returns its index in
784    SESE_PARAMS.  Otherwise this function inserts NAME in SESE_PARAMS
785    and returns the index of NAME.  */
786
787 static int
788 parameter_index_in_region (tree name, sese region)
789 {
790   int i;
791
792   gcc_assert (TREE_CODE (name) == SSA_NAME);
793
794   i = parameter_index_in_region_1 (name, region);
795   if (i != -1)
796     return i;
797
798   gcc_assert (SESE_ADD_PARAMS (region));
799
800   i = VEC_length (tree, SESE_PARAMS (region));
801   save_var_name (SESE_PARAMS_NAMES (region), i, name);
802   save_clast_name_index (SESE_PARAMS_INDEX (region),
803                          SESE_PARAMS_NAMES (region)[i], i);
804   VEC_safe_push (tree, heap, SESE_PARAMS (region), name);
805   return i;
806 }
807
808 /* In the context of sese S, scan the expression E and translate it to
809    a linear expression C.  When parsing a symbolic multiplication, K
810    represents the constant multiplier of an expression containing
811    parameters.  */
812
813 static void
814 scan_tree_for_params (sese s, tree e, ppl_Linear_Expression_t c,
815                       Value k)
816 {
817   if (e == chrec_dont_know)
818     return;
819
820   switch (TREE_CODE (e))
821     {
822     case POLYNOMIAL_CHREC:
823       scan_tree_for_params_right_scev (s, CHREC_RIGHT (e),
824                                        CHREC_VARIABLE (e), c);
825       scan_tree_for_params (s, CHREC_LEFT (e), c, k);
826       break;
827
828     case MULT_EXPR:
829       if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
830         {
831           if (c)
832             {
833               Value val;
834               gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0));
835               value_init (val);
836               value_set_si (val, int_cst_value (TREE_OPERAND (e, 1)));
837               value_multiply (val, val, k);
838               scan_tree_for_params (s, TREE_OPERAND (e, 0), c, val);
839               value_clear (val);
840             }
841           else
842             scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
843         }
844       else
845         {
846           if (c)
847             {
848               Value val;
849               gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0));
850               value_init (val);
851               value_set_si (val, int_cst_value (TREE_OPERAND (e, 0)));
852               value_multiply (val, val, k);
853               scan_tree_for_params (s, TREE_OPERAND (e, 1), c, val);
854               value_clear (val);
855             }
856           else
857             scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k);
858         }
859       break;
860
861     case PLUS_EXPR:
862     case POINTER_PLUS_EXPR:
863       scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
864       scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k);
865       break;
866
867     case MINUS_EXPR:
868       {
869         ppl_Linear_Expression_t tmp_expr = NULL;
870
871         if (c)
872           {
873             ppl_dimension_type dim;
874             ppl_Linear_Expression_space_dimension (c, &dim);
875             ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
876           }
877
878         scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
879         scan_tree_for_params (s, TREE_OPERAND (e, 1), 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 NEGATE_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_subtract_Linear_Expression_from_Linear_Expression (c,
907                                                                    tmp_expr);
908             ppl_delete_Linear_Expression (tmp_expr);
909           }
910
911         break;
912       }
913
914     case BIT_NOT_EXPR:
915       {
916         ppl_Linear_Expression_t tmp_expr = NULL;
917
918         if (c)
919           {
920             ppl_dimension_type dim;
921             ppl_Linear_Expression_space_dimension (c, &dim);
922             ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
923           }
924
925         scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k);
926
927         if (c)
928           {
929             ppl_Coefficient_t coef;
930             Value minus_one;
931
932             ppl_subtract_Linear_Expression_from_Linear_Expression (c,
933                                                                    tmp_expr);
934             ppl_delete_Linear_Expression (tmp_expr);
935             value_init (minus_one);
936             value_set_si (minus_one, -1);
937             ppl_new_Coefficient_from_mpz_t (&coef, minus_one);
938             ppl_Linear_Expression_add_to_inhomogeneous (c, coef);
939             value_clear (minus_one);
940             ppl_delete_Coefficient (coef);
941           }
942
943         break;
944       }
945
946     case SSA_NAME:
947       {
948         ppl_dimension_type p = parameter_index_in_region (e, s);
949
950         if (c)
951           {
952             ppl_dimension_type dim;
953             ppl_Linear_Expression_space_dimension (c, &dim);
954             p += dim - sese_nb_params (s);
955             add_value_to_dim (p, c, k);
956           }
957         break;
958       }
959
960     case INTEGER_CST:
961       if (c)
962         scan_tree_for_params_int (e, c, k);
963       break;
964
965     CASE_CONVERT:
966     case NON_LVALUE_EXPR:
967       scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
968       break;
969
970    default:
971       gcc_unreachable ();
972       break;
973     }
974 }
975
976 /* Find parameters with respect to REGION in BB. We are looking in memory
977    access functions, conditions and loop bounds.  */
978
979 static void
980 find_params_in_bb (sese region, gimple_bb_p gbb)
981 {
982   int i;
983   unsigned j;
984   data_reference_p dr;
985   gimple stmt;
986   loop_p loop = GBB_BB (gbb)->loop_father;
987   Value one;
988
989   value_init (one);
990   value_set_si (one, 1);
991
992   /* Find parameters in the access functions of data references.  */
993   for (i = 0; VEC_iterate (data_reference_p, GBB_DATA_REFS (gbb), i, dr); i++)
994     for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
995       scan_tree_for_params (region, DR_ACCESS_FN (dr, j), NULL, one);
996
997   /* Find parameters in conditional statements.  */
998   for (i = 0; VEC_iterate (gimple, GBB_CONDITIONS (gbb), i, stmt); i++)
999     {
1000       tree lhs = scalar_evolution_in_region (region, loop,
1001                                              gimple_cond_lhs (stmt));
1002       tree rhs = scalar_evolution_in_region (region, loop,
1003                                              gimple_cond_rhs (stmt));
1004
1005       scan_tree_for_params (region, lhs, NULL, one);
1006       scan_tree_for_params (region, rhs, NULL, one);
1007     }
1008
1009   value_clear (one);
1010 }
1011
1012 /* Record the parameters used in the SCOP.  A variable is a parameter
1013    in a scop if it does not vary during the execution of that scop.  */
1014
1015 static void
1016 find_scop_parameters (scop_p scop)
1017 {
1018   poly_bb_p pbb;
1019   unsigned i;
1020   sese region = SCOP_REGION (scop);
1021   struct loop *loop;
1022   Value one;
1023
1024   value_init (one);
1025   value_set_si (one, 1);
1026
1027   /* Find the parameters used in the loop bounds.  */
1028   for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1029     {
1030       tree nb_iters = number_of_latch_executions (loop);
1031
1032       if (!chrec_contains_symbols (nb_iters))
1033         continue;
1034
1035       nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1036       scan_tree_for_params (region, nb_iters, NULL, one);
1037     }
1038
1039   value_clear (one);
1040
1041   /* Find the parameters used in data accesses.  */
1042   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1043     find_params_in_bb (region, PBB_BLACK_BOX (pbb));
1044
1045   scop_set_nb_params (scop, sese_nb_params (region));
1046   SESE_ADD_PARAMS (region) = false;
1047 }
1048
1049 /* Returns a gimple_bb from BB.  */
1050
1051 static inline gimple_bb_p
1052 gbb_from_bb (basic_block bb)
1053 {
1054   return (gimple_bb_p) bb->aux;
1055 }
1056
1057 /* Builds the constraint polyhedra for LOOP in SCOP.  OUTER_PH gives
1058    the constraints for the surrounding loops.  */
1059
1060 static void
1061 build_loop_iteration_domains (scop_p scop, struct loop *loop,
1062                               ppl_Polyhedron_t outer_ph, int nb)
1063 {
1064   int i;
1065   ppl_Polyhedron_t ph;
1066   tree nb_iters = number_of_latch_executions (loop);
1067   ppl_dimension_type dim = nb + 1 + scop_nb_params (scop);
1068   sese region = SCOP_REGION (scop);
1069
1070   {
1071     ppl_const_Constraint_System_t pcs;
1072     ppl_dimension_type *map
1073       = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim);
1074
1075     ppl_new_C_Polyhedron_from_space_dimension (&ph, dim, 0);
1076     ppl_Polyhedron_get_constraints (outer_ph, &pcs);
1077     ppl_Polyhedron_add_constraints (ph, pcs);
1078
1079     for (i = 0; i < (int) nb; i++)
1080       map[i] = i;
1081     for (i = (int) nb; i < (int) dim - 1; i++)
1082       map[i] = i + 1;
1083     map[dim - 1] = nb;
1084
1085     ppl_Polyhedron_map_space_dimensions (ph, map, dim);
1086     free (map);
1087   }
1088
1089   /* 0 <= loop_i */
1090   {
1091     ppl_Constraint_t lb;
1092     ppl_Linear_Expression_t lb_expr;
1093
1094     ppl_new_Linear_Expression_with_dimension (&lb_expr, dim);
1095     ppl_set_coef (lb_expr, nb, 1);
1096     ppl_new_Constraint (&lb, lb_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1097     ppl_delete_Linear_Expression (lb_expr);
1098     ppl_Polyhedron_add_constraint (ph, lb);
1099     ppl_delete_Constraint (lb);
1100   }
1101
1102   if (TREE_CODE (nb_iters) == INTEGER_CST)
1103     {
1104       ppl_Constraint_t ub;
1105       ppl_Linear_Expression_t ub_expr;
1106
1107       ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1108
1109       /* loop_i <= cst_nb_iters */
1110       ppl_set_coef (ub_expr, nb, -1);
1111       ppl_set_inhomogeneous_tree (ub_expr, nb_iters);
1112       ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1113       ppl_Polyhedron_add_constraint (ph, ub);
1114       ppl_delete_Linear_Expression (ub_expr);
1115       ppl_delete_Constraint (ub);
1116     }
1117   else if (!chrec_contains_undetermined (nb_iters))
1118     {
1119       Value one;
1120       ppl_Constraint_t ub;
1121       ppl_Linear_Expression_t ub_expr;
1122
1123       value_init (one);
1124       value_set_si (one, 1);
1125       ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1126       nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1127       scan_tree_for_params (SCOP_REGION (scop), nb_iters, ub_expr, one);
1128       value_clear (one);
1129
1130       /* loop_i <= expr_nb_iters */
1131       ppl_set_coef (ub_expr, nb, -1);
1132       ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1133       ppl_Polyhedron_add_constraint (ph, ub);
1134       ppl_delete_Linear_Expression (ub_expr);
1135       ppl_delete_Constraint (ub);
1136     }
1137   else
1138     gcc_unreachable ();
1139
1140   if (loop->inner && loop_in_sese_p (loop->inner, region))
1141     build_loop_iteration_domains (scop, loop->inner, ph, nb + 1);
1142
1143   if (nb != 0
1144       && loop->next
1145       && loop_in_sese_p (loop->next, region))
1146     build_loop_iteration_domains (scop, loop->next, outer_ph, nb);
1147
1148   ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1149     ((ppl_Pointset_Powerset_C_Polyhedron_t *) &loop->aux, ph);
1150
1151   ppl_delete_Polyhedron (ph);
1152 }
1153
1154 /* Returns a linear expression for tree T evaluated in PBB.  */
1155
1156 static ppl_Linear_Expression_t
1157 create_linear_expr_from_tree (poly_bb_p pbb, tree t)
1158 {
1159   Value one;
1160   ppl_Linear_Expression_t res;
1161   ppl_dimension_type dim;
1162   sese region = SCOP_REGION (PBB_SCOP (pbb));
1163   loop_p loop = pbb_loop (pbb);
1164
1165   dim = pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb);
1166   ppl_new_Linear_Expression_with_dimension (&res, dim);
1167
1168   t = scalar_evolution_in_region (region, loop, t);
1169   gcc_assert (!automatically_generated_chrec_p (t));
1170
1171   value_init (one);
1172   value_set_si (one, 1);
1173   scan_tree_for_params (region, t, res, one);
1174   value_clear (one);
1175
1176   return res;
1177 }
1178
1179 /* Returns the ppl constraint type from the gimple tree code CODE.  */
1180
1181 static enum ppl_enum_Constraint_Type
1182 ppl_constraint_type_from_tree_code (enum tree_code code)
1183 {
1184   switch (code)
1185     {
1186     /* We do not support LT and GT to be able to work with C_Polyhedron.
1187        As we work on integer polyhedron "a < b" can be expressed by
1188        "a + 1 <= b".  */
1189     case LT_EXPR:
1190     case GT_EXPR:
1191       gcc_unreachable ();
1192
1193     case LE_EXPR:
1194       return PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL;
1195
1196     case GE_EXPR:
1197       return PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL;
1198
1199     case EQ_EXPR:
1200       return PPL_CONSTRAINT_TYPE_EQUAL;
1201
1202     default:
1203       gcc_unreachable ();
1204     }
1205 }
1206
1207 /* Add conditional statement STMT to PS.  It is evaluated in PBB and
1208    CODE is used as the comparison operator.  This allows us to invert the
1209    condition or to handle inequalities.  */
1210
1211 static void
1212 add_condition_to_domain (ppl_Pointset_Powerset_C_Polyhedron_t ps, gimple stmt,
1213                          poly_bb_p pbb, enum tree_code code)
1214 {
1215   Value v;
1216   ppl_Coefficient_t c;
1217   ppl_Linear_Expression_t left, right;
1218   ppl_Constraint_t cstr;
1219   enum ppl_enum_Constraint_Type type;
1220
1221   left = create_linear_expr_from_tree (pbb, gimple_cond_lhs (stmt));
1222   right = create_linear_expr_from_tree (pbb, gimple_cond_rhs (stmt));
1223
1224   /* If we have < or > expressions convert them to <= or >= by adding 1 to
1225      the left or the right side of the expression. */
1226   if (code == LT_EXPR)
1227     {
1228       value_init (v);
1229       value_set_si (v, 1);
1230       ppl_new_Coefficient (&c);
1231       ppl_assign_Coefficient_from_mpz_t (c, v);
1232       ppl_Linear_Expression_add_to_inhomogeneous (left, c);
1233       ppl_delete_Coefficient (c);
1234       value_clear (v);
1235
1236       code = LE_EXPR;
1237     }
1238   else if (code == GT_EXPR)
1239     {
1240       value_init (v);
1241       value_set_si (v, 1);
1242       ppl_new_Coefficient (&c);
1243       ppl_assign_Coefficient_from_mpz_t (c, v);
1244       ppl_Linear_Expression_add_to_inhomogeneous (right, c);
1245       ppl_delete_Coefficient (c);
1246       value_clear (v);
1247
1248       code = GE_EXPR;
1249     }
1250
1251   type = ppl_constraint_type_from_tree_code (code);
1252
1253   ppl_subtract_Linear_Expression_from_Linear_Expression (left, right);
1254
1255   ppl_new_Constraint (&cstr, left, type);
1256   ppl_Pointset_Powerset_C_Polyhedron_add_constraint (ps, cstr);
1257
1258   ppl_delete_Constraint (cstr);
1259   ppl_delete_Linear_Expression (left);
1260   ppl_delete_Linear_Expression (right);
1261 }
1262
1263 /* Add conditional statement STMT to pbb.  CODE is used as the comparision
1264    operator.  This allows us to invert the condition or to handle
1265    inequalities.  */
1266
1267 static void
1268 add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code)
1269 {
1270   if (code == NE_EXPR)
1271     {
1272       ppl_Pointset_Powerset_C_Polyhedron_t left = PBB_DOMAIN (pbb);
1273       ppl_Pointset_Powerset_C_Polyhedron_t right;
1274       ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1275         (&right, left);
1276       add_condition_to_domain (left, stmt, pbb, LT_EXPR);
1277       add_condition_to_domain (right, stmt, pbb, GT_EXPR);
1278       ppl_Pointset_Powerset_C_Polyhedron_upper_bound_assign (left,
1279                                                                right);
1280       ppl_delete_Pointset_Powerset_C_Polyhedron (right);
1281     }
1282   else
1283     add_condition_to_domain (PBB_DOMAIN (pbb), stmt, pbb, code);
1284 }
1285
1286 /* Add conditions to the domain of PBB.  */
1287
1288 static void
1289 add_conditions_to_domain (poly_bb_p pbb)
1290 {
1291   unsigned int i;
1292   gimple stmt;
1293   gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1294   VEC (gimple, heap) *conditions = GBB_CONDITIONS (gbb);
1295
1296   if (VEC_empty (gimple, conditions))
1297     return;
1298
1299   for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
1300     switch (gimple_code (stmt))
1301       {
1302       case GIMPLE_COND:
1303           {
1304             enum tree_code code = gimple_cond_code (stmt);
1305
1306             /* The conditions for ELSE-branches are inverted.  */
1307             if (VEC_index (gimple, gbb->condition_cases, i) == NULL)
1308               code = invert_tree_comparison (code, false);
1309
1310             add_condition_to_pbb (pbb, stmt, code);
1311             break;
1312           }
1313
1314       case GIMPLE_SWITCH:
1315         /* Switch statements are not supported right now - fall throught.  */
1316
1317       default:
1318         gcc_unreachable ();
1319         break;
1320       }
1321 }
1322
1323 /* Structure used to pass data to dom_walk.  */
1324
1325 struct bsc
1326 {
1327   VEC (gimple, heap) **conditions, **cases;
1328   sese region;
1329 };
1330
1331 /* Returns non NULL when BB has a single predecessor and the last
1332    statement of that predecessor is a COND_EXPR.  */
1333
1334 static gimple
1335 single_pred_cond (basic_block bb)
1336 {
1337   if (single_pred_p (bb))
1338     {
1339       edge e = single_pred_edge (bb);
1340       basic_block pred = e->src;
1341       gimple stmt = last_stmt (pred);
1342
1343       if (stmt && gimple_code (stmt) == GIMPLE_COND)
1344         return stmt;
1345     }
1346   return NULL;
1347 }
1348
1349 /* Call-back for dom_walk executed before visiting the dominated
1350    blocks.  */
1351
1352 static void
1353 build_sese_conditions_before (struct dom_walk_data *dw_data,
1354                               basic_block bb)
1355 {
1356   struct bsc *data = (struct bsc *) dw_data->global_data;
1357   VEC (gimple, heap) **conditions = data->conditions;
1358   VEC (gimple, heap) **cases = data->cases;
1359   gimple_bb_p gbb = gbb_from_bb (bb);
1360   gimple stmt = single_pred_cond (bb);
1361
1362   if (!bb_in_sese_p (bb, data->region))
1363     return;
1364
1365   if (stmt)
1366     {
1367       edge e = single_pred_edge (bb);
1368
1369       VEC_safe_push (gimple, heap, *conditions, stmt);
1370
1371       if (e->flags & EDGE_TRUE_VALUE)
1372         VEC_safe_push (gimple, heap, *cases, stmt);
1373       else
1374         VEC_safe_push (gimple, heap, *cases, NULL);
1375     }
1376
1377   if (gbb)
1378     {
1379       GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
1380       GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
1381     }
1382 }
1383
1384 /* Call-back for dom_walk executed after visiting the dominated
1385    blocks.  */
1386
1387 static void
1388 build_sese_conditions_after (struct dom_walk_data *dw_data,
1389                              basic_block bb)
1390 {
1391   struct bsc *data = (struct bsc *) dw_data->global_data;
1392   VEC (gimple, heap) **conditions = data->conditions;
1393   VEC (gimple, heap) **cases = data->cases;
1394
1395   if (!bb_in_sese_p (bb, data->region))
1396     return;
1397
1398   if (single_pred_cond (bb))
1399     {
1400       VEC_pop (gimple, *conditions);
1401       VEC_pop (gimple, *cases);
1402     }
1403 }
1404
1405 /* Record all conditions in REGION.  */
1406
1407 static void
1408 build_sese_conditions (sese region)
1409 {
1410   struct dom_walk_data walk_data;
1411   VEC (gimple, heap) *conditions = VEC_alloc (gimple, heap, 3);
1412   VEC (gimple, heap) *cases = VEC_alloc (gimple, heap, 3);
1413   struct bsc data;
1414
1415   data.conditions = &conditions;
1416   data.cases = &cases;
1417   data.region = region;
1418
1419   walk_data.dom_direction = CDI_DOMINATORS;
1420   walk_data.initialize_block_local_data = NULL;
1421   walk_data.before_dom_children = build_sese_conditions_before;
1422   walk_data.after_dom_children = build_sese_conditions_after;
1423   walk_data.global_data = &data;
1424   walk_data.block_local_data_size = 0;
1425
1426   init_walk_dominator_tree (&walk_data);
1427   walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region));
1428   fini_walk_dominator_tree (&walk_data);
1429
1430   VEC_free (gimple, heap, conditions);
1431   VEC_free (gimple, heap, cases);
1432 }
1433
1434 /* Traverses all the GBBs of the SCOP and add their constraints to the
1435    iteration domains.  */
1436
1437 static void
1438 add_conditions_to_constraints (scop_p scop)
1439 {
1440   int i;
1441   poly_bb_p pbb;
1442
1443   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1444     add_conditions_to_domain (pbb);
1445 }
1446
1447 /* Add constraints on the possible values of parameter P from the type
1448    of P.  */
1449
1450 static void
1451 add_param_constraints (scop_p scop, ppl_Polyhedron_t context, graphite_dim_t p)
1452 {
1453   ppl_Constraint_t cstr;
1454   ppl_Linear_Expression_t le;
1455   tree parameter = VEC_index (tree, SESE_PARAMS (SCOP_REGION (scop)), p);
1456   tree type = TREE_TYPE (parameter);
1457   tree lb, ub;
1458
1459   /* Disabled until we fix CPU2006.  */
1460   return;
1461
1462   if (!INTEGRAL_TYPE_P (type))
1463     return;
1464
1465   lb = TYPE_MIN_VALUE (type);
1466   ub = TYPE_MAX_VALUE (type);
1467
1468   if (lb)
1469     {
1470       ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1471       ppl_set_coef (le, p, -1);
1472       ppl_set_inhomogeneous_tree (le, lb);
1473       ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL);
1474       ppl_Polyhedron_add_constraint (context, cstr);
1475       ppl_delete_Linear_Expression (le);
1476       ppl_delete_Constraint (cstr);
1477     }
1478
1479   if (ub)
1480     {
1481       ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1482       ppl_set_coef (le, p, -1);
1483       ppl_set_inhomogeneous_tree (le, ub);
1484       ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1485       ppl_Polyhedron_add_constraint (context, cstr);
1486       ppl_delete_Linear_Expression (le);
1487       ppl_delete_Constraint (cstr);
1488     }
1489 }
1490
1491 /* Build the context of the SCOP.  The context usually contains extra
1492    constraints that are added to the iteration domains that constrain
1493    some parameters.  */
1494
1495 static void
1496 build_scop_context (scop_p scop)
1497 {
1498   ppl_Polyhedron_t context;
1499   graphite_dim_t p, n = scop_nb_params (scop);
1500
1501   ppl_new_C_Polyhedron_from_space_dimension (&context, n, 0);
1502
1503   for (p = 0; p < n; p++)
1504     add_param_constraints (scop, context, p);
1505
1506   ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1507     (&SCOP_CONTEXT (scop), context);
1508
1509   ppl_delete_Polyhedron (context);
1510 }
1511
1512 /* Build the iteration domains: the loops belonging to the current
1513    SCOP, and that vary for the execution of the current basic block.
1514    Returns false if there is no loop in SCOP.  */
1515
1516 static void
1517 build_scop_iteration_domain (scop_p scop)
1518 {
1519   struct loop *loop;
1520   sese region = SCOP_REGION (scop);
1521   int i;
1522   ppl_Polyhedron_t ph;
1523   poly_bb_p pbb;
1524
1525   ppl_new_C_Polyhedron_from_space_dimension (&ph, scop_nb_params (scop), 0);
1526
1527   for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1528     if (!loop_in_sese_p (loop_outer (loop), region))
1529       build_loop_iteration_domains (scop, loop, ph, 0);
1530
1531   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1532     if (gbb_loop (PBB_BLACK_BOX (pbb))->aux)
1533       ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1534         (&PBB_DOMAIN (pbb), (ppl_const_Pointset_Powerset_C_Polyhedron_t)
1535          gbb_loop (PBB_BLACK_BOX (pbb))->aux);
1536     else
1537       ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1538         (&PBB_DOMAIN (pbb), ph);
1539
1540   for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1541     if (loop->aux)
1542       {
1543         ppl_delete_Pointset_Powerset_C_Polyhedron
1544           ((ppl_Pointset_Powerset_C_Polyhedron_t) loop->aux);
1545         loop->aux = NULL;
1546       }
1547
1548   ppl_delete_Polyhedron (ph);
1549 }
1550
1551 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1552    data reference DR.  ACCESSP_NB_DIMS is the dimension of the
1553    ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1554    domain.  */
1555
1556 static void
1557 pdr_add_alias_set (ppl_Polyhedron_t accesses, data_reference_p dr,
1558                    ppl_dimension_type accessp_nb_dims,
1559                    ppl_dimension_type dom_nb_dims)
1560 {
1561   ppl_Linear_Expression_t alias;
1562   ppl_Constraint_t cstr;
1563   int alias_set_num = 0;
1564
1565   if (dr->aux != NULL)
1566     alias_set_num = ((int *)(dr->aux))[ALIAS_SET_INDEX];
1567
1568   ppl_new_Linear_Expression_with_dimension (&alias, accessp_nb_dims);
1569
1570   ppl_set_coef (alias, dom_nb_dims, 1);
1571   ppl_set_inhomogeneous (alias, -alias_set_num);
1572   ppl_new_Constraint (&cstr, alias, PPL_CONSTRAINT_TYPE_EQUAL);
1573   ppl_Polyhedron_add_constraint (accesses, cstr);
1574
1575   ppl_delete_Linear_Expression (alias);
1576   ppl_delete_Constraint (cstr);
1577 }
1578
1579 /* Add to ACCESSES polyhedron equalities defining the access functions
1580    to the memory.  ACCESSP_NB_DIMS is the dimension of the ACCESSES
1581    polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1582    PBB is the poly_bb_p that contains the data reference DR.  */
1583
1584 static void
1585 pdr_add_memory_accesses (ppl_Polyhedron_t accesses, data_reference_p dr,
1586                          ppl_dimension_type accessp_nb_dims,
1587                          ppl_dimension_type dom_nb_dims,
1588                          poly_bb_p pbb)
1589 {
1590   int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1591   Value v;
1592   scop_p scop = PBB_SCOP (pbb);
1593   sese region = SCOP_REGION (scop);
1594
1595   value_init (v);
1596
1597   for (i = 0; i < nb_subscripts; i++)
1598     {
1599       ppl_Linear_Expression_t fn, access;
1600       ppl_Constraint_t cstr;
1601       ppl_dimension_type subscript = dom_nb_dims + 1 + i;
1602       tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1603
1604       ppl_new_Linear_Expression_with_dimension (&fn, dom_nb_dims);
1605       ppl_new_Linear_Expression_with_dimension (&access, accessp_nb_dims);
1606
1607       value_set_si (v, 1);
1608       scan_tree_for_params (region, afn, fn, v);
1609       ppl_assign_Linear_Expression_from_Linear_Expression (access, fn);
1610
1611       ppl_set_coef (access, subscript, -1);
1612       ppl_new_Constraint (&cstr, access, PPL_CONSTRAINT_TYPE_EQUAL);
1613       ppl_Polyhedron_add_constraint (accesses, cstr);
1614
1615       ppl_delete_Linear_Expression (fn);
1616       ppl_delete_Linear_Expression (access);
1617       ppl_delete_Constraint (cstr);
1618     }
1619
1620   value_clear (v);
1621 }
1622
1623 /* Add constrains representing the size of the accessed data to the
1624    ACCESSES polyhedron.  ACCESSP_NB_DIMS is the dimension of the
1625    ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1626    domain.  */
1627
1628 static void
1629 pdr_add_data_dimensions (ppl_Polyhedron_t accesses, data_reference_p dr,
1630                          ppl_dimension_type accessp_nb_dims,
1631                          ppl_dimension_type dom_nb_dims)
1632 {
1633   tree ref = DR_REF (dr);
1634   int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1635
1636   for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1637     {
1638       ppl_Linear_Expression_t expr;
1639       ppl_Constraint_t cstr;
1640       ppl_dimension_type subscript = dom_nb_dims + 1 + i;
1641       tree low, high;
1642
1643       if (TREE_CODE (ref) != ARRAY_REF)
1644         break;
1645
1646       low = array_ref_low_bound (ref);
1647
1648       /* subscript - low >= 0 */
1649       if (host_integerp (low, 0))
1650         {
1651           ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1652           ppl_set_coef (expr, subscript, 1);
1653
1654           ppl_set_inhomogeneous (expr, -int_cst_value (low));
1655
1656           ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1657           ppl_Polyhedron_add_constraint (accesses, cstr);
1658           ppl_delete_Linear_Expression (expr);
1659           ppl_delete_Constraint (cstr);
1660         }
1661
1662       high = array_ref_up_bound (ref);
1663
1664       /* high - subscript >= 0
1665          XXX: 1-element arrays at end of structures may extend over their
1666          declared size.  */
1667       if (high && host_integerp (high, 0))
1668         {
1669           ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1670           ppl_set_coef (expr, subscript, -1);
1671
1672           ppl_set_inhomogeneous (expr, int_cst_value (high));
1673
1674           ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1675           ppl_Polyhedron_add_constraint (accesses, cstr);
1676           ppl_delete_Linear_Expression (expr);
1677           ppl_delete_Constraint (cstr);
1678         }
1679     }
1680 }
1681
1682 /* Build data accesses for DR in PBB.  */
1683
1684 static void
1685 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1686 {
1687   ppl_Polyhedron_t accesses;
1688   ppl_Pointset_Powerset_C_Polyhedron_t accesses_ps;
1689   ppl_dimension_type dom_nb_dims;
1690   ppl_dimension_type accessp_nb_dims;
1691   int dr_base_object_set;
1692
1693   ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PBB_DOMAIN (pbb),
1694                                                       &dom_nb_dims);
1695   accessp_nb_dims = dom_nb_dims + 1 + DR_NUM_DIMENSIONS (dr);
1696
1697   ppl_new_C_Polyhedron_from_space_dimension (&accesses, accessp_nb_dims, 0);
1698
1699   pdr_add_alias_set (accesses, dr, accessp_nb_dims, dom_nb_dims);
1700   pdr_add_memory_accesses (accesses, dr, accessp_nb_dims, dom_nb_dims, pbb);
1701   pdr_add_data_dimensions (accesses, dr, accessp_nb_dims, dom_nb_dims);
1702
1703   ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&accesses_ps,
1704                                                             accesses);
1705   ppl_delete_Polyhedron (accesses);
1706
1707   dr_base_object_set = ((int *)(dr->aux))[BASE_OBJECT_SET_INDEX];
1708
1709   new_poly_dr (pbb, dr_base_object_set, accesses_ps, DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1710                dr, DR_NUM_DIMENSIONS (dr));
1711 }
1712
1713 /* Write to FILE the alias graph of data references in DIMACS format.  */
1714
1715 static inline bool
1716 write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
1717                                    VEC (data_reference_p, heap) *drs)
1718 {
1719   int num_vertex = VEC_length (data_reference_p, drs);
1720   int edge_num = 0;
1721   data_reference_p dr1, dr2;
1722   int i, j;
1723
1724   if (num_vertex == 0)
1725     return true;
1726
1727   for (i = 0; VEC_iterate (data_reference_p, drs, i, dr1); i++)
1728     for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1729       if (dr_may_alias_p (dr1, dr2))
1730         edge_num++;
1731
1732   fprintf (file, "$\n");
1733
1734   if (comment)
1735     fprintf (file, "c %s\n", comment);
1736
1737   fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1738
1739   for (i = 0; VEC_iterate (data_reference_p, drs, i, dr1); i++)
1740     for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1741       if (dr_may_alias_p (dr1, dr2))
1742         fprintf (file, "e %d %d\n", i + 1, j + 1);
1743
1744   return true;
1745 }
1746
1747 /* Write to FILE the alias graph of data references in DOT format.  */
1748
1749 static inline bool
1750 write_alias_graph_to_ascii_dot (FILE *file, char *comment,
1751                                 VEC (data_reference_p, heap) *drs)
1752 {
1753   int num_vertex = VEC_length (data_reference_p, drs);
1754   data_reference_p dr1, dr2;
1755   int i, j;
1756
1757   if (num_vertex == 0)
1758     return true;
1759
1760   fprintf (file, "$\n");
1761
1762   if (comment)
1763     fprintf (file, "c %s\n", comment);
1764
1765   /* First print all the vertices.  */
1766   for (i = 0; VEC_iterate (data_reference_p, drs, i, dr1); i++)
1767     fprintf (file, "n%d;\n", i);
1768
1769   for (i = 0; VEC_iterate (data_reference_p, drs, i, dr1); i++)
1770     for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1771       if (dr_may_alias_p (dr1, dr2))
1772         fprintf (file, "n%d n%d\n", i, j);
1773
1774   return true;
1775 }
1776
1777 /* Write to FILE the alias graph of data references in ECC format.  */
1778
1779 static inline bool
1780 write_alias_graph_to_ascii_ecc (FILE *file, char *comment,
1781                                 VEC (data_reference_p, heap) *drs)
1782 {
1783   int num_vertex = VEC_length (data_reference_p, drs);
1784   data_reference_p dr1, dr2;
1785   int i, j;
1786
1787   if (num_vertex == 0)
1788     return true;
1789
1790   fprintf (file, "$\n");
1791
1792   if (comment)
1793     fprintf (file, "c %s\n", comment);
1794
1795   for (i = 0; VEC_iterate (data_reference_p, drs, i, dr1); i++)
1796     for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1797       if (dr_may_alias_p (dr1, dr2))
1798         fprintf (file, "%d %d\n", i, j);
1799
1800   return true;
1801 }
1802
1803
1804 /* Uses DFS component number as representative of alias-sets. Also tests for
1805    optimality by verifying if every connected component is a clique. Returns
1806    true (1) if the above test is true, and false (0) otherwise.  */
1807
1808 static int
1809 partition_drs_to_sets (VEC (data_reference_p, heap) *drs, int choice,
1810                        bool (* edge_exist_p) (const struct data_reference *,
1811                                               const struct data_reference *))
1812 {
1813
1814   int num_vertices = VEC_length (data_reference_p, drs);
1815   struct graph *g = new_graph (num_vertices);
1816   data_reference_p dr1, dr2;
1817   int i, j;
1818   int num_connected_components;
1819   int v_indx1, v_indx2, num_vertices_in_component;
1820   int *all_vertices;
1821   int *vertices;
1822   struct graph_edge *e;
1823   int this_component_is_clique, all_components_are_cliques;
1824
1825   for (i = 0; VEC_iterate (data_reference_p, drs, i, dr1); i++)
1826     for (j = i+1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1827       if (edge_exist_p (dr1, dr2))
1828         {
1829           add_edge (g, i, j);
1830           add_edge (g, j, i);
1831         }
1832
1833   all_vertices = XNEWVEC (int, num_vertices);
1834   vertices = XNEWVEC (int, num_vertices);
1835   for (i = 0; i < num_vertices; i++)
1836     all_vertices[i] = i;
1837
1838   num_connected_components = graphds_dfs (g, all_vertices, num_vertices, NULL, true, NULL);
1839
1840   /* Verify if the DFS numbering results in optimal solution.  */
1841   for (i = 0; i < num_connected_components; i++)
1842     {
1843       num_vertices_in_component = 0;
1844       /* Get all vertices whose DFS component number is the same as i.  */
1845       for (j = 0; j < num_vertices; j++)
1846         if (g->vertices[j].component == i)
1847           vertices[num_vertices_in_component++] = j;
1848
1849       /* Now test if the vertices in 'vertices' form a clique, by testing
1850          for edges among each pair.  */
1851       this_component_is_clique = 1;
1852       for (v_indx1 = 0; v_indx1 < num_vertices_in_component; v_indx1++)
1853         {
1854           for (v_indx2 = v_indx1+1; v_indx2 < num_vertices_in_component; v_indx2++)
1855             {
1856               /* Check if the two vertices are connected by iterating
1857                  through all the edges which have one of these are source.  */
1858               e = g->vertices[vertices[v_indx2]].pred;
1859               while (e)
1860                 {
1861                   if (e->src == vertices[v_indx1])
1862                     break;
1863                   e = e->pred_next;
1864                 }
1865               if (!e)
1866                 {
1867                   this_component_is_clique = 0;
1868                   break;
1869                 }
1870             }
1871           if (!this_component_is_clique)
1872             all_components_are_cliques = 0;
1873         }
1874     }
1875
1876   for (i = 0; i < g->n_vertices; i++)
1877     {
1878       data_reference_p dr = VEC_index (data_reference_p, drs, i);
1879       if (!dr->aux)
1880         dr->aux = XNEWVEC (int, 2);
1881       ((int *)(dr->aux))[choice] = g->vertices[i].component + 1;
1882     }
1883
1884   free (all_vertices);
1885   free (vertices);
1886   free_graph (g);
1887   return all_components_are_cliques;
1888 }
1889
1890 static bool
1891 dr_same_base_object_p (const struct data_reference *dr1,
1892                        const struct data_reference *dr2)
1893 {
1894   return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1895 }
1896
1897 /* Group each data reference in DRS with it's alias set num.  */
1898
1899 static void
1900 build_alias_set_for_drs (VEC (data_reference_p, heap) *drs)
1901 {
1902   partition_drs_to_sets (drs, ALIAS_SET_INDEX, dr_may_alias_p);
1903 }
1904
1905 /* Group each data reference in DRS with it's base object set num.  */
1906
1907 static void
1908 build_base_obj_set_for_drs (VEC (data_reference_p, heap) *drs)
1909 {
1910   partition_drs_to_sets (drs, BASE_OBJECT_SET_INDEX, dr_same_base_object_p);
1911 }
1912
1913 /* Build the data references for PBB.  */
1914
1915 static void
1916 build_pbb_drs (poly_bb_p pbb)
1917 {
1918   int j;
1919   data_reference_p dr;
1920   VEC (data_reference_p, heap) *gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1921
1922   for (j = 0; VEC_iterate (data_reference_p, gbb_drs, j, dr); j++)
1923     build_poly_dr (dr, pbb);
1924 }
1925
1926 /* Build data references in SCOP.  */
1927
1928 static void
1929 build_scop_drs (scop_p scop)
1930 {
1931   int i, j;
1932   poly_bb_p pbb;
1933   data_reference_p dr;
1934   VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
1935
1936   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1937     for (j = 0; VEC_iterate (data_reference_p,
1938                              GBB_DATA_REFS (PBB_BLACK_BOX (pbb)), j, dr); j++)
1939       VEC_safe_push (data_reference_p, heap, drs, dr);
1940
1941   build_alias_set_for_drs (drs);
1942   build_base_obj_set_for_drs (drs);
1943
1944   /* When debugging, enable the following code.  This cannot be used
1945      in production compilers.  */
1946 #if 0
1947   {
1948     char comment[100];
1949     FILE *file_dimacs, *file_ecc, *file_dot;
1950
1951     file_dimacs = fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1952     file_ecc = fopen ("/tmp/dr_alias_graph_ecc", "ab");
1953     file_dot = fopen ("/tmp/dr_alias_graph_dot", "ab");
1954     if (file_dimacs)
1955       {
1956         snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1957                   current_function_name ());
1958         write_alias_graph_to_ascii_dimacs (file_dimacs, comment, drs);
1959         fclose (file_dimacs);
1960       }
1961     if (file_ecc)
1962       {
1963         snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1964                   current_function_name ());
1965         write_alias_graph_to_ascii_ecc (file_ecc, comment, drs);
1966         fclose (file_ecc);
1967       }
1968     if (file_dot)
1969       {
1970         snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1971                   current_function_name ());
1972         write_alias_graph_to_ascii_dot (file_dot, comment, drs);
1973         fclose (file_dot);
1974       }
1975   }
1976 #endif
1977
1978   VEC_free (data_reference_p, heap, drs);
1979
1980   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1981     build_pbb_drs (pbb);
1982 }
1983
1984 /* Return a gsi at the position of the phi node STMT.  */
1985
1986 static gimple_stmt_iterator
1987 gsi_for_phi_node (gimple stmt)
1988 {
1989   gimple_stmt_iterator psi;
1990   basic_block bb = gimple_bb (stmt);
1991
1992   for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1993     if (stmt == gsi_stmt (psi))
1994       return psi;
1995
1996   gcc_unreachable ();
1997   return psi;
1998 }
1999
2000 /* Insert the assignment "RES := VAR" just after the definition of VAR.  */
2001
2002 static void
2003 insert_out_of_ssa_copy (tree res, tree var)
2004 {
2005   gimple stmt;
2006   gimple_seq stmts;
2007   gimple_stmt_iterator si;
2008   gimple_stmt_iterator gsi;
2009
2010   var = force_gimple_operand (var, &stmts, true, NULL_TREE);
2011   stmt = gimple_build_assign (res, var);
2012   if (!stmts)
2013     stmts = gimple_seq_alloc ();
2014   si = gsi_last (stmts);
2015   gsi_insert_after (&si, stmt, GSI_NEW_STMT);
2016
2017   stmt = SSA_NAME_DEF_STMT (var);
2018   if (gimple_code (stmt) == GIMPLE_PHI)
2019     {
2020       gsi = gsi_after_labels (gimple_bb (stmt));
2021       gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2022     }
2023   else
2024     {
2025       gsi = gsi_for_stmt (stmt);
2026       gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
2027     }
2028 }
2029
2030 /* Insert on edge E the assignment "RES := EXPR".  */
2031
2032 static void
2033 insert_out_of_ssa_copy_on_edge (edge e, tree res, tree expr)
2034 {
2035   gimple_stmt_iterator gsi;
2036   gimple_seq stmts;
2037   tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2038   gimple stmt = gimple_build_assign (res, var);
2039
2040   if (!stmts)
2041     stmts = gimple_seq_alloc ();
2042
2043   gsi = gsi_last (stmts);
2044   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
2045   gsi_insert_seq_on_edge (e, stmts);
2046   gsi_commit_edge_inserts ();
2047 }
2048
2049 /* Creates a zero dimension array of the same type as VAR.  */
2050
2051 static tree
2052 create_zero_dim_array (tree var)
2053 {
2054   tree index_type = build_index_type (integer_zero_node);
2055   tree elt_type = TREE_TYPE (var);
2056   tree array_type = build_array_type (elt_type, index_type);
2057   tree base = create_tmp_var (array_type, "Red");
2058
2059   add_referenced_var (base);
2060
2061   return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
2062                  NULL_TREE);
2063 }
2064
2065 /* Returns true when PHI is a loop close phi node.  */
2066
2067 static bool
2068 scalar_close_phi_node_p (gimple phi)
2069 {
2070   if (gimple_code (phi) != GIMPLE_PHI
2071       || !is_gimple_reg (gimple_phi_result (phi)))
2072     return false;
2073
2074   return (gimple_phi_num_args (phi) == 1);
2075 }
2076
2077 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2078    dimension array for it.  */
2079
2080 static void
2081 rewrite_close_phi_out_of_ssa (gimple_stmt_iterator *psi)
2082 {
2083   gimple phi = gsi_stmt (*psi);
2084   tree res = gimple_phi_result (phi);
2085   tree var = SSA_NAME_VAR (res);
2086   tree zero_dim_array = create_zero_dim_array (var);
2087   gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (phi));
2088   gimple stmt = gimple_build_assign (res, zero_dim_array);
2089   tree arg = gimple_phi_arg_def (phi, 0);
2090
2091   insert_out_of_ssa_copy (zero_dim_array, arg);
2092
2093   remove_phi_node (psi, false);
2094   gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2095   SSA_NAME_DEF_STMT (res) = stmt;
2096 }
2097
2098 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2099    dimension array for it.  */
2100
2101 static void
2102 rewrite_phi_out_of_ssa (gimple_stmt_iterator *psi)
2103 {
2104   size_t i;
2105   gimple phi = gsi_stmt (*psi);
2106   basic_block bb = gimple_bb (phi);
2107   tree res = gimple_phi_result (phi);
2108   tree var = SSA_NAME_VAR (res);
2109   tree zero_dim_array = create_zero_dim_array (var);
2110   gimple_stmt_iterator gsi;
2111   gimple stmt;
2112   gimple_seq stmts;
2113
2114   for (i = 0; i < gimple_phi_num_args (phi); i++)
2115     {
2116       tree arg = gimple_phi_arg_def (phi, i);
2117
2118       /* Try to avoid the insertion on edges as much as possible: this
2119          would avoid the insertion of code on loop latch edges, making
2120          the pattern matching of the vectorizer happy, or it would
2121          avoid the insertion of useless basic blocks.  Note that it is
2122          incorrect to insert out of SSA copies close by their
2123          definition when they are more than two loop levels apart:
2124          for example, starting from a double nested loop
2125
2126          | a = ...
2127          | loop_1
2128          |  loop_2
2129          |    b = phi (a, c)
2130          |    c = ...
2131          |  end_2
2132          | end_1
2133
2134          the following transform is incorrect
2135
2136          | a = ...
2137          | Red[0] = a
2138          | loop_1
2139          |  loop_2
2140          |    b = Red[0]
2141          |    c = ...
2142          |    Red[0] = c
2143          |  end_2
2144          | end_1
2145
2146          whereas inserting the copy on the incomming edge is correct
2147
2148          | a = ...
2149          | loop_1
2150          |  Red[0] = a
2151          |  loop_2
2152          |    b = Red[0]
2153          |    c = ...
2154          |    Red[0] = c
2155          |  end_2
2156          | end_1
2157       */
2158       if (TREE_CODE (arg) == SSA_NAME
2159           && is_gimple_reg (arg)
2160           && gimple_bb (SSA_NAME_DEF_STMT (arg))
2161           && (flow_bb_inside_loop_p (bb->loop_father,
2162                                      gimple_bb (SSA_NAME_DEF_STMT (arg)))
2163               || flow_bb_inside_loop_p (loop_outer (bb->loop_father),
2164                                         gimple_bb (SSA_NAME_DEF_STMT (arg)))))
2165         insert_out_of_ssa_copy (zero_dim_array, arg);
2166       else
2167         insert_out_of_ssa_copy_on_edge (gimple_phi_arg_edge (phi, i),
2168                                         zero_dim_array, arg);
2169     }
2170
2171   var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
2172
2173   if (!stmts)
2174     stmts = gimple_seq_alloc ();
2175
2176   stmt = gimple_build_assign (res, var);
2177   remove_phi_node (psi, false);
2178   SSA_NAME_DEF_STMT (res) = stmt;
2179
2180   gsi = gsi_last (stmts);
2181   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
2182
2183   gsi = gsi_after_labels (bb);
2184   gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2185 }
2186
2187 /* Return true when DEF can be analyzed in REGION by the scalar
2188    evolution analyzer.  */
2189
2190 static bool
2191 scev_analyzable_p (tree def, sese region)
2192 {
2193   gimple stmt = SSA_NAME_DEF_STMT (def);
2194   loop_p loop = loop_containing_stmt (stmt);
2195   tree scev = scalar_evolution_in_region (region, loop, def);
2196
2197   return !chrec_contains_undetermined (scev);
2198 }
2199
2200 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2201    read from ZERO_DIM_ARRAY.  */
2202
2203 static void
2204 rewrite_cross_bb_scalar_dependence (tree zero_dim_array, tree def, gimple use_stmt)
2205 {
2206   tree var = SSA_NAME_VAR (def);
2207   gimple name_stmt = gimple_build_assign (var, zero_dim_array);
2208   tree name = make_ssa_name (var, name_stmt);
2209   ssa_op_iter iter;
2210   use_operand_p use_p;
2211   gimple_stmt_iterator gsi;
2212
2213   gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2214
2215   gimple_assign_set_lhs (name_stmt, name);
2216
2217   gsi = gsi_for_stmt (use_stmt);
2218   gsi_insert_before (&gsi, name_stmt, GSI_NEW_STMT);
2219
2220   FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2221     if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2222       replace_exp (use_p, name);
2223
2224   update_stmt (use_stmt);
2225 }
2226
2227 /* Rewrite the scalar dependences crossing the boundary of the BB
2228    containing STMT with an array.  */
2229
2230 static void
2231 rewrite_cross_bb_scalar_deps (sese region, gimple_stmt_iterator *gsi)
2232 {
2233   gimple stmt = gsi_stmt (*gsi);
2234   imm_use_iterator imm_iter;
2235   tree def;
2236   basic_block def_bb;
2237   tree zero_dim_array = NULL_TREE;
2238   gimple use_stmt;
2239
2240   if (gimple_code (stmt) != GIMPLE_ASSIGN)
2241     return;
2242
2243   def = gimple_assign_lhs (stmt);
2244   if (!is_gimple_reg (def)
2245       || scev_analyzable_p (def, region))
2246     return;
2247
2248   def_bb = gimple_bb (stmt);
2249
2250   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2251     if (def_bb != gimple_bb (use_stmt)
2252         && gimple_code (use_stmt) != GIMPLE_PHI)
2253       {
2254         if (!zero_dim_array)
2255           {
2256             zero_dim_array = create_zero_dim_array (SSA_NAME_VAR (def));
2257             insert_out_of_ssa_copy (zero_dim_array, def);
2258             gsi_next (gsi);
2259           }
2260
2261         rewrite_cross_bb_scalar_dependence (zero_dim_array, def, use_stmt);
2262       }
2263 }
2264
2265 /* Rewrite out of SSA all the reduction phi nodes of SCOP.  */
2266
2267 static void
2268 rewrite_reductions_out_of_ssa (scop_p scop)
2269 {
2270   basic_block bb;
2271   gimple_stmt_iterator psi;
2272   sese region = SCOP_REGION (scop);
2273
2274   FOR_EACH_BB (bb)
2275     if (bb_in_sese_p (bb, region))
2276       for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2277         {
2278           if (scalar_close_phi_node_p (gsi_stmt (psi)))
2279             rewrite_close_phi_out_of_ssa (&psi);
2280           else if (reduction_phi_p (region, &psi))
2281             rewrite_phi_out_of_ssa (&psi);
2282         }
2283
2284   update_ssa (TODO_update_ssa);
2285 #ifdef ENABLE_CHECKING
2286   verify_ssa (false);
2287   verify_loop_closed_ssa ();
2288 #endif
2289
2290   FOR_EACH_BB (bb)
2291     if (bb_in_sese_p (bb, region))
2292       for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2293         rewrite_cross_bb_scalar_deps (region, &psi);
2294
2295   update_ssa (TODO_update_ssa);
2296 #ifdef ENABLE_CHECKING
2297   verify_ssa (false);
2298   verify_loop_closed_ssa ();
2299 #endif
2300 }
2301
2302 /* Returns the number of pbbs that are in loops contained in SCOP.  */
2303
2304 static int
2305 nb_pbbs_in_loops (scop_p scop)
2306 {
2307   int i;
2308   poly_bb_p pbb;
2309   int res = 0;
2310
2311   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
2312     if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2313       res++;
2314
2315   return res;
2316 }
2317
2318 /* Return the number of data references in BB that write in
2319    memory.  */
2320
2321 static int
2322 nb_data_writes_in_bb (basic_block bb)
2323 {
2324   int res = 0;
2325   gimple_stmt_iterator gsi;
2326
2327   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2328     if (gimple_vdef (gsi_stmt (gsi)))
2329       res++;
2330
2331   return res;
2332 }
2333
2334 /* Splits STMT out of its current BB.  */
2335
2336 static basic_block
2337 split_reduction_stmt (gimple stmt)
2338 {
2339   gimple_stmt_iterator gsi;
2340   basic_block bb = gimple_bb (stmt);
2341   edge e;
2342
2343   /* Do not split basic blocks with no writes to memory: the reduction
2344      will be the only write to memory.  */
2345   if (nb_data_writes_in_bb (bb) == 0)
2346     return bb;
2347
2348   split_block (bb, stmt);
2349
2350   gsi = gsi_last_bb (bb);
2351   gsi_prev (&gsi);
2352   e = split_block (bb, gsi_stmt (gsi));
2353
2354   return e->dest;
2355 }
2356
2357 /* Return true when stmt is a reduction operation.  */
2358
2359 static inline bool
2360 is_reduction_operation_p (gimple stmt)
2361 {
2362   return flag_associative_math
2363     && commutative_tree_code (gimple_assign_rhs_code (stmt))
2364     && associative_tree_code (gimple_assign_rhs_code (stmt));
2365 }
2366
2367 /* Returns true when PHI contains an argument ARG.  */
2368
2369 static bool
2370 phi_contains_arg (gimple phi, tree arg)
2371 {
2372   size_t i;
2373
2374   for (i = 0; i < gimple_phi_num_args (phi); i++)
2375     if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2376       return true;
2377
2378   return false;
2379 }
2380
2381 /* Return a loop phi node that corresponds to a reduction containing LHS.  */
2382
2383 static gimple
2384 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2385 {
2386   gimple stmt;
2387
2388   if (TREE_CODE (arg) != SSA_NAME)
2389     return NULL;
2390
2391   stmt = SSA_NAME_DEF_STMT (arg);
2392
2393   if (gimple_code (stmt) == GIMPLE_PHI)
2394     {
2395       if (phi_contains_arg (stmt, lhs))
2396         return stmt;
2397       return NULL;
2398     }
2399
2400   if (gimple_num_ops (stmt) == 2)
2401     return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2402
2403   if (is_reduction_operation_p (stmt))
2404     {
2405       gimple res = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2406
2407       return res ? res :
2408         follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2409     }
2410
2411   return NULL;
2412 }
2413
2414 /* Detect commutative and associative scalar reductions starting at
2415    the STMT.  */
2416
2417 static gimple
2418 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2419                                   VEC (gimple, heap) **in,
2420                                   VEC (gimple, heap) **out)
2421 {
2422   gimple phi = follow_ssa_with_commutative_ops (arg, lhs);
2423
2424   if (phi)
2425     {
2426       VEC_safe_push (gimple, heap, *in, stmt);
2427       VEC_safe_push (gimple, heap, *out, stmt);
2428       return phi;
2429     }
2430
2431   return NULL;
2432 }
2433
2434 /* Detect commutative and associative scalar reductions starting at
2435    the STMT.  */
2436
2437 static gimple
2438 detect_commutative_reduction_assign (gimple stmt, VEC (gimple, heap) **in,
2439                                      VEC (gimple, heap) **out)
2440 {
2441   tree lhs = gimple_assign_lhs (stmt);
2442
2443   if (gimple_num_ops (stmt) == 2)
2444     return detect_commutative_reduction_arg (lhs, stmt,
2445                                              gimple_assign_rhs1 (stmt),
2446                                              in, out);
2447
2448   if (is_reduction_operation_p (stmt))
2449     {
2450       gimple res = detect_commutative_reduction_arg (lhs, stmt,
2451                                                      gimple_assign_rhs1 (stmt),
2452                                                      in, out);
2453       return res ? res
2454         : detect_commutative_reduction_arg (lhs, stmt,
2455                                             gimple_assign_rhs2 (stmt),
2456                                             in, out);
2457     }
2458
2459   return NULL;
2460 }
2461
2462 /* Return a loop phi node that corresponds to a reduction containing LHS.  */
2463
2464 static gimple
2465 follow_inital_value_to_phi (tree arg, tree lhs)
2466 {
2467   gimple stmt;
2468
2469   if (!arg || TREE_CODE (arg) != SSA_NAME)
2470     return NULL;
2471
2472   stmt = SSA_NAME_DEF_STMT (arg);
2473
2474   if (gimple_code (stmt) == GIMPLE_PHI
2475       && phi_contains_arg (stmt, lhs))
2476     return stmt;
2477
2478   return NULL;
2479 }
2480
2481
2482 /* Return the argument of the loop PHI that is the inital value coming
2483    from outside the loop.  */
2484
2485 static edge
2486 edge_initial_value_for_loop_phi (gimple phi)
2487 {
2488   size_t i;
2489
2490   for (i = 0; i < gimple_phi_num_args (phi); i++)
2491     {
2492       edge e = gimple_phi_arg_edge (phi, i);
2493
2494       if (loop_depth (e->src->loop_father)
2495           < loop_depth (e->dest->loop_father))
2496         return e;
2497     }
2498
2499   return NULL;
2500 }
2501
2502 /* Return the argument of the loop PHI that is the inital value coming
2503    from outside the loop.  */
2504
2505 static tree
2506 initial_value_for_loop_phi (gimple phi)
2507 {
2508   size_t i;
2509
2510   for (i = 0; i < gimple_phi_num_args (phi); i++)
2511     {
2512       edge e = gimple_phi_arg_edge (phi, i);
2513
2514       if (loop_depth (e->src->loop_father)
2515           < loop_depth (e->dest->loop_father))
2516         return gimple_phi_arg_def (phi, i);
2517     }
2518
2519   return NULL_TREE;
2520 }
2521
2522 /* Detect commutative and associative scalar reductions starting at
2523    the loop closed phi node CLOSE_PHI.  */
2524
2525 static gimple
2526 detect_commutative_reduction (gimple stmt, VEC (gimple, heap) **in,
2527                               VEC (gimple, heap) **out)
2528 {
2529   if (scalar_close_phi_node_p (stmt))
2530     {
2531       tree arg = gimple_phi_arg_def (stmt, 0);
2532       gimple def = SSA_NAME_DEF_STMT (arg);
2533       gimple loop_phi = detect_commutative_reduction (def, in, out);
2534
2535       if (loop_phi)
2536         {
2537           tree lhs = gimple_phi_result (stmt);
2538           tree init = initial_value_for_loop_phi (loop_phi);
2539           gimple phi = follow_inital_value_to_phi (init, lhs);
2540
2541           VEC_safe_push (gimple, heap, *in, loop_phi);
2542           VEC_safe_push (gimple, heap, *out, stmt);
2543           return phi;
2544         }
2545       else
2546         return NULL;
2547     }
2548
2549   if (gimple_code (stmt) == GIMPLE_ASSIGN)
2550     return detect_commutative_reduction_assign (stmt, in, out);
2551
2552   return NULL;
2553 }
2554
2555 /* Translate the scalar reduction statement STMT to an array RED
2556    knowing that its recursive phi node is LOOP_PHI.  */
2557
2558 static void
2559 translate_scalar_reduction_to_array_for_stmt (tree red, gimple stmt,
2560                                               gimple loop_phi)
2561 {
2562   basic_block bb = gimple_bb (stmt);
2563   gimple_stmt_iterator insert_gsi = gsi_after_labels (bb);
2564   tree res = gimple_phi_result (loop_phi);
2565   gimple assign = gimple_build_assign (res, red);
2566
2567   gsi_insert_before (&insert_gsi, assign, GSI_SAME_STMT);
2568
2569   assign = gimple_build_assign (red, gimple_assign_lhs (stmt));
2570   insert_gsi = gsi_for_stmt (stmt);
2571   gsi_insert_after (&insert_gsi, assign, GSI_SAME_STMT);
2572 }
2573
2574 /* Insert the assignment "result (CLOSE_PHI) = RED".  */
2575
2576 static void
2577 insert_copyout (tree red, gimple close_phi)
2578 {
2579   tree res = gimple_phi_result (close_phi);
2580   basic_block bb = gimple_bb (close_phi);
2581   gimple_stmt_iterator insert_gsi = gsi_after_labels (bb);
2582   gimple assign = gimple_build_assign (res, red);
2583
2584   gsi_insert_before (&insert_gsi, assign, GSI_SAME_STMT);
2585 }
2586
2587 /* Insert the assignment "RED = initial_value (LOOP_PHI)".  */
2588
2589 static void
2590 insert_copyin (tree red, gimple loop_phi)
2591 {
2592   gimple_seq stmts;
2593   tree init = initial_value_for_loop_phi (loop_phi);
2594   tree expr = build2 (MODIFY_EXPR, TREE_TYPE (init), red, init);
2595
2596   force_gimple_operand (expr, &stmts, true, NULL);
2597   gsi_insert_seq_on_edge (edge_initial_value_for_loop_phi (loop_phi), stmts);
2598 }
2599
2600 /* Rewrite out of SSA the reduction described by the loop phi nodes
2601    IN, and the close phi nodes OUT.  IN and OUT are structured by loop
2602    levels like this:
2603
2604    IN: stmt, loop_n, ..., loop_0
2605    OUT: stmt, close_n, ..., close_0
2606
2607    the first element is the reduction statement, and the next elements
2608    are the loop and close phi nodes of each of the outer loops.  */
2609
2610 static void
2611 translate_scalar_reduction_to_array (VEC (gimple, heap) *in,
2612                                      VEC (gimple, heap) *out,
2613                                      sbitmap reductions)
2614 {
2615   unsigned int i;
2616   gimple loop_phi;
2617   tree red;
2618   gimple_stmt_iterator gsi;
2619
2620   for (i = 0; VEC_iterate (gimple, in, i, loop_phi); i++)
2621     {
2622       gimple close_phi = VEC_index (gimple, out, i);
2623
2624       if (i == 0)
2625         {
2626           gimple stmt = loop_phi;
2627           basic_block bb = split_reduction_stmt (stmt);
2628
2629           SET_BIT (reductions, bb->index);
2630           gcc_assert (close_phi == loop_phi);
2631
2632           red = create_zero_dim_array (gimple_assign_lhs (stmt));
2633           translate_scalar_reduction_to_array_for_stmt
2634             (red, stmt, VEC_index (gimple, in, 1));
2635           continue;
2636         }
2637
2638       if (i == VEC_length (gimple, in) - 1)
2639         {
2640           insert_copyout (red, close_phi);
2641           insert_copyin (red, loop_phi);
2642         }
2643
2644       gsi = gsi_for_phi_node (loop_phi);
2645       remove_phi_node (&gsi, false);
2646
2647       gsi = gsi_for_phi_node (close_phi);
2648       remove_phi_node (&gsi, false);
2649     }
2650 }
2651
2652 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI.  */
2653
2654 static void
2655 rewrite_commutative_reductions_out_of_ssa_close_phi (gimple close_phi,
2656                                                      sbitmap reductions)
2657 {
2658   VEC (gimple, heap) *in = VEC_alloc (gimple, heap, 10);
2659   VEC (gimple, heap) *out = VEC_alloc (gimple, heap, 10);
2660
2661   detect_commutative_reduction (close_phi, &in, &out);
2662   if (VEC_length (gimple, in) > 0)
2663     translate_scalar_reduction_to_array (in, out, reductions);
2664
2665   VEC_free (gimple, heap, in);
2666   VEC_free (gimple, heap, out);
2667 }
2668
2669 /* Rewrites all the commutative reductions from LOOP out of SSA.  */
2670
2671 static void
2672 rewrite_commutative_reductions_out_of_ssa_loop (loop_p loop,
2673                                                 sbitmap reductions)
2674 {
2675   gimple_stmt_iterator gsi;
2676   edge exit = single_exit (loop);
2677
2678   if (!exit)
2679     return;
2680
2681   for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
2682     rewrite_commutative_reductions_out_of_ssa_close_phi (gsi_stmt (gsi),
2683                                                          reductions);
2684 }
2685
2686 /* Rewrites all the commutative reductions from SCOP out of SSA.  */
2687
2688 static void
2689 rewrite_commutative_reductions_out_of_ssa (sese region, sbitmap reductions)
2690 {
2691   loop_iterator li;
2692   loop_p loop;
2693
2694   FOR_EACH_LOOP (li, loop, 0)
2695     if (loop_in_sese_p (loop, region))
2696       rewrite_commutative_reductions_out_of_ssa_loop (loop, reductions);
2697
2698   gsi_commit_edge_inserts ();
2699   update_ssa (TODO_update_ssa);
2700 #ifdef ENABLE_CHECKING
2701   verify_ssa (false);
2702   verify_loop_closed_ssa ();
2703 #endif
2704 }
2705
2706 /* Builds the polyhedral representation for a SESE region.  */
2707
2708 bool
2709 build_poly_scop (scop_p scop)
2710 {
2711   sese region = SCOP_REGION (scop);
2712   sbitmap reductions = sbitmap_alloc (last_basic_block * 2);
2713
2714   sbitmap_zero (reductions);
2715   rewrite_commutative_reductions_out_of_ssa (region, reductions);
2716   rewrite_reductions_out_of_ssa (scop);
2717   build_scop_bbs (scop, reductions);
2718   sbitmap_free (reductions);
2719
2720   /* FIXME: This restriction is needed to avoid a problem in CLooG.
2721      Once CLooG is fixed, remove this guard.  Anyways, it makes no
2722      sense to optimize a scop containing only PBBs that do not belong
2723      to any loops.  */
2724   if (nb_pbbs_in_loops (scop) == 0)
2725     return false;
2726
2727   build_sese_loop_nests (region);
2728   build_sese_conditions (region);
2729   find_scop_parameters (scop);
2730
2731   build_scop_iteration_domain (scop);
2732   build_scop_context (scop);
2733
2734   add_conditions_to_constraints (scop);
2735   scop_to_lst (scop);
2736   build_scop_scattering (scop);
2737   build_scop_drs (scop);
2738
2739   return true;
2740 }
2741
2742 /* Always return false.  Exercise the scop_to_clast function.  */
2743
2744 void
2745 check_poly_representation (scop_p scop ATTRIBUTE_UNUSED)
2746 {
2747 #ifdef ENABLE_CHECKING
2748   cloog_prog_clast pc = scop_to_clast (scop);
2749   cloog_clast_free (pc.stmt);
2750   cloog_program_free (pc.prog);
2751 #endif
2752 }
2753 #endif