OSDN Git Service

Add -m8bit-idiv for x86.
[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_EACH_VEC_ELT (data_reference_p, datarefs, i, dr)
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_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
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_EACH_VEC_ELT (scop_p, scops, i, scop)
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_EACH_VEC_ELT (basic_block, dom, i, dom_bb)
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_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
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_EACH_VEC_ELT (tree, SESE_PARAMS (region), i, p)
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_EACH_VEC_ELT (data_reference_p, GBB_DATA_REFS (gbb), i, dr)
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_EACH_VEC_ELT (gimple, GBB_CONDITIONS (gbb), i, stmt)
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_EACH_VEC_ELT (loop_p, SESE_LOOP_NEST (region), i, loop)
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_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
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_EACH_VEC_ELT (gimple, GBB_CONDITIONS (gbb), i, stmt)
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_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
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_EACH_VEC_ELT (loop_p, SESE_LOOP_NEST (region), i, loop)
1590     if (!loop_in_sese_p (loop_outer (loop), region))
1591       build_loop_iteration_domains (scop, loop, ph, 0, domains);
1592
1593   FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
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_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
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_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
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_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1831     fprintf (file, "n%d;\n", i);
1832
1833   FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
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_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
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_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
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_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
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_EACH_VEC_ELT (data_reference_p, gbb_drs, j, dr)
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_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
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_EACH_VEC_ELT (data_reference_p, drs, i, dr)
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_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
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 a default definition.  */
2244   if (is_gimple_min_invariant (arg)
2245       || SSA_NAME_IS_DEFAULT_DEF (arg))
2246     {
2247       propagate_expr_outside_region (res, arg, region);
2248       gsi_next (psi);
2249       return;
2250     }
2251
2252   else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
2253     {
2254       propagate_expr_outside_region (res, arg, region);
2255       stmt = gimple_build_assign (res, arg);
2256       remove_phi_node (psi, false);
2257       gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2258       SSA_NAME_DEF_STMT (res) = stmt;
2259       return;
2260     }
2261
2262   /* If res is scev analyzable and is not a scalar value, it is safe
2263      to ignore the close phi node: it will be code generated in the
2264      out of Graphite pass.  */
2265   else if (scev_analyzable_p (res, region))
2266     {
2267       loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2268       tree scev;
2269
2270       if (!loop_in_sese_p (loop, region))
2271         {
2272           loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2273           scev = scalar_evolution_in_region (region, loop, arg);
2274           scev = compute_overall_effect_of_inner_loop (loop, scev);
2275         }
2276       else
2277         scev = scalar_evolution_in_region (region, loop, res);
2278
2279       if (tree_does_not_contain_chrecs (scev))
2280         propagate_expr_outside_region (res, scev, region);
2281
2282       gsi_next (psi);
2283       return;
2284     }
2285   else
2286     {
2287       tree zero_dim_array = create_zero_dim_array (var, "Close_Phi");
2288
2289       stmt = gimple_build_assign (res, zero_dim_array);
2290
2291       if (TREE_CODE (arg) == SSA_NAME)
2292         insert_out_of_ssa_copy (zero_dim_array, arg, SSA_NAME_DEF_STMT (arg));
2293       else
2294         insert_out_of_ssa_copy_on_edge (single_pred_edge (bb),
2295                                         zero_dim_array, arg);
2296     }
2297
2298   remove_phi_node (psi, false);
2299   gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2300   SSA_NAME_DEF_STMT (res) = stmt;
2301 }
2302
2303 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2304    dimension array for it.  */
2305
2306 static void
2307 rewrite_phi_out_of_ssa (gimple_stmt_iterator *psi)
2308 {
2309   size_t i;
2310   gimple phi = gsi_stmt (*psi);
2311   basic_block bb = gimple_bb (phi);
2312   tree res = gimple_phi_result (phi);
2313   tree var = SSA_NAME_VAR (res);
2314   tree zero_dim_array = create_zero_dim_array (var, "phi_out_of_ssa");
2315   gimple_stmt_iterator gsi;
2316   gimple stmt;
2317   gimple_seq stmts;
2318
2319   for (i = 0; i < gimple_phi_num_args (phi); i++)
2320     {
2321       tree arg = gimple_phi_arg_def (phi, i);
2322       edge e = gimple_phi_arg_edge (phi, i);
2323
2324       /* Avoid the insertion of code in the loop latch to please the
2325          pattern matching of the vectorizer.  */
2326       if (TREE_CODE (arg) == SSA_NAME
2327           && e->src == bb->loop_father->latch)
2328         insert_out_of_ssa_copy (zero_dim_array, arg, SSA_NAME_DEF_STMT (arg));
2329       else
2330         insert_out_of_ssa_copy_on_edge (e, zero_dim_array, arg);
2331     }
2332
2333   var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
2334
2335   if (!stmts)
2336     stmts = gimple_seq_alloc ();
2337
2338   stmt = gimple_build_assign (res, var);
2339   remove_phi_node (psi, false);
2340   SSA_NAME_DEF_STMT (res) = stmt;
2341
2342   gsi = gsi_last (stmts);
2343   gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
2344
2345   gsi = gsi_after_labels (bb);
2346   gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2347 }
2348
2349 /* Rewrite the degenerate phi node at position PSI from the degenerate
2350    form "x = phi (y, y, ..., y)" to "x = y".  */
2351
2352 static void
2353 rewrite_degenerate_phi (gimple_stmt_iterator *psi)
2354 {
2355   tree rhs;
2356   gimple stmt;
2357   gimple_stmt_iterator gsi;
2358   gimple phi = gsi_stmt (*psi);
2359   tree res = gimple_phi_result (phi);
2360   basic_block bb;
2361
2362   if (!is_gimple_reg (res))
2363     {
2364       gsi_next (psi);
2365       return;
2366     }
2367
2368   bb = gimple_bb (phi);
2369   rhs = degenerate_phi_result (phi);
2370   gcc_assert (rhs);
2371
2372   stmt = gimple_build_assign (res, rhs);
2373   remove_phi_node (psi, false);
2374   SSA_NAME_DEF_STMT (res) = stmt;
2375
2376   gsi = gsi_after_labels (bb);
2377   gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2378 }
2379
2380 /* Rewrite out of SSA all the reduction phi nodes of SCOP.  */
2381
2382 void
2383 rewrite_reductions_out_of_ssa (scop_p scop)
2384 {
2385   basic_block bb;
2386   gimple_stmt_iterator psi;
2387   sese region = SCOP_REGION (scop);
2388
2389   FOR_EACH_BB (bb)
2390     if (bb_in_sese_p (bb, region))
2391       for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2392         {
2393           gimple phi = gsi_stmt (psi);
2394
2395           if (gimple_phi_num_args (phi) > 1
2396               && degenerate_phi_result (phi))
2397             rewrite_degenerate_phi (&psi);
2398
2399           else if (scalar_close_phi_node_p (phi))
2400             rewrite_close_phi_out_of_ssa (&psi, region);
2401
2402           else if (reduction_phi_p (region, &psi))
2403             rewrite_phi_out_of_ssa (&psi);
2404         }
2405
2406   update_ssa (TODO_update_ssa);
2407 #ifdef ENABLE_CHECKING
2408   verify_loop_closed_ssa (true);
2409 #endif
2410 }
2411
2412 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2413    read from ZERO_DIM_ARRAY.  */
2414
2415 static void
2416 rewrite_cross_bb_scalar_dependence (tree zero_dim_array, tree def, gimple use_stmt)
2417 {
2418   tree var = SSA_NAME_VAR (def);
2419   gimple name_stmt = gimple_build_assign (var, zero_dim_array);
2420   tree name = make_ssa_name (var, name_stmt);
2421   ssa_op_iter iter;
2422   use_operand_p use_p;
2423   gimple_stmt_iterator gsi;
2424
2425   gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2426
2427   gimple_assign_set_lhs (name_stmt, name);
2428
2429   gsi = gsi_for_stmt (use_stmt);
2430   gsi_insert_before (&gsi, name_stmt, GSI_NEW_STMT);
2431
2432   FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2433     if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2434       replace_exp (use_p, name);
2435
2436   update_stmt (use_stmt);
2437 }
2438
2439 /* Rewrite the scalar dependences crossing the boundary of the BB
2440    containing STMT with an array.  Return true when something has been
2441    changed.  */
2442
2443 static bool
2444 rewrite_cross_bb_scalar_deps (sese region, gimple_stmt_iterator *gsi)
2445 {
2446   gimple stmt = gsi_stmt (*gsi);
2447   imm_use_iterator imm_iter;
2448   tree def;
2449   basic_block def_bb;
2450   tree zero_dim_array = NULL_TREE;
2451   gimple use_stmt;
2452   bool res = false;
2453
2454   switch (gimple_code (stmt))
2455     {
2456     case GIMPLE_ASSIGN:
2457       def = gimple_assign_lhs (stmt);
2458       break;
2459
2460     case GIMPLE_CALL:
2461       def = gimple_call_lhs (stmt);
2462       break;
2463
2464     default:
2465       return false;
2466     }
2467
2468   if (!is_gimple_reg (def))
2469     return false;
2470
2471   if (scev_analyzable_p (def, region))
2472     {
2473       loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
2474       tree scev = scalar_evolution_in_region (region, loop, def);
2475
2476       if (tree_contains_chrecs (scev, NULL))
2477         return false;
2478
2479       propagate_expr_outside_region (def, scev, region);
2480       return true;
2481     }
2482
2483   def_bb = gimple_bb (stmt);
2484
2485   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2486     if (gimple_code (use_stmt) == GIMPLE_PHI
2487         && (res = true))
2488       {
2489         gimple_stmt_iterator psi = gsi_for_stmt (use_stmt);
2490
2491         if (scalar_close_phi_node_p (gsi_stmt (psi)))
2492           rewrite_close_phi_out_of_ssa (&psi, region);
2493         else
2494           rewrite_phi_out_of_ssa (&psi);
2495       }
2496
2497   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2498     if (gimple_code (use_stmt) != GIMPLE_PHI
2499         && def_bb != gimple_bb (use_stmt)
2500         && !is_gimple_debug (use_stmt)
2501         && (res = true))
2502       {
2503         if (!zero_dim_array)
2504           {
2505             zero_dim_array = create_zero_dim_array
2506               (SSA_NAME_VAR (def), "Cross_BB_scalar_dependence");
2507             insert_out_of_ssa_copy (zero_dim_array, def,
2508                                     SSA_NAME_DEF_STMT (def));
2509             gsi_next (gsi);
2510           }
2511
2512         rewrite_cross_bb_scalar_dependence (zero_dim_array, def, use_stmt);
2513       }
2514
2515   return res;
2516 }
2517
2518 /* Rewrite out of SSA all the reduction phi nodes of SCOP.  */
2519
2520 void
2521 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
2522 {
2523   basic_block bb;
2524   gimple_stmt_iterator psi;
2525   sese region = SCOP_REGION (scop);
2526   bool changed = false;
2527
2528   FOR_EACH_BB (bb)
2529     if (bb_in_sese_p (bb, region))
2530       for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2531         changed |= rewrite_cross_bb_scalar_deps (region, &psi);
2532
2533   if (changed)
2534     {
2535       scev_reset_htab ();
2536       update_ssa (TODO_update_ssa);
2537 #ifdef ENABLE_CHECKING
2538       verify_loop_closed_ssa (true);
2539 #endif
2540     }
2541 }
2542
2543 /* Returns the number of pbbs that are in loops contained in SCOP.  */
2544
2545 static int
2546 nb_pbbs_in_loops (scop_p scop)
2547 {
2548   int i;
2549   poly_bb_p pbb;
2550   int res = 0;
2551
2552   FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
2553     if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2554       res++;
2555
2556   return res;
2557 }
2558
2559 /* Return the number of data references in BB that write in
2560    memory.  */
2561
2562 static int
2563 nb_data_writes_in_bb (basic_block bb)
2564 {
2565   int res = 0;
2566   gimple_stmt_iterator gsi;
2567
2568   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2569     if (gimple_vdef (gsi_stmt (gsi)))
2570       res++;
2571
2572   return res;
2573 }
2574
2575 /* Splits STMT out of its current BB.  */
2576
2577 static basic_block
2578 split_reduction_stmt (gimple stmt)
2579 {
2580   gimple_stmt_iterator gsi;
2581   basic_block bb = gimple_bb (stmt);
2582   edge e;
2583
2584   /* Do not split basic blocks with no writes to memory: the reduction
2585      will be the only write to memory.  */
2586   if (nb_data_writes_in_bb (bb) == 0)
2587     return bb;
2588
2589   split_block (bb, stmt);
2590
2591   if (gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
2592     return bb;
2593
2594   gsi = gsi_last_bb (bb);
2595   gsi_prev (&gsi);
2596   e = split_block (bb, gsi_stmt (gsi));
2597
2598   return e->dest;
2599 }
2600
2601 /* Return true when stmt is a reduction operation.  */
2602
2603 static inline bool
2604 is_reduction_operation_p (gimple stmt)
2605 {
2606   enum tree_code code;
2607
2608   gcc_assert (is_gimple_assign (stmt));
2609   code = gimple_assign_rhs_code (stmt);
2610
2611   return flag_associative_math
2612     && commutative_tree_code (code)
2613     && associative_tree_code (code);
2614 }
2615
2616 /* Returns true when PHI contains an argument ARG.  */
2617
2618 static bool
2619 phi_contains_arg (gimple phi, tree arg)
2620 {
2621   size_t i;
2622
2623   for (i = 0; i < gimple_phi_num_args (phi); i++)
2624     if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2625       return true;
2626
2627   return false;
2628 }
2629
2630 /* Return a loop phi node that corresponds to a reduction containing LHS.  */
2631
2632 static gimple
2633 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2634 {
2635   gimple stmt;
2636
2637   if (TREE_CODE (arg) != SSA_NAME)
2638     return NULL;
2639
2640   stmt = SSA_NAME_DEF_STMT (arg);
2641
2642   if (gimple_code (stmt) == GIMPLE_NOP
2643       || gimple_code (stmt) == GIMPLE_CALL)
2644     return NULL;
2645
2646   if (gimple_code (stmt) == GIMPLE_PHI)
2647     {
2648       if (phi_contains_arg (stmt, lhs))
2649         return stmt;
2650       return NULL;
2651     }
2652
2653   if (!is_gimple_assign (stmt))
2654     return NULL;
2655
2656   if (gimple_num_ops (stmt) == 2)
2657     return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2658
2659   if (is_reduction_operation_p (stmt))
2660     {
2661       gimple res = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2662
2663       return res ? res :
2664         follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2665     }
2666
2667   return NULL;
2668 }
2669
2670 /* Detect commutative and associative scalar reductions starting at
2671    the STMT.  Return the phi node of the reduction cycle, or NULL.  */
2672
2673 static gimple
2674 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2675                                   VEC (gimple, heap) **in,
2676                                   VEC (gimple, heap) **out)
2677 {
2678   gimple phi = follow_ssa_with_commutative_ops (arg, lhs);
2679
2680   if (!phi)
2681     return NULL;
2682
2683   VEC_safe_push (gimple, heap, *in, stmt);
2684   VEC_safe_push (gimple, heap, *out, stmt);
2685   return phi;
2686 }
2687
2688 /* Detect commutative and associative scalar reductions starting at
2689    STMT.  Return the phi node of the reduction cycle, or NULL.  */
2690
2691 static gimple
2692 detect_commutative_reduction_assign (gimple stmt, VEC (gimple, heap) **in,
2693                                      VEC (gimple, heap) **out)
2694 {
2695   tree lhs = gimple_assign_lhs (stmt);
2696
2697   if (gimple_num_ops (stmt) == 2)
2698     return detect_commutative_reduction_arg (lhs, stmt,
2699                                              gimple_assign_rhs1 (stmt),
2700                                              in, out);
2701
2702   if (is_reduction_operation_p (stmt))
2703     {
2704       gimple res = detect_commutative_reduction_arg (lhs, stmt,
2705                                                      gimple_assign_rhs1 (stmt),
2706                                                      in, out);
2707       return res ? res
2708         : detect_commutative_reduction_arg (lhs, stmt,
2709                                             gimple_assign_rhs2 (stmt),
2710                                             in, out);
2711     }
2712
2713   return NULL;
2714 }
2715
2716 /* Return a loop phi node that corresponds to a reduction containing LHS.  */
2717
2718 static gimple
2719 follow_inital_value_to_phi (tree arg, tree lhs)
2720 {
2721   gimple stmt;
2722
2723   if (!arg || TREE_CODE (arg) != SSA_NAME)
2724     return NULL;
2725
2726   stmt = SSA_NAME_DEF_STMT (arg);
2727
2728   if (gimple_code (stmt) == GIMPLE_PHI
2729       && phi_contains_arg (stmt, lhs))
2730     return stmt;
2731
2732   return NULL;
2733 }
2734
2735
2736 /* Return the argument of the loop PHI that is the inital value coming
2737    from outside the loop.  */
2738
2739 static edge
2740 edge_initial_value_for_loop_phi (gimple phi)
2741 {
2742   size_t i;
2743
2744   for (i = 0; i < gimple_phi_num_args (phi); i++)
2745     {
2746       edge e = gimple_phi_arg_edge (phi, i);
2747
2748       if (loop_depth (e->src->loop_father)
2749           < loop_depth (e->dest->loop_father))
2750         return e;
2751     }
2752
2753   return NULL;
2754 }
2755
2756 /* Return the argument of the loop PHI that is the inital value coming
2757    from outside the loop.  */
2758
2759 static tree
2760 initial_value_for_loop_phi (gimple phi)
2761 {
2762   size_t i;
2763
2764   for (i = 0; i < gimple_phi_num_args (phi); i++)
2765     {
2766       edge e = gimple_phi_arg_edge (phi, i);
2767
2768       if (loop_depth (e->src->loop_father)
2769           < loop_depth (e->dest->loop_father))
2770         return gimple_phi_arg_def (phi, i);
2771     }
2772
2773   return NULL_TREE;
2774 }
2775
2776 /* Detect commutative and associative scalar reductions starting at
2777    the loop closed phi node STMT.  Return the phi node of the
2778    reduction cycle, or NULL.  */
2779
2780 static gimple
2781 detect_commutative_reduction (gimple stmt, VEC (gimple, heap) **in,
2782                               VEC (gimple, heap) **out)
2783 {
2784   if (scalar_close_phi_node_p (stmt))
2785     {
2786       tree arg = gimple_phi_arg_def (stmt, 0);
2787       gimple def, loop_phi;
2788
2789       if (TREE_CODE (arg) != SSA_NAME)
2790         return NULL;
2791
2792       /* Note that loop close phi nodes should have a single argument
2793          because we translated the representation into a canonical form
2794          before Graphite: see canonicalize_loop_closed_ssa_form.  */
2795       gcc_assert (gimple_phi_num_args (stmt) == 1);
2796
2797       def = SSA_NAME_DEF_STMT (arg);
2798       loop_phi = detect_commutative_reduction (def, in, out);
2799
2800       if (loop_phi)
2801         {
2802           tree lhs = gimple_phi_result (stmt);
2803           tree init = initial_value_for_loop_phi (loop_phi);
2804           gimple phi = follow_inital_value_to_phi (init, lhs);
2805
2806           VEC_safe_push (gimple, heap, *in, loop_phi);
2807           VEC_safe_push (gimple, heap, *out, stmt);
2808           return phi;
2809         }
2810       else
2811         return NULL;
2812     }
2813
2814   if (gimple_code (stmt) == GIMPLE_ASSIGN)
2815     return detect_commutative_reduction_assign (stmt, in, out);
2816
2817   return NULL;
2818 }
2819
2820 /* Translate the scalar reduction statement STMT to an array RED
2821    knowing that its recursive phi node is LOOP_PHI.  */
2822
2823 static void
2824 translate_scalar_reduction_to_array_for_stmt (tree red, gimple stmt,
2825                                               gimple loop_phi)
2826 {
2827   gimple_stmt_iterator insert_gsi = gsi_after_labels (gimple_bb (loop_phi));
2828   tree res = gimple_phi_result (loop_phi);
2829   gimple assign = gimple_build_assign (res, red);
2830
2831   gsi_insert_before (&insert_gsi, assign, GSI_SAME_STMT);
2832
2833   insert_gsi = gsi_after_labels (gimple_bb (stmt));
2834   assign = gimple_build_assign (red, gimple_assign_lhs (stmt));
2835   insert_gsi = gsi_for_stmt (stmt);
2836   gsi_insert_after (&insert_gsi, assign, GSI_SAME_STMT);
2837 }
2838
2839 /* Removes the PHI node and resets all the debug stmts that are using
2840    the PHI_RESULT.  */
2841
2842 static void
2843 remove_phi (gimple phi)
2844 {
2845   imm_use_iterator imm_iter;
2846   tree def;
2847   use_operand_p use_p;
2848   gimple_stmt_iterator gsi;
2849   VEC (gimple, heap) *update = VEC_alloc (gimple, heap, 3);
2850   unsigned int i;
2851   gimple stmt;
2852
2853   def = PHI_RESULT (phi);
2854   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2855     {
2856       stmt = USE_STMT (use_p);
2857
2858       if (is_gimple_debug (stmt))
2859         {
2860           gimple_debug_bind_reset_value (stmt);
2861           VEC_safe_push (gimple, heap, update, stmt);
2862         }
2863     }
2864
2865   FOR_EACH_VEC_ELT (gimple, update, i, stmt)
2866     update_stmt (stmt);
2867
2868   VEC_free (gimple, heap, update);
2869
2870   gsi = gsi_for_phi_node (phi);
2871   remove_phi_node (&gsi, false);
2872 }
2873
2874 /* Rewrite out of SSA the reduction described by the loop phi nodes
2875    IN, and the close phi nodes OUT.  IN and OUT are structured by loop
2876    levels like this:
2877
2878    IN: stmt, loop_n, ..., loop_0
2879    OUT: stmt, close_n, ..., close_0
2880
2881    the first element is the reduction statement, and the next elements
2882    are the loop and close phi nodes of each of the outer loops.  */
2883
2884 static void
2885 translate_scalar_reduction_to_array (VEC (gimple, heap) *in,
2886                                      VEC (gimple, heap) *out,
2887                                      sbitmap reductions)
2888 {
2889   unsigned int i;
2890   gimple loop_phi;
2891   tree red = NULL_TREE;
2892
2893   FOR_EACH_VEC_ELT (gimple, in, i, loop_phi)
2894     {
2895       gimple close_phi = VEC_index (gimple, out, i);
2896
2897       if (i == 0)
2898         {
2899           gimple stmt = loop_phi;
2900           basic_block bb = split_reduction_stmt (stmt);
2901
2902           SET_BIT (reductions, bb->index);
2903           gcc_assert (close_phi == loop_phi);
2904
2905           red = create_zero_dim_array
2906             (gimple_assign_lhs (stmt), "Commutative_Associative_Reduction");
2907           translate_scalar_reduction_to_array_for_stmt
2908             (red, stmt, VEC_index (gimple, in, 1));
2909           continue;
2910         }
2911
2912       if (i == VEC_length (gimple, in) - 1)
2913         {
2914           insert_out_of_ssa_copy (gimple_phi_result (close_phi), red,
2915                                   close_phi);
2916           insert_out_of_ssa_copy_on_edge
2917             (edge_initial_value_for_loop_phi (loop_phi),
2918              red, initial_value_for_loop_phi (loop_phi));
2919         }
2920
2921       remove_phi (loop_phi);
2922       remove_phi (close_phi);
2923     }
2924 }
2925
2926 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI.  Returns
2927    true when something has been changed.  */
2928
2929 static bool
2930 rewrite_commutative_reductions_out_of_ssa_close_phi (gimple close_phi,
2931                                                      sbitmap reductions)
2932 {
2933   bool res;
2934   VEC (gimple, heap) *in = VEC_alloc (gimple, heap, 10);
2935   VEC (gimple, heap) *out = VEC_alloc (gimple, heap, 10);
2936
2937   detect_commutative_reduction (close_phi, &in, &out);
2938   res = VEC_length (gimple, in) > 0;
2939   if (res)
2940     translate_scalar_reduction_to_array (in, out, reductions);
2941
2942   VEC_free (gimple, heap, in);
2943   VEC_free (gimple, heap, out);
2944   return res;
2945 }
2946
2947 /* Rewrites all the commutative reductions from LOOP out of SSA.
2948    Returns true when something has been changed.  */
2949
2950 static bool
2951 rewrite_commutative_reductions_out_of_ssa_loop (loop_p loop,
2952                                                 sbitmap reductions,
2953                                                 sese region)
2954 {
2955   gimple_stmt_iterator gsi;
2956   edge exit = single_exit (loop);
2957   tree res;
2958   bool changed = false;
2959
2960   if (!exit)
2961     return false;
2962
2963   for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
2964     if ((res = gimple_phi_result (gsi_stmt (gsi)))
2965         && is_gimple_reg (res)
2966         && !scev_analyzable_p (res, region))
2967       changed |= rewrite_commutative_reductions_out_of_ssa_close_phi
2968         (gsi_stmt (gsi), reductions);
2969
2970   return changed;
2971 }
2972
2973 /* Rewrites all the commutative reductions from SCOP out of SSA.  */
2974
2975 void
2976 rewrite_commutative_reductions_out_of_ssa (sese region, sbitmap reductions)
2977 {
2978   loop_iterator li;
2979   loop_p loop;
2980   bool changed = false;
2981
2982   if (!flag_associative_math)
2983     return;
2984
2985   FOR_EACH_LOOP (li, loop, 0)
2986     if (loop_in_sese_p (loop, region))
2987       changed |= rewrite_commutative_reductions_out_of_ssa_loop (loop,
2988                                                                  reductions,
2989                                                                  region);
2990
2991   if (changed)
2992     {
2993       scev_reset_htab ();
2994       gsi_commit_edge_inserts ();
2995       update_ssa (TODO_update_ssa);
2996 #ifdef ENABLE_CHECKING
2997       verify_loop_closed_ssa (true);
2998 #endif
2999     }
3000 }
3001
3002 /* Java does not initialize long_long_integer_type_node.  */
3003 #define my_long_long (long_long_integer_type_node ? long_long_integer_type_node : ssizetype)
3004
3005 /* Can all ivs be represented by a signed integer?
3006    As CLooG might generate negative values in its expressions, signed loop ivs
3007    are required in the backend. */
3008
3009 static bool
3010 scop_ivs_can_be_represented (scop_p scop)
3011 {
3012   loop_iterator li;
3013   loop_p loop;
3014   gimple_stmt_iterator psi;
3015
3016   FOR_EACH_LOOP (li, loop, 0)
3017     {
3018       if (!loop_in_sese_p (loop, SCOP_REGION (scop)))
3019         continue;
3020
3021       for (psi = gsi_start_phis (loop->header);
3022            !gsi_end_p (psi); gsi_next (&psi))
3023         {
3024           gimple phi = gsi_stmt (psi);
3025           tree res = PHI_RESULT (phi);
3026           tree type = TREE_TYPE (res);
3027
3028           if (TYPE_UNSIGNED (type)
3029               && TYPE_PRECISION (type) >= TYPE_PRECISION (my_long_long))
3030             return false;
3031         }
3032     }
3033
3034   return true;
3035 }
3036
3037 #undef my_long_long
3038
3039 /* Builds the polyhedral representation for a SESE region.  */
3040
3041 void
3042 build_poly_scop (scop_p scop)
3043 {
3044   sese region = SCOP_REGION (scop);
3045   graphite_dim_t max_dim;
3046
3047
3048   /* FIXME: This restriction is needed to avoid a problem in CLooG.
3049      Once CLooG is fixed, remove this guard.  Anyways, it makes no
3050      sense to optimize a scop containing only PBBs that do not belong
3051      to any loops.  */
3052   if (nb_pbbs_in_loops (scop) == 0)
3053     return;
3054
3055   if (!scop_ivs_can_be_represented (scop))
3056     return;
3057
3058   build_sese_loop_nests (region);
3059   build_sese_conditions (region);
3060   find_scop_parameters (scop);
3061
3062   max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
3063   if (scop_nb_params (scop) > max_dim)
3064     return;
3065
3066   build_scop_iteration_domain (scop);
3067   build_scop_context (scop);
3068
3069   add_conditions_to_constraints (scop);
3070   scop_to_lst (scop);
3071   build_scop_scattering (scop);
3072   build_scop_drs (scop);
3073
3074   /* This SCoP has been translated to the polyhedral
3075      representation.  */
3076   POLY_SCOP_P (scop) = true;
3077 }
3078 #endif