OSDN Git Service

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