OSDN Git Service

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