OSDN Git Service

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