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