OSDN Git Service

Add statements to type switch even if there are no valid types.
[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         VEC_ordered_remove (poly_bb_p, SCOP_BBS (scop), i);
1975         i--;
1976       }
1977
1978   FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
1979     for (j = 0; VEC_iterate (data_reference_p,
1980                              GBB_DATA_REFS (PBB_BLACK_BOX (pbb)), j, dr); j++)
1981       VEC_safe_push (data_reference_p, heap, drs, dr);
1982
1983   FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr)
1984     dr->aux = XNEW (base_alias_pair);
1985
1986   if (!build_alias_set_optimal_p (drs))
1987     {
1988       /* TODO: Add support when building alias set is not optimal.  */
1989       ;
1990     }
1991
1992   build_base_obj_set_for_drs (drs);
1993
1994   /* When debugging, enable the following code.  This cannot be used
1995      in production compilers.  */
1996   if (0)
1997     dump_alias_graphs (drs);
1998
1999   VEC_free (data_reference_p, heap, drs);
2000
2001   FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
2002     build_pbb_drs (pbb);
2003 }
2004
2005 /* Return a gsi at the position of the phi node STMT.  */
2006
2007 static gimple_stmt_iterator
2008 gsi_for_phi_node (gimple stmt)
2009 {
2010   gimple_stmt_iterator psi;
2011   basic_block bb = gimple_bb (stmt);
2012
2013   for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
2014     if (stmt == gsi_stmt (psi))
2015       return psi;
2016
2017   gcc_unreachable ();
2018   return psi;
2019 }
2020
2021 /* Analyze all the data references of STMTS and add them to the
2022    GBB_DATA_REFS vector of BB.  */
2023
2024 static void
2025 analyze_drs_in_stmts (scop_p scop, basic_block bb, VEC (gimple, heap) *stmts)
2026 {
2027   loop_p nest;
2028   gimple_bb_p gbb;
2029   gimple stmt;
2030   int i;
2031
2032   if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2033     return;
2034
2035   nest = outermost_loop_in_sese (SCOP_REGION (scop), bb);
2036   gbb = gbb_from_bb (bb);
2037
2038   FOR_EACH_VEC_ELT (gimple, stmts, i, stmt)
2039     if (!is_gimple_debug (stmt))
2040       graphite_find_data_references_in_stmt (nest, stmt,
2041                                              &GBB_DATA_REFS (gbb));
2042 }
2043
2044 /* Insert STMT at the end of the STMTS sequence and then insert the
2045    statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
2046    on STMTS.  */
2047
2048 static void
2049 insert_stmts (scop_p scop, gimple stmt, gimple_seq stmts,
2050               gimple_stmt_iterator insert_gsi)
2051 {
2052   gimple_stmt_iterator gsi;
2053   VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
2054
2055   if (!stmts)
2056     stmts = gimple_seq_alloc ();
2057
2058   gsi = gsi_last (stmts);
2059   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
2060   for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2061     VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
2062
2063   gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
2064   analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
2065   VEC_free (gimple, heap, x);
2066 }
2067
2068 /* Insert the assignment "RES := EXPR" just after AFTER_STMT.  */
2069
2070 static void
2071 insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple after_stmt)
2072 {
2073   gimple_seq stmts;
2074   gimple_stmt_iterator si;
2075   gimple_stmt_iterator gsi;
2076   tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2077   gimple stmt = gimple_build_assign (res, var);
2078   VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
2079
2080   if (!stmts)
2081     stmts = gimple_seq_alloc ();
2082   si = gsi_last (stmts);
2083   gsi_insert_after (&si, stmt, GSI_NEW_STMT);
2084   for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2085     VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
2086
2087   if (gimple_code (after_stmt) == GIMPLE_PHI)
2088     {
2089       gsi = gsi_after_labels (gimple_bb (after_stmt));
2090       gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2091     }
2092   else
2093     {
2094       gsi = gsi_for_stmt (after_stmt);
2095       gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
2096     }
2097
2098   analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
2099   VEC_free (gimple, heap, x);
2100 }
2101
2102 /* Creates a poly_bb_p for basic_block BB from the existing PBB.  */
2103
2104 static void
2105 new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
2106 {
2107   VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
2108   gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
2109   gimple_bb_p gbb1 = new_gimple_bb (bb, drs);
2110   poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
2111   int index, n = VEC_length (poly_bb_p, SCOP_BBS (scop));
2112
2113   /* The INDEX of PBB in SCOP_BBS.  */
2114   for (index = 0; index < n; index++)
2115     if (VEC_index (poly_bb_p, SCOP_BBS (scop), index) == pbb)
2116       break;
2117
2118   GBB_PBB (gbb1) = pbb1;
2119   ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
2120     (&PBB_DOMAIN (pbb1), PBB_DOMAIN (pbb));
2121   GBB_CONDITIONS (gbb1) = VEC_copy (gimple, heap, GBB_CONDITIONS (gbb));
2122   GBB_CONDITION_CASES (gbb1) = VEC_copy (gimple, heap, GBB_CONDITION_CASES (gbb));
2123   VEC_safe_insert (poly_bb_p, heap, SCOP_BBS (scop), index + 1, pbb1);
2124 }
2125
2126 /* Insert on edge E the assignment "RES := EXPR".  */
2127
2128 static void
2129 insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
2130 {
2131   gimple_stmt_iterator gsi;
2132   gimple_seq stmts;
2133   tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2134   gimple stmt = gimple_build_assign (res, var);
2135   basic_block bb;
2136   VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
2137
2138   if (!stmts)
2139     stmts = gimple_seq_alloc ();
2140
2141   gsi = gsi_last (stmts);
2142   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
2143   for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2144     VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
2145
2146   gsi_insert_seq_on_edge (e, stmts);
2147   gsi_commit_edge_inserts ();
2148   bb = gimple_bb (stmt);
2149
2150   if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2151     return;
2152
2153   if (!gbb_from_bb (bb))
2154     new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
2155
2156   analyze_drs_in_stmts (scop, bb, x);
2157   VEC_free (gimple, heap, x);
2158 }
2159
2160 /* Creates a zero dimension array of the same type as VAR.  */
2161
2162 static tree
2163 create_zero_dim_array (tree var, const char *base_name)
2164 {
2165   tree index_type = build_index_type (integer_zero_node);
2166   tree elt_type = TREE_TYPE (var);
2167   tree array_type = build_array_type (elt_type, index_type);
2168   tree base = create_tmp_var (array_type, base_name);
2169
2170   add_referenced_var (base);
2171
2172   return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
2173                  NULL_TREE);
2174 }
2175
2176 /* Returns true when PHI is a loop close phi node.  */
2177
2178 static bool
2179 scalar_close_phi_node_p (gimple phi)
2180 {
2181   if (gimple_code (phi) != GIMPLE_PHI
2182       || !is_gimple_reg (gimple_phi_result (phi)))
2183     return false;
2184
2185   /* Note that loop close phi nodes should have a single argument
2186      because we translated the representation into a canonical form
2187      before Graphite: see canonicalize_loop_closed_ssa_form.  */
2188   return (gimple_phi_num_args (phi) == 1);
2189 }
2190
2191 /* For a definition DEF in REGION, propagates the expression EXPR in
2192    all the uses of DEF outside REGION.  */
2193
2194 static void
2195 propagate_expr_outside_region (tree def, tree expr, sese region)
2196 {
2197   imm_use_iterator imm_iter;
2198   gimple use_stmt;
2199   gimple_seq stmts;
2200   bool replaced_once = false;
2201
2202   gcc_assert (TREE_CODE (def) == SSA_NAME);
2203
2204   expr = force_gimple_operand (unshare_expr (expr), &stmts, true,
2205                                NULL_TREE);
2206
2207   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2208     if (!is_gimple_debug (use_stmt)
2209         && !bb_in_sese_p (gimple_bb (use_stmt), region))
2210       {
2211         ssa_op_iter iter;
2212         use_operand_p use_p;
2213
2214         FOR_EACH_PHI_OR_STMT_USE (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2215           if (operand_equal_p (def, USE_FROM_PTR (use_p), 0)
2216               && (replaced_once = true))
2217             replace_exp (use_p, expr);
2218
2219         update_stmt (use_stmt);
2220       }
2221
2222   if (replaced_once)
2223     {
2224       gsi_insert_seq_on_edge (SESE_ENTRY (region), stmts);
2225       gsi_commit_edge_inserts ();
2226     }
2227 }
2228
2229 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2230    dimension array for it.  */
2231
2232 static void
2233 rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2234 {
2235   sese region = SCOP_REGION (scop);
2236   gimple phi = gsi_stmt (*psi);
2237   tree res = gimple_phi_result (phi);
2238   tree var = SSA_NAME_VAR (res);
2239   basic_block bb = gimple_bb (phi);
2240   gimple_stmt_iterator gsi = gsi_after_labels (bb);
2241   tree arg = gimple_phi_arg_def (phi, 0);
2242   gimple stmt;
2243
2244   /* Note that loop close phi nodes should have a single argument
2245      because we translated the representation into a canonical form
2246      before Graphite: see canonicalize_loop_closed_ssa_form.  */
2247   gcc_assert (gimple_phi_num_args (phi) == 1);
2248
2249   /* The phi node can be a non close phi node, when its argument is
2250      invariant, or a default definition.  */
2251   if (is_gimple_min_invariant (arg)
2252       || SSA_NAME_IS_DEFAULT_DEF (arg))
2253     {
2254       propagate_expr_outside_region (res, arg, region);
2255       gsi_next (psi);
2256       return;
2257     }
2258
2259   else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
2260     {
2261       propagate_expr_outside_region (res, arg, region);
2262       stmt = gimple_build_assign (res, arg);
2263       remove_phi_node (psi, false);
2264       gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2265       SSA_NAME_DEF_STMT (res) = stmt;
2266       return;
2267     }
2268
2269   /* If res is scev analyzable and is not a scalar value, it is safe
2270      to ignore the close phi node: it will be code generated in the
2271      out of Graphite pass.  */
2272   else if (scev_analyzable_p (res, region))
2273     {
2274       loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2275       tree scev;
2276
2277       if (!loop_in_sese_p (loop, region))
2278         {
2279           loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2280           scev = scalar_evolution_in_region (region, loop, arg);
2281           scev = compute_overall_effect_of_inner_loop (loop, scev);
2282         }
2283       else
2284         scev = scalar_evolution_in_region (region, loop, res);
2285
2286       if (tree_does_not_contain_chrecs (scev))
2287         propagate_expr_outside_region (res, scev, region);
2288
2289       gsi_next (psi);
2290       return;
2291     }
2292   else
2293     {
2294       tree zero_dim_array = create_zero_dim_array (var, "Close_Phi");
2295
2296       stmt = gimple_build_assign (res, zero_dim_array);
2297
2298       if (TREE_CODE (arg) == SSA_NAME)
2299         insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2300                                 SSA_NAME_DEF_STMT (arg));
2301       else
2302         insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
2303                                         zero_dim_array, arg);
2304     }
2305
2306   remove_phi_node (psi, false);
2307   SSA_NAME_DEF_STMT (res) = stmt;
2308
2309   insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2310 }
2311
2312 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2313    dimension array for it.  */
2314
2315 static void
2316 rewrite_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2317 {
2318   size_t i;
2319   gimple phi = gsi_stmt (*psi);
2320   basic_block bb = gimple_bb (phi);
2321   tree res = gimple_phi_result (phi);
2322   tree var = SSA_NAME_VAR (res);
2323   tree zero_dim_array = create_zero_dim_array (var, "phi_out_of_ssa");
2324   gimple stmt;
2325   gimple_seq stmts;
2326
2327   for (i = 0; i < gimple_phi_num_args (phi); i++)
2328     {
2329       tree arg = gimple_phi_arg_def (phi, i);
2330       edge e = gimple_phi_arg_edge (phi, i);
2331
2332       /* Avoid the insertion of code in the loop latch to please the
2333          pattern matching of the vectorizer.  */
2334       if (TREE_CODE (arg) == SSA_NAME
2335           && e->src == bb->loop_father->latch)
2336         insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2337                                 SSA_NAME_DEF_STMT (arg));
2338       else
2339         insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
2340     }
2341
2342   var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
2343
2344   stmt = gimple_build_assign (res, var);
2345   remove_phi_node (psi, false);
2346   SSA_NAME_DEF_STMT (res) = stmt;
2347
2348   insert_stmts (scop, stmt, stmts, gsi_after_labels (bb));
2349 }
2350
2351 /* Rewrite the degenerate phi node at position PSI from the degenerate
2352    form "x = phi (y, y, ..., y)" to "x = y".  */
2353
2354 static void
2355 rewrite_degenerate_phi (gimple_stmt_iterator *psi)
2356 {
2357   tree rhs;
2358   gimple stmt;
2359   gimple_stmt_iterator gsi;
2360   gimple phi = gsi_stmt (*psi);
2361   tree res = gimple_phi_result (phi);
2362   basic_block bb;
2363
2364   bb = gimple_bb (phi);
2365   rhs = degenerate_phi_result (phi);
2366   gcc_assert (rhs);
2367
2368   stmt = gimple_build_assign (res, rhs);
2369   remove_phi_node (psi, false);
2370   SSA_NAME_DEF_STMT (res) = stmt;
2371
2372   gsi = gsi_after_labels (bb);
2373   gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2374 }
2375
2376 /* Rewrite out of SSA all the reduction phi nodes of SCOP.  */
2377
2378 static void
2379 rewrite_reductions_out_of_ssa (scop_p scop)
2380 {
2381   basic_block bb;
2382   gimple_stmt_iterator psi;
2383   sese region = SCOP_REGION (scop);
2384
2385   FOR_EACH_BB (bb)
2386     if (bb_in_sese_p (bb, region))
2387       for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2388         {
2389           gimple phi = gsi_stmt (psi);
2390
2391           if (!is_gimple_reg (gimple_phi_result (phi)))
2392             {
2393               gsi_next (&psi);
2394               continue;
2395             }
2396
2397           if (gimple_phi_num_args (phi) > 1
2398               && degenerate_phi_result (phi))
2399             rewrite_degenerate_phi (&psi);
2400
2401           else if (scalar_close_phi_node_p (phi))
2402             rewrite_close_phi_out_of_ssa (scop, &psi);
2403
2404           else if (reduction_phi_p (region, &psi))
2405             rewrite_phi_out_of_ssa (scop, &psi);
2406         }
2407
2408   update_ssa (TODO_update_ssa);
2409 #ifdef ENABLE_CHECKING
2410   verify_loop_closed_ssa (true);
2411 #endif
2412 }
2413
2414 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2415    read from ZERO_DIM_ARRAY.  */
2416
2417 static void
2418 rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
2419                                     tree def, gimple use_stmt)
2420 {
2421   tree var = SSA_NAME_VAR (def);
2422   gimple name_stmt = gimple_build_assign (var, zero_dim_array);
2423   tree name = make_ssa_name (var, name_stmt);
2424   ssa_op_iter iter;
2425   use_operand_p use_p;
2426
2427   gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2428
2429   gimple_assign_set_lhs (name_stmt, name);
2430   insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
2431
2432   FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2433     if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2434       replace_exp (use_p, name);
2435
2436   update_stmt (use_stmt);
2437 }
2438
2439 /* For every definition DEF in the SCOP that is used outside the scop,
2440    insert a closing-scop definition in the basic block just after this
2441    SCOP.  */
2442
2443 static void
2444 handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple stmt)
2445 {
2446   tree var = create_tmp_reg (TREE_TYPE (def), NULL);
2447   tree new_name = make_ssa_name (var, stmt);
2448   bool needs_copy = false;
2449   use_operand_p use_p;
2450   imm_use_iterator imm_iter;
2451   gimple use_stmt;
2452   sese region = SCOP_REGION (scop);
2453
2454   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2455     {
2456       if (!bb_in_sese_p (gimple_bb (use_stmt), region))
2457         {
2458           FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2459             {
2460               SET_USE (use_p, new_name);
2461             }
2462           update_stmt (use_stmt);
2463           needs_copy = true;
2464         }
2465     }
2466
2467   /* Insert in the empty BB just after the scop a use of DEF such
2468      that the rewrite of cross_bb_scalar_dependences won't insert
2469      arrays everywhere else.  */
2470   if (needs_copy)
2471     {
2472       gimple assign = gimple_build_assign (new_name, def);
2473       gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
2474
2475       add_referenced_var (var);
2476       SSA_NAME_DEF_STMT (new_name) = assign;
2477       update_stmt (assign);
2478       gsi_insert_before (&psi, assign, GSI_SAME_STMT);
2479     }
2480 }
2481
2482 /* Rewrite the scalar dependences crossing the boundary of the BB
2483    containing STMT with an array.  Return true when something has been
2484    changed.  */
2485
2486 static bool
2487 rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
2488 {
2489   sese region = SCOP_REGION (scop);
2490   gimple stmt = gsi_stmt (*gsi);
2491   imm_use_iterator imm_iter;
2492   tree def;
2493   basic_block def_bb;
2494   tree zero_dim_array = NULL_TREE;
2495   gimple use_stmt;
2496   bool res = false;
2497
2498   switch (gimple_code (stmt))
2499     {
2500     case GIMPLE_ASSIGN:
2501       def = gimple_assign_lhs (stmt);
2502       break;
2503
2504     case GIMPLE_CALL:
2505       def = gimple_call_lhs (stmt);
2506       break;
2507
2508     default:
2509       return false;
2510     }
2511
2512   if (!def
2513       || !is_gimple_reg (def))
2514     return false;
2515
2516   if (scev_analyzable_p (def, region))
2517     {
2518       loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
2519       tree scev = scalar_evolution_in_region (region, loop, def);
2520
2521       if (tree_contains_chrecs (scev, NULL))
2522         return false;
2523
2524       propagate_expr_outside_region (def, scev, region);
2525       return true;
2526     }
2527
2528   def_bb = gimple_bb (stmt);
2529
2530   handle_scalar_deps_crossing_scop_limits (scop, def, stmt);
2531
2532   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2533     if (gimple_code (use_stmt) == GIMPLE_PHI
2534         && (res = true))
2535       {
2536         gimple_stmt_iterator psi = gsi_for_stmt (use_stmt);
2537
2538         if (scalar_close_phi_node_p (gsi_stmt (psi)))
2539           rewrite_close_phi_out_of_ssa (scop, &psi);
2540         else
2541           rewrite_phi_out_of_ssa (scop, &psi);
2542       }
2543
2544   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2545     if (gimple_code (use_stmt) != GIMPLE_PHI
2546         && def_bb != gimple_bb (use_stmt)
2547         && !is_gimple_debug (use_stmt)
2548         && (res = true))
2549       {
2550         if (!zero_dim_array)
2551           {
2552             zero_dim_array = create_zero_dim_array
2553               (SSA_NAME_VAR (def), "Cross_BB_scalar_dependence");
2554             insert_out_of_ssa_copy (scop, zero_dim_array, def,
2555                                     SSA_NAME_DEF_STMT (def));
2556             gsi_next (gsi);
2557           }
2558
2559         rewrite_cross_bb_scalar_dependence (scop, zero_dim_array,
2560                                             def, use_stmt);
2561       }
2562
2563   return res;
2564 }
2565
2566 /* Rewrite out of SSA all the reduction phi nodes of SCOP.  */
2567
2568 static void
2569 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
2570 {
2571   basic_block bb;
2572   gimple_stmt_iterator psi;
2573   sese region = SCOP_REGION (scop);
2574   bool changed = false;
2575
2576   /* Create an extra empty BB after the scop.  */
2577   split_edge (SESE_EXIT (region));
2578
2579   FOR_EACH_BB (bb)
2580     if (bb_in_sese_p (bb, region))
2581       for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2582         changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
2583
2584   if (changed)
2585     {
2586       scev_reset_htab ();
2587       update_ssa (TODO_update_ssa);
2588 #ifdef ENABLE_CHECKING
2589       verify_loop_closed_ssa (true);
2590 #endif
2591     }
2592 }
2593
2594 /* Returns the number of pbbs that are in loops contained in SCOP.  */
2595
2596 static int
2597 nb_pbbs_in_loops (scop_p scop)
2598 {
2599   int i;
2600   poly_bb_p pbb;
2601   int res = 0;
2602
2603   FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
2604     if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2605       res++;
2606
2607   return res;
2608 }
2609
2610 /* Return the number of data references in BB that write in
2611    memory.  */
2612
2613 static int
2614 nb_data_writes_in_bb (basic_block bb)
2615 {
2616   int res = 0;
2617   gimple_stmt_iterator gsi;
2618
2619   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2620     if (gimple_vdef (gsi_stmt (gsi)))
2621       res++;
2622
2623   return res;
2624 }
2625
2626 /* Splits at STMT the basic block BB represented as PBB in the
2627    polyhedral form.  */
2628
2629 static edge
2630 split_pbb (scop_p scop, poly_bb_p pbb, basic_block bb, gimple stmt)
2631 {
2632   edge e1 = split_block (bb, stmt);
2633   new_pbb_from_pbb (scop, pbb, e1->dest);
2634   return e1;
2635 }
2636
2637 /* Splits STMT out of its current BB.  This is done for reduction
2638    statements for which we want to ignore data dependences.  */
2639
2640 static basic_block
2641 split_reduction_stmt (scop_p scop, gimple stmt)
2642 {
2643   basic_block bb = gimple_bb (stmt);
2644   poly_bb_p pbb = pbb_from_bb (bb);
2645   gimple_bb_p gbb = gbb_from_bb (bb);
2646   edge e1;
2647   int i;
2648   data_reference_p dr;
2649
2650   /* Do not split basic blocks with no writes to memory: the reduction
2651      will be the only write to memory.  */
2652   if (nb_data_writes_in_bb (bb) == 0)
2653     return bb;
2654
2655   e1 = split_pbb (scop, pbb, bb, stmt);
2656
2657   /* Split once more only when the reduction stmt is not the only one
2658      left in the original BB.  */
2659   if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
2660     {
2661       gimple_stmt_iterator gsi = gsi_last_bb (bb);
2662       gsi_prev (&gsi);
2663       e1 = split_pbb (scop, pbb, bb, gsi_stmt (gsi));
2664     }
2665
2666   /* A part of the data references will end in a different basic block
2667      after the split: move the DRs from the original GBB to the newly
2668      created GBB1.  */
2669   FOR_EACH_VEC_ELT (data_reference_p, GBB_DATA_REFS (gbb), i, dr)
2670     {
2671       basic_block bb1 = gimple_bb (DR_STMT (dr));
2672
2673       if (bb1 != bb)
2674         {
2675           gimple_bb_p gbb1 = gbb_from_bb (bb1);
2676           VEC_safe_push (data_reference_p, heap, GBB_DATA_REFS (gbb1), dr);
2677           VEC_ordered_remove (data_reference_p, GBB_DATA_REFS (gbb), i);
2678           i--;
2679         }
2680     }
2681
2682   return e1->dest;
2683 }
2684
2685 /* Return true when stmt is a reduction operation.  */
2686
2687 static inline bool
2688 is_reduction_operation_p (gimple stmt)
2689 {
2690   enum tree_code code;
2691
2692   gcc_assert (is_gimple_assign (stmt));
2693   code = gimple_assign_rhs_code (stmt);
2694
2695   return flag_associative_math
2696     && commutative_tree_code (code)
2697     && associative_tree_code (code);
2698 }
2699
2700 /* Returns true when PHI contains an argument ARG.  */
2701
2702 static bool
2703 phi_contains_arg (gimple phi, tree arg)
2704 {
2705   size_t i;
2706
2707   for (i = 0; i < gimple_phi_num_args (phi); i++)
2708     if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2709       return true;
2710
2711   return false;
2712 }
2713
2714 /* Return a loop phi node that corresponds to a reduction containing LHS.  */
2715
2716 static gimple
2717 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2718 {
2719   gimple stmt;
2720
2721   if (TREE_CODE (arg) != SSA_NAME)
2722     return NULL;
2723
2724   stmt = SSA_NAME_DEF_STMT (arg);
2725
2726   if (gimple_code (stmt) == GIMPLE_NOP
2727       || gimple_code (stmt) == GIMPLE_CALL)
2728     return NULL;
2729
2730   if (gimple_code (stmt) == GIMPLE_PHI)
2731     {
2732       if (phi_contains_arg (stmt, lhs))
2733         return stmt;
2734       return NULL;
2735     }
2736
2737   if (!is_gimple_assign (stmt))
2738     return NULL;
2739
2740   if (gimple_num_ops (stmt) == 2)
2741     return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2742
2743   if (is_reduction_operation_p (stmt))
2744     {
2745       gimple res = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2746
2747       return res ? res :
2748         follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2749     }
2750
2751   return NULL;
2752 }
2753
2754 /* Detect commutative and associative scalar reductions starting at
2755    the STMT.  Return the phi node of the reduction cycle, or NULL.  */
2756
2757 static gimple
2758 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2759                                   VEC (gimple, heap) **in,
2760                                   VEC (gimple, heap) **out)
2761 {
2762   gimple phi = follow_ssa_with_commutative_ops (arg, lhs);
2763
2764   if (!phi)
2765     return NULL;
2766
2767   VEC_safe_push (gimple, heap, *in, stmt);
2768   VEC_safe_push (gimple, heap, *out, stmt);
2769   return phi;
2770 }
2771
2772 /* Detect commutative and associative scalar reductions starting at
2773    STMT.  Return the phi node of the reduction cycle, or NULL.  */
2774
2775 static gimple
2776 detect_commutative_reduction_assign (gimple stmt, VEC (gimple, heap) **in,
2777                                      VEC (gimple, heap) **out)
2778 {
2779   tree lhs = gimple_assign_lhs (stmt);
2780
2781   if (gimple_num_ops (stmt) == 2)
2782     return detect_commutative_reduction_arg (lhs, stmt,
2783                                              gimple_assign_rhs1 (stmt),
2784                                              in, out);
2785
2786   if (is_reduction_operation_p (stmt))
2787     {
2788       gimple res = detect_commutative_reduction_arg (lhs, stmt,
2789                                                      gimple_assign_rhs1 (stmt),
2790                                                      in, out);
2791       return res ? res
2792         : detect_commutative_reduction_arg (lhs, stmt,
2793                                             gimple_assign_rhs2 (stmt),
2794                                             in, out);
2795     }
2796
2797   return NULL;
2798 }
2799
2800 /* Return a loop phi node that corresponds to a reduction containing LHS.  */
2801
2802 static gimple
2803 follow_inital_value_to_phi (tree arg, tree lhs)
2804 {
2805   gimple stmt;
2806
2807   if (!arg || TREE_CODE (arg) != SSA_NAME)
2808     return NULL;
2809
2810   stmt = SSA_NAME_DEF_STMT (arg);
2811
2812   if (gimple_code (stmt) == GIMPLE_PHI
2813       && phi_contains_arg (stmt, lhs))
2814     return stmt;
2815
2816   return NULL;
2817 }
2818
2819
2820 /* Return the argument of the loop PHI that is the inital value coming
2821    from outside the loop.  */
2822
2823 static edge
2824 edge_initial_value_for_loop_phi (gimple phi)
2825 {
2826   size_t i;
2827
2828   for (i = 0; i < gimple_phi_num_args (phi); i++)
2829     {
2830       edge e = gimple_phi_arg_edge (phi, i);
2831
2832       if (loop_depth (e->src->loop_father)
2833           < loop_depth (e->dest->loop_father))
2834         return e;
2835     }
2836
2837   return NULL;
2838 }
2839
2840 /* Return the argument of the loop PHI that is the inital value coming
2841    from outside the loop.  */
2842
2843 static tree
2844 initial_value_for_loop_phi (gimple phi)
2845 {
2846   size_t i;
2847
2848   for (i = 0; i < gimple_phi_num_args (phi); i++)
2849     {
2850       edge e = gimple_phi_arg_edge (phi, i);
2851
2852       if (loop_depth (e->src->loop_father)
2853           < loop_depth (e->dest->loop_father))
2854         return gimple_phi_arg_def (phi, i);
2855     }
2856
2857   return NULL_TREE;
2858 }
2859
2860 /* Detect commutative and associative scalar reductions starting at
2861    the loop closed phi node STMT.  Return the phi node of the
2862    reduction cycle, or NULL.  */
2863
2864 static gimple
2865 detect_commutative_reduction (gimple stmt, VEC (gimple, heap) **in,
2866                               VEC (gimple, heap) **out)
2867 {
2868   if (scalar_close_phi_node_p (stmt))
2869     {
2870       tree arg = gimple_phi_arg_def (stmt, 0);
2871       gimple def, loop_phi;
2872
2873       if (TREE_CODE (arg) != SSA_NAME)
2874         return NULL;
2875
2876       /* Note that loop close phi nodes should have a single argument
2877          because we translated the representation into a canonical form
2878          before Graphite: see canonicalize_loop_closed_ssa_form.  */
2879       gcc_assert (gimple_phi_num_args (stmt) == 1);
2880
2881       def = SSA_NAME_DEF_STMT (arg);
2882       loop_phi = detect_commutative_reduction (def, in, out);
2883
2884       if (loop_phi)
2885         {
2886           tree lhs = gimple_phi_result (stmt);
2887           tree init = initial_value_for_loop_phi (loop_phi);
2888           gimple phi = follow_inital_value_to_phi (init, lhs);
2889
2890           VEC_safe_push (gimple, heap, *in, loop_phi);
2891           VEC_safe_push (gimple, heap, *out, stmt);
2892           return phi;
2893         }
2894       else
2895         return NULL;
2896     }
2897
2898   if (gimple_code (stmt) == GIMPLE_ASSIGN)
2899     return detect_commutative_reduction_assign (stmt, in, out);
2900
2901   return NULL;
2902 }
2903
2904 /* Translate the scalar reduction statement STMT to an array RED
2905    knowing that its recursive phi node is LOOP_PHI.  */
2906
2907 static void
2908 translate_scalar_reduction_to_array_for_stmt (scop_p scop, tree red,
2909                                               gimple stmt, gimple loop_phi)
2910 {
2911   tree res = gimple_phi_result (loop_phi);
2912   gimple assign = gimple_build_assign (res, red);
2913   gimple_stmt_iterator gsi;
2914
2915   insert_stmts (scop, assign, NULL, gsi_after_labels (gimple_bb (loop_phi)));
2916
2917   assign = gimple_build_assign (red, gimple_assign_lhs (stmt));
2918   gsi = gsi_for_stmt (stmt);
2919   gsi_next (&gsi);
2920   insert_stmts (scop, assign, NULL, gsi);
2921 }
2922
2923 /* Removes the PHI node and resets all the debug stmts that are using
2924    the PHI_RESULT.  */
2925
2926 static void
2927 remove_phi (gimple phi)
2928 {
2929   imm_use_iterator imm_iter;
2930   tree def;
2931   use_operand_p use_p;
2932   gimple_stmt_iterator gsi;
2933   VEC (gimple, heap) *update = VEC_alloc (gimple, heap, 3);
2934   unsigned int i;
2935   gimple stmt;
2936
2937   def = PHI_RESULT (phi);
2938   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2939     {
2940       stmt = USE_STMT (use_p);
2941
2942       if (is_gimple_debug (stmt))
2943         {
2944           gimple_debug_bind_reset_value (stmt);
2945           VEC_safe_push (gimple, heap, update, stmt);
2946         }
2947     }
2948
2949   FOR_EACH_VEC_ELT (gimple, update, i, stmt)
2950     update_stmt (stmt);
2951
2952   VEC_free (gimple, heap, update);
2953
2954   gsi = gsi_for_phi_node (phi);
2955   remove_phi_node (&gsi, false);
2956 }
2957
2958 /* Rewrite out of SSA the reduction described by the loop phi nodes
2959    IN, and the close phi nodes OUT.  IN and OUT are structured by loop
2960    levels like this:
2961
2962    IN: stmt, loop_n, ..., loop_0
2963    OUT: stmt, close_n, ..., close_0
2964
2965    the first element is the reduction statement, and the next elements
2966    are the loop and close phi nodes of each of the outer loops.  */
2967
2968 static void
2969 translate_scalar_reduction_to_array (scop_p scop,
2970                                      VEC (gimple, heap) *in,
2971                                      VEC (gimple, heap) *out)
2972 {
2973   unsigned int i;
2974   gimple loop_phi;
2975   tree red = NULL_TREE;
2976
2977   FOR_EACH_VEC_ELT (gimple, in, i, loop_phi)
2978     {
2979       gimple close_phi = VEC_index (gimple, out, i);
2980
2981       if (i == 0)
2982         {
2983           gimple stmt = loop_phi;
2984           basic_block bb = split_reduction_stmt (scop, stmt);
2985           poly_bb_p pbb = pbb_from_bb (bb);
2986           PBB_IS_REDUCTION (pbb) = true;
2987           gcc_assert (close_phi == loop_phi);
2988
2989           red = create_zero_dim_array
2990             (gimple_assign_lhs (stmt), "Commutative_Associative_Reduction");
2991           translate_scalar_reduction_to_array_for_stmt
2992             (scop, red, stmt, VEC_index (gimple, in, 1));
2993           continue;
2994         }
2995
2996       if (i == VEC_length (gimple, in) - 1)
2997         {
2998           insert_out_of_ssa_copy (scop, gimple_phi_result (close_phi), red,
2999                                   close_phi);
3000           insert_out_of_ssa_copy_on_edge
3001             (scop, edge_initial_value_for_loop_phi (loop_phi),
3002              red, initial_value_for_loop_phi (loop_phi));
3003         }
3004
3005       remove_phi (loop_phi);
3006       remove_phi (close_phi);
3007     }
3008 }
3009
3010 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI.  Returns
3011    true when something has been changed.  */
3012
3013 static bool
3014 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop,
3015                                                      gimple close_phi)
3016 {
3017   bool res;
3018   VEC (gimple, heap) *in = VEC_alloc (gimple, heap, 10);
3019   VEC (gimple, heap) *out = VEC_alloc (gimple, heap, 10);
3020
3021   detect_commutative_reduction (close_phi, &in, &out);
3022   res = VEC_length (gimple, in) > 0;
3023   if (res)
3024     translate_scalar_reduction_to_array (scop, in, out);
3025
3026   VEC_free (gimple, heap, in);
3027   VEC_free (gimple, heap, out);
3028   return res;
3029 }
3030
3031 /* Rewrites all the commutative reductions from LOOP out of SSA.
3032    Returns true when something has been changed.  */
3033
3034 static bool
3035 rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop,
3036                                                 loop_p loop)
3037 {
3038   gimple_stmt_iterator gsi;
3039   edge exit = single_exit (loop);
3040   tree res;
3041   bool changed = false;
3042
3043   if (!exit)
3044     return false;
3045
3046   for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
3047     if ((res = gimple_phi_result (gsi_stmt (gsi)))
3048         && is_gimple_reg (res)
3049         && !scev_analyzable_p (res, SCOP_REGION (scop)))
3050       changed |= rewrite_commutative_reductions_out_of_ssa_close_phi
3051         (scop, gsi_stmt (gsi));
3052
3053   return changed;
3054 }
3055
3056 /* Rewrites all the commutative reductions from SCOP out of SSA.  */
3057
3058 static void
3059 rewrite_commutative_reductions_out_of_ssa (scop_p scop)
3060 {
3061   loop_iterator li;
3062   loop_p loop;
3063   bool changed = false;
3064   sese region = SCOP_REGION (scop);
3065
3066   FOR_EACH_LOOP (li, loop, 0)
3067     if (loop_in_sese_p (loop, region))
3068       changed |= rewrite_commutative_reductions_out_of_ssa_loop (scop, loop);
3069
3070   if (changed)
3071     {
3072       scev_reset_htab ();
3073       gsi_commit_edge_inserts ();
3074       update_ssa (TODO_update_ssa);
3075 #ifdef ENABLE_CHECKING
3076       verify_loop_closed_ssa (true);
3077 #endif
3078     }
3079 }
3080
3081 /* Java does not initialize long_long_integer_type_node.  */
3082 #define my_long_long (long_long_integer_type_node ? long_long_integer_type_node : ssizetype)
3083
3084 /* Can all ivs be represented by a signed integer?
3085    As CLooG might generate negative values in its expressions, signed loop ivs
3086    are required in the backend. */
3087
3088 static bool
3089 scop_ivs_can_be_represented (scop_p scop)
3090 {
3091   loop_iterator li;
3092   loop_p loop;
3093   gimple_stmt_iterator psi;
3094
3095   FOR_EACH_LOOP (li, loop, 0)
3096     {
3097       if (!loop_in_sese_p (loop, SCOP_REGION (scop)))
3098         continue;
3099
3100       for (psi = gsi_start_phis (loop->header);
3101            !gsi_end_p (psi); gsi_next (&psi))
3102         {
3103           gimple phi = gsi_stmt (psi);
3104           tree res = PHI_RESULT (phi);
3105           tree type = TREE_TYPE (res);
3106
3107           if (TYPE_UNSIGNED (type)
3108               && TYPE_PRECISION (type) >= TYPE_PRECISION (my_long_long))
3109             return false;
3110         }
3111     }
3112
3113   return true;
3114 }
3115
3116 #undef my_long_long
3117
3118 /* Builds the polyhedral representation for a SESE region.  */
3119
3120 void
3121 build_poly_scop (scop_p scop)
3122 {
3123   sese region = SCOP_REGION (scop);
3124   graphite_dim_t max_dim;
3125
3126   build_scop_bbs (scop);
3127
3128   /* FIXME: This restriction is needed to avoid a problem in CLooG.
3129      Once CLooG is fixed, remove this guard.  Anyways, it makes no
3130      sense to optimize a scop containing only PBBs that do not belong
3131      to any loops.  */
3132   if (nb_pbbs_in_loops (scop) == 0)
3133     return;
3134
3135   if (!scop_ivs_can_be_represented (scop))
3136     return;
3137
3138   build_sese_loop_nests (region);
3139   build_sese_conditions (region);
3140   find_scop_parameters (scop);
3141
3142   max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
3143   if (scop_nb_params (scop) > max_dim)
3144     return;
3145
3146   build_scop_iteration_domain (scop);
3147   build_scop_context (scop);
3148   add_conditions_to_constraints (scop);
3149
3150   /* Rewrite out of SSA only after having translated the
3151      representation to the polyhedral representation to avoid scev
3152      analysis failures.  That means that these functions will insert
3153      new data references that they create in the right place.  */
3154   if (flag_associative_math)
3155     rewrite_commutative_reductions_out_of_ssa (scop);
3156   rewrite_reductions_out_of_ssa (scop);
3157   rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
3158
3159   build_scop_drs (scop);
3160   scop_to_lst (scop);
3161   build_scop_scattering (scop);
3162
3163   /* This SCoP has been translated to the polyhedral
3164      representation.  */
3165   POLY_SCOP_P (scop) = true;
3166 }
3167 #endif