OSDN Git Service

Fix PR46924: Do not detect reductions outside the current SESE region.
[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       mpz_set_si (val, int_cst_value (e));
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   int v = int_cst_value (cst);
630
631   mpz_init (val);
632   mpz_set_si (val, 0);
633
634   /* Necessary to not get "-1 = 2^n - 1". */
635   if (v < 0)
636     mpz_sub_ui (val, val, -v);
637   else
638     mpz_add_ui (val, val, v);
639
640   mpz_mul (val, val, k);
641   ppl_new_Coefficient (&coef);
642   ppl_assign_Coefficient_from_mpz_t (coef, val);
643   ppl_Linear_Expression_add_to_inhomogeneous (expr, coef);
644   mpz_clear (val);
645   ppl_delete_Coefficient (coef);
646 }
647
648 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
649    Otherwise returns -1.  */
650
651 static inline int
652 parameter_index_in_region_1 (tree name, sese region)
653 {
654   int i;
655   tree p;
656
657   gcc_assert (TREE_CODE (name) == SSA_NAME);
658
659   FOR_EACH_VEC_ELT (tree, SESE_PARAMS (region), i, p)
660     if (p == name)
661       return i;
662
663   return -1;
664 }
665
666 /* When the parameter NAME is in REGION, returns its index in
667    SESE_PARAMS.  Otherwise this function inserts NAME in SESE_PARAMS
668    and returns the index of NAME.  */
669
670 static int
671 parameter_index_in_region (tree name, sese region)
672 {
673   int i;
674
675   gcc_assert (TREE_CODE (name) == SSA_NAME);
676
677   i = parameter_index_in_region_1 (name, region);
678   if (i != -1)
679     return i;
680
681   gcc_assert (SESE_ADD_PARAMS (region));
682
683   i = VEC_length (tree, SESE_PARAMS (region));
684   VEC_safe_push (tree, heap, SESE_PARAMS (region), name);
685   return i;
686 }
687
688 /* In the context of sese S, scan the expression E and translate it to
689    a linear expression C.  When parsing a symbolic multiplication, K
690    represents the constant multiplier of an expression containing
691    parameters.  */
692
693 static void
694 scan_tree_for_params (sese s, tree e, ppl_Linear_Expression_t c,
695                       mpz_t k)
696 {
697   if (e == chrec_dont_know)
698     return;
699
700   switch (TREE_CODE (e))
701     {
702     case POLYNOMIAL_CHREC:
703       scan_tree_for_params_right_scev (s, CHREC_RIGHT (e),
704                                        CHREC_VARIABLE (e), c);
705       scan_tree_for_params (s, CHREC_LEFT (e), c, k);
706       break;
707
708     case MULT_EXPR:
709       if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
710         {
711           if (c)
712             {
713               mpz_t val;
714               gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0));
715               mpz_init (val);
716               mpz_set_si (val, int_cst_value (TREE_OPERAND (e, 1)));
717               mpz_mul (val, val, k);
718               scan_tree_for_params (s, TREE_OPERAND (e, 0), c, val);
719               mpz_clear (val);
720             }
721           else
722             scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
723         }
724       else
725         {
726           if (c)
727             {
728               mpz_t val;
729               gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0));
730               mpz_init (val);
731               mpz_set_si (val, int_cst_value (TREE_OPERAND (e, 0)));
732               mpz_mul (val, val, k);
733               scan_tree_for_params (s, TREE_OPERAND (e, 1), c, val);
734               mpz_clear (val);
735             }
736           else
737             scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k);
738         }
739       break;
740
741     case PLUS_EXPR:
742     case POINTER_PLUS_EXPR:
743       scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
744       scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k);
745       break;
746
747     case MINUS_EXPR:
748       {
749         ppl_Linear_Expression_t tmp_expr = NULL;
750
751         if (c)
752           {
753             ppl_dimension_type dim;
754             ppl_Linear_Expression_space_dimension (c, &dim);
755             ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
756           }
757
758         scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
759         scan_tree_for_params (s, TREE_OPERAND (e, 1), tmp_expr, k);
760
761         if (c)
762           {
763             ppl_subtract_Linear_Expression_from_Linear_Expression (c,
764                                                                    tmp_expr);
765             ppl_delete_Linear_Expression (tmp_expr);
766           }
767
768         break;
769       }
770
771     case NEGATE_EXPR:
772       {
773         ppl_Linear_Expression_t tmp_expr = NULL;
774
775         if (c)
776           {
777             ppl_dimension_type dim;
778             ppl_Linear_Expression_space_dimension (c, &dim);
779             ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
780           }
781
782         scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k);
783
784         if (c)
785           {
786             ppl_subtract_Linear_Expression_from_Linear_Expression (c,
787                                                                    tmp_expr);
788             ppl_delete_Linear_Expression (tmp_expr);
789           }
790
791         break;
792       }
793
794     case BIT_NOT_EXPR:
795       {
796         ppl_Linear_Expression_t tmp_expr = NULL;
797
798         if (c)
799           {
800             ppl_dimension_type dim;
801             ppl_Linear_Expression_space_dimension (c, &dim);
802             ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
803           }
804
805         scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k);
806
807         if (c)
808           {
809             ppl_Coefficient_t coef;
810             mpz_t minus_one;
811
812             ppl_subtract_Linear_Expression_from_Linear_Expression (c,
813                                                                    tmp_expr);
814             ppl_delete_Linear_Expression (tmp_expr);
815             mpz_init (minus_one);
816             mpz_set_si (minus_one, -1);
817             ppl_new_Coefficient_from_mpz_t (&coef, minus_one);
818             ppl_Linear_Expression_add_to_inhomogeneous (c, coef);
819             mpz_clear (minus_one);
820             ppl_delete_Coefficient (coef);
821           }
822
823         break;
824       }
825
826     case SSA_NAME:
827       {
828         ppl_dimension_type p = parameter_index_in_region (e, s);
829
830         if (c)
831           {
832             ppl_dimension_type dim;
833             ppl_Linear_Expression_space_dimension (c, &dim);
834             p += dim - sese_nb_params (s);
835             add_value_to_dim (p, c, k);
836           }
837         break;
838       }
839
840     case INTEGER_CST:
841       if (c)
842         scan_tree_for_params_int (e, c, k);
843       break;
844
845     CASE_CONVERT:
846     case NON_LVALUE_EXPR:
847       scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
848       break;
849
850    default:
851       gcc_unreachable ();
852       break;
853     }
854 }
855
856 /* Find parameters with respect to REGION in BB. We are looking in memory
857    access functions, conditions and loop bounds.  */
858
859 static void
860 find_params_in_bb (sese region, gimple_bb_p gbb)
861 {
862   int i;
863   unsigned j;
864   data_reference_p dr;
865   gimple stmt;
866   loop_p loop = GBB_BB (gbb)->loop_father;
867   mpz_t one;
868
869   mpz_init (one);
870   mpz_set_si (one, 1);
871
872   /* Find parameters in the access functions of data references.  */
873   FOR_EACH_VEC_ELT (data_reference_p, GBB_DATA_REFS (gbb), i, dr)
874     for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
875       scan_tree_for_params (region, DR_ACCESS_FN (dr, j), NULL, one);
876
877   /* Find parameters in conditional statements.  */
878   FOR_EACH_VEC_ELT (gimple, GBB_CONDITIONS (gbb), i, stmt)
879     {
880       tree lhs = scalar_evolution_in_region (region, loop,
881                                              gimple_cond_lhs (stmt));
882       tree rhs = scalar_evolution_in_region (region, loop,
883                                              gimple_cond_rhs (stmt));
884
885       scan_tree_for_params (region, lhs, NULL, one);
886       scan_tree_for_params (region, rhs, NULL, one);
887     }
888
889   mpz_clear (one);
890 }
891
892 /* Record the parameters used in the SCOP.  A variable is a parameter
893    in a scop if it does not vary during the execution of that scop.  */
894
895 static void
896 find_scop_parameters (scop_p scop)
897 {
898   poly_bb_p pbb;
899   unsigned i;
900   sese region = SCOP_REGION (scop);
901   struct loop *loop;
902   mpz_t one;
903
904   mpz_init (one);
905   mpz_set_si (one, 1);
906
907   /* Find the parameters used in the loop bounds.  */
908   FOR_EACH_VEC_ELT (loop_p, SESE_LOOP_NEST (region), i, loop)
909     {
910       tree nb_iters = number_of_latch_executions (loop);
911
912       if (!chrec_contains_symbols (nb_iters))
913         continue;
914
915       nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
916       scan_tree_for_params (region, nb_iters, NULL, one);
917     }
918
919   mpz_clear (one);
920
921   /* Find the parameters used in data accesses.  */
922   FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
923     find_params_in_bb (region, PBB_BLACK_BOX (pbb));
924
925   scop_set_nb_params (scop, sese_nb_params (region));
926   SESE_ADD_PARAMS (region) = false;
927
928   ppl_new_Pointset_Powerset_C_Polyhedron_from_space_dimension
929     (&SCOP_CONTEXT (scop), scop_nb_params (scop), 0);
930 }
931
932 /* Insert in the SCOP context constraints from the estimation of the
933    number of iterations.  UB_EXPR is a linear expression describing
934    the number of iterations in a loop.  This expression is bounded by
935    the estimation NIT.  */
936
937 static void
938 add_upper_bounds_from_estimated_nit (scop_p scop, double_int nit,
939                                      ppl_dimension_type dim,
940                                      ppl_Linear_Expression_t ub_expr)
941 {
942   mpz_t val;
943   ppl_Linear_Expression_t nb_iters_le;
944   ppl_Polyhedron_t pol;
945   ppl_Coefficient_t coef;
946   ppl_Constraint_t ub;
947
948   ppl_new_C_Polyhedron_from_space_dimension (&pol, dim, 0);
949   ppl_new_Linear_Expression_from_Linear_Expression (&nb_iters_le,
950                                                     ub_expr);
951
952   /* Construct the negated number of last iteration in VAL.  */
953   mpz_init (val);
954   mpz_set_double_int (val, nit, false);
955   mpz_sub_ui (val, val, 1);
956   mpz_neg (val, val);
957
958   /* NB_ITERS_LE holds the number of last iteration in
959      parametrical form.  Subtract estimated number of last
960      iteration and assert that result is not positive.  */
961   ppl_new_Coefficient_from_mpz_t (&coef, val);
962   ppl_Linear_Expression_add_to_inhomogeneous (nb_iters_le, coef);
963   ppl_delete_Coefficient (coef);
964   ppl_new_Constraint (&ub, nb_iters_le,
965                       PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL);
966   ppl_Polyhedron_add_constraint (pol, ub);
967
968   /* Remove all but last GDIM dimensions from POL to obtain
969      only the constraints on the parameters.  */
970   {
971     graphite_dim_t gdim = scop_nb_params (scop);
972     ppl_dimension_type *dims = XNEWVEC (ppl_dimension_type, dim - gdim);
973     graphite_dim_t i;
974
975     for (i = 0; i < dim - gdim; i++)
976       dims[i] = i;
977
978     ppl_Polyhedron_remove_space_dimensions (pol, dims, dim - gdim);
979     XDELETEVEC (dims);
980   }
981
982   /* Add the constraints on the parameters to the SCoP context.  */
983   {
984     ppl_Pointset_Powerset_C_Polyhedron_t constraints_ps;
985
986     ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
987       (&constraints_ps, pol);
988     ppl_Pointset_Powerset_C_Polyhedron_intersection_assign
989       (SCOP_CONTEXT (scop), constraints_ps);
990     ppl_delete_Pointset_Powerset_C_Polyhedron (constraints_ps);
991   }
992
993   ppl_delete_Polyhedron (pol);
994   ppl_delete_Linear_Expression (nb_iters_le);
995   ppl_delete_Constraint (ub);
996   mpz_clear (val);
997 }
998
999 /* Builds the constraint polyhedra for LOOP in SCOP.  OUTER_PH gives
1000    the constraints for the surrounding loops.  */
1001
1002 static void
1003 build_loop_iteration_domains (scop_p scop, struct loop *loop,
1004                               ppl_Polyhedron_t outer_ph, int nb,
1005                               ppl_Pointset_Powerset_C_Polyhedron_t *domains)
1006 {
1007   int i;
1008   ppl_Polyhedron_t ph;
1009   tree nb_iters = number_of_latch_executions (loop);
1010   ppl_dimension_type dim = nb + 1 + scop_nb_params (scop);
1011   sese region = SCOP_REGION (scop);
1012
1013   {
1014     ppl_const_Constraint_System_t pcs;
1015     ppl_dimension_type *map
1016       = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim);
1017
1018     ppl_new_C_Polyhedron_from_space_dimension (&ph, dim, 0);
1019     ppl_Polyhedron_get_constraints (outer_ph, &pcs);
1020     ppl_Polyhedron_add_constraints (ph, pcs);
1021
1022     for (i = 0; i < (int) nb; i++)
1023       map[i] = i;
1024     for (i = (int) nb; i < (int) dim - 1; i++)
1025       map[i] = i + 1;
1026     map[dim - 1] = nb;
1027
1028     ppl_Polyhedron_map_space_dimensions (ph, map, dim);
1029     free (map);
1030   }
1031
1032   /* 0 <= loop_i */
1033   {
1034     ppl_Constraint_t lb;
1035     ppl_Linear_Expression_t lb_expr;
1036
1037     ppl_new_Linear_Expression_with_dimension (&lb_expr, dim);
1038     ppl_set_coef (lb_expr, nb, 1);
1039     ppl_new_Constraint (&lb, lb_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1040     ppl_delete_Linear_Expression (lb_expr);
1041     ppl_Polyhedron_add_constraint (ph, lb);
1042     ppl_delete_Constraint (lb);
1043   }
1044
1045   if (TREE_CODE (nb_iters) == INTEGER_CST)
1046     {
1047       ppl_Constraint_t ub;
1048       ppl_Linear_Expression_t ub_expr;
1049
1050       ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1051
1052       /* loop_i <= cst_nb_iters */
1053       ppl_set_coef (ub_expr, nb, -1);
1054       ppl_set_inhomogeneous_tree (ub_expr, nb_iters);
1055       ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1056       ppl_Polyhedron_add_constraint (ph, ub);
1057       ppl_delete_Linear_Expression (ub_expr);
1058       ppl_delete_Constraint (ub);
1059     }
1060   else if (!chrec_contains_undetermined (nb_iters))
1061     {
1062       mpz_t one;
1063       ppl_Constraint_t ub;
1064       ppl_Linear_Expression_t ub_expr;
1065       double_int nit;
1066
1067       mpz_init (one);
1068       mpz_set_si (one, 1);
1069       ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1070       nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1071       scan_tree_for_params (SCOP_REGION (scop), nb_iters, ub_expr, one);
1072       mpz_clear (one);
1073
1074       if (estimated_loop_iterations (loop, true, &nit))
1075         add_upper_bounds_from_estimated_nit (scop, nit, dim, ub_expr);
1076
1077       /* loop_i <= expr_nb_iters */
1078       ppl_set_coef (ub_expr, nb, -1);
1079       ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1080       ppl_Polyhedron_add_constraint (ph, ub);
1081       ppl_delete_Linear_Expression (ub_expr);
1082       ppl_delete_Constraint (ub);
1083     }
1084   else
1085     gcc_unreachable ();
1086
1087   if (loop->inner && loop_in_sese_p (loop->inner, region))
1088     build_loop_iteration_domains (scop, loop->inner, ph, nb + 1, domains);
1089
1090   if (nb != 0
1091       && loop->next
1092       && loop_in_sese_p (loop->next, region))
1093     build_loop_iteration_domains (scop, loop->next, outer_ph, nb, domains);
1094
1095   ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1096     (&domains[loop->num], ph);
1097
1098   ppl_delete_Polyhedron (ph);
1099 }
1100
1101 /* Returns a linear expression for tree T evaluated in PBB.  */
1102
1103 static ppl_Linear_Expression_t
1104 create_linear_expr_from_tree (poly_bb_p pbb, tree t)
1105 {
1106   mpz_t one;
1107   ppl_Linear_Expression_t res;
1108   ppl_dimension_type dim;
1109   sese region = SCOP_REGION (PBB_SCOP (pbb));
1110   loop_p loop = pbb_loop (pbb);
1111
1112   dim = pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb);
1113   ppl_new_Linear_Expression_with_dimension (&res, dim);
1114
1115   t = scalar_evolution_in_region (region, loop, t);
1116   gcc_assert (!automatically_generated_chrec_p (t));
1117
1118   mpz_init (one);
1119   mpz_set_si (one, 1);
1120   scan_tree_for_params (region, t, res, one);
1121   mpz_clear (one);
1122
1123   return res;
1124 }
1125
1126 /* Returns the ppl constraint type from the gimple tree code CODE.  */
1127
1128 static enum ppl_enum_Constraint_Type
1129 ppl_constraint_type_from_tree_code (enum tree_code code)
1130 {
1131   switch (code)
1132     {
1133     /* We do not support LT and GT to be able to work with C_Polyhedron.
1134        As we work on integer polyhedron "a < b" can be expressed by
1135        "a + 1 <= b".  */
1136     case LT_EXPR:
1137     case GT_EXPR:
1138       gcc_unreachable ();
1139
1140     case LE_EXPR:
1141       return PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL;
1142
1143     case GE_EXPR:
1144       return PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL;
1145
1146     case EQ_EXPR:
1147       return PPL_CONSTRAINT_TYPE_EQUAL;
1148
1149     default:
1150       gcc_unreachable ();
1151     }
1152 }
1153
1154 /* Add conditional statement STMT to PS.  It is evaluated in PBB and
1155    CODE is used as the comparison operator.  This allows us to invert the
1156    condition or to handle inequalities.  */
1157
1158 static void
1159 add_condition_to_domain (ppl_Pointset_Powerset_C_Polyhedron_t ps, gimple stmt,
1160                          poly_bb_p pbb, enum tree_code code)
1161 {
1162   mpz_t v;
1163   ppl_Coefficient_t c;
1164   ppl_Linear_Expression_t left, right;
1165   ppl_Constraint_t cstr;
1166   enum ppl_enum_Constraint_Type type;
1167
1168   left = create_linear_expr_from_tree (pbb, gimple_cond_lhs (stmt));
1169   right = create_linear_expr_from_tree (pbb, gimple_cond_rhs (stmt));
1170
1171   /* If we have < or > expressions convert them to <= or >= by adding 1 to
1172      the left or the right side of the expression. */
1173   if (code == LT_EXPR)
1174     {
1175       mpz_init (v);
1176       mpz_set_si (v, 1);
1177       ppl_new_Coefficient (&c);
1178       ppl_assign_Coefficient_from_mpz_t (c, v);
1179       ppl_Linear_Expression_add_to_inhomogeneous (left, c);
1180       ppl_delete_Coefficient (c);
1181       mpz_clear (v);
1182
1183       code = LE_EXPR;
1184     }
1185   else if (code == GT_EXPR)
1186     {
1187       mpz_init (v);
1188       mpz_set_si (v, 1);
1189       ppl_new_Coefficient (&c);
1190       ppl_assign_Coefficient_from_mpz_t (c, v);
1191       ppl_Linear_Expression_add_to_inhomogeneous (right, c);
1192       ppl_delete_Coefficient (c);
1193       mpz_clear (v);
1194
1195       code = GE_EXPR;
1196     }
1197
1198   type = ppl_constraint_type_from_tree_code (code);
1199
1200   ppl_subtract_Linear_Expression_from_Linear_Expression (left, right);
1201
1202   ppl_new_Constraint (&cstr, left, type);
1203   ppl_Pointset_Powerset_C_Polyhedron_add_constraint (ps, cstr);
1204
1205   ppl_delete_Constraint (cstr);
1206   ppl_delete_Linear_Expression (left);
1207   ppl_delete_Linear_Expression (right);
1208 }
1209
1210 /* Add conditional statement STMT to pbb.  CODE is used as the comparision
1211    operator.  This allows us to invert the condition or to handle
1212    inequalities.  */
1213
1214 static void
1215 add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code)
1216 {
1217   if (code == NE_EXPR)
1218     {
1219       ppl_Pointset_Powerset_C_Polyhedron_t left = PBB_DOMAIN (pbb);
1220       ppl_Pointset_Powerset_C_Polyhedron_t right;
1221       ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1222         (&right, left);
1223       add_condition_to_domain (left, stmt, pbb, LT_EXPR);
1224       add_condition_to_domain (right, stmt, pbb, GT_EXPR);
1225       ppl_Pointset_Powerset_C_Polyhedron_upper_bound_assign (left, right);
1226       ppl_delete_Pointset_Powerset_C_Polyhedron (right);
1227     }
1228   else
1229     add_condition_to_domain (PBB_DOMAIN (pbb), stmt, pbb, code);
1230 }
1231
1232 /* Add conditions to the domain of PBB.  */
1233
1234 static void
1235 add_conditions_to_domain (poly_bb_p pbb)
1236 {
1237   unsigned int i;
1238   gimple stmt;
1239   gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1240
1241   if (VEC_empty (gimple, GBB_CONDITIONS (gbb)))
1242     return;
1243
1244   FOR_EACH_VEC_ELT (gimple, GBB_CONDITIONS (gbb), i, stmt)
1245     switch (gimple_code (stmt))
1246       {
1247       case GIMPLE_COND:
1248           {
1249             enum tree_code code = gimple_cond_code (stmt);
1250
1251             /* The conditions for ELSE-branches are inverted.  */
1252             if (!VEC_index (gimple, GBB_CONDITION_CASES (gbb), i))
1253               code = invert_tree_comparison (code, false);
1254
1255             add_condition_to_pbb (pbb, stmt, code);
1256             break;
1257           }
1258
1259       case GIMPLE_SWITCH:
1260         /* Switch statements are not supported right now - fall throught.  */
1261
1262       default:
1263         gcc_unreachable ();
1264         break;
1265       }
1266 }
1267
1268 /* Traverses all the GBBs of the SCOP and add their constraints to the
1269    iteration domains.  */
1270
1271 static void
1272 add_conditions_to_constraints (scop_p scop)
1273 {
1274   int i;
1275   poly_bb_p pbb;
1276
1277   FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
1278     add_conditions_to_domain (pbb);
1279 }
1280
1281 /* Structure used to pass data to dom_walk.  */
1282
1283 struct bsc
1284 {
1285   VEC (gimple, heap) **conditions, **cases;
1286   sese region;
1287 };
1288
1289 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1290    edge between BB and its predecessor is not a loop exit edge, and
1291    the last statement of the single predecessor is a COND_EXPR.  */
1292
1293 static gimple
1294 single_pred_cond_non_loop_exit (basic_block bb)
1295 {
1296   if (single_pred_p (bb))
1297     {
1298       edge e = single_pred_edge (bb);
1299       basic_block pred = e->src;
1300       gimple stmt;
1301
1302       if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
1303         return NULL;
1304
1305       stmt = last_stmt (pred);
1306
1307       if (stmt && gimple_code (stmt) == GIMPLE_COND)
1308         return stmt;
1309     }
1310
1311   return NULL;
1312 }
1313
1314 /* Call-back for dom_walk executed before visiting the dominated
1315    blocks.  */
1316
1317 static void
1318 build_sese_conditions_before (struct dom_walk_data *dw_data,
1319                               basic_block bb)
1320 {
1321   struct bsc *data = (struct bsc *) dw_data->global_data;
1322   VEC (gimple, heap) **conditions = data->conditions;
1323   VEC (gimple, heap) **cases = data->cases;
1324   gimple_bb_p gbb;
1325   gimple stmt;
1326
1327   if (!bb_in_sese_p (bb, data->region))
1328     return;
1329
1330   stmt = single_pred_cond_non_loop_exit (bb);
1331
1332   if (stmt)
1333     {
1334       edge e = single_pred_edge (bb);
1335
1336       VEC_safe_push (gimple, heap, *conditions, stmt);
1337
1338       if (e->flags & EDGE_TRUE_VALUE)
1339         VEC_safe_push (gimple, heap, *cases, stmt);
1340       else
1341         VEC_safe_push (gimple, heap, *cases, NULL);
1342     }
1343
1344   gbb = gbb_from_bb (bb);
1345
1346   if (gbb)
1347     {
1348       GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
1349       GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
1350     }
1351 }
1352
1353 /* Call-back for dom_walk executed after visiting the dominated
1354    blocks.  */
1355
1356 static void
1357 build_sese_conditions_after (struct dom_walk_data *dw_data,
1358                              basic_block bb)
1359 {
1360   struct bsc *data = (struct bsc *) dw_data->global_data;
1361   VEC (gimple, heap) **conditions = data->conditions;
1362   VEC (gimple, heap) **cases = data->cases;
1363
1364   if (!bb_in_sese_p (bb, data->region))
1365     return;
1366
1367   if (single_pred_cond_non_loop_exit (bb))
1368     {
1369       VEC_pop (gimple, *conditions);
1370       VEC_pop (gimple, *cases);
1371     }
1372 }
1373
1374 /* Record all conditions in REGION.  */
1375
1376 static void
1377 build_sese_conditions (sese region)
1378 {
1379   struct dom_walk_data walk_data;
1380   VEC (gimple, heap) *conditions = VEC_alloc (gimple, heap, 3);
1381   VEC (gimple, heap) *cases = VEC_alloc (gimple, heap, 3);
1382   struct bsc data;
1383
1384   data.conditions = &conditions;
1385   data.cases = &cases;
1386   data.region = region;
1387
1388   walk_data.dom_direction = CDI_DOMINATORS;
1389   walk_data.initialize_block_local_data = NULL;
1390   walk_data.before_dom_children = build_sese_conditions_before;
1391   walk_data.after_dom_children = build_sese_conditions_after;
1392   walk_data.global_data = &data;
1393   walk_data.block_local_data_size = 0;
1394
1395   init_walk_dominator_tree (&walk_data);
1396   walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region));
1397   fini_walk_dominator_tree (&walk_data);
1398
1399   VEC_free (gimple, heap, conditions);
1400   VEC_free (gimple, heap, cases);
1401 }
1402
1403 /* Add constraints on the possible values of parameter P from the type
1404    of P.  */
1405
1406 static void
1407 add_param_constraints (scop_p scop, ppl_Polyhedron_t context, graphite_dim_t p)
1408 {
1409   ppl_Constraint_t cstr;
1410   ppl_Linear_Expression_t le;
1411   tree parameter = VEC_index (tree, SESE_PARAMS (SCOP_REGION (scop)), p);
1412   tree type = TREE_TYPE (parameter);
1413   tree lb = NULL_TREE;
1414   tree ub = NULL_TREE;
1415
1416   if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
1417     lb = lower_bound_in_type (type, type);
1418   else
1419     lb = TYPE_MIN_VALUE (type);
1420
1421   if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
1422     ub = upper_bound_in_type (type, type);
1423   else
1424     ub = TYPE_MAX_VALUE (type);
1425
1426   if (lb)
1427     {
1428       ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1429       ppl_set_coef (le, p, -1);
1430       ppl_set_inhomogeneous_tree (le, lb);
1431       ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL);
1432       ppl_Polyhedron_add_constraint (context, cstr);
1433       ppl_delete_Linear_Expression (le);
1434       ppl_delete_Constraint (cstr);
1435     }
1436
1437   if (ub)
1438     {
1439       ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1440       ppl_set_coef (le, p, -1);
1441       ppl_set_inhomogeneous_tree (le, ub);
1442       ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1443       ppl_Polyhedron_add_constraint (context, cstr);
1444       ppl_delete_Linear_Expression (le);
1445       ppl_delete_Constraint (cstr);
1446     }
1447 }
1448
1449 /* Build the context of the SCOP.  The context usually contains extra
1450    constraints that are added to the iteration domains that constrain
1451    some parameters.  */
1452
1453 static void
1454 build_scop_context (scop_p scop)
1455 {
1456   ppl_Polyhedron_t context;
1457   ppl_Pointset_Powerset_C_Polyhedron_t ps;
1458   graphite_dim_t p, n = scop_nb_params (scop);
1459
1460   ppl_new_C_Polyhedron_from_space_dimension (&context, n, 0);
1461
1462   for (p = 0; p < n; p++)
1463     add_param_constraints (scop, context, p);
1464
1465   ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1466     (&ps, context);
1467   ppl_Pointset_Powerset_C_Polyhedron_intersection_assign
1468     (SCOP_CONTEXT (scop), ps);
1469
1470   ppl_delete_Pointset_Powerset_C_Polyhedron (ps);
1471   ppl_delete_Polyhedron (context);
1472 }
1473
1474 /* Build the iteration domains: the loops belonging to the current
1475    SCOP, and that vary for the execution of the current basic block.
1476    Returns false if there is no loop in SCOP.  */
1477
1478 static void
1479 build_scop_iteration_domain (scop_p scop)
1480 {
1481   struct loop *loop;
1482   sese region = SCOP_REGION (scop);
1483   int i;
1484   ppl_Polyhedron_t ph;
1485   poly_bb_p pbb;
1486   int nb_loops = number_of_loops ();
1487   ppl_Pointset_Powerset_C_Polyhedron_t *domains
1488     = XNEWVEC (ppl_Pointset_Powerset_C_Polyhedron_t, nb_loops);
1489
1490   for (i = 0; i < nb_loops; i++)
1491     domains[i] = NULL;
1492
1493   ppl_new_C_Polyhedron_from_space_dimension (&ph, scop_nb_params (scop), 0);
1494
1495   FOR_EACH_VEC_ELT (loop_p, SESE_LOOP_NEST (region), i, loop)
1496     if (!loop_in_sese_p (loop_outer (loop), region))
1497       build_loop_iteration_domains (scop, loop, ph, 0, domains);
1498
1499   FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
1500     if (domains[gbb_loop (PBB_BLACK_BOX (pbb))->num])
1501       ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1502         (&PBB_DOMAIN (pbb), (ppl_const_Pointset_Powerset_C_Polyhedron_t)
1503          domains[gbb_loop (PBB_BLACK_BOX (pbb))->num]);
1504     else
1505       ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1506         (&PBB_DOMAIN (pbb), ph);
1507
1508   for (i = 0; i < nb_loops; i++)
1509     if (domains[i])
1510       ppl_delete_Pointset_Powerset_C_Polyhedron (domains[i]);
1511
1512   ppl_delete_Polyhedron (ph);
1513   free (domains);
1514 }
1515
1516 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1517    data reference DR.  ACCESSP_NB_DIMS is the dimension of the
1518    ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1519    domain.  */
1520
1521 static void
1522 pdr_add_alias_set (ppl_Polyhedron_t accesses, data_reference_p dr,
1523                    ppl_dimension_type accessp_nb_dims,
1524                    ppl_dimension_type dom_nb_dims)
1525 {
1526   ppl_Linear_Expression_t alias;
1527   ppl_Constraint_t cstr;
1528   int alias_set_num = 0;
1529   base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1530
1531   if (bap && bap->alias_set)
1532     alias_set_num = *(bap->alias_set);
1533
1534   ppl_new_Linear_Expression_with_dimension (&alias, accessp_nb_dims);
1535
1536   ppl_set_coef (alias, dom_nb_dims, 1);
1537   ppl_set_inhomogeneous (alias, -alias_set_num);
1538   ppl_new_Constraint (&cstr, alias, PPL_CONSTRAINT_TYPE_EQUAL);
1539   ppl_Polyhedron_add_constraint (accesses, cstr);
1540
1541   ppl_delete_Linear_Expression (alias);
1542   ppl_delete_Constraint (cstr);
1543 }
1544
1545 /* Add to ACCESSES polyhedron equalities defining the access functions
1546    to the memory.  ACCESSP_NB_DIMS is the dimension of the ACCESSES
1547    polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1548    PBB is the poly_bb_p that contains the data reference DR.  */
1549
1550 static void
1551 pdr_add_memory_accesses (ppl_Polyhedron_t accesses, data_reference_p dr,
1552                          ppl_dimension_type accessp_nb_dims,
1553                          ppl_dimension_type dom_nb_dims,
1554                          poly_bb_p pbb)
1555 {
1556   int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1557   mpz_t v;
1558   scop_p scop = PBB_SCOP (pbb);
1559   sese region = SCOP_REGION (scop);
1560
1561   mpz_init (v);
1562
1563   for (i = 0; i < nb_subscripts; i++)
1564     {
1565       ppl_Linear_Expression_t fn, access;
1566       ppl_Constraint_t cstr;
1567       ppl_dimension_type subscript = dom_nb_dims + 1 + i;
1568       tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1569
1570       ppl_new_Linear_Expression_with_dimension (&fn, dom_nb_dims);
1571       ppl_new_Linear_Expression_with_dimension (&access, accessp_nb_dims);
1572
1573       mpz_set_si (v, 1);
1574       scan_tree_for_params (region, afn, fn, v);
1575       ppl_assign_Linear_Expression_from_Linear_Expression (access, fn);
1576
1577       ppl_set_coef (access, subscript, -1);
1578       ppl_new_Constraint (&cstr, access, PPL_CONSTRAINT_TYPE_EQUAL);
1579       ppl_Polyhedron_add_constraint (accesses, cstr);
1580
1581       ppl_delete_Linear_Expression (fn);
1582       ppl_delete_Linear_Expression (access);
1583       ppl_delete_Constraint (cstr);
1584     }
1585
1586   mpz_clear (v);
1587 }
1588
1589 /* Add constrains representing the size of the accessed data to the
1590    ACCESSES polyhedron.  ACCESSP_NB_DIMS is the dimension of the
1591    ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1592    domain.  */
1593
1594 static void
1595 pdr_add_data_dimensions (ppl_Polyhedron_t accesses, data_reference_p dr,
1596                          ppl_dimension_type accessp_nb_dims,
1597                          ppl_dimension_type dom_nb_dims)
1598 {
1599   tree ref = DR_REF (dr);
1600   int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1601
1602   for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1603     {
1604       ppl_Linear_Expression_t expr;
1605       ppl_Constraint_t cstr;
1606       ppl_dimension_type subscript = dom_nb_dims + 1 + i;
1607       tree low, high;
1608
1609       if (TREE_CODE (ref) != ARRAY_REF)
1610         break;
1611
1612       low = array_ref_low_bound (ref);
1613
1614       /* subscript - low >= 0 */
1615       if (host_integerp (low, 0))
1616         {
1617           ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1618           ppl_set_coef (expr, subscript, 1);
1619
1620           ppl_set_inhomogeneous (expr, -int_cst_value (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 (expr, int_cst_value (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