OSDN Git Service

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