OSDN Git Service

b0f385b0a20454f0be3c59c3a066fdd90f4fb5cc
[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, all_components_are_cliques;
1901
1902   for (i = 0; VEC_iterate (data_reference_p, drs, i, dr1); i++)
1903     for (j = i+1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1904       if (dr_may_alias_p (dr1, dr2))
1905         {
1906           add_edge (g, i, j);
1907           add_edge (g, j, i);
1908         }
1909
1910   all_vertices = XNEWVEC (int, num_vertices);
1911   vertices = XNEWVEC (int, num_vertices);
1912   for (i = 0; i < num_vertices; i++)
1913     all_vertices[i] = i;
1914
1915   num_connected_components = graphds_dfs (g, all_vertices, num_vertices,
1916                                           NULL, true, NULL);
1917   for (i = 0; i < g->n_vertices; i++)
1918     {
1919       data_reference_p dr = VEC_index (data_reference_p, drs, i);
1920       base_alias_pair *bap;
1921       if (dr->aux != NULL)
1922         bap = (base_alias_pair *)(dr->aux);
1923       bap->alias_set = XNEW (int);
1924       *(bap->alias_set) = g->vertices[i].component + 1;
1925     }
1926
1927
1928   /* Verify if the DFS numbering results in optimal solution.  */
1929   for (i = 0; i < num_connected_components; i++)
1930     {
1931       num_vertices_in_component = 0;
1932       /* Get all vertices whose DFS component number is the same as i.  */
1933       for (j = 0; j < num_vertices; j++)
1934         if (g->vertices[j].component == i)
1935           vertices[num_vertices_in_component++] = j;
1936
1937       /* Now test if the vertices in 'vertices' form a clique, by testing
1938          for edges among each pair.  */
1939       this_component_is_clique = 1;
1940       for (v_indx1 = 0; v_indx1 < num_vertices_in_component; v_indx1++)
1941         {
1942           for (v_indx2 = v_indx1+1; v_indx2 < num_vertices_in_component; v_indx2++)
1943             {
1944               /* Check if the two vertices are connected by iterating
1945                  through all the edges which have one of these are source.  */
1946               e = g->vertices[vertices[v_indx2]].pred;
1947               while (e)
1948                 {
1949                   if (e->src == vertices[v_indx1])
1950                     break;
1951                   e = e->pred_next;
1952                 }
1953               if (!e)
1954                 {
1955                   this_component_is_clique = 0;
1956                   break;
1957                 }
1958             }
1959           if (!this_component_is_clique)
1960             all_components_are_cliques = 0;
1961         }
1962     }
1963
1964   free (all_vertices);
1965   free (vertices);
1966   free_graph (g);
1967   return all_components_are_cliques;
1968 }
1969
1970 /* Group each data reference in DRS with it's base object set num.  */
1971
1972 static void
1973 build_base_obj_set_for_drs (VEC (data_reference_p, heap) *drs)
1974 {
1975   int num_vertex = VEC_length (data_reference_p, drs);
1976   struct graph *g = new_graph (num_vertex);
1977   data_reference_p dr1, dr2;
1978   int i, j;
1979   int num_component;
1980   int *queue;
1981
1982   for (i = 0; VEC_iterate (data_reference_p, drs, i, dr1); i++)
1983     for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1984       if (dr_same_base_object_p (dr1, dr2))
1985         {
1986           add_edge (g, i, j);
1987           add_edge (g, j, i);
1988         }
1989
1990   queue = XNEWVEC (int, num_vertex);
1991   for (i = 0; i < num_vertex; i++)
1992     queue[i] = i;
1993
1994   num_component = graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1995
1996   for (i = 0; i < g->n_vertices; i++)
1997     {
1998       data_reference_p dr = VEC_index (data_reference_p, drs, i);
1999       base_alias_pair *bap;
2000       if (dr->aux != NULL)
2001         bap = (base_alias_pair *)(dr->aux);
2002       bap->base_obj_set = g->vertices[i].component + 1;
2003     }
2004
2005   free (queue);
2006   free_graph (g);
2007 }
2008
2009 /* Build the data references for PBB.  */
2010
2011 static void
2012 build_pbb_drs (poly_bb_p pbb)
2013 {
2014   int j;
2015   data_reference_p dr;
2016   VEC (data_reference_p, heap) *gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
2017
2018   for (j = 0; VEC_iterate (data_reference_p, gbb_drs, j, dr); j++)
2019     build_poly_dr (dr, pbb);
2020 }
2021
2022 /* Build data references in SCOP.  */
2023
2024 static void
2025 build_scop_drs (scop_p scop)
2026 {
2027   int i, j;
2028   poly_bb_p pbb;
2029   data_reference_p dr;
2030   VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
2031
2032   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
2033     for (j = 0; VEC_iterate (data_reference_p,
2034                              GBB_DATA_REFS (PBB_BLACK_BOX (pbb)), j, dr); j++)
2035       VEC_safe_push (data_reference_p, heap, drs, dr);
2036
2037   for (i = 0; VEC_iterate (data_reference_p, drs, i, dr); i++)
2038     dr->aux = XNEW (base_alias_pair);
2039
2040   if (!build_alias_set_optimal_p (drs))
2041     {
2042       /* TODO: Add support when building alias set is not optimal.  */
2043       ;
2044     }
2045
2046   build_base_obj_set_for_drs (drs);
2047
2048   /* When debugging, enable the following code.  This cannot be used
2049      in production compilers.  */
2050 #if 0
2051   {
2052     char comment[100];
2053     FILE *file_dimacs, *file_ecc, *file_dot;
2054
2055     file_dimacs = fopen ("/tmp/dr_alias_graph_dimacs", "ab");
2056     file_ecc = fopen ("/tmp/dr_alias_graph_ecc", "ab");
2057     file_dot = fopen ("/tmp/dr_alias_graph_dot", "ab");
2058     if (file_dimacs)
2059       {
2060         snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
2061                   current_function_name ());
2062         write_alias_graph_to_ascii_dimacs (file_dimacs, comment, drs);
2063         fclose (file_dimacs);
2064       }
2065     if (file_ecc)
2066       {
2067         snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
2068                   current_function_name ());
2069         write_alias_graph_to_ascii_ecc (file_ecc, comment, drs);
2070         fclose (file_ecc);
2071       }
2072     if (file_dot)
2073       {
2074         snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
2075                   current_function_name ());
2076         write_alias_graph_to_ascii_dot (file_dot, comment, drs);
2077         fclose (file_dot);
2078       }
2079   }
2080 #endif
2081
2082   VEC_free (data_reference_p, heap, drs);
2083
2084   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
2085     build_pbb_drs (pbb);
2086 }
2087
2088 /* Return a gsi at the position of the phi node STMT.  */
2089
2090 static gimple_stmt_iterator
2091 gsi_for_phi_node (gimple stmt)
2092 {
2093   gimple_stmt_iterator psi;
2094   basic_block bb = gimple_bb (stmt);
2095
2096   for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
2097     if (stmt == gsi_stmt (psi))
2098       return psi;
2099
2100   gcc_unreachable ();
2101   return psi;
2102 }
2103
2104 /* Insert the assignment "RES := VAR" just after the definition of VAR.  */
2105
2106 static void
2107 insert_out_of_ssa_copy (tree res, tree var)
2108 {
2109   gimple stmt;
2110   gimple_seq stmts;
2111   gimple_stmt_iterator si;
2112   gimple_stmt_iterator gsi;
2113
2114   var = force_gimple_operand (var, &stmts, true, NULL_TREE);
2115   stmt = gimple_build_assign (res, var);
2116   if (!stmts)
2117     stmts = gimple_seq_alloc ();
2118   si = gsi_last (stmts);
2119   gsi_insert_after (&si, stmt, GSI_NEW_STMT);
2120
2121   stmt = SSA_NAME_DEF_STMT (var);
2122   if (gimple_code (stmt) == GIMPLE_PHI)
2123     {
2124       gsi = gsi_after_labels (gimple_bb (stmt));
2125       gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2126     }
2127   else
2128     {
2129       gsi = gsi_for_stmt (stmt);
2130       gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
2131     }
2132 }
2133
2134 /* Insert on edge E the assignment "RES := EXPR".  */
2135
2136 static void
2137 insert_out_of_ssa_copy_on_edge (edge e, tree res, tree expr)
2138 {
2139   gimple_stmt_iterator gsi;
2140   gimple_seq stmts;
2141   tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2142   gimple stmt = gimple_build_assign (res, var);
2143
2144   if (!stmts)
2145     stmts = gimple_seq_alloc ();
2146
2147   gsi = gsi_last (stmts);
2148   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
2149   gsi_insert_seq_on_edge (e, stmts);
2150   gsi_commit_edge_inserts ();
2151 }
2152
2153 /* Creates a zero dimension array of the same type as VAR.  */
2154
2155 static tree
2156 create_zero_dim_array (tree var)
2157 {
2158   tree index_type = build_index_type (integer_zero_node);
2159   tree elt_type = TREE_TYPE (var);
2160   tree array_type = build_array_type (elt_type, index_type);
2161   tree base = create_tmp_var (array_type, "Red");
2162
2163   add_referenced_var (base);
2164
2165   return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
2166                  NULL_TREE);
2167 }
2168
2169 /* Returns true when PHI is a loop close phi node.  */
2170
2171 static bool
2172 scalar_close_phi_node_p (gimple phi)
2173 {
2174   if (gimple_code (phi) != GIMPLE_PHI
2175       || !is_gimple_reg (gimple_phi_result (phi)))
2176     return false;
2177
2178   return (gimple_phi_num_args (phi) == 1);
2179 }
2180
2181 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2182    dimension array for it.  */
2183
2184 static void
2185 rewrite_close_phi_out_of_ssa (gimple_stmt_iterator *psi)
2186 {
2187   gimple phi = gsi_stmt (*psi);
2188   tree res = gimple_phi_result (phi);
2189   tree var = SSA_NAME_VAR (res);
2190   tree zero_dim_array = create_zero_dim_array (var);
2191   gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (phi));
2192   gimple stmt = gimple_build_assign (res, zero_dim_array);
2193   tree arg = gimple_phi_arg_def (phi, 0);
2194
2195   insert_out_of_ssa_copy (zero_dim_array, arg);
2196
2197   remove_phi_node (psi, false);
2198   gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2199   SSA_NAME_DEF_STMT (res) = stmt;
2200 }
2201
2202 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2203    dimension array for it.  */
2204
2205 static void
2206 rewrite_phi_out_of_ssa (gimple_stmt_iterator *psi)
2207 {
2208   size_t i;
2209   gimple phi = gsi_stmt (*psi);
2210   basic_block bb = gimple_bb (phi);
2211   tree res = gimple_phi_result (phi);
2212   tree var = SSA_NAME_VAR (res);
2213   tree zero_dim_array = create_zero_dim_array (var);
2214   gimple_stmt_iterator gsi;
2215   gimple stmt;
2216   gimple_seq stmts;
2217
2218   for (i = 0; i < gimple_phi_num_args (phi); i++)
2219     {
2220       tree arg = gimple_phi_arg_def (phi, i);
2221
2222       /* Try to avoid the insertion on edges as much as possible: this
2223          would avoid the insertion of code on loop latch edges, making
2224          the pattern matching of the vectorizer happy, or it would
2225          avoid the insertion of useless basic blocks.  Note that it is
2226          incorrect to insert out of SSA copies close by their
2227          definition when they are more than two loop levels apart:
2228          for example, starting from a double nested loop
2229
2230          | a = ...
2231          | loop_1
2232          |  loop_2
2233          |    b = phi (a, c)
2234          |    c = ...
2235          |  end_2
2236          | end_1
2237
2238          the following transform is incorrect
2239
2240          | a = ...
2241          | Red[0] = a
2242          | loop_1
2243          |  loop_2
2244          |    b = Red[0]
2245          |    c = ...
2246          |    Red[0] = c
2247          |  end_2
2248          | end_1
2249
2250          whereas inserting the copy on the incomming edge is correct
2251
2252          | a = ...
2253          | loop_1
2254          |  Red[0] = a
2255          |  loop_2
2256          |    b = Red[0]
2257          |    c = ...
2258          |    Red[0] = c
2259          |  end_2
2260          | end_1
2261       */
2262       if (TREE_CODE (arg) == SSA_NAME
2263           && is_gimple_reg (arg)
2264           && gimple_bb (SSA_NAME_DEF_STMT (arg))
2265           && (flow_bb_inside_loop_p (bb->loop_father,
2266                                      gimple_bb (SSA_NAME_DEF_STMT (arg)))
2267               || flow_bb_inside_loop_p (loop_outer (bb->loop_father),
2268                                         gimple_bb (SSA_NAME_DEF_STMT (arg)))))
2269         insert_out_of_ssa_copy (zero_dim_array, arg);
2270       else
2271         insert_out_of_ssa_copy_on_edge (gimple_phi_arg_edge (phi, i),
2272                                         zero_dim_array, arg);
2273     }
2274
2275   var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
2276
2277   if (!stmts)
2278     stmts = gimple_seq_alloc ();
2279
2280   stmt = gimple_build_assign (res, var);
2281   remove_phi_node (psi, false);
2282   SSA_NAME_DEF_STMT (res) = stmt;
2283
2284   gsi = gsi_last (stmts);
2285   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
2286
2287   gsi = gsi_after_labels (bb);
2288   gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2289 }
2290
2291 /* Return true when DEF can be analyzed in REGION by the scalar
2292    evolution analyzer.  */
2293
2294 static bool
2295 scev_analyzable_p (tree def, sese region)
2296 {
2297   gimple stmt = SSA_NAME_DEF_STMT (def);
2298   loop_p loop = loop_containing_stmt (stmt);
2299   tree scev = scalar_evolution_in_region (region, loop, def);
2300
2301   return !chrec_contains_undetermined (scev);
2302 }
2303
2304 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2305    read from ZERO_DIM_ARRAY.  */
2306
2307 static void
2308 rewrite_cross_bb_scalar_dependence (tree zero_dim_array, tree def, gimple use_stmt)
2309 {
2310   tree var = SSA_NAME_VAR (def);
2311   gimple name_stmt = gimple_build_assign (var, zero_dim_array);
2312   tree name = make_ssa_name (var, name_stmt);
2313   ssa_op_iter iter;
2314   use_operand_p use_p;
2315   gimple_stmt_iterator gsi;
2316
2317   gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2318
2319   gimple_assign_set_lhs (name_stmt, name);
2320
2321   gsi = gsi_for_stmt (use_stmt);
2322   gsi_insert_before (&gsi, name_stmt, GSI_NEW_STMT);
2323
2324   FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2325     if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2326       replace_exp (use_p, name);
2327
2328   update_stmt (use_stmt);
2329 }
2330
2331 /* Rewrite the scalar dependences crossing the boundary of the BB
2332    containing STMT with an array.  */
2333
2334 static void
2335 rewrite_cross_bb_scalar_deps (sese region, gimple_stmt_iterator *gsi)
2336 {
2337   gimple stmt = gsi_stmt (*gsi);
2338   imm_use_iterator imm_iter;
2339   tree def;
2340   basic_block def_bb;
2341   tree zero_dim_array = NULL_TREE;
2342   gimple use_stmt;
2343
2344   if (gimple_code (stmt) != GIMPLE_ASSIGN)
2345     return;
2346
2347   def = gimple_assign_lhs (stmt);
2348   if (!is_gimple_reg (def)
2349       || scev_analyzable_p (def, region))
2350     return;
2351
2352   def_bb = gimple_bb (stmt);
2353
2354   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2355     if (def_bb != gimple_bb (use_stmt)
2356         && gimple_code (use_stmt) != GIMPLE_PHI)
2357       {
2358         if (!zero_dim_array)
2359           {
2360             zero_dim_array = create_zero_dim_array (SSA_NAME_VAR (def));
2361             insert_out_of_ssa_copy (zero_dim_array, def);
2362             gsi_next (gsi);
2363           }
2364
2365         rewrite_cross_bb_scalar_dependence (zero_dim_array, def, use_stmt);
2366       }
2367 }
2368
2369 /* Rewrite out of SSA all the reduction phi nodes of SCOP.  */
2370
2371 static void
2372 rewrite_reductions_out_of_ssa (scop_p scop)
2373 {
2374   basic_block bb;
2375   gimple_stmt_iterator psi;
2376   sese region = SCOP_REGION (scop);
2377
2378   FOR_EACH_BB (bb)
2379     if (bb_in_sese_p (bb, region))
2380       for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2381         {
2382           if (scalar_close_phi_node_p (gsi_stmt (psi)))
2383             rewrite_close_phi_out_of_ssa (&psi);
2384           else if (reduction_phi_p (region, &psi))
2385             rewrite_phi_out_of_ssa (&psi);
2386         }
2387
2388   update_ssa (TODO_update_ssa);
2389 #ifdef ENABLE_CHECKING
2390   verify_ssa (false);
2391   verify_loop_closed_ssa ();
2392 #endif
2393
2394   FOR_EACH_BB (bb)
2395     if (bb_in_sese_p (bb, region))
2396       for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2397         rewrite_cross_bb_scalar_deps (region, &psi);
2398
2399   update_ssa (TODO_update_ssa);
2400 #ifdef ENABLE_CHECKING
2401   verify_ssa (false);
2402   verify_loop_closed_ssa ();
2403 #endif
2404 }
2405
2406 /* Returns the number of pbbs that are in loops contained in SCOP.  */
2407
2408 static int
2409 nb_pbbs_in_loops (scop_p scop)
2410 {
2411   int i;
2412   poly_bb_p pbb;
2413   int res = 0;
2414
2415   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
2416     if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2417       res++;
2418
2419   return res;
2420 }
2421
2422 /* Return the number of data references in BB that write in
2423    memory.  */
2424
2425 static int
2426 nb_data_writes_in_bb (basic_block bb)
2427 {
2428   int res = 0;
2429   gimple_stmt_iterator gsi;
2430
2431   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2432     if (gimple_vdef (gsi_stmt (gsi)))
2433       res++;
2434
2435   return res;
2436 }
2437
2438 /* Splits STMT out of its current BB.  */
2439
2440 static basic_block
2441 split_reduction_stmt (gimple stmt)
2442 {
2443   gimple_stmt_iterator gsi;
2444   basic_block bb = gimple_bb (stmt);
2445   edge e;
2446
2447   /* Do not split basic blocks with no writes to memory: the reduction
2448      will be the only write to memory.  */
2449   if (nb_data_writes_in_bb (bb) == 0)
2450     return bb;
2451
2452   split_block (bb, stmt);
2453
2454   gsi = gsi_last_bb (bb);
2455   gsi_prev (&gsi);
2456   e = split_block (bb, gsi_stmt (gsi));
2457
2458   return e->dest;
2459 }
2460
2461 /* Return true when stmt is a reduction operation.  */
2462
2463 static inline bool
2464 is_reduction_operation_p (gimple stmt)
2465 {
2466   return flag_associative_math
2467     && commutative_tree_code (gimple_assign_rhs_code (stmt))
2468     && associative_tree_code (gimple_assign_rhs_code (stmt));
2469 }
2470
2471 /* Returns true when PHI contains an argument ARG.  */
2472
2473 static bool
2474 phi_contains_arg (gimple phi, tree arg)
2475 {
2476   size_t i;
2477
2478   for (i = 0; i < gimple_phi_num_args (phi); i++)
2479     if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2480       return true;
2481
2482   return false;
2483 }
2484
2485 /* Return a loop phi node that corresponds to a reduction containing LHS.  */
2486
2487 static gimple
2488 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2489 {
2490   gimple stmt;
2491
2492   if (TREE_CODE (arg) != SSA_NAME)
2493     return NULL;
2494
2495   stmt = SSA_NAME_DEF_STMT (arg);
2496
2497   if (gimple_code (stmt) == GIMPLE_PHI)
2498     {
2499       if (phi_contains_arg (stmt, lhs))
2500         return stmt;
2501       return NULL;
2502     }
2503
2504   if (gimple_num_ops (stmt) == 2)
2505     return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2506
2507   if (is_reduction_operation_p (stmt))
2508     {
2509       gimple res = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2510
2511       return res ? res :
2512         follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2513     }
2514
2515   return NULL;
2516 }
2517
2518 /* Detect commutative and associative scalar reductions starting at
2519    the STMT.  */
2520
2521 static gimple
2522 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2523                                   VEC (gimple, heap) **in,
2524                                   VEC (gimple, heap) **out)
2525 {
2526   gimple phi = follow_ssa_with_commutative_ops (arg, lhs);
2527
2528   if (phi)
2529     {
2530       VEC_safe_push (gimple, heap, *in, stmt);
2531       VEC_safe_push (gimple, heap, *out, stmt);
2532       return phi;
2533     }
2534
2535   return NULL;
2536 }
2537
2538 /* Detect commutative and associative scalar reductions starting at
2539    the STMT.  */
2540
2541 static gimple
2542 detect_commutative_reduction_assign (gimple stmt, VEC (gimple, heap) **in,
2543                                      VEC (gimple, heap) **out)
2544 {
2545   tree lhs = gimple_assign_lhs (stmt);
2546
2547   if (gimple_num_ops (stmt) == 2)
2548     return detect_commutative_reduction_arg (lhs, stmt,
2549                                              gimple_assign_rhs1 (stmt),
2550                                              in, out);
2551
2552   if (is_reduction_operation_p (stmt))
2553     {
2554       gimple res = detect_commutative_reduction_arg (lhs, stmt,
2555                                                      gimple_assign_rhs1 (stmt),
2556                                                      in, out);
2557       return res ? res
2558         : detect_commutative_reduction_arg (lhs, stmt,
2559                                             gimple_assign_rhs2 (stmt),
2560                                             in, out);
2561     }
2562
2563   return NULL;
2564 }
2565
2566 /* Return a loop phi node that corresponds to a reduction containing LHS.  */
2567
2568 static gimple
2569 follow_inital_value_to_phi (tree arg, tree lhs)
2570 {
2571   gimple stmt;
2572
2573   if (!arg || TREE_CODE (arg) != SSA_NAME)
2574     return NULL;
2575
2576   stmt = SSA_NAME_DEF_STMT (arg);
2577
2578   if (gimple_code (stmt) == GIMPLE_PHI
2579       && phi_contains_arg (stmt, lhs))
2580     return stmt;
2581
2582   return NULL;
2583 }
2584
2585
2586 /* Return the argument of the loop PHI that is the inital value coming
2587    from outside the loop.  */
2588
2589 static edge
2590 edge_initial_value_for_loop_phi (gimple phi)
2591 {
2592   size_t i;
2593
2594   for (i = 0; i < gimple_phi_num_args (phi); i++)
2595     {
2596       edge e = gimple_phi_arg_edge (phi, i);
2597
2598       if (loop_depth (e->src->loop_father)
2599           < loop_depth (e->dest->loop_father))
2600         return e;
2601     }
2602
2603   return NULL;
2604 }
2605
2606 /* Return the argument of the loop PHI that is the inital value coming
2607    from outside the loop.  */
2608
2609 static tree
2610 initial_value_for_loop_phi (gimple phi)
2611 {
2612   size_t i;
2613
2614   for (i = 0; i < gimple_phi_num_args (phi); i++)
2615     {
2616       edge e = gimple_phi_arg_edge (phi, i);
2617
2618       if (loop_depth (e->src->loop_father)
2619           < loop_depth (e->dest->loop_father))
2620         return gimple_phi_arg_def (phi, i);
2621     }
2622
2623   return NULL_TREE;
2624 }
2625
2626 /* Detect commutative and associative scalar reductions starting at
2627    the loop closed phi node CLOSE_PHI.  */
2628
2629 static gimple
2630 detect_commutative_reduction (gimple stmt, VEC (gimple, heap) **in,
2631                               VEC (gimple, heap) **out)
2632 {
2633   if (scalar_close_phi_node_p (stmt))
2634     {
2635       tree arg = gimple_phi_arg_def (stmt, 0);
2636       gimple def = SSA_NAME_DEF_STMT (arg);
2637       gimple loop_phi = detect_commutative_reduction (def, in, out);
2638
2639       if (loop_phi)
2640         {
2641           tree lhs = gimple_phi_result (stmt);
2642           tree init = initial_value_for_loop_phi (loop_phi);
2643           gimple phi = follow_inital_value_to_phi (init, lhs);
2644
2645           VEC_safe_push (gimple, heap, *in, loop_phi);
2646           VEC_safe_push (gimple, heap, *out, stmt);
2647           return phi;
2648         }
2649       else
2650         return NULL;
2651     }
2652
2653   if (gimple_code (stmt) == GIMPLE_ASSIGN)
2654     return detect_commutative_reduction_assign (stmt, in, out);
2655
2656   return NULL;
2657 }
2658
2659 /* Translate the scalar reduction statement STMT to an array RED
2660    knowing that its recursive phi node is LOOP_PHI.  */
2661
2662 static void
2663 translate_scalar_reduction_to_array_for_stmt (tree red, gimple stmt,
2664                                               gimple loop_phi)
2665 {
2666   basic_block bb = gimple_bb (stmt);
2667   gimple_stmt_iterator insert_gsi = gsi_after_labels (bb);
2668   tree res = gimple_phi_result (loop_phi);
2669   gimple assign = gimple_build_assign (res, red);
2670
2671   gsi_insert_before (&insert_gsi, assign, GSI_SAME_STMT);
2672
2673   assign = gimple_build_assign (red, gimple_assign_lhs (stmt));
2674   insert_gsi = gsi_for_stmt (stmt);
2675   gsi_insert_after (&insert_gsi, assign, GSI_SAME_STMT);
2676 }
2677
2678 /* Insert the assignment "result (CLOSE_PHI) = RED".  */
2679
2680 static void
2681 insert_copyout (tree red, gimple close_phi)
2682 {
2683   tree res = gimple_phi_result (close_phi);
2684   basic_block bb = gimple_bb (close_phi);
2685   gimple_stmt_iterator insert_gsi = gsi_after_labels (bb);
2686   gimple assign = gimple_build_assign (res, red);
2687
2688   gsi_insert_before (&insert_gsi, assign, GSI_SAME_STMT);
2689 }
2690
2691 /* Insert the assignment "RED = initial_value (LOOP_PHI)".  */
2692
2693 static void
2694 insert_copyin (tree red, gimple loop_phi)
2695 {
2696   gimple_seq stmts;
2697   tree init = initial_value_for_loop_phi (loop_phi);
2698   tree expr = build2 (MODIFY_EXPR, TREE_TYPE (init), red, init);
2699
2700   force_gimple_operand (expr, &stmts, true, NULL);
2701   gsi_insert_seq_on_edge (edge_initial_value_for_loop_phi (loop_phi), stmts);
2702 }
2703
2704 /* Rewrite out of SSA the reduction described by the loop phi nodes
2705    IN, and the close phi nodes OUT.  IN and OUT are structured by loop
2706    levels like this:
2707
2708    IN: stmt, loop_n, ..., loop_0
2709    OUT: stmt, close_n, ..., close_0
2710
2711    the first element is the reduction statement, and the next elements
2712    are the loop and close phi nodes of each of the outer loops.  */
2713
2714 static void
2715 translate_scalar_reduction_to_array (VEC (gimple, heap) *in,
2716                                      VEC (gimple, heap) *out,
2717                                      sbitmap reductions)
2718 {
2719   unsigned int i;
2720   gimple loop_phi;
2721   tree red;
2722   gimple_stmt_iterator gsi;
2723
2724   for (i = 0; VEC_iterate (gimple, in, i, loop_phi); i++)
2725     {
2726       gimple close_phi = VEC_index (gimple, out, i);
2727
2728       if (i == 0)
2729         {
2730           gimple stmt = loop_phi;
2731           basic_block bb = split_reduction_stmt (stmt);
2732
2733           SET_BIT (reductions, bb->index);
2734           gcc_assert (close_phi == loop_phi);
2735
2736           red = create_zero_dim_array (gimple_assign_lhs (stmt));
2737           translate_scalar_reduction_to_array_for_stmt
2738             (red, stmt, VEC_index (gimple, in, 1));
2739           continue;
2740         }
2741
2742       if (i == VEC_length (gimple, in) - 1)
2743         {
2744           insert_copyout (red, close_phi);
2745           insert_copyin (red, loop_phi);
2746         }
2747
2748       gsi = gsi_for_phi_node (loop_phi);
2749       remove_phi_node (&gsi, false);
2750
2751       gsi = gsi_for_phi_node (close_phi);
2752       remove_phi_node (&gsi, false);
2753     }
2754 }
2755
2756 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI.  */
2757
2758 static void
2759 rewrite_commutative_reductions_out_of_ssa_close_phi (gimple close_phi,
2760                                                      sbitmap reductions)
2761 {
2762   VEC (gimple, heap) *in = VEC_alloc (gimple, heap, 10);
2763   VEC (gimple, heap) *out = VEC_alloc (gimple, heap, 10);
2764
2765   detect_commutative_reduction (close_phi, &in, &out);
2766   if (VEC_length (gimple, in) > 0)
2767     translate_scalar_reduction_to_array (in, out, reductions);
2768
2769   VEC_free (gimple, heap, in);
2770   VEC_free (gimple, heap, out);
2771 }
2772
2773 /* Rewrites all the commutative reductions from LOOP out of SSA.  */
2774
2775 static void
2776 rewrite_commutative_reductions_out_of_ssa_loop (loop_p loop,
2777                                                 sbitmap reductions)
2778 {
2779   gimple_stmt_iterator gsi;
2780   edge exit = single_exit (loop);
2781
2782   if (!exit)
2783     return;
2784
2785   for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
2786     rewrite_commutative_reductions_out_of_ssa_close_phi (gsi_stmt (gsi),
2787                                                          reductions);
2788 }
2789
2790 /* Rewrites all the commutative reductions from SCOP out of SSA.  */
2791
2792 static void
2793 rewrite_commutative_reductions_out_of_ssa (sese region, sbitmap reductions)
2794 {
2795   loop_iterator li;
2796   loop_p loop;
2797
2798   FOR_EACH_LOOP (li, loop, 0)
2799     if (loop_in_sese_p (loop, region))
2800       rewrite_commutative_reductions_out_of_ssa_loop (loop, reductions);
2801
2802   gsi_commit_edge_inserts ();
2803   update_ssa (TODO_update_ssa);
2804 #ifdef ENABLE_CHECKING
2805   verify_ssa (false);
2806   verify_loop_closed_ssa ();
2807 #endif
2808 }
2809
2810 /* Builds the polyhedral representation for a SESE region.  */
2811
2812 bool
2813 build_poly_scop (scop_p scop)
2814 {
2815   sese region = SCOP_REGION (scop);
2816   sbitmap reductions = sbitmap_alloc (last_basic_block * 2);
2817
2818   sbitmap_zero (reductions);
2819   rewrite_commutative_reductions_out_of_ssa (region, reductions);
2820   rewrite_reductions_out_of_ssa (scop);
2821   build_scop_bbs (scop, reductions);
2822   sbitmap_free (reductions);
2823
2824   /* FIXME: This restriction is needed to avoid a problem in CLooG.
2825      Once CLooG is fixed, remove this guard.  Anyways, it makes no
2826      sense to optimize a scop containing only PBBs that do not belong
2827      to any loops.  */
2828   if (nb_pbbs_in_loops (scop) == 0)
2829     return false;
2830
2831   build_sese_loop_nests (region);
2832   build_sese_conditions (region);
2833   find_scop_parameters (scop);
2834
2835   build_scop_iteration_domain (scop);
2836   build_scop_context (scop);
2837
2838   add_conditions_to_constraints (scop);
2839   scop_to_lst (scop);
2840   build_scop_scattering (scop);
2841   build_scop_drs (scop);
2842
2843   return true;
2844 }
2845
2846 /* Always return false.  Exercise the scop_to_clast function.  */
2847
2848 void
2849 check_poly_representation (scop_p scop ATTRIBUTE_UNUSED)
2850 {
2851 #ifdef ENABLE_CHECKING
2852   cloog_prog_clast pc = scop_to_clast (scop);
2853   cloog_clast_free (pc.stmt);
2854   cloog_program_free (pc.prog);
2855 #endif
2856 }
2857 #endif