OSDN Git Service

Add fixme comment.
[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 gcc_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 gcc_type_for_value (mpz_t val)
438 {
439   return gcc_type_for_interval (val, val);
440 }
441
442 /* Return the type for the clast_term T used in STMT.  */
443
444 static tree
445 gcc_type_for_clast_term (struct clast_term *t,
446                          ivs_params_p ip)
447 {
448   gcc_assert (t->expr.type == clast_expr_term);
449
450   if (!t->var)
451     return gcc_type_for_value (t->val);
452
453   return TREE_TYPE (clast_name_to_gcc (t->var, ip));
454 }
455
456 static tree
457 gcc_type_for_clast_expr (struct clast_expr *, ivs_params_p);
458
459 /* Return the type for the clast_reduction R used in STMT.  */
460
461 static tree
462 gcc_type_for_clast_red (struct clast_reduction *r,
463                         ivs_params_p ip)
464 {
465   int i;
466   tree type = NULL_TREE;
467
468   if (r->n == 1)
469     return gcc_type_for_clast_expr (r->elts[0], ip);
470
471   switch (r->type)
472     {
473     case clast_red_sum:
474     case clast_red_min:
475     case clast_red_max:
476       type = gcc_type_for_clast_expr (r->elts[0], ip);
477       for (i = 1; i < r->n; i++)
478         type = max_precision_type (type, gcc_type_for_clast_expr
479                                    (r->elts[i], ip));
480
481       return type;
482
483     default:
484       break;
485     }
486
487   gcc_unreachable ();
488   return NULL_TREE;
489 }
490
491 /* Return the type for the clast_binary B used in STMT.  */
492
493 static tree
494 gcc_type_for_clast_bin (struct clast_binary *b, ivs_params_p ip)
495 {
496   tree l = gcc_type_for_clast_expr ((struct clast_expr *) b->LHS, ip);
497   tree r = gcc_type_for_value (b->RHS);
498   return max_signed_precision_type (l, r);
499 }
500
501 /* Returns the type for the CLAST expression E when used in statement
502    STMT.  */
503
504 static tree
505 gcc_type_for_clast_expr (struct clast_expr *e,
506                          ivs_params_p ip)
507 {
508   switch (e->type)
509     {
510     case clast_expr_term:
511       return gcc_type_for_clast_term ((struct clast_term *) e, ip);
512
513     case clast_expr_red:
514       return gcc_type_for_clast_red ((struct clast_reduction *) e, ip);
515
516     case clast_expr_bin:
517       return gcc_type_for_clast_bin ((struct clast_binary *) e, ip);
518
519     default:
520       gcc_unreachable ();
521     }
522
523   return NULL_TREE;
524 }
525
526 /* Returns the type for the equation CLEQ.  */
527
528 static tree
529 gcc_type_for_clast_eq (struct clast_equation *cleq,
530                        ivs_params_p ip)
531 {
532   tree l = gcc_type_for_clast_expr (cleq->LHS, ip);
533   tree r = gcc_type_for_clast_expr (cleq->RHS, ip);
534   return max_precision_type (l, r);
535 }
536
537 /* Translates a clast equation CLEQ to a tree.  */
538
539 static tree
540 graphite_translate_clast_equation (struct clast_equation *cleq,
541                                    ivs_params_p ip)
542 {
543   enum tree_code comp;
544   tree type = gcc_type_for_clast_eq (cleq, ip);
545   tree lhs = clast_to_gcc_expression (type, cleq->LHS, ip);
546   tree rhs = clast_to_gcc_expression (type, cleq->RHS, ip);
547
548   if (cleq->sign == 0)
549     comp = EQ_EXPR;
550
551   else if (cleq->sign > 0)
552     comp = GE_EXPR;
553
554   else
555     comp = LE_EXPR;
556
557   return fold_build2 (comp, boolean_type_node, lhs, rhs);
558 }
559
560 /* Creates the test for the condition in STMT.  */
561
562 static tree
563 graphite_create_guard_cond_expr (struct clast_guard *stmt,
564                                  ivs_params_p ip)
565 {
566   tree cond = NULL;
567   int i;
568
569   for (i = 0; i < stmt->n; i++)
570     {
571       tree eq = graphite_translate_clast_equation (&stmt->eq[i], ip);
572
573       if (cond)
574         cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
575       else
576         cond = eq;
577     }
578
579   return cond;
580 }
581
582 /* Creates a new if region corresponding to Cloog's guard.  */
583
584 static edge
585 graphite_create_new_guard (edge entry_edge, struct clast_guard *stmt,
586                            ivs_params_p ip)
587 {
588   tree cond_expr = graphite_create_guard_cond_expr (stmt, ip);
589   edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
590   return exit_edge;
591 }
592
593 /* Compute the lower bound LOW and upper bound UP for the induction
594    variable at LEVEL for the statement PBB, based on the transformed
595    scattering of PBB: T|I|G|Cst, with T the scattering transform, I
596    the iteration domain, and G the context parameters.  */
597
598 static void
599 compute_bounds_for_level (poly_bb_p pbb, int level, mpz_t low, mpz_t up)
600 {
601   ppl_Pointset_Powerset_C_Polyhedron_t ps;
602   ppl_Linear_Expression_t le;
603
604   combine_context_id_scat (&ps, pbb, false);
605
606   /* Prepare the linear expression corresponding to the level that we
607      want to maximize/minimize.  */
608   {
609     ppl_dimension_type dim = pbb_nb_scattering_transform (pbb)
610       + pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb);
611
612     ppl_new_Linear_Expression_with_dimension (&le, dim);
613     ppl_set_coef (le, psct_dynamic_dim (pbb, level), 1);
614   }
615
616   ppl_max_for_le_pointset (ps, le, up);
617   ppl_min_for_le_pointset (ps, le, low);
618   ppl_delete_Linear_Expression (le);
619   ppl_delete_Pointset_Powerset_C_Polyhedron (ps);
620 }
621
622 /* Compute the type for the induction variable at LEVEL for the
623    statement PBB, based on the transformed schedule of PBB.  */
624
625 static tree
626 compute_type_for_level (poly_bb_p pbb, int level)
627 {
628   mpz_t low, up;
629   tree type;
630
631   mpz_init (low);
632   mpz_init (up);
633
634   compute_bounds_for_level (pbb, level, low, up);
635   type = gcc_type_for_interval (low, up);
636
637   mpz_clear (low);
638   mpz_clear (up);
639   return type;
640 }
641
642 /* Walks a CLAST and returns the first statement in the body of a
643    loop.
644
645    FIXME: This function should not be used to get a PBB in the STMT
646    loop in order to find out the iteration domain of the loop: the
647    counter example from Tobias is:
648
649    | for (i = 0; i < 100; i++)
650    |   {
651    |     if (i == 0)
652    |       S1;
653    |     S2;
654    |   }
655
656    This function would return S1 whose iteration domain contains only
657    one point "i = 0", whereas the iteration domain of S2 has 100 points.
658
659    This should be implemented using some functionality existing in
660    CLooG-ISL.  */
661
662 static struct clast_user_stmt *
663 clast_get_body_of_loop (struct clast_stmt *stmt)
664 {
665   if (!stmt
666       || CLAST_STMT_IS_A (stmt, stmt_user))
667     return (struct clast_user_stmt *) stmt;
668
669   if (CLAST_STMT_IS_A (stmt, stmt_for))
670     return clast_get_body_of_loop (((struct clast_for *) stmt)->body);
671
672   if (CLAST_STMT_IS_A (stmt, stmt_guard))
673     return clast_get_body_of_loop (((struct clast_guard *) stmt)->then);
674
675   if (CLAST_STMT_IS_A (stmt, stmt_block))
676     return clast_get_body_of_loop (((struct clast_block *) stmt)->body);
677
678   gcc_unreachable ();
679 }
680
681 /* Returns the type for the induction variable for the loop translated
682    from STMT_FOR.  */
683
684 static tree
685 gcc_type_for_iv_of_clast_loop (struct clast_for *stmt_for, int level,
686                                tree lb_type, tree ub_type)
687 {
688   struct clast_stmt *stmt = (struct clast_stmt *) stmt_for;
689   struct clast_user_stmt *body = clast_get_body_of_loop (stmt);
690   CloogStatement *cs = body->statement;
691   poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
692
693   return max_signed_precision_type (lb_type, max_precision_type
694                                     (ub_type, compute_type_for_level
695                                      (pbb, level)));
696 }
697
698 /* Creates a new LOOP corresponding to Cloog's STMT.  Inserts an
699    induction variable for the new LOOP.  New LOOP is attached to CFG
700    starting at ENTRY_EDGE.  LOOP is inserted into the loop tree and
701    becomes the child loop of the OUTER_LOOP.  NEWIVS_INDEX binds
702    CLooG's scattering name to the induction variable created for the
703    loop of STMT.  The new induction variable is inserted in the NEWIVS
704    vector and is of type TYPE.  */
705
706 static struct loop *
707 graphite_create_new_loop (edge entry_edge, struct clast_for *stmt,
708                           loop_p outer, tree type, tree lb, tree ub,
709                           int level, ivs_params_p ip)
710 {
711   tree stride = gmp_cst_to_tree (type, stmt->stride);
712   tree ivvar = create_tmp_var (type, "graphite_IV");
713   tree iv, iv_after_increment;
714   loop_p loop = create_empty_loop_on_edge
715     (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
716      outer ? outer : entry_edge->src->loop_father);
717
718   add_referenced_var (ivvar);
719
720   save_clast_name_index (ip->newivs_index, stmt->iterator,
721                          VEC_length (tree, *(ip->newivs)), level);
722   VEC_safe_push (tree, heap, *(ip->newivs), iv);
723   return loop;
724 }
725
726 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
727    induction variables of the loops around GBB in SESE.  */
728
729 static void
730 build_iv_mapping (VEC (tree, heap) *iv_map, struct clast_user_stmt *user_stmt,
731                   ivs_params_p ip)
732 {
733   struct clast_stmt *t;
734   int depth = 0;
735   CloogStatement *cs = user_stmt->statement;
736   poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
737   gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
738
739   for (t = user_stmt->substitutions; t; t = t->next, depth++)
740     {
741       struct clast_expr *expr = (struct clast_expr *)
742        ((struct clast_assignment *)t)->RHS;
743       tree type = gcc_type_for_clast_expr (expr, ip);
744       tree new_name = clast_to_gcc_expression (type, expr, ip);
745       loop_p old_loop = gbb_loop_at_index (gbb, ip->region, depth);
746
747       VEC_replace (tree, iv_map, old_loop->num, new_name);
748     }
749 }
750
751 /* Construct bb_pbb_def with BB and PBB.  */
752
753 static bb_pbb_def *
754 new_bb_pbb_def (basic_block bb, poly_bb_p pbb)
755 {
756   bb_pbb_def *bb_pbb_p;
757
758   bb_pbb_p = XNEW (bb_pbb_def);
759   bb_pbb_p->bb = bb;
760   bb_pbb_p->pbb = pbb;
761
762   return bb_pbb_p;
763 }
764
765 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING.  */
766
767 static void
768 mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping)
769 {
770   bb_pbb_def tmp;
771   PTR *x;
772
773   tmp.bb = bb;
774   x = htab_find_slot (bb_pbb_mapping, &tmp, INSERT);
775
776   if (x && !*x)
777     *x = new_bb_pbb_def (bb, pbb);
778 }
779
780 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING.  */
781
782 static poly_bb_p
783 find_pbb_via_hash (htab_t bb_pbb_mapping, basic_block bb)
784 {
785   bb_pbb_def tmp;
786   PTR *slot;
787
788   tmp.bb = bb;
789   slot = htab_find_slot (bb_pbb_mapping, &tmp, NO_INSERT);
790
791   if (slot && *slot)
792     return ((bb_pbb_def *) *slot)->pbb;
793
794   return NULL;
795 }
796
797 /* Check data dependency in LOOP at level LEVEL.
798    BB_PBB_MAPPING is a basic_block and it's related poly_bb_p
799    mapping.  */
800
801 static bool
802 dependency_in_loop_p (loop_p loop, htab_t bb_pbb_mapping, int level)
803 {
804   unsigned i,j;
805   basic_block *bbs = get_loop_body_in_dom_order (loop);
806
807   for (i = 0; i < loop->num_nodes; i++)
808     {
809       poly_bb_p pbb1 = find_pbb_via_hash (bb_pbb_mapping, bbs[i]);
810
811       if (pbb1 == NULL)
812        continue;
813
814       for (j = 0; j < loop->num_nodes; j++)
815        {
816          poly_bb_p pbb2 = find_pbb_via_hash (bb_pbb_mapping, bbs[j]);
817
818          if (pbb2 == NULL)
819            continue;
820
821          if (dependency_between_pbbs_p (pbb1, pbb2, level))
822            {
823              free (bbs);
824              return true;
825            }
826        }
827     }
828
829   free (bbs);
830
831   return false;
832 }
833
834 /* Translates a clast user statement STMT to gimple.
835
836    - NEXT_E is the edge where new generated code should be attached.
837    - CONTEXT_LOOP is the loop in which the generated code will be placed
838    - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.  */
839
840 static edge
841 translate_clast_user (struct clast_user_stmt *stmt, edge next_e,
842                       htab_t bb_pbb_mapping, ivs_params_p ip)
843 {
844   int i, nb_loops;
845   basic_block new_bb;
846   poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (stmt->statement);
847   gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
848   VEC (tree, heap) *iv_map;
849
850   if (GBB_BB (gbb) == ENTRY_BLOCK_PTR)
851     return next_e;
852
853   nb_loops = number_of_loops ();
854   iv_map = VEC_alloc (tree, heap, nb_loops);
855   for (i = 0; i < nb_loops; i++)
856     VEC_quick_push (tree, iv_map, NULL_TREE);
857
858   build_iv_mapping (iv_map, stmt, ip);
859   next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), ip->region,
860                                            next_e, iv_map);
861   VEC_free (tree, heap, iv_map);
862
863   new_bb = next_e->src;
864   mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
865   update_ssa (TODO_update_ssa);
866
867   return next_e;
868 }
869
870 /* Creates a new if region protecting the loop to be executed, if the execution
871    count is zero (lb > ub).  */
872
873 static edge
874 graphite_create_new_loop_guard (edge entry_edge, struct clast_for *stmt,
875                                 int level, tree *type, tree *lb, tree *ub,
876                                 ivs_params_p ip)
877 {
878   tree cond_expr;
879   edge exit_edge;
880   tree lb_type = gcc_type_for_clast_expr (stmt->LB, ip);
881   tree ub_type = gcc_type_for_clast_expr (stmt->UB, ip);
882
883   *type = gcc_type_for_iv_of_clast_loop (stmt, level, lb_type, ub_type);
884   *lb = clast_to_gcc_expression (*type, stmt->LB, ip);
885   *ub = clast_to_gcc_expression (*type, stmt->UB, ip);
886
887   /* When ub is simply a constant or a parameter, use lb <= ub.  */
888   if (TREE_CODE (*ub) == INTEGER_CST || TREE_CODE (*ub) == SSA_NAME)
889     cond_expr = fold_build2 (LE_EXPR, boolean_type_node, *lb, *ub);
890   else
891     {
892       tree one = (POINTER_TYPE_P (*type)
893                   ? size_one_node
894                   : fold_convert (*type, integer_one_node));
895       /* Adding +1 and using LT_EXPR helps with loop latches that have a
896          loop iteration count of "PARAMETER - 1".  For PARAMETER == 0 this becomes
897          2^k-1 due to integer overflow, and the condition lb <= ub is true,
898          even if we do not want this.  However lb < ub + 1 is false, as
899          expected.  */
900       tree ub_one = fold_build2 (POINTER_TYPE_P (*type) ? POINTER_PLUS_EXPR
901                                  : PLUS_EXPR, *type, *ub, one);
902
903       cond_expr = fold_build2 (LT_EXPR, boolean_type_node, *lb, ub_one);
904     }
905
906   exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
907
908   return exit_edge;
909 }
910
911 static edge
912 translate_clast (loop_p, struct clast_stmt *, edge, htab_t, int, ivs_params_p);
913
914 /* Create the loop for a clast for statement.
915
916    - NEXT_E is the edge where new generated code should be attached.
917    - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.  */
918
919 static edge
920 translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt,
921                           edge next_e, htab_t bb_pbb_mapping, int level,
922                           tree type, tree lb, tree ub, ivs_params_p ip)
923 {
924   struct loop *loop = graphite_create_new_loop (next_e, stmt, context_loop,
925                                                 type, lb, ub, level, ip);
926   edge last_e = single_exit (loop);
927   edge to_body = single_succ_edge (loop->header);
928   basic_block after = to_body->dest;
929
930   /* Create a basic block for loop close phi nodes.  */
931   last_e = single_succ_edge (split_edge (last_e));
932
933   /* Translate the body of the loop.  */
934   next_e = translate_clast (loop, stmt->body, to_body, bb_pbb_mapping,
935                             level + 1, ip);
936   redirect_edge_succ_nodup (next_e, after);
937   set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
938
939   if (flag_loop_parallelize_all
940       && !dependency_in_loop_p (loop, bb_pbb_mapping, level))
941     loop->can_be_parallel = true;
942
943   return last_e;
944 }
945
946 /* Translates a clast for statement STMT to gimple.  First a guard is created
947    protecting the loop, if it is executed zero times.  In this guard we create
948    the real loop structure.
949
950    - NEXT_E is the edge where new generated code should be attached.
951    - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.  */
952
953 static edge
954 translate_clast_for (loop_p context_loop, struct clast_for *stmt, edge next_e,
955                      htab_t bb_pbb_mapping, int level, ivs_params_p ip)
956 {
957   tree type, lb, ub;
958   edge last_e = graphite_create_new_loop_guard (next_e, stmt, level, &type,
959                                                 &lb, &ub, ip);
960   edge true_e = get_true_edge_from_guard_bb (next_e->dest);
961
962   translate_clast_for_loop (context_loop, stmt, true_e, bb_pbb_mapping, level,
963                             type, lb, ub, ip);
964   return last_e;
965 }
966
967 /* Translates a clast guard statement STMT to gimple.
968
969    - NEXT_E is the edge where new generated code should be attached.
970    - CONTEXT_LOOP is the loop in which the generated code will be placed
971    - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.  */
972
973 static edge
974 translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
975                        edge next_e, htab_t bb_pbb_mapping, int level,
976                        ivs_params_p ip)
977 {
978   edge last_e = graphite_create_new_guard (next_e, stmt, ip);
979   edge true_e = get_true_edge_from_guard_bb (next_e->dest);
980
981   translate_clast (context_loop, stmt->then, true_e, bb_pbb_mapping, level, ip);
982   return last_e;
983 }
984
985 /* Translates a CLAST statement STMT to GCC representation in the
986    context of a SESE.
987
988    - NEXT_E is the edge where new generated code should be attached.
989    - CONTEXT_LOOP is the loop in which the generated code will be placed
990    - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.  */
991
992 static edge
993 translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
994                  htab_t bb_pbb_mapping, int level, ivs_params_p ip)
995 {
996   if (!stmt)
997     return next_e;
998
999   if (CLAST_STMT_IS_A (stmt, stmt_root))
1000     ; /* Do nothing.  */
1001
1002   else if (CLAST_STMT_IS_A (stmt, stmt_user))
1003     next_e = translate_clast_user ((struct clast_user_stmt *) stmt,
1004                                    next_e, bb_pbb_mapping, ip);
1005
1006   else if (CLAST_STMT_IS_A (stmt, stmt_for))
1007     next_e = translate_clast_for (context_loop, (struct clast_for *) stmt,
1008                                   next_e, bb_pbb_mapping, level, ip);
1009
1010   else if (CLAST_STMT_IS_A (stmt, stmt_guard))
1011     next_e = translate_clast_guard (context_loop, (struct clast_guard *) stmt,
1012                                     next_e, bb_pbb_mapping, level, ip);
1013
1014   else if (CLAST_STMT_IS_A (stmt, stmt_block))
1015     next_e = translate_clast (context_loop, ((struct clast_block *) stmt)->body,
1016                               next_e, bb_pbb_mapping, level, ip);
1017   else
1018     gcc_unreachable();
1019
1020   recompute_all_dominators ();
1021   graphite_verify ();
1022
1023   return translate_clast (context_loop, stmt->next, next_e, bb_pbb_mapping,
1024                           level, ip);
1025 }
1026
1027 /* Free the SCATTERING domain list.  */
1028
1029 static void
1030 free_scattering (CloogScatteringList *scattering)
1031 {
1032   while (scattering)
1033     {
1034       CloogScattering *dom = cloog_scattering (scattering);
1035       CloogScatteringList *next = cloog_next_scattering (scattering);
1036
1037       cloog_scattering_free (dom);
1038       free (scattering);
1039       scattering = next;
1040     }
1041 }
1042
1043 /* Initialize Cloog's parameter names from the names used in GIMPLE.
1044    Initialize Cloog's iterator names, using 'graphite_iterator_%d'
1045    from 0 to scop_nb_loops (scop).  */
1046
1047 static void
1048 initialize_cloog_names (scop_p scop, CloogProgram *prog)
1049 {
1050   sese region = SCOP_REGION (scop);
1051   int i;
1052   int nb_iterators = scop_max_loop_depth (scop);
1053   int nb_scattering = cloog_program_nb_scattdims (prog);
1054   int nb_parameters = VEC_length (tree, SESE_PARAMS (region));
1055   char **iterators = XNEWVEC (char *, nb_iterators * 2);
1056   char **scattering = XNEWVEC (char *, nb_scattering);
1057   char **parameters= XNEWVEC (char *, nb_parameters);
1058
1059   cloog_program_set_names (prog, cloog_names_malloc ());
1060
1061   for (i = 0; i < nb_parameters; i++)
1062     {
1063       tree param = VEC_index (tree, SESE_PARAMS (region), i);
1064       const char *name = get_name (param);
1065       int len;
1066
1067       if (!name)
1068         name = "T";
1069
1070       len = strlen (name);
1071       len += 17;
1072       parameters[i] = XNEWVEC (char, len + 1);
1073       snprintf (parameters[i], len, "%s_%d", name, SSA_NAME_VERSION (param));
1074     }
1075
1076   cloog_names_set_nb_parameters (cloog_program_names (prog), nb_parameters);
1077   cloog_names_set_parameters (cloog_program_names (prog), parameters);
1078
1079   for (i = 0; i < nb_iterators; i++)
1080     {
1081       int len = 4 + 16;
1082       iterators[i] = XNEWVEC (char, len);
1083       snprintf (iterators[i], len, "git_%d", i);
1084     }
1085
1086   cloog_names_set_nb_iterators (cloog_program_names (prog),
1087                                 nb_iterators);
1088   cloog_names_set_iterators (cloog_program_names (prog),
1089                              iterators);
1090
1091   for (i = 0; i < nb_scattering; i++)
1092     {
1093       int len = 5 + 16;
1094       scattering[i] = XNEWVEC (char, len);
1095       snprintf (scattering[i], len, "scat_%d", i);
1096     }
1097
1098   cloog_names_set_nb_scattering (cloog_program_names (prog),
1099                                  nb_scattering);
1100   cloog_names_set_scattering (cloog_program_names (prog),
1101                               scattering);
1102 }
1103
1104 /* Initialize a CLooG input file.  */
1105
1106 static FILE *
1107 init_cloog_input_file (int scop_number)
1108 {
1109   FILE *graphite_out_file;
1110   int len = strlen (dump_base_name);
1111   char *dumpname = XNEWVEC (char, len + 25);
1112   char *s_scop_number = XNEWVEC (char, 15);
1113
1114   memcpy (dumpname, dump_base_name, len + 1);
1115   strip_off_ending (dumpname, len);
1116   sprintf (s_scop_number, ".%d", scop_number);
1117   strcat (dumpname, s_scop_number);
1118   strcat (dumpname, ".cloog");
1119   graphite_out_file = fopen (dumpname, "w+b");
1120
1121   if (graphite_out_file == 0)
1122     fatal_error ("can%'t open %s for writing: %m", dumpname);
1123
1124   free (dumpname);
1125
1126   return graphite_out_file;
1127 }
1128
1129 /* Build cloog program for SCoP.  */
1130
1131 static void
1132 build_cloog_prog (scop_p scop, CloogProgram *prog,
1133                   CloogOptions *options)
1134 {
1135   int i;
1136   int max_nb_loops = scop_max_loop_depth (scop);
1137   poly_bb_p pbb;
1138   CloogLoop *loop_list = NULL;
1139   CloogBlockList *block_list = NULL;
1140   CloogScatteringList *scattering = NULL;
1141   int nbs = 2 * max_nb_loops + 1;
1142   int *scaldims;
1143
1144   cloog_program_set_context
1145     (prog, new_Cloog_Domain_from_ppl_Pointset_Powerset (SCOP_CONTEXT (scop),
1146       scop_nb_params (scop), cloog_state));
1147   nbs = unify_scattering_dimensions (scop);
1148   scaldims = (int *) xmalloc (nbs * (sizeof (int)));
1149   cloog_program_set_nb_scattdims (prog, nbs);
1150   initialize_cloog_names (scop, prog);
1151
1152   FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
1153     {
1154       CloogStatement *stmt;
1155       CloogBlock *block;
1156       CloogDomain *dom;
1157
1158       /* Dead code elimination: when the domain of a PBB is empty,
1159          don't generate code for the PBB.  */
1160       if (ppl_Pointset_Powerset_C_Polyhedron_is_empty (PBB_DOMAIN (pbb)))
1161         continue;
1162
1163       /* Build the new statement and its block.  */
1164       stmt = cloog_statement_alloc (cloog_state, pbb_index (pbb));
1165       dom = new_Cloog_Domain_from_ppl_Pointset_Powerset (PBB_DOMAIN (pbb),
1166                                                          scop_nb_params (scop),
1167                                                          cloog_state);
1168       block = cloog_block_alloc (stmt, 0, NULL, pbb_dim_iter_domain (pbb));
1169       cloog_statement_set_usr (stmt, pbb);
1170
1171       /* Build loop list.  */
1172       {
1173         CloogLoop *new_loop_list = cloog_loop_malloc (cloog_state);
1174         cloog_loop_set_next (new_loop_list, loop_list);
1175         cloog_loop_set_domain (new_loop_list, dom);
1176         cloog_loop_set_block (new_loop_list, block);
1177         loop_list = new_loop_list;
1178       }
1179
1180       /* Build block list.  */
1181       {
1182         CloogBlockList *new_block_list = cloog_block_list_malloc ();
1183
1184         cloog_block_list_set_next (new_block_list, block_list);
1185         cloog_block_list_set_block (new_block_list, block);
1186         block_list = new_block_list;
1187       }
1188
1189       /* Build scattering list.  */
1190       {
1191         /* XXX: Replace with cloog_domain_list_alloc(), when available.  */
1192         CloogScatteringList *new_scattering
1193           = (CloogScatteringList *) xmalloc (sizeof (CloogScatteringList));
1194         ppl_Polyhedron_t scat;
1195         CloogScattering *dom;
1196
1197         scat = PBB_TRANSFORMED_SCATTERING (pbb);
1198         dom = new_Cloog_Scattering_from_ppl_Polyhedron
1199           (scat, scop_nb_params (scop), pbb_nb_scattering_transform (pbb),
1200            cloog_state);
1201
1202         cloog_set_next_scattering (new_scattering, scattering);
1203         cloog_set_scattering (new_scattering, dom);
1204         scattering = new_scattering;
1205       }
1206     }
1207
1208   cloog_program_set_loop (prog, loop_list);
1209   cloog_program_set_blocklist (prog, block_list);
1210
1211   for (i = 0; i < nbs; i++)
1212     scaldims[i] = 0 ;
1213
1214   cloog_program_set_scaldims (prog, scaldims);
1215
1216   /* Extract scalar dimensions to simplify the code generation problem.  */
1217   cloog_program_extract_scalars (prog, scattering, options);
1218
1219   /* Dump a .cloog input file, if requested.  This feature is only
1220      enabled in the Graphite branch.  */
1221   if (0)
1222     {
1223       static size_t file_scop_number = 0;
1224       FILE *cloog_file = init_cloog_input_file (file_scop_number);
1225
1226       cloog_program_dump_cloog (cloog_file, prog, scattering);
1227       ++file_scop_number;
1228     }
1229
1230   /* Apply scattering.  */
1231   cloog_program_scatter (prog, scattering, options);
1232   free_scattering (scattering);
1233
1234   /* Iterators corresponding to scalar dimensions have to be extracted.  */
1235   cloog_names_scalarize (cloog_program_names (prog), nbs,
1236                          cloog_program_scaldims (prog));
1237
1238   /* Free blocklist.  */
1239   {
1240     CloogBlockList *next = cloog_program_blocklist (prog);
1241
1242     while (next)
1243       {
1244         CloogBlockList *toDelete = next;
1245         next = cloog_block_list_next (next);
1246         cloog_block_list_set_next (toDelete, NULL);
1247         cloog_block_list_set_block (toDelete, NULL);
1248         cloog_block_list_free (toDelete);
1249       }
1250     cloog_program_set_blocklist (prog, NULL);
1251   }
1252 }
1253
1254 /* Return the options that will be used in GLOOG.  */
1255
1256 static CloogOptions *
1257 set_cloog_options (void)
1258 {
1259   CloogOptions *options = cloog_options_malloc (cloog_state);
1260
1261   /* Change cloog output language to C.  If we do use FORTRAN instead, cloog
1262      will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1263      we pass an incomplete program to cloog.  */
1264   options->language = LANGUAGE_C;
1265
1266   /* Enable complex equality spreading: removes dummy statements
1267      (assignments) in the generated code which repeats the
1268      substitution equations for statements.  This is useless for
1269      GLooG.  */
1270   options->esp = 1;
1271
1272 #ifdef CLOOG_ORG
1273   /* Silence CLooG to avoid failing tests due to debug output to stderr.  */
1274   options->quiet = 1;
1275 #else
1276   /* Enable C pretty-printing mode: normalizes the substitution
1277      equations for statements.  */
1278   options->cpp = 1;
1279 #endif
1280
1281   /* Allow cloog to build strides with a stride width different to one.
1282      This example has stride = 4:
1283
1284      for (i = 0; i < 20; i += 4)
1285        A  */
1286   options->strides = 1;
1287
1288   /* Disable optimizations and make cloog generate source code closer to the
1289      input.  This is useful for debugging,  but later we want the optimized
1290      code.
1291
1292      XXX: We can not disable optimizations, as loop blocking is not working
1293      without them.  */
1294   if (0)
1295     {
1296       options->f = -1;
1297       options->l = INT_MAX;
1298     }
1299
1300   return options;
1301 }
1302
1303 /* Prints STMT to STDERR.  */
1304
1305 void
1306 print_clast_stmt (FILE *file, struct clast_stmt *stmt)
1307 {
1308   CloogOptions *options = set_cloog_options ();
1309
1310   clast_pprint (file, stmt, 0, options);
1311   cloog_options_free (options);
1312 }
1313
1314 /* Prints STMT to STDERR.  */
1315
1316 DEBUG_FUNCTION void
1317 debug_clast_stmt (struct clast_stmt *stmt)
1318 {
1319   print_clast_stmt (stderr, stmt);
1320 }
1321
1322 /* Translate SCOP to a CLooG program and clast.  These two
1323    representations should be freed together: a clast cannot be used
1324    without a program.  */
1325
1326 cloog_prog_clast
1327 scop_to_clast (scop_p scop)
1328 {
1329   CloogOptions *options = set_cloog_options ();
1330   cloog_prog_clast pc;
1331
1332   /* Connect new cloog prog generation to graphite.  */
1333   pc.prog = cloog_program_malloc ();
1334   build_cloog_prog (scop, pc.prog, options);
1335   pc.prog = cloog_program_generate (pc.prog, options);
1336   pc.stmt = cloog_clast_create (pc.prog, options);
1337
1338   cloog_options_free (options);
1339   return pc;
1340 }
1341
1342 /* Prints to FILE the code generated by CLooG for SCOP.  */
1343
1344 void
1345 print_generated_program (FILE *file, scop_p scop)
1346 {
1347   CloogOptions *options = set_cloog_options ();
1348
1349   cloog_prog_clast pc = scop_to_clast (scop);
1350
1351   fprintf (file, "       (prog: \n");
1352   cloog_program_print (file, pc.prog);
1353   fprintf (file, "       )\n");
1354
1355   fprintf (file, "       (clast: \n");
1356   clast_pprint (file, pc.stmt, 0, options);
1357   fprintf (file, "       )\n");
1358
1359   cloog_options_free (options);
1360   cloog_clast_free (pc.stmt);
1361   cloog_program_free (pc.prog);
1362 }
1363
1364 /* Prints to STDERR the code generated by CLooG for SCOP.  */
1365
1366 DEBUG_FUNCTION void
1367 debug_generated_program (scop_p scop)
1368 {
1369   print_generated_program (stderr, scop);
1370 }
1371
1372 /* Add CLooG names to parameter index.  The index is used to translate
1373    back from CLooG names to GCC trees.  */
1374
1375 static void
1376 create_params_index (htab_t index_table, CloogProgram *prog) {
1377   CloogNames* names = cloog_program_names (prog);
1378   int nb_parameters = cloog_names_nb_parameters (names);
1379   char **parameters = cloog_names_parameters (names);
1380   int i;
1381
1382   for (i = 0; i < nb_parameters; i++)
1383     save_clast_name_index (index_table, parameters[i], i, i);
1384 }
1385
1386 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1387    the given SCOP.  Return true if code generation succeeded.
1388    BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1389 */
1390
1391 bool
1392 gloog (scop_p scop, htab_t bb_pbb_mapping)
1393 {
1394   VEC (tree, heap) *newivs = VEC_alloc (tree, heap, 10);
1395   loop_p context_loop;
1396   sese region = SCOP_REGION (scop);
1397   ifsese if_region = NULL;
1398   htab_t newivs_index, params_index;
1399   cloog_prog_clast pc;
1400   struct ivs_params ip;
1401
1402   timevar_push (TV_GRAPHITE_CODE_GEN);
1403   gloog_error = false;
1404
1405   pc = scop_to_clast (scop);
1406
1407   if (dump_file && (dump_flags & TDF_DETAILS))
1408     {
1409       fprintf (dump_file, "\nCLAST generated by CLooG: \n");
1410       print_clast_stmt (dump_file, pc.stmt);
1411       fprintf (dump_file, "\n");
1412     }
1413
1414   recompute_all_dominators ();
1415   graphite_verify ();
1416
1417   if_region = move_sese_in_condition (region);
1418   sese_insert_phis_for_liveouts (region,
1419                                  if_region->region->exit->src,
1420                                  if_region->false_region->exit,
1421                                  if_region->true_region->exit);
1422   recompute_all_dominators ();
1423   graphite_verify ();
1424
1425   context_loop = SESE_ENTRY (region)->src->loop_father;
1426   newivs_index = htab_create (10, clast_name_index_elt_info,
1427                               eq_clast_name_indexes, free);
1428   params_index = htab_create (10, clast_name_index_elt_info,
1429                               eq_clast_name_indexes, free);
1430
1431   create_params_index (params_index, pc.prog);
1432
1433   ip.newivs = &newivs;
1434   ip.newivs_index = newivs_index;
1435   ip.params = SESE_PARAMS (region);
1436   ip.params_index = params_index;
1437   ip.region = region;
1438
1439   translate_clast (context_loop, pc.stmt, if_region->true_region->entry,
1440                    bb_pbb_mapping, 0, &ip);
1441   graphite_verify ();
1442   scev_reset ();
1443   recompute_all_dominators ();
1444   graphite_verify ();
1445
1446   if (gloog_error)
1447     set_ifsese_condition (if_region, integer_zero_node);
1448
1449   free (if_region->true_region);
1450   free (if_region->region);
1451   free (if_region);
1452
1453   htab_delete (newivs_index);
1454   htab_delete (params_index);
1455   VEC_free (tree, heap, newivs);
1456   cloog_clast_free (pc.stmt);
1457   cloog_program_free (pc.prog);
1458   timevar_pop (TV_GRAPHITE_CODE_GEN);
1459
1460   if (dump_file && (dump_flags & TDF_DETAILS))
1461     {
1462       loop_p loop;
1463       loop_iterator li;
1464       int num_no_dependency = 0;
1465
1466       FOR_EACH_LOOP (li, loop, 0)
1467         if (loop->can_be_parallel)
1468           num_no_dependency++;
1469
1470       fprintf (dump_file, "\n%d loops carried no dependency.\n",
1471                num_no_dependency);
1472     }
1473
1474   return !gloog_error;
1475 }
1476 #endif