OSDN Git Service

09c703baa3afa827fbe7c041d8ab8a618a7f962b
[pf3gnuchains/gcc-fork.git] / gcc / graphite-clast-to-gimple.c
1 /* Translation of CLAST (CLooG AST) to Gimple.
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 "langhooks.h"
44 #include "sese.h"
45
46 #ifdef HAVE_cloog
47 #include "cloog/cloog.h"
48 #include "ppl_c.h"
49 #include "graphite-ppl.h"
50 #include "graphite.h"
51 #include "graphite-poly.h"
52 #include "graphite-scop-detection.h"
53 #include "graphite-clast-to-gimple.h"
54 #include "graphite-dependences.h"
55
56 /* This flag is set when an error occurred during the translation of
57    CLAST to Gimple.  */
58 static bool gloog_error;
59
60 /* Verifies properties that GRAPHITE should maintain during translation.  */
61
62 static inline void
63 graphite_verify (void)
64 {
65 #ifdef ENABLE_CHECKING
66   verify_loop_structure ();
67   verify_dominators (CDI_DOMINATORS);
68   verify_dominators (CDI_POST_DOMINATORS);
69   verify_loop_closed_ssa (true);
70 #endif
71 }
72
73 /* Stores the INDEX in a vector for a given clast NAME.  */
74
75 typedef struct clast_name_index {
76   int index;
77   const char *name;
78 } *clast_name_index_p;
79
80 /* Returns a pointer to a new element of type clast_name_index_p built
81    from NAME and INDEX.  */
82
83 static inline clast_name_index_p
84 new_clast_name_index (const char *name, int index)
85 {
86   clast_name_index_p res = XNEW (struct clast_name_index);
87
88   res->name = name;
89   res->index = index;
90   return res;
91 }
92
93 /* For a given clast NAME, returns -1 if it does not correspond to any
94    parameter, or otherwise, returns the index in the PARAMS or
95    SCATTERING_DIMENSIONS vector.  */
96
97 static inline int
98 clast_name_to_index (const char *name, htab_t index_table)
99 {
100   struct clast_name_index tmp;
101   PTR *slot;
102
103   tmp.name = name;
104   slot = htab_find_slot (index_table, &tmp, NO_INSERT);
105
106   if (slot && *slot)
107     return ((struct clast_name_index *) *slot)->index;
108
109   return -1;
110 }
111
112 /* Records in INDEX_TABLE the INDEX for NAME.  */
113
114 static inline void
115 save_clast_name_index (htab_t index_table, const char *name, int index)
116 {
117   struct clast_name_index tmp;
118   PTR *slot;
119
120   tmp.name = name;
121   slot = htab_find_slot (index_table, &tmp, INSERT);
122
123   if (slot)
124     {
125       if (*slot)
126         free (*slot);
127
128       *slot = new_clast_name_index (name, index);
129     }
130 }
131
132 /* Print to stderr the element ELT.  */
133
134 static inline void
135 debug_clast_name_index (clast_name_index_p elt)
136 {
137   fprintf (stderr, "(index = %d, name = %s)\n", elt->index, elt->name);
138 }
139
140 /* Helper function for debug_rename_map.  */
141
142 static inline int
143 debug_clast_name_indexes_1 (void **slot, void *s ATTRIBUTE_UNUSED)
144 {
145   struct clast_name_index *entry = (struct clast_name_index *) *slot;
146   debug_clast_name_index (entry);
147   return 1;
148 }
149
150 /* Print to stderr all the elements of MAP.  */
151
152 void
153 debug_clast_name_indexes (htab_t map)
154 {
155   htab_traverse (map, debug_clast_name_indexes_1, NULL);
156 }
157
158 /* Computes a hash function for database element ELT.  */
159
160 static inline hashval_t
161 clast_name_index_elt_info (const void *elt)
162 {
163   return htab_hash_pointer (((const struct clast_name_index *) elt)->name);
164 }
165
166 /* Compares database elements E1 and E2.  */
167
168 static inline int
169 eq_clast_name_indexes (const void *e1, const void *e2)
170 {
171   const struct clast_name_index *elt1 = (const struct clast_name_index *) e1;
172   const struct clast_name_index *elt2 = (const struct clast_name_index *) e2;
173
174   return (elt1->name == elt2->name);
175 }
176
177
178 /* For a given loop DEPTH in the loop nest of the original black box
179    PBB, return the old induction variable associated to that loop.  */
180
181 static inline tree
182 pbb_to_depth_to_oldiv (poly_bb_p pbb, int depth)
183 {
184   gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
185   sese region = SCOP_REGION (PBB_SCOP (pbb));
186   loop_p loop = gbb_loop_at_index (gbb, region, depth);
187
188   return loop->single_iv;
189 }
190
191 /* For a given scattering dimension, return the new induction variable
192    associated to it.  */
193
194 static inline tree
195 newivs_to_depth_to_newiv (VEC (tree, heap) *newivs, int depth)
196 {
197   return VEC_index (tree, newivs, depth);
198 }
199
200 \f
201
202 /* Returns the tree variable from the name NAME that was given in
203    Cloog representation.  */
204
205 static tree
206 clast_name_to_gcc (const char *name, sese region, VEC (tree, heap) *newivs,
207                    htab_t newivs_index, htab_t params_index)
208 {
209   int index;
210   VEC (tree, heap) *params = SESE_PARAMS (region);
211
212   if (params && params_index)
213     {
214       index = clast_name_to_index (name, params_index);
215
216       if (index >= 0)
217         return VEC_index (tree, params, index);
218     }
219
220   gcc_assert (newivs && newivs_index);
221   index = clast_name_to_index (name, newivs_index);
222   gcc_assert (index >= 0);
223
224   return newivs_to_depth_to_newiv (newivs, index);
225 }
226
227 /* Returns the signed maximal precision type for expressions TYPE1 and TYPE2.  */
228
229 static tree
230 max_signed_precision_type (tree type1, tree type2)
231 {
232   int p1 = TYPE_PRECISION (type1);
233   int p2 = TYPE_PRECISION (type2);
234   int precision;
235   tree type;
236
237   if (p1 > p2)
238     precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1;
239   else
240     precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2;
241
242   type = lang_hooks.types.type_for_size (precision, false);
243
244   if (!type)
245     {
246       gloog_error = true;
247       return integer_type_node;
248     }
249   return type;
250 }
251
252 /* Returns the maximal precision type for expressions TYPE1 and TYPE2.  */
253
254 static tree
255 max_precision_type (tree type1, tree type2)
256 {
257   if (POINTER_TYPE_P (type1))
258     return type1;
259
260   if (POINTER_TYPE_P (type2))
261     return type2;
262
263   if (!TYPE_UNSIGNED (type1)
264       || !TYPE_UNSIGNED (type2))
265     return max_signed_precision_type (type1, type2);
266
267   return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
268 }
269
270 static tree
271 clast_to_gcc_expression (tree, struct clast_expr *, sese, VEC (tree, heap) *,
272                          htab_t, htab_t);
273
274 /* Converts a Cloog reduction expression R with reduction operation OP
275    to a GCC expression tree of type TYPE.  */
276
277 static tree
278 clast_to_gcc_expression_red (tree type, enum tree_code op,
279                              struct clast_reduction *r,
280                              sese region, VEC (tree, heap) *newivs,
281                              htab_t newivs_index, htab_t params_index)
282 {
283   int i;
284   tree res = clast_to_gcc_expression (type, r->elts[0], region, newivs,
285                                       newivs_index, params_index);
286   tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type;
287
288   for (i = 1; i < r->n; i++)
289     {
290       tree t = clast_to_gcc_expression (operand_type, r->elts[i], region,
291                                         newivs, newivs_index, params_index);
292       res = fold_build2 (op, type, res, t);
293     }
294
295   return res;
296 }
297
298 /* Converts a Cloog AST expression E back to a GCC expression tree of
299    type TYPE.  */
300
301 static tree
302 clast_to_gcc_expression (tree type, struct clast_expr *e,
303                          sese region, VEC (tree, heap) *newivs,
304                          htab_t newivs_index, htab_t params_index)
305 {
306   switch (e->type)
307     {
308     case expr_term:
309       {
310         struct clast_term *t = (struct clast_term *) e;
311
312         if (t->var)
313           {
314             if (mpz_cmp_si (t->val, 1) == 0)
315               {
316                 tree name = clast_name_to_gcc (t->var, region, newivs,
317                                                newivs_index, params_index);
318
319                 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
320                   name = fold_convert (sizetype, name);
321
322                 name = fold_convert (type, name);
323                 return name;
324               }
325
326             else if (mpz_cmp_si (t->val, -1) == 0)
327               {
328                 tree name = clast_name_to_gcc (t->var, region, newivs,
329                                                newivs_index, params_index);
330
331                 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
332                   name = fold_convert (sizetype, name);
333
334                 name = fold_convert (type, name);
335
336                 return fold_build1 (NEGATE_EXPR, type, name);
337               }
338             else
339               {
340                 tree name = clast_name_to_gcc (t->var, region, newivs,
341                                                newivs_index, params_index);
342                 tree cst = gmp_cst_to_tree (type, t->val);
343
344                 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
345                   name = fold_convert (sizetype, name);
346
347                 name = fold_convert (type, name);
348
349                 if (!POINTER_TYPE_P (type))
350                   return fold_build2 (MULT_EXPR, type, cst, name);
351
352                 gloog_error = true;
353                 return cst;
354               }
355           }
356         else
357           return gmp_cst_to_tree (type, t->val);
358       }
359
360     case expr_red:
361       {
362         struct clast_reduction *r = (struct clast_reduction *) e;
363
364         switch (r->type)
365           {
366           case clast_red_sum:
367             return clast_to_gcc_expression_red
368               (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
369                r, region, newivs, newivs_index, params_index);
370
371           case clast_red_min:
372             return clast_to_gcc_expression_red (type, MIN_EXPR, r, region,
373                                                 newivs, newivs_index,
374                                                 params_index);
375
376           case clast_red_max:
377             return clast_to_gcc_expression_red (type, MAX_EXPR, r, region,
378                                                 newivs, newivs_index,
379                                                 params_index);
380
381           default:
382             gcc_unreachable ();
383           }
384         break;
385       }
386
387     case expr_bin:
388       {
389         struct clast_binary *b = (struct clast_binary *) e;
390         struct clast_expr *lhs = (struct clast_expr *) b->LHS;
391         tree tl = clast_to_gcc_expression (type, lhs, region, newivs,
392                                            newivs_index, params_index);
393         tree tr = gmp_cst_to_tree (type, b->RHS);
394
395         switch (b->type)
396           {
397           case clast_bin_fdiv:
398             return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
399
400           case clast_bin_cdiv:
401             return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
402
403           case clast_bin_div:
404             return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
405
406           case clast_bin_mod:
407             return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
408
409           default:
410             gcc_unreachable ();
411           }
412       }
413
414     default:
415       gcc_unreachable ();
416     }
417
418   return NULL_TREE;
419 }
420
421 /* Return the precision needed to represent the value VAL.  */
422
423 static int
424 precision_for_value (mpz_t val)
425 {
426   mpz_t x, y, two;
427   int precision;
428
429   value_init (x);
430   value_init (y);
431   value_init (two);
432   value_set_si (x, 2);
433   value_assign (y, val);
434   value_set_si (two, 2);
435   precision = 1;
436
437   if (value_neg_p (y))
438     value_oppose (y, y);
439
440   while (value_gt (y, x))
441     {
442       value_multiply (x, x, two);
443       precision++;
444     }
445
446   value_clear (x);
447   value_clear (y);
448   value_clear (two);
449
450   return precision;
451 }
452
453 /* Return the precision needed to represent the values between LOW and
454    UP.  */
455
456 static int
457 precision_for_interval (mpz_t low, mpz_t up)
458 {
459   mpz_t diff;
460   int precision;
461
462   gcc_assert (value_le (low, up));
463
464   value_init (diff);
465   value_subtract (diff, up, low);
466   precision = precision_for_value (diff);
467   value_clear (diff);
468
469   return precision;
470 }
471
472 /* Return a type that could represent the integer value VAL, or
473    otherwise return NULL_TREE.  */
474
475 static tree
476 gcc_type_for_interval (mpz_t low, mpz_t up, tree old_type)
477 {
478   bool unsigned_p = true;
479   int precision, prec_up, prec_int;
480   tree type;
481
482   gcc_assert (value_le (low, up));
483
484   /* Preserve the signedness of the old IV.  */
485   if ((old_type && !TYPE_UNSIGNED (old_type))
486       || value_neg_p (low))
487     unsigned_p = false;
488
489   prec_up = precision_for_value (up);
490   prec_int = precision_for_interval (low, up);
491   precision = prec_up > prec_int ? prec_up : prec_int;
492
493   type = lang_hooks.types.type_for_size (precision, unsigned_p);
494   if (!type)
495     {
496       gloog_error = true;
497       return integer_type_node;
498     }
499
500   return type;
501 }
502
503 /* Return a type that could represent the integer value VAL, or
504    otherwise return NULL_TREE.  */
505
506 static tree
507 gcc_type_for_value (mpz_t val)
508 {
509   return gcc_type_for_interval (val, val, NULL_TREE);
510 }
511
512 /* Return the type for the clast_term T used in STMT.  */
513
514 static tree
515 gcc_type_for_clast_term (struct clast_term *t,
516                          sese region, VEC (tree, heap) *newivs,
517                          htab_t newivs_index, htab_t params_index)
518 {
519   gcc_assert (t->expr.type == expr_term);
520
521   if (!t->var)
522     return gcc_type_for_value (t->val);
523
524   return TREE_TYPE (clast_name_to_gcc (t->var, region, newivs,
525                                        newivs_index, params_index));
526 }
527
528 static tree
529 gcc_type_for_clast_expr (struct clast_expr *, sese,
530                          VEC (tree, heap) *, htab_t, htab_t);
531
532 /* Return the type for the clast_reduction R used in STMT.  */
533
534 static tree
535 gcc_type_for_clast_red (struct clast_reduction *r, sese region,
536                         VEC (tree, heap) *newivs,
537                         htab_t newivs_index, htab_t params_index)
538 {
539   int i;
540   tree type = NULL_TREE;
541
542   if (r->n == 1)
543     return gcc_type_for_clast_expr (r->elts[0], region, newivs,
544                                     newivs_index, params_index);
545
546   switch (r->type)
547     {
548     case clast_red_sum:
549     case clast_red_min:
550     case clast_red_max:
551       type = gcc_type_for_clast_expr (r->elts[0], region, newivs,
552                                       newivs_index, params_index);
553       for (i = 1; i < r->n; i++)
554         type = max_precision_type (type, gcc_type_for_clast_expr
555                                    (r->elts[i], region, newivs,
556                                     newivs_index, params_index));
557
558       return type;
559
560     default:
561       break;
562     }
563
564   gcc_unreachable ();
565   return NULL_TREE;
566 }
567
568 /* Return the type for the clast_binary B used in STMT.  */
569
570 static tree
571 gcc_type_for_clast_bin (struct clast_binary *b,
572                         sese region, VEC (tree, heap) *newivs,
573                         htab_t newivs_index, htab_t params_index)
574 {
575   tree l = gcc_type_for_clast_expr ((struct clast_expr *) b->LHS, region,
576                                     newivs, newivs_index, params_index);
577   tree r = gcc_type_for_value (b->RHS);
578   return max_signed_precision_type (l, r);
579 }
580
581 /* Returns the type for the CLAST expression E when used in statement
582    STMT.  */
583
584 static tree
585 gcc_type_for_clast_expr (struct clast_expr *e,
586                          sese region, VEC (tree, heap) *newivs,
587                          htab_t newivs_index, htab_t params_index)
588 {
589   switch (e->type)
590     {
591     case expr_term:
592       return gcc_type_for_clast_term ((struct clast_term *) e, region,
593                                       newivs, newivs_index, params_index);
594
595     case expr_red:
596       return gcc_type_for_clast_red ((struct clast_reduction *) e, region,
597                                      newivs, newivs_index, params_index);
598
599     case expr_bin:
600       return gcc_type_for_clast_bin ((struct clast_binary *) e, region,
601                                      newivs, newivs_index, params_index);
602
603     default:
604       gcc_unreachable ();
605     }
606
607   return NULL_TREE;
608 }
609
610 /* Returns the type for the equation CLEQ.  */
611
612 static tree
613 gcc_type_for_clast_eq (struct clast_equation *cleq,
614                        sese region, VEC (tree, heap) *newivs,
615                        htab_t newivs_index, htab_t params_index)
616 {
617   tree l = gcc_type_for_clast_expr (cleq->LHS, region, newivs,
618                                     newivs_index, params_index);
619   tree r = gcc_type_for_clast_expr (cleq->RHS, region, newivs,
620                                     newivs_index, params_index);
621   return max_precision_type (l, r);
622 }
623
624 /* Translates a clast equation CLEQ to a tree.  */
625
626 static tree
627 graphite_translate_clast_equation (sese region,
628                                    struct clast_equation *cleq,
629                                    VEC (tree, heap) *newivs,
630                                    htab_t newivs_index, htab_t params_index)
631 {
632   enum tree_code comp;
633   tree type = gcc_type_for_clast_eq (cleq, region, newivs, newivs_index,
634                                      params_index);
635   tree lhs = clast_to_gcc_expression (type, cleq->LHS, region, newivs,
636                                       newivs_index, params_index);
637   tree rhs = clast_to_gcc_expression (type, cleq->RHS, region, newivs,
638                                       newivs_index, params_index);
639
640   if (cleq->sign == 0)
641     comp = EQ_EXPR;
642
643   else if (cleq->sign > 0)
644     comp = GE_EXPR;
645
646   else
647     comp = LE_EXPR;
648
649   return fold_build2 (comp, boolean_type_node, lhs, rhs);
650 }
651
652 /* Creates the test for the condition in STMT.  */
653
654 static tree
655 graphite_create_guard_cond_expr (sese region, struct clast_guard *stmt,
656                                  VEC (tree, heap) *newivs,
657                                  htab_t newivs_index, htab_t params_index)
658 {
659   tree cond = NULL;
660   int i;
661
662   for (i = 0; i < stmt->n; i++)
663     {
664       tree eq = graphite_translate_clast_equation (region, &stmt->eq[i],
665                                                    newivs, newivs_index,
666                                                    params_index);
667
668       if (cond)
669         cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
670       else
671         cond = eq;
672     }
673
674   return cond;
675 }
676
677 /* Creates a new if region corresponding to Cloog's guard.  */
678
679 static edge
680 graphite_create_new_guard (sese region, edge entry_edge,
681                            struct clast_guard *stmt,
682                            VEC (tree, heap) *newivs,
683                            htab_t newivs_index, htab_t params_index)
684 {
685   tree cond_expr = graphite_create_guard_cond_expr (region, stmt, newivs,
686                                                     newivs_index, params_index);
687   edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
688   return exit_edge;
689 }
690
691 /* Compute the lower bound LOW and upper bound UP for the induction
692    variable at LEVEL for the statement PBB, based on the transformed
693    scattering of PBB: T|I|G|Cst, with T the scattering transform, I
694    the iteration domain, and G the context parameters.  */
695
696 static void
697 compute_bounds_for_level (poly_bb_p pbb, int level, mpz_t low, mpz_t up)
698 {
699   ppl_Pointset_Powerset_C_Polyhedron_t ps;
700   ppl_Linear_Expression_t le;
701
702   combine_context_id_scat (&ps, pbb, false);
703
704   /* Prepare the linear expression corresponding to the level that we
705      want to maximize/minimize.  */
706   {
707     ppl_dimension_type dim = pbb_nb_scattering_transform (pbb)
708       + pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb);
709
710     ppl_new_Linear_Expression_with_dimension (&le, dim);
711     ppl_set_coef (le, 2 * level + 1, 1);
712   }
713
714   ppl_max_for_le_pointset (ps, le, up);
715   ppl_min_for_le_pointset (ps, le, low);
716 }
717
718 /* Compute the type for the induction variable at LEVEL for the
719    statement PBB, based on the transformed schedule of PBB.  OLD_TYPE
720    is the type of the old induction variable for that loop.  */
721 /* Java does not initialize long_long_integer_type_node.  */
722 #define my_long_long (long_long_integer_type_node ? long_long_integer_type_node : ssizetype)
723
724 /* Given a CLOOG_IV, return the type that CLOOG_IV should have in GCC
725    land.  The selected type is big enough to include the original loop
726    iteration variable, but signed to work with the subtractions CLooG
727    may have introduced.  If such a type is not available, we fail.
728
729 static tree
730 compute_type_for_level_1 (poly_bb_p pbb, int level, tree old_type)
731 {
732   mpz_t low, up;
733   tree type;
734
735   value_init (low);
736   value_init (up);
737
738   compute_bounds_for_level (pbb, level, low, up);
739   type = gcc_type_for_interval (low, up, old_type);
740
741   value_clear (low);
742   value_clear (up);
743   return type;
744 }
745
746 /* Compute the type for the induction variable at LEVEL for the
747    statement PBB, based on the transformed schedule of PBB.  */
748
749 static tree
750 compute_type_for_level (poly_bb_p pbb, int level)
751 {
752   tree oldiv = pbb_to_depth_to_oldiv (pbb, level);
753   tree type = TREE_TYPE (oldiv);
754
755   if (type && POINTER_TYPE_P (type))
756     {
757 #ifdef ENABLE_CHECKING
758       tree ctype = compute_type_for_level_1 (pbb, level, type);
759
760       /* In the case of a pointer type, check that after the loop
761          transform, the lower and the upper bounds of the type fit the
762          oldiv pointer type.  */
763       gcc_assert (TYPE_PRECISION (type) >= TYPE_PRECISION (ctype)
764                   && integer_zerop (lower_bound_in_type (ctype, ctype)));
765 #endif
766       return type;
767     }
768
769   return compute_type_for_level_1 (pbb, level, type);
770 }
771
772 /* Walks a CLAST and returns the first statement in the body of a
773    loop.  */
774
775 static struct clast_user_stmt *
776 clast_get_body_of_loop (struct clast_stmt *stmt)
777 {
778   if (!stmt
779       || CLAST_STMT_IS_A (stmt, stmt_user))
780     return (struct clast_user_stmt *) stmt;
781
782   if (CLAST_STMT_IS_A (stmt, stmt_for))
783     return clast_get_body_of_loop (((struct clast_for *) stmt)->body);
784
785       if (type_precision < TYPE_PRECISION (my_long_long))
786         return my_long_long;
787
788   if (CLAST_STMT_IS_A (stmt, stmt_block))
789     return clast_get_body_of_loop (((struct clast_block *) stmt)->body);
790
791   return my_long_long;
792 }
793
794 #undef my_long_long
795
796 /* Returns the induction variable for the loop that gets translated to
797    STMT.  */
798
799 static tree
800 gcc_type_for_iv_of_clast_loop (struct clast_for *stmt_for, int level,
801                                tree lb_type, tree ub_type)
802 {
803   struct clast_stmt *stmt = (struct clast_stmt *) stmt_for;
804   struct clast_user_stmt *body = clast_get_body_of_loop (stmt);
805   CloogStatement *cs = body->statement;
806   poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
807
808   return max_signed_precision_type (lb_type, max_precision_type
809                                     (ub_type, compute_type_for_level
810                                      (pbb, level - 1)));
811 }
812
813 /* Creates a new LOOP corresponding to Cloog's STMT.  Inserts an
814    induction variable for the new LOOP.  New LOOP is attached to CFG
815    starting at ENTRY_EDGE.  LOOP is inserted into the loop tree and
816    becomes the child loop of the OUTER_LOOP.  NEWIVS_INDEX binds
817    CLooG's scattering name to the induction variable created for the
818    loop of STMT.  The new induction variable is inserted in the NEWIVS
819    vector.  */
820
821 static struct loop *
822 graphite_create_new_loop (sese region, edge entry_edge,
823                           struct clast_for *stmt,
824                           loop_p outer, VEC (tree, heap) **newivs,
825                           htab_t newivs_index, htab_t params_index, int level)
826 {
827   tree lb_type = gcc_type_for_clast_expr (stmt->LB, region, *newivs,
828                                           newivs_index, params_index);
829   tree ub_type = gcc_type_for_clast_expr (stmt->UB, region, *newivs,
830                                           newivs_index, params_index);
831   tree type = gcc_type_for_iv_of_clast_loop (stmt, level, lb_type, ub_type);
832   tree lb = clast_to_gcc_expression (type, stmt->LB, region, *newivs,
833                                      newivs_index, params_index);
834   tree ub = clast_to_gcc_expression (type, stmt->UB, region, *newivs,
835                                      newivs_index, params_index);
836   tree stride = gmp_cst_to_tree (type, stmt->stride);
837   tree ivvar = create_tmp_var (type, "graphite_IV");
838   tree iv, iv_after_increment;
839   loop_p loop = create_empty_loop_on_edge
840     (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
841      outer ? outer : entry_edge->src->loop_father);
842
843   add_referenced_var (ivvar);
844
845   save_clast_name_index (newivs_index, stmt->iterator,
846                          VEC_length (tree, *newivs));
847   VEC_safe_push (tree, heap, *newivs, iv);
848   return loop;
849 }
850
851 /* Inserts in MAP a tuple (OLD_NAME, NEW_NAME) for the induction
852    variables of the loops around GBB in SESE.  */
853
854 static void
855 build_iv_mapping (htab_t map, sese region,
856                   VEC (tree, heap) *newivs, htab_t newivs_index,
857                   struct clast_user_stmt *user_stmt,
858                   htab_t params_index)
859 {
860   struct clast_stmt *t;
861   int index = 0;
862   CloogStatement *cs = user_stmt->statement;
863   poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
864
865   for (t = user_stmt->substitutions; t; t = t->next, index++)
866     {
867       struct clast_expr *expr = (struct clast_expr *)
868        ((struct clast_assignment *)t)->RHS;
869       tree type = gcc_type_for_clast_expr (expr, region, newivs,
870                                            newivs_index, params_index);
871       tree old_name = pbb_to_depth_to_oldiv (pbb, index);
872       tree e = clast_to_gcc_expression (type, expr, region, newivs,
873                                         newivs_index, params_index);
874       set_rename (map, old_name, e);
875     }
876 }
877
878 /* Helper function for htab_traverse.  */
879
880 static int
881 copy_renames (void **slot, void *s)
882 {
883   struct rename_map_elt_s *entry = (struct rename_map_elt_s *) *slot;
884   htab_t res = (htab_t) s;
885   tree old_name = entry->old_name;
886   tree expr = entry->expr;
887   struct rename_map_elt_s tmp;
888   PTR *x;
889
890   tmp.old_name = old_name;
891   x = htab_find_slot (res, &tmp, INSERT);
892
893   if (x && !*x)
894     *x = new_rename_map_elt (old_name, expr);
895
896   return 1;
897 }
898
899 /* Construct bb_pbb_def with BB and PBB. */
900
901 static bb_pbb_def *
902 new_bb_pbb_def (basic_block bb, poly_bb_p pbb)
903 {
904   bb_pbb_def *bb_pbb_p;
905
906   bb_pbb_p = XNEW (bb_pbb_def);
907   bb_pbb_p->bb = bb;
908   bb_pbb_p->pbb = pbb;
909
910   return bb_pbb_p;
911 }
912
913 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING.  */
914
915 static void
916 mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping)
917 {
918   bb_pbb_def tmp;
919   PTR *x;
920
921   tmp.bb = bb;
922   x = htab_find_slot (bb_pbb_mapping, &tmp, INSERT);
923
924   if (x && !*x)
925     *x = new_bb_pbb_def (bb, pbb);
926 }
927
928 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING.  */
929
930 static poly_bb_p
931 find_pbb_via_hash (htab_t bb_pbb_mapping, basic_block bb)
932 {
933   bb_pbb_def tmp;
934   PTR *slot;
935
936   tmp.bb = bb;
937   slot = htab_find_slot (bb_pbb_mapping, &tmp, NO_INSERT);
938
939   if (slot && *slot)
940     return ((bb_pbb_def *) *slot)->pbb;
941
942   return NULL;
943 }
944
945 /* Check data dependency in LOOP at scattering level LEVEL.
946    BB_PBB_MAPPING is a basic_block and it's related poly_bb_p
947    mapping.  */
948
949 static bool
950 dependency_in_loop_p (loop_p loop, htab_t bb_pbb_mapping, int level)
951 {
952   unsigned i,j;
953   basic_block *bbs = get_loop_body_in_dom_order (loop);
954
955   for (i = 0; i < loop->num_nodes; i++)
956     {
957       poly_bb_p pbb1 = find_pbb_via_hash (bb_pbb_mapping, bbs[i]);
958
959       if (pbb1 == NULL)
960        continue;
961
962       for (j = 0; j < loop->num_nodes; j++)
963        {
964          poly_bb_p pbb2 = find_pbb_via_hash (bb_pbb_mapping, bbs[j]);
965
966          if (pbb2 == NULL)
967            continue;
968
969          if (dependency_between_pbbs_p (pbb1, pbb2, level))
970            {
971              free (bbs);
972              return true;
973            }
974        }
975     }
976
977   free (bbs);
978
979   return false;
980 }
981
982 static edge
983 translate_clast (sese, loop_p, struct clast_stmt *, edge, htab_t,
984                  VEC (tree, heap) **, htab_t, htab_t, int, htab_t);
985
986 /* Translates a clast user statement STMT to gimple.
987
988    - REGION is the sese region we used to generate the scop.
989    - NEXT_E is the edge where new generated code should be attached.
990    - CONTEXT_LOOP is the loop in which the generated code will be placed
991    - RENAME_MAP contains a set of tuples of new names associated to
992      the original variables names.
993    - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
994    - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
995      the sese region.  */
996 static edge
997 translate_clast_user (sese region, struct clast_user_stmt *stmt, edge next_e,
998                       htab_t rename_map, VEC (tree, heap) **newivs,
999                       htab_t newivs_index, htab_t bb_pbb_mapping,
1000                       htab_t params_index)
1001 {
1002   gimple_bb_p gbb;
1003   basic_block new_bb;
1004   poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (stmt->statement);
1005   gbb = PBB_BLACK_BOX (pbb);
1006
1007   if (GBB_BB (gbb) == ENTRY_BLOCK_PTR)
1008     return next_e;
1009
1010   build_iv_mapping (rename_map, region, *newivs, newivs_index, stmt,
1011                     params_index);
1012   next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), region,
1013                                            next_e, rename_map);
1014   new_bb = next_e->src;
1015   mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
1016   update_ssa (TODO_update_ssa);
1017
1018   return next_e;
1019 }
1020
1021 /* Creates a new if region protecting the loop to be executed, if the execution
1022    count is zero (lb > ub).  */
1023 static edge
1024 graphite_create_new_loop_guard (sese region, edge entry_edge,
1025                                 struct clast_for *stmt,
1026                                 VEC (tree, heap) *newivs,
1027                                 htab_t newivs_index, htab_t params_index)
1028 {
1029   tree cond_expr;
1030   edge exit_edge;
1031   tree lb_type = gcc_type_for_clast_expr (stmt->LB, region, newivs,
1032                                           newivs_index, params_index);
1033   tree ub_type = gcc_type_for_clast_expr (stmt->UB, region, newivs,
1034                                           newivs_index, params_index);
1035   tree type = max_precision_type (lb_type, ub_type);
1036   tree lb = clast_to_gcc_expression (type, stmt->LB, region, newivs,
1037                                      newivs_index, params_index);
1038   tree ub = clast_to_gcc_expression (type, stmt->UB, region, newivs,
1039                                      newivs_index, params_index);
1040   tree ub_one;
1041
1042   /* Adding +1 and using LT_EXPR helps with loop latches that have a
1043      loop iteration count of "PARAMETER - 1".  For PARAMETER == 0 this becomes
1044      2^{32|64}, and the condition lb <= ub is true, even if we do not want this.
1045      However lb < ub + 1 is false, as expected.  */
1046   tree one;
1047   mpz_t gmp_one;
1048   
1049   mpz_init (gmp_one);
1050   mpz_set_si (gmp_one, 1);
1051   one = gmp_cst_to_tree (type, gmp_one);
1052   mpz_clear (gmp_one);
1053
1054   ub_one = fold_build2 (POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
1055                         type, ub, one);
1056
1057   /* When ub + 1 wraps around, use lb <= ub.  */
1058   if (integer_zerop (ub_one))
1059     cond_expr = fold_build2 (LE_EXPR, boolean_type_node, lb, ub);
1060   else
1061     cond_expr = fold_build2 (LT_EXPR, boolean_type_node, lb, ub_one);
1062
1063   exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
1064
1065   return exit_edge;
1066 }
1067
1068
1069 /* Create the loop for a clast for statement.
1070
1071    - REGION is the sese region we used to generate the scop.
1072    - NEXT_E is the edge where new generated code should be attached.
1073    - RENAME_MAP contains a set of tuples of new names associated to
1074      the original variables names.
1075    - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
1076    - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
1077      the sese region.  */
1078 static edge
1079 translate_clast_for_loop (sese region, loop_p context_loop,
1080                           struct clast_for *stmt, edge next_e,
1081                           htab_t rename_map, VEC (tree, heap) **newivs,
1082                           htab_t newivs_index, htab_t bb_pbb_mapping,
1083                           int level, htab_t params_index)
1084 {
1085   struct loop *loop = graphite_create_new_loop (region, next_e, stmt,
1086                                                 context_loop, newivs,
1087                                                 newivs_index, params_index,
1088                                                 level);
1089   edge last_e = single_exit (loop);
1090   edge to_body = single_succ_edge (loop->header);
1091   basic_block after = to_body->dest;
1092
1093   /* Create a basic block for loop close phi nodes.  */
1094   last_e = single_succ_edge (split_edge (last_e));
1095
1096   /* Translate the body of the loop.  */
1097   next_e = translate_clast (region, loop, stmt->body, to_body, rename_map,
1098                             newivs, newivs_index, bb_pbb_mapping, level + 1,
1099                             params_index);
1100   redirect_edge_succ_nodup (next_e, after);
1101   set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
1102
1103    /* Remove from rename_map all the tuples containing variables
1104       defined in loop's body.  */
1105   insert_loop_close_phis (rename_map, loop);
1106
1107   if (flag_loop_parallelize_all
1108       && !dependency_in_loop_p (loop, bb_pbb_mapping,
1109                                 get_scattering_level (level)))
1110     loop->can_be_parallel = true;
1111
1112   return last_e;
1113 }
1114
1115 /* Translates a clast for statement STMT to gimple.  First a guard is created
1116    protecting the loop, if it is executed zero times.  In this guard we create
1117    the real loop structure.
1118
1119    - REGION is the sese region we used to generate the scop.
1120    - NEXT_E is the edge where new generated code should be attached.
1121    - RENAME_MAP contains a set of tuples of new names associated to
1122      the original variables names.
1123    - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
1124    - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
1125      the sese region.  */
1126 static edge
1127 translate_clast_for (sese region, loop_p context_loop, struct clast_for *stmt,
1128                      edge next_e, htab_t rename_map, VEC (tree, heap) **newivs,
1129                      htab_t newivs_index, htab_t bb_pbb_mapping, int level,
1130                      htab_t params_index)
1131 {
1132   edge last_e = graphite_create_new_loop_guard (region, next_e, stmt, *newivs,
1133                                                 newivs_index, params_index);
1134
1135   edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1136   edge false_e = get_false_edge_from_guard_bb (next_e->dest);
1137   edge exit_true_e = single_succ_edge (true_e->dest);
1138   edge exit_false_e = single_succ_edge (false_e->dest);
1139
1140   htab_t before_guard = htab_create (10, rename_map_elt_info,
1141                                      eq_rename_map_elts, free);
1142   htab_traverse (rename_map, copy_renames, before_guard);
1143
1144   next_e = translate_clast_for_loop (region, context_loop, stmt, true_e,
1145                                      rename_map, newivs,
1146                                      newivs_index, bb_pbb_mapping, level,
1147                                      params_index);
1148
1149   insert_guard_phis (last_e->src, exit_true_e, exit_false_e,
1150                      before_guard, rename_map);
1151
1152   htab_delete (before_guard);
1153
1154   return last_e;
1155 }
1156
1157 /* Translates a clast guard statement STMT to gimple.
1158
1159    - REGION is the sese region we used to generate the scop.
1160    - NEXT_E is the edge where new generated code should be attached.
1161    - CONTEXT_LOOP is the loop in which the generated code will be placed
1162    - RENAME_MAP contains a set of tuples of new names associated to
1163      the original variables names.
1164    - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
1165    - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
1166      the sese region.  */
1167 static edge
1168 translate_clast_guard (sese region, loop_p context_loop,
1169                        struct clast_guard *stmt, edge next_e,
1170                        htab_t rename_map, VEC (tree, heap) **newivs,
1171                        htab_t newivs_index, htab_t bb_pbb_mapping, int level,
1172                        htab_t params_index)
1173 {
1174   edge last_e = graphite_create_new_guard (region, next_e, stmt, *newivs,
1175                                            newivs_index, params_index);
1176
1177   edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1178   edge false_e = get_false_edge_from_guard_bb (next_e->dest);
1179   edge exit_true_e = single_succ_edge (true_e->dest);
1180   edge exit_false_e = single_succ_edge (false_e->dest);
1181
1182   htab_t before_guard = htab_create (10, rename_map_elt_info,
1183                                      eq_rename_map_elts, free);
1184   htab_traverse (rename_map, copy_renames, before_guard);
1185
1186   next_e = translate_clast (region, context_loop, stmt->then, true_e,
1187                             rename_map, newivs, newivs_index, bb_pbb_mapping,
1188                             level, params_index);
1189
1190   insert_guard_phis (last_e->src, exit_true_e, exit_false_e,
1191                      before_guard, rename_map);
1192
1193   htab_delete (before_guard);
1194
1195   return last_e;
1196 }
1197
1198 /* Translates a CLAST statement STMT to GCC representation in the
1199    context of a SESE.
1200
1201    - NEXT_E is the edge where new generated code should be attached.
1202    - CONTEXT_LOOP is the loop in which the generated code will be placed
1203    - RENAME_MAP contains a set of tuples of new names associated to
1204      the original variables names.
1205    - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.  */
1206 static edge
1207 translate_clast (sese region, loop_p context_loop, struct clast_stmt *stmt,
1208                  edge next_e, htab_t rename_map, VEC (tree, heap) **newivs,
1209                  htab_t newivs_index, htab_t bb_pbb_mapping, int level,
1210                  htab_t params_index)
1211 {
1212   if (!stmt)
1213     return next_e;
1214
1215   if (CLAST_STMT_IS_A (stmt, stmt_root))
1216     ; /* Do nothing.  */
1217
1218   else if (CLAST_STMT_IS_A (stmt, stmt_user))
1219     next_e = translate_clast_user (region, (struct clast_user_stmt *) stmt,
1220                                    next_e, rename_map, newivs, newivs_index,
1221                                    bb_pbb_mapping, params_index);
1222
1223   else if (CLAST_STMT_IS_A (stmt, stmt_for))
1224     next_e = translate_clast_for (region, context_loop,
1225                                   (struct clast_for *) stmt, next_e,
1226                                   rename_map, newivs, newivs_index,
1227                                   bb_pbb_mapping, level, params_index);
1228
1229   else if (CLAST_STMT_IS_A (stmt, stmt_guard))
1230     next_e = translate_clast_guard (region, context_loop,
1231                                     (struct clast_guard *) stmt, next_e,
1232                                     rename_map, newivs, newivs_index,
1233                                     bb_pbb_mapping, level, params_index);
1234
1235   else if (CLAST_STMT_IS_A (stmt, stmt_block))
1236     next_e = translate_clast (region, context_loop,
1237                               ((struct clast_block *) stmt)->body,
1238                               next_e, rename_map, newivs, newivs_index,
1239                               bb_pbb_mapping, level, params_index);
1240   else
1241     gcc_unreachable();
1242
1243   recompute_all_dominators ();
1244   graphite_verify ();
1245
1246   return translate_clast (region, context_loop, stmt->next, next_e,
1247                           rename_map, newivs, newivs_index,
1248                           bb_pbb_mapping, level, params_index);
1249 }
1250
1251 /* Free the SCATTERING domain list.  */
1252
1253 static void
1254 free_scattering (CloogDomainList *scattering)
1255 {
1256   while (scattering)
1257     {
1258       CloogDomain *dom = cloog_domain (scattering);
1259       CloogDomainList *next = cloog_next_domain (scattering);
1260
1261       cloog_domain_free (dom);
1262       free (scattering);
1263       scattering = next;
1264     }
1265 }
1266
1267 /* Initialize Cloog's parameter names from the names used in GIMPLE.
1268    Initialize Cloog's iterator names, using 'graphite_iterator_%d'
1269    from 0 to scop_nb_loops (scop).  */
1270
1271 static void
1272 initialize_cloog_names (scop_p scop, CloogProgram *prog)
1273 {
1274   sese region = SCOP_REGION (scop);
1275   int i;
1276   int nb_iterators = scop_max_loop_depth (scop);
1277   int nb_scattering = cloog_program_nb_scattdims (prog);
1278   int nb_parameters = VEC_length (tree, SESE_PARAMS (region));
1279   char **iterators = XNEWVEC (char *, nb_iterators * 2);
1280   char **scattering = XNEWVEC (char *, nb_scattering);
1281   char **parameters= XNEWVEC (char *, nb_parameters);
1282
1283   cloog_program_set_names (prog, cloog_names_malloc ());
1284
1285   for (i = 0; i < nb_parameters; i++)
1286     {
1287       tree param = VEC_index (tree, SESE_PARAMS(region), i);
1288       const char *name = get_name (param);
1289       int len;
1290
1291       if (!name)
1292         name = "T";
1293
1294       len = strlen (name);
1295       len += 17;
1296       parameters[i] = XNEWVEC (char, len + 1);
1297       snprintf (parameters[i], len, "%s_%d", name, SSA_NAME_VERSION (param));
1298     }
1299
1300   cloog_names_set_nb_parameters (cloog_program_names (prog), nb_parameters);
1301   cloog_names_set_parameters (cloog_program_names (prog), parameters);
1302
1303   for (i = 0; i < nb_iterators; i++)
1304     {
1305       int len = 4 + 16;
1306       iterators[i] = XNEWVEC (char, len);
1307       snprintf (iterators[i], len, "git_%d", i);
1308     }
1309
1310   cloog_names_set_nb_iterators (cloog_program_names (prog),
1311                                 nb_iterators);
1312   cloog_names_set_iterators (cloog_program_names (prog),
1313                              iterators);
1314
1315   for (i = 0; i < nb_scattering; i++)
1316     {
1317       int len = 5 + 16;
1318       scattering[i] = XNEWVEC (char, len);
1319       snprintf (scattering[i], len, "scat_%d", i);
1320     }
1321
1322   cloog_names_set_nb_scattering (cloog_program_names (prog),
1323                                  nb_scattering);
1324   cloog_names_set_scattering (cloog_program_names (prog),
1325                               scattering);
1326 }
1327
1328 /* Build cloog program for SCoP.  */
1329
1330 static void
1331 build_cloog_prog (scop_p scop, CloogProgram *prog)
1332 {
1333   int i;
1334   int max_nb_loops = scop_max_loop_depth (scop);
1335   poly_bb_p pbb;
1336   CloogLoop *loop_list = NULL;
1337   CloogBlockList *block_list = NULL;
1338   CloogDomainList *scattering = NULL;
1339   int nbs = 2 * max_nb_loops + 1;
1340   int *scaldims;
1341
1342   cloog_program_set_context
1343     (prog, new_Cloog_Domain_from_ppl_Pointset_Powerset (SCOP_CONTEXT (scop)));
1344   nbs = unify_scattering_dimensions (scop);
1345   scaldims = (int *) xmalloc (nbs * (sizeof (int)));
1346   cloog_program_set_nb_scattdims (prog, nbs);
1347   initialize_cloog_names (scop, prog);
1348
1349   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1350     {
1351       CloogStatement *stmt;
1352       CloogBlock *block;
1353
1354       /* Dead code elimination: when the domain of a PBB is empty,
1355          don't generate code for the PBB.  */
1356       if (ppl_Pointset_Powerset_C_Polyhedron_is_empty (PBB_DOMAIN (pbb)))
1357         continue;
1358
1359       /* Build the new statement and its block.  */
1360       stmt = cloog_statement_alloc (pbb_index (pbb));
1361       block = cloog_block_alloc (stmt, 0, NULL, pbb_dim_iter_domain (pbb));
1362       cloog_statement_set_usr (stmt, pbb);
1363
1364       /* Build loop list.  */
1365       {
1366         CloogLoop *new_loop_list = cloog_loop_malloc ();
1367         cloog_loop_set_next (new_loop_list, loop_list);
1368         cloog_loop_set_domain
1369           (new_loop_list,
1370            new_Cloog_Domain_from_ppl_Pointset_Powerset (PBB_DOMAIN (pbb)));
1371         cloog_loop_set_block (new_loop_list, block);
1372         loop_list = new_loop_list;
1373       }
1374
1375       /* Build block list.  */
1376       {
1377         CloogBlockList *new_block_list = cloog_block_list_malloc ();
1378
1379         cloog_block_list_set_next (new_block_list, block_list);
1380         cloog_block_list_set_block (new_block_list, block);
1381         block_list = new_block_list;
1382       }
1383
1384       /* Build scattering list.  */
1385       {
1386         /* XXX: Replace with cloog_domain_list_alloc(), when available.  */
1387         CloogDomainList *new_scattering
1388           = (CloogDomainList *) xmalloc (sizeof (CloogDomainList));
1389         ppl_Polyhedron_t scat;
1390         CloogDomain *dom;
1391
1392         scat = PBB_TRANSFORMED_SCATTERING (pbb);
1393         dom = new_Cloog_Domain_from_ppl_Polyhedron (scat);
1394
1395         cloog_set_next_domain (new_scattering, scattering);
1396         cloog_set_domain (new_scattering, dom);
1397         scattering = new_scattering;
1398       }
1399     }
1400
1401   cloog_program_set_loop (prog, loop_list);
1402   cloog_program_set_blocklist (prog, block_list);
1403
1404   for (i = 0; i < nbs; i++)
1405     scaldims[i] = 0 ;
1406
1407   cloog_program_set_scaldims (prog, scaldims);
1408
1409   /* Extract scalar dimensions to simplify the code generation problem.  */
1410   cloog_program_extract_scalars (prog, scattering);
1411
1412   /* Apply scattering.  */
1413   cloog_program_scatter (prog, scattering);
1414   free_scattering (scattering);
1415
1416   /* Iterators corresponding to scalar dimensions have to be extracted.  */
1417   cloog_names_scalarize (cloog_program_names (prog), nbs,
1418                          cloog_program_scaldims (prog));
1419
1420   /* Free blocklist.  */
1421   {
1422     CloogBlockList *next = cloog_program_blocklist (prog);
1423
1424     while (next)
1425       {
1426         CloogBlockList *toDelete = next;
1427         next = cloog_block_list_next (next);
1428         cloog_block_list_set_next (toDelete, NULL);
1429         cloog_block_list_set_block (toDelete, NULL);
1430         cloog_block_list_free (toDelete);
1431       }
1432     cloog_program_set_blocklist (prog, NULL);
1433   }
1434 }
1435
1436 /* Return the options that will be used in GLOOG.  */
1437
1438 static CloogOptions *
1439 set_cloog_options (void)
1440 {
1441   CloogOptions *options = cloog_options_malloc ();
1442
1443   /* Change cloog output language to C.  If we do use FORTRAN instead, cloog
1444      will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1445      we pass an incomplete program to cloog.  */
1446   options->language = LANGUAGE_C;
1447
1448   /* Enable complex equality spreading: removes dummy statements
1449      (assignments) in the generated code which repeats the
1450      substitution equations for statements.  This is useless for
1451      GLooG.  */
1452   options->esp = 1;
1453
1454   /* Enable C pretty-printing mode: normalizes the substitution
1455      equations for statements.  */
1456   options->cpp = 1;
1457
1458   /* Allow cloog to build strides with a stride width different to one.
1459      This example has stride = 4:
1460
1461      for (i = 0; i < 20; i += 4)
1462        A  */
1463   options->strides = 1;
1464
1465   /* Disable optimizations and make cloog generate source code closer to the
1466      input.  This is useful for debugging,  but later we want the optimized
1467      code.
1468
1469      XXX: We can not disable optimizations, as loop blocking is not working
1470      without them.  */
1471   if (0)
1472     {
1473       options->f = -1;
1474       options->l = INT_MAX;
1475     }
1476
1477   return options;
1478 }
1479
1480 /* Prints STMT to STDERR.  */
1481
1482 void
1483 print_clast_stmt (FILE *file, struct clast_stmt *stmt)
1484 {
1485   CloogOptions *options = set_cloog_options ();
1486
1487   pprint (file, stmt, 0, options);
1488   cloog_options_free (options);
1489 }
1490
1491 /* Prints STMT to STDERR.  */
1492
1493 void
1494 debug_clast_stmt (struct clast_stmt *stmt)
1495 {
1496   print_clast_stmt (stderr, stmt);
1497 }
1498
1499 /* Translate SCOP to a CLooG program and clast.  These two
1500    representations should be freed together: a clast cannot be used
1501    without a program.  */
1502
1503 cloog_prog_clast
1504 scop_to_clast (scop_p scop)
1505 {
1506   CloogOptions *options = set_cloog_options ();
1507   cloog_prog_clast pc;
1508
1509   /* Connect new cloog prog generation to graphite.  */
1510   pc.prog = cloog_program_malloc ();
1511   build_cloog_prog (scop, pc.prog);
1512   pc.prog = cloog_program_generate (pc.prog, options);
1513   pc.stmt = cloog_clast_create (pc.prog, options);
1514
1515   cloog_options_free (options);
1516   return pc;
1517 }
1518
1519 /* Prints to FILE the code generated by CLooG for SCOP.  */
1520
1521 void
1522 print_generated_program (FILE *file, scop_p scop)
1523 {
1524   CloogOptions *options = set_cloog_options ();
1525   cloog_prog_clast pc = scop_to_clast (scop);
1526
1527   fprintf (file, "       (prog: \n");
1528   cloog_program_print (file, pc.prog);
1529   fprintf (file, "       )\n");
1530
1531   fprintf (file, "       (clast: \n");
1532   pprint (file, pc.stmt, 0, options);
1533   fprintf (file, "       )\n");
1534
1535   cloog_options_free (options);
1536   cloog_clast_free (pc.stmt);
1537   cloog_program_free (pc.prog);
1538 }
1539
1540 /* Prints to STDERR the code generated by CLooG for SCOP.  */
1541
1542 void
1543 debug_generated_program (scop_p scop)
1544 {
1545   print_generated_program (stderr, scop);
1546 }
1547
1548 /* Add CLooG names to parameter index.  The index is used to translate
1549    back from CLooG names to GCC trees.  */
1550
1551 static void
1552 create_params_index (htab_t index_table, CloogProgram *prog) {
1553   CloogNames* names = cloog_program_names (prog);
1554   int nb_parameters = cloog_names_nb_parameters (names);
1555   char **parameters = cloog_names_parameters (names);
1556   int i;
1557
1558   for (i = 0; i < nb_parameters; i++)
1559     save_clast_name_index (index_table, parameters[i], i);
1560 }
1561
1562 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1563    the given SCOP.  Return true if code generation succeeded.
1564    BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1565 */
1566
1567 bool
1568 gloog (scop_p scop, VEC (scop_p, heap) *scops, htab_t bb_pbb_mapping)
1569 {
1570   VEC (tree, heap) *newivs = VEC_alloc (tree, heap, 10);
1571   loop_p context_loop;
1572   sese region = SCOP_REGION (scop);
1573   ifsese if_region = NULL;
1574   htab_t rename_map, newivs_index, params_index;
1575   cloog_prog_clast pc;
1576   int i;
1577
1578   timevar_push (TV_GRAPHITE_CODE_GEN);
1579   gloog_error = false;
1580
1581   pc = scop_to_clast (scop);
1582
1583   if (dump_file && (dump_flags & TDF_DETAILS))
1584     {
1585       fprintf (dump_file, "\nCLAST generated by CLooG: \n");
1586       print_clast_stmt (dump_file, pc.stmt);
1587       fprintf (dump_file, "\n");
1588     }
1589
1590   recompute_all_dominators ();
1591   graphite_verify ();
1592
1593   if_region = move_sese_in_condition (region);
1594   sese_insert_phis_for_liveouts (region,
1595                                  if_region->region->exit->src,
1596                                  if_region->false_region->exit,
1597                                  if_region->true_region->exit);
1598   recompute_all_dominators ();
1599   graphite_verify ();
1600
1601   context_loop = SESE_ENTRY (region)->src->loop_father;
1602   rename_map = htab_create (10, rename_map_elt_info, eq_rename_map_elts, free);
1603   newivs_index = htab_create (10, clast_name_index_elt_info,
1604                               eq_clast_name_indexes, free);
1605   params_index = htab_create (10, clast_name_index_elt_info,
1606                               eq_clast_name_indexes, free);
1607
1608   create_params_index (params_index, pc.prog);
1609
1610   translate_clast (region, context_loop, pc.stmt,
1611                    if_region->true_region->entry,
1612                    rename_map, &newivs, newivs_index,
1613                    bb_pbb_mapping, 1, params_index);
1614   graphite_verify ();
1615   sese_adjust_liveout_phis (region, rename_map,
1616                             if_region->region->exit->src,
1617                             if_region->false_region->exit,
1618                             if_region->true_region->exit);
1619   scev_reset_htab ();
1620   rename_nb_iterations (rename_map);
1621
1622   for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++)
1623     rename_sese_parameters (rename_map, SCOP_REGION (scop));
1624
1625   recompute_all_dominators ();
1626   graphite_verify ();
1627
1628   if (gloog_error)
1629     set_ifsese_condition (if_region, integer_zero_node);
1630
1631   free (if_region->true_region);
1632   free (if_region->region);
1633   free (if_region);
1634
1635   htab_delete (rename_map);
1636   htab_delete (newivs_index);
1637   htab_delete (params_index);
1638   VEC_free (tree, heap, newivs);
1639   cloog_clast_free (pc.stmt);
1640   cloog_program_free (pc.prog);
1641   timevar_pop (TV_GRAPHITE_CODE_GEN);
1642
1643   if (dump_file && (dump_flags & TDF_DETAILS))
1644     {
1645       loop_p loop;
1646       loop_iterator li;
1647       int num_no_dependency = 0;
1648
1649       FOR_EACH_LOOP (li, loop, 0)
1650         if (loop->can_be_parallel)
1651           num_no_dependency++;
1652
1653       fprintf (dump_file, "\n%d loops carried no dependency.\n",
1654                num_no_dependency);
1655     }
1656
1657   return !gloog_error;
1658 }
1659
1660 #endif