OSDN Git Service

2009-09-26 Li Feng <nemokingdom@gmail.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 = GBB_BB (PBB_BLACK_BOX (pbb))->loop_father;
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     {
1831       VEC (data_reference_p, heap) *gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1832       for (j = 0; VEC_iterate (data_reference_p, gbb_drs, j, dr); j++)
1833        VEC_safe_push (data_reference_p, heap, drs, dr);
1834     }
1835
1836   build_alias_set_for_drs (&drs);
1837   build_base_obj_set_for_drs (&drs);
1838
1839   /* When debugging, enable the following code.  This cannot be used
1840      in production compilers.  */
1841 #if 0
1842   {
1843     char comment[100];
1844     FILE *file;
1845
1846     file = fopen ("/tmp/dr_alias_graph", "ab");
1847     if (file)
1848       {
1849         snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1850                   current_function_name ());
1851         write_alias_graph_to_ascii_dimacs (file, comment, drs);
1852         fclose (file);
1853       }
1854   }
1855 #endif
1856
1857   VEC_free (data_reference_p, heap, drs);
1858
1859   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1860     build_pbb_drs (pbb);
1861 }
1862
1863 /* Return a gsi at the position of the VAR definition.  */
1864
1865 static gimple_stmt_iterator
1866 gsi_for_ssa_name_def (tree var)
1867 {
1868   gimple stmt;
1869   basic_block bb;
1870   gimple_stmt_iterator gsi;
1871   gimple_stmt_iterator psi;
1872
1873   gcc_assert (TREE_CODE (var) == SSA_NAME);
1874
1875   stmt = SSA_NAME_DEF_STMT (var);
1876   bb = gimple_bb (stmt);
1877
1878   for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1879     if (stmt == gsi_stmt (psi))
1880       return gsi_after_labels (bb);
1881
1882   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1883     if (stmt == gsi_stmt (gsi))
1884       {
1885         gsi_next (&gsi);
1886         return gsi;
1887       }
1888
1889   gcc_unreachable ();
1890   return gsi;
1891 }
1892
1893 /* Insert the assignment "RES := VAR" just after the definition of VAR.  */
1894
1895 static void
1896 insert_out_of_ssa_copy (tree res, tree var)
1897 {
1898   gimple_stmt_iterator gsi = gsi_for_ssa_name_def (var);
1899   gimple stmt;
1900   gimple_seq stmts;
1901   gimple_stmt_iterator si;
1902
1903   var = force_gimple_operand (var, &stmts, true, NULL_TREE);
1904   stmt = gimple_build_assign (res, var);
1905   if (!stmts)
1906     stmts = gimple_seq_alloc ();
1907   si = gsi_last (stmts);
1908   gsi_insert_after (&si, stmt, GSI_NEW_STMT);
1909   gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
1910 }
1911
1912 /* Insert on edge E the assignment "RES := EXPR".  */
1913
1914 static void
1915 insert_out_of_ssa_copy_on_edge (edge e, tree res, tree expr)
1916 {
1917   gimple_stmt_iterator gsi;
1918   gimple_seq stmts;
1919   tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
1920   gimple stmt = gimple_build_assign (res, var);
1921
1922   if (!stmts)
1923     stmts = gimple_seq_alloc ();
1924
1925   gsi = gsi_last (stmts);
1926   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
1927   gsi_insert_seq_on_edge (e, stmts);
1928   gsi_commit_edge_inserts ();
1929 }
1930
1931 /* Creates a zero dimension array of the same type as VAR.  */
1932
1933 static tree
1934 create_zero_dim_array (tree var)
1935 {
1936   tree index_type = build_index_type (integer_zero_node);
1937   tree elt_type = TREE_TYPE (var);
1938   tree array_type = build_array_type (elt_type, index_type);
1939   tree base = create_tmp_var (array_type, "Red");
1940
1941   add_referenced_var (base);
1942
1943   return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
1944                  NULL_TREE);
1945 }
1946
1947 /* Returns true when PHI is a loop close phi node.  */
1948
1949 static bool
1950 scalar_close_phi_node_p (gimple phi)
1951 {
1952   gcc_assert (gimple_code (phi) == GIMPLE_PHI);
1953
1954   if (!is_gimple_reg (gimple_phi_result (phi)))
1955     return false;
1956
1957   return (gimple_phi_num_args (phi) == 1);
1958 }
1959
1960 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
1961    dimension array for it.  */
1962
1963 static void
1964 rewrite_close_phi_out_of_ssa (gimple_stmt_iterator *psi)
1965 {
1966   gimple phi = gsi_stmt (*psi);
1967   tree res = gimple_phi_result (phi);
1968   tree var = SSA_NAME_VAR (res);
1969   tree zero_dim_array = create_zero_dim_array (var);
1970   gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (phi));
1971   gimple stmt = gimple_build_assign (res, zero_dim_array);
1972   tree arg = gimple_phi_arg_def (phi, 0);
1973
1974   insert_out_of_ssa_copy (zero_dim_array, arg);
1975
1976   remove_phi_node (psi, false);
1977   gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
1978   SSA_NAME_DEF_STMT (res) = stmt;
1979 }
1980
1981 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
1982    dimension array for it.  */
1983
1984 static void
1985 rewrite_phi_out_of_ssa (gimple_stmt_iterator *psi)
1986 {
1987   size_t i;
1988   gimple phi = gsi_stmt (*psi);
1989   basic_block bb = gimple_bb (phi);
1990   tree res = gimple_phi_result (phi);
1991   tree var = SSA_NAME_VAR (res);
1992   tree zero_dim_array = create_zero_dim_array (var);
1993   gimple_stmt_iterator gsi;
1994   gimple stmt;
1995   gimple_seq stmts;
1996
1997   for (i = 0; i < gimple_phi_num_args (phi); i++)
1998     {
1999       tree arg = gimple_phi_arg_def (phi, i);
2000
2001       /* Try to avoid the insertion on edges as much as possible: this
2002          would avoid the insertion of code on loop latch edges, making
2003          the pattern matching of the vectorizer happy, or it would
2004          avoid the insertion of useless basic blocks.  Note that it is
2005          incorrect to insert out of SSA copies close by their
2006          definition when they are more than two loop levels apart:
2007          for example, starting from a double nested loop
2008
2009          | a = ...
2010          | loop_1
2011          |  loop_2
2012          |    b = phi (a, c)
2013          |    c = ...
2014          |  end_2
2015          | end_1
2016
2017          the following transform is incorrect
2018
2019          | a = ...
2020          | Red[0] = a
2021          | loop_1
2022          |  loop_2
2023          |    b = Red[0]
2024          |    c = ...
2025          |    Red[0] = c
2026          |  end_2
2027          | end_1
2028
2029          whereas inserting the copy on the incomming edge is correct
2030
2031          | a = ...
2032          | loop_1
2033          |  Red[0] = a
2034          |  loop_2
2035          |    b = Red[0]
2036          |    c = ...
2037          |    Red[0] = c
2038          |  end_2
2039          | end_1
2040       */
2041       if (TREE_CODE (arg) == SSA_NAME
2042           && is_gimple_reg (arg)
2043           && gimple_bb (SSA_NAME_DEF_STMT (arg))
2044           && (flow_bb_inside_loop_p (bb->loop_father,
2045                                      gimple_bb (SSA_NAME_DEF_STMT (arg)))
2046               || flow_bb_inside_loop_p (loop_outer (bb->loop_father),
2047                                         gimple_bb (SSA_NAME_DEF_STMT (arg)))))
2048         insert_out_of_ssa_copy (zero_dim_array, arg);
2049       else
2050         insert_out_of_ssa_copy_on_edge (gimple_phi_arg_edge (phi, i),
2051                                         zero_dim_array, arg);
2052     }
2053
2054   var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
2055
2056   if (!stmts)
2057     stmts = gimple_seq_alloc ();
2058
2059   stmt = gimple_build_assign (res, var);
2060   remove_phi_node (psi, false);
2061   SSA_NAME_DEF_STMT (res) = stmt;
2062
2063   gsi = gsi_last (stmts);
2064   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
2065
2066   gsi = gsi_after_labels (bb);
2067   gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2068 }
2069
2070 /* Rewrite out of SSA all the reduction phi nodes of SCOP.  */
2071
2072 static void
2073 rewrite_reductions_out_of_ssa (scop_p scop)
2074 {
2075   basic_block bb;
2076   gimple_stmt_iterator psi;
2077   sese region = SCOP_REGION (scop);
2078
2079   FOR_EACH_BB (bb)
2080     if (bb_in_region (bb, SESE_ENTRY_BB (region), SESE_EXIT_BB (region)))
2081       for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2082         {
2083           if (scalar_close_phi_node_p (gsi_stmt (psi)))
2084             rewrite_close_phi_out_of_ssa (&psi);
2085           else if (reduction_phi_p (region, &psi))
2086             rewrite_phi_out_of_ssa (&psi);
2087         }
2088
2089   update_ssa (TODO_update_ssa);
2090 #ifdef ENABLE_CHECKING
2091   verify_ssa (false);
2092   verify_loop_closed_ssa ();
2093 #endif
2094 }
2095
2096 /* Returns the number of pbbs that are in loops contained in SCOP.  */
2097
2098 static int
2099 nb_pbbs_in_loops (scop_p scop)
2100 {
2101   int i;
2102   poly_bb_p pbb;
2103   int res = 0;
2104
2105   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
2106     if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2107       res++;
2108
2109   return res;
2110 }
2111
2112 /* Builds the polyhedral representation for a SESE region.  */
2113
2114 bool
2115 build_poly_scop (scop_p scop)
2116 {
2117   sese region = SCOP_REGION (scop);
2118   rewrite_reductions_out_of_ssa (scop);
2119   build_scop_bbs (scop);
2120
2121   /* FIXME: This restriction is needed to avoid a problem in CLooG.
2122      Once CLooG is fixed, remove this guard.  Anyways, it makes no
2123      sense to optimize a scop containing only PBBs that do not belong
2124      to any loops.  */
2125   if (nb_pbbs_in_loops (scop) == 0)
2126     return false;
2127
2128   build_sese_loop_nests (region);
2129   build_sese_conditions (region);
2130   find_scop_parameters (scop);
2131
2132   build_scop_iteration_domain (scop);
2133   build_scop_context (scop);
2134
2135   add_conditions_to_constraints (scop);
2136   build_scop_scattering (scop);
2137   build_scop_drs (scop);
2138
2139   return true;
2140 }
2141
2142 /* Always return false.  Exercise the scop_to_clast function.  */
2143
2144 void
2145 check_poly_representation (scop_p scop ATTRIBUTE_UNUSED)
2146 {
2147 #ifdef ENABLE_CHECKING
2148   cloog_prog_clast pc = scop_to_clast (scop);
2149   cloog_clast_free (pc.stmt);
2150   cloog_program_free (pc.prog);
2151 #endif
2152 }
2153 #endif