OSDN Git Service

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