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