OSDN Git Service

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