OSDN Git Service

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