OSDN Git Service

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