OSDN Git Service

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