OSDN Git Service

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