OSDN Git Service

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