2009-11-30 Dave Korn <dave.korn.cygwin@gmail.com>
[official-gcc.git] / gcc / graphite-clast-to-gimple.c
blob93138b6bd899a5b796a9a12aadacef4b9c61d9d2
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>.
5 This file is part of GCC.
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.
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.
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/>. */
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"
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"
55 /* Verifies properties that GRAPHITE should maintain during translation. */
57 static inline void
58 graphite_verify (void)
60 #ifdef ENABLE_CHECKING
61 verify_loop_structure ();
62 verify_dominators (CDI_DOMINATORS);
63 verify_dominators (CDI_POST_DOMINATORS);
64 verify_ssa (false);
65 verify_loop_closed_ssa ();
66 #endif
69 /* Stores the INDEX in a vector for a given clast NAME. */
71 typedef struct clast_name_index {
72 int index;
73 const char *name;
74 } *clast_name_index_p;
76 /* Returns a pointer to a new element of type clast_name_index_p built
77 from NAME and INDEX. */
79 static inline clast_name_index_p
80 new_clast_name_index (const char *name, int index)
82 clast_name_index_p res = XNEW (struct clast_name_index);
84 res->name = name;
85 res->index = index;
86 return res;
89 /* For a given clast NAME, returns -1 if it does not correspond to any
90 parameter, or otherwise, returns the index in the PARAMS or
91 SCATTERING_DIMENSIONS vector. */
93 static inline int
94 clast_name_to_index (const char *name, htab_t index_table)
96 struct clast_name_index tmp;
97 PTR *slot;
99 tmp.name = name;
100 slot = htab_find_slot (index_table, &tmp, NO_INSERT);
102 if (slot && *slot)
103 return ((struct clast_name_index *) *slot)->index;
105 return -1;
108 /* Records in INDEX_TABLE the INDEX for NAME. */
110 static inline void
111 save_clast_name_index (htab_t index_table, const char *name, int index)
113 struct clast_name_index tmp;
114 PTR *slot;
116 tmp.name = name;
117 slot = htab_find_slot (index_table, &tmp, INSERT);
119 if (slot)
120 *slot = new_clast_name_index (name, index);
123 /* Print to stderr the element ELT. */
125 static inline void
126 debug_clast_name_index (clast_name_index_p elt)
128 fprintf (stderr, "(index = %d, name = %s)\n", elt->index, elt->name);
131 /* Helper function for debug_rename_map. */
133 static inline int
134 debug_clast_name_indexes_1 (void **slot, void *s ATTRIBUTE_UNUSED)
136 struct clast_name_index *entry = (struct clast_name_index *) *slot;
137 debug_clast_name_index (entry);
138 return 1;
141 /* Print to stderr all the elements of MAP. */
143 void
144 debug_clast_name_indexes (htab_t map)
146 htab_traverse (map, debug_clast_name_indexes_1, NULL);
149 /* Computes a hash function for database element ELT. */
151 static inline hashval_t
152 clast_name_index_elt_info (const void *elt)
154 return htab_hash_pointer (((const struct clast_name_index *) elt)->name);
157 /* Compares database elements E1 and E2. */
159 static inline int
160 eq_clast_name_indexes (const void *e1, const void *e2)
162 const struct clast_name_index *elt1 = (const struct clast_name_index *) e1;
163 const struct clast_name_index *elt2 = (const struct clast_name_index *) e2;
165 return (elt1->name == elt2->name);
169 /* For a given loop DEPTH in the loop nest of the original black box
170 PBB, return the old induction variable associated to that loop. */
172 static inline tree
173 pbb_to_depth_to_oldiv (poly_bb_p pbb, int depth)
175 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
176 sese region = SCOP_REGION (PBB_SCOP (pbb));
177 loop_p loop = gbb_loop_at_index (gbb, region, depth);
179 return loop->single_iv;
182 /* For a given scattering dimension, return the new induction variable
183 associated to it. */
185 static inline tree
186 newivs_to_depth_to_newiv (VEC (tree, heap) *newivs, int depth)
188 return VEC_index (tree, newivs, depth);
193 /* Returns the tree variable from the name NAME that was given in
194 Cloog representation. */
196 static tree
197 clast_name_to_gcc (const char *name, sese region, VEC (tree, heap) *newivs,
198 htab_t newivs_index, htab_t params_index)
200 int index;
201 VEC (tree, heap) *params = SESE_PARAMS (region);
203 if (params && params_index)
205 index = clast_name_to_index (name, params_index);
207 if (index >= 0)
208 return VEC_index (tree, params, index);
211 gcc_assert (newivs && newivs_index);
212 index = clast_name_to_index (name, newivs_index);
213 gcc_assert (index >= 0);
215 return newivs_to_depth_to_newiv (newivs, index);
218 /* Returns the maximal precision type for expressions E1 and E2. */
220 static inline tree
221 max_precision_type (tree e1, tree e2)
223 tree type1 = TREE_TYPE (e1);
224 tree type2 = TREE_TYPE (e2);
225 return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
228 static tree
229 clast_to_gcc_expression (tree, struct clast_expr *, sese, VEC (tree, heap) *,
230 htab_t, htab_t);
232 /* Converts a Cloog reduction expression R with reduction operation OP
233 to a GCC expression tree of type TYPE. */
235 static tree
236 clast_to_gcc_expression_red (tree type, enum tree_code op,
237 struct clast_reduction *r,
238 sese region, VEC (tree, heap) *newivs,
239 htab_t newivs_index, htab_t params_index)
241 int i;
242 tree res = clast_to_gcc_expression (type, r->elts[0], region, newivs,
243 newivs_index, params_index);
244 tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type;
246 for (i = 1; i < r->n; i++)
248 tree t = clast_to_gcc_expression (operand_type, r->elts[i], region,
249 newivs, newivs_index, params_index);
250 res = fold_build2 (op, type, res, t);
253 return res;
256 /* Converts a Cloog AST expression E back to a GCC expression tree of
257 type TYPE. */
259 static tree
260 clast_to_gcc_expression (tree type, struct clast_expr *e,
261 sese region, VEC (tree, heap) *newivs,
262 htab_t newivs_index, htab_t params_index)
264 switch (e->type)
266 case expr_term:
268 struct clast_term *t = (struct clast_term *) e;
270 if (t->var)
272 if (value_one_p (t->val))
274 tree name = clast_name_to_gcc (t->var, region, newivs,
275 newivs_index, params_index);
276 return fold_convert (type, name);
279 else if (value_mone_p (t->val))
281 tree name = clast_name_to_gcc (t->var, region, newivs,
282 newivs_index, params_index);
283 name = fold_convert (type, name);
284 return fold_build1 (NEGATE_EXPR, type, name);
286 else
288 tree name = clast_name_to_gcc (t->var, region, newivs,
289 newivs_index, params_index);
290 tree cst = gmp_cst_to_tree (type, t->val);
291 name = fold_convert (type, name);
292 return fold_build2 (MULT_EXPR, type, cst, name);
295 else
296 return gmp_cst_to_tree (type, t->val);
299 case expr_red:
301 struct clast_reduction *r = (struct clast_reduction *) e;
303 switch (r->type)
305 case clast_red_sum:
306 return clast_to_gcc_expression_red
307 (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
308 r, region, newivs, newivs_index, params_index);
310 case clast_red_min:
311 return clast_to_gcc_expression_red (type, MIN_EXPR, r, region,
312 newivs, newivs_index,
313 params_index);
315 case clast_red_max:
316 return clast_to_gcc_expression_red (type, MAX_EXPR, r, region,
317 newivs, newivs_index,
318 params_index);
320 default:
321 gcc_unreachable ();
323 break;
326 case expr_bin:
328 struct clast_binary *b = (struct clast_binary *) e;
329 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
330 tree tl = clast_to_gcc_expression (type, lhs, region, newivs,
331 newivs_index, params_index);
332 tree tr = gmp_cst_to_tree (type, b->RHS);
334 switch (b->type)
336 case clast_bin_fdiv:
337 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
339 case clast_bin_cdiv:
340 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
342 case clast_bin_div:
343 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
345 case clast_bin_mod:
346 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
348 default:
349 gcc_unreachable ();
353 default:
354 gcc_unreachable ();
357 return NULL_TREE;
360 /* Returns the type for the expression E. */
362 static tree
363 gcc_type_for_clast_expr (struct clast_expr *e,
364 sese region, VEC (tree, heap) *newivs,
365 htab_t newivs_index, htab_t params_index)
367 switch (e->type)
369 case expr_term:
371 struct clast_term *t = (struct clast_term *) e;
373 if (t->var)
374 return TREE_TYPE (clast_name_to_gcc (t->var, region, newivs,
375 newivs_index, params_index));
376 else
377 return NULL_TREE;
380 case expr_red:
382 struct clast_reduction *r = (struct clast_reduction *) e;
384 if (r->n == 1)
385 return gcc_type_for_clast_expr (r->elts[0], region, newivs,
386 newivs_index, params_index);
387 else
389 int i;
390 for (i = 0; i < r->n; i++)
392 tree type = gcc_type_for_clast_expr (r->elts[i], region,
393 newivs, newivs_index,
394 params_index);
395 if (type)
396 return type;
398 return NULL_TREE;
402 case expr_bin:
404 struct clast_binary *b = (struct clast_binary *) e;
405 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
406 return gcc_type_for_clast_expr (lhs, region, newivs,
407 newivs_index, params_index);
410 default:
411 gcc_unreachable ();
414 return NULL_TREE;
417 /* Returns the type for the equation CLEQ. */
419 static tree
420 gcc_type_for_clast_eq (struct clast_equation *cleq,
421 sese region, VEC (tree, heap) *newivs,
422 htab_t newivs_index, htab_t params_index)
424 tree type = gcc_type_for_clast_expr (cleq->LHS, region, newivs,
425 newivs_index, params_index);
426 if (type)
427 return type;
429 return gcc_type_for_clast_expr (cleq->RHS, region, newivs, newivs_index,
430 params_index);
433 /* Translates a clast equation CLEQ to a tree. */
435 static tree
436 graphite_translate_clast_equation (sese region,
437 struct clast_equation *cleq,
438 VEC (tree, heap) *newivs,
439 htab_t newivs_index, htab_t params_index)
441 enum tree_code comp;
442 tree type = gcc_type_for_clast_eq (cleq, region, newivs, newivs_index,
443 params_index);
444 tree lhs = clast_to_gcc_expression (type, cleq->LHS, region, newivs,
445 newivs_index, params_index);
446 tree rhs = clast_to_gcc_expression (type, cleq->RHS, region, newivs,
447 newivs_index, params_index);
449 if (cleq->sign == 0)
450 comp = EQ_EXPR;
452 else if (cleq->sign > 0)
453 comp = GE_EXPR;
455 else
456 comp = LE_EXPR;
458 return fold_build2 (comp, boolean_type_node, lhs, rhs);
461 /* Creates the test for the condition in STMT. */
463 static tree
464 graphite_create_guard_cond_expr (sese region, struct clast_guard *stmt,
465 VEC (tree, heap) *newivs,
466 htab_t newivs_index, htab_t params_index)
468 tree cond = NULL;
469 int i;
471 for (i = 0; i < stmt->n; i++)
473 tree eq = graphite_translate_clast_equation (region, &stmt->eq[i],
474 newivs, newivs_index,
475 params_index);
477 if (cond)
478 cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
479 else
480 cond = eq;
483 return cond;
486 /* Creates a new if region corresponding to Cloog's guard. */
488 static edge
489 graphite_create_new_guard (sese region, edge entry_edge,
490 struct clast_guard *stmt,
491 VEC (tree, heap) *newivs,
492 htab_t newivs_index, htab_t params_index)
494 tree cond_expr = graphite_create_guard_cond_expr (region, stmt, newivs,
495 newivs_index, params_index);
496 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
497 return exit_edge;
500 /* Walks a CLAST and returns the first statement in the body of a
501 loop. */
503 static struct clast_user_stmt *
504 clast_get_body_of_loop (struct clast_stmt *stmt)
506 if (!stmt
507 || CLAST_STMT_IS_A (stmt, stmt_user))
508 return (struct clast_user_stmt *) stmt;
510 if (CLAST_STMT_IS_A (stmt, stmt_for))
511 return clast_get_body_of_loop (((struct clast_for *) stmt)->body);
513 if (CLAST_STMT_IS_A (stmt, stmt_guard))
514 return clast_get_body_of_loop (((struct clast_guard *) stmt)->then);
516 if (CLAST_STMT_IS_A (stmt, stmt_block))
517 return clast_get_body_of_loop (((struct clast_block *) stmt)->body);
519 gcc_unreachable ();
522 /* Given a CLOOG_IV, returns the type that it should have in GCC land.
523 If the information is not available, i.e. in the case one of the
524 transforms created the loop, just return integer_type_node. */
526 static tree
527 gcc_type_for_cloog_iv (const char *cloog_iv, gimple_bb_p gbb)
529 struct ivtype_map_elt_s tmp;
530 PTR *slot;
532 tmp.cloog_iv = cloog_iv;
533 slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, NO_INSERT);
535 if (slot && *slot)
536 return ((ivtype_map_elt) *slot)->type;
538 return integer_type_node;
541 /* Returns the induction variable for the loop that gets translated to
542 STMT. */
544 static tree
545 gcc_type_for_iv_of_clast_loop (struct clast_for *stmt_for)
547 struct clast_stmt *stmt = (struct clast_stmt *) stmt_for;
548 struct clast_user_stmt *body = clast_get_body_of_loop (stmt);
549 const char *cloog_iv = stmt_for->iterator;
550 CloogStatement *cs = body->statement;
551 poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
553 return gcc_type_for_cloog_iv (cloog_iv, PBB_BLACK_BOX (pbb));
556 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
557 induction variable for the new LOOP. New LOOP is attached to CFG
558 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
559 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
560 CLooG's scattering name to the induction variable created for the
561 loop of STMT. The new induction variable is inserted in the NEWIVS
562 vector. */
564 static struct loop *
565 graphite_create_new_loop (sese region, edge entry_edge,
566 struct clast_for *stmt,
567 loop_p outer, VEC (tree, heap) **newivs,
568 htab_t newivs_index, htab_t params_index)
570 tree type = gcc_type_for_iv_of_clast_loop (stmt);
571 tree lb = clast_to_gcc_expression (type, stmt->LB, region, *newivs,
572 newivs_index, params_index);
573 tree ub = clast_to_gcc_expression (type, stmt->UB, region, *newivs,
574 newivs_index, params_index);
575 tree stride = gmp_cst_to_tree (type, stmt->stride);
576 tree ivvar = create_tmp_var (type, "graphite_IV");
577 tree iv, iv_after_increment;
578 loop_p loop = create_empty_loop_on_edge
579 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
580 outer ? outer : entry_edge->src->loop_father);
582 add_referenced_var (ivvar);
584 save_clast_name_index (newivs_index, stmt->iterator,
585 VEC_length (tree, *newivs));
586 VEC_safe_push (tree, heap, *newivs, iv);
587 return loop;
590 /* Inserts in MAP a tuple (OLD_NAME, NEW_NAME) for the induction
591 variables of the loops around GBB in SESE. */
593 static void
594 build_iv_mapping (htab_t map, sese region,
595 VEC (tree, heap) *newivs, htab_t newivs_index,
596 struct clast_user_stmt *user_stmt,
597 htab_t params_index)
599 struct clast_stmt *t;
600 int index = 0;
601 CloogStatement *cs = user_stmt->statement;
602 poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
604 for (t = user_stmt->substitutions; t; t = t->next, index++)
606 struct clast_expr *expr = (struct clast_expr *)
607 ((struct clast_assignment *)t)->RHS;
608 tree type = gcc_type_for_clast_expr (expr, region, newivs,
609 newivs_index, params_index);
610 tree old_name = pbb_to_depth_to_oldiv (pbb, index);
611 tree e = clast_to_gcc_expression (type, expr, region, newivs,
612 newivs_index, params_index);
613 set_rename (map, old_name, e);
617 /* Helper function for htab_traverse. */
619 static int
620 copy_renames (void **slot, void *s)
622 struct rename_map_elt_s *entry = (struct rename_map_elt_s *) *slot;
623 htab_t res = (htab_t) s;
624 tree old_name = entry->old_name;
625 tree expr = entry->expr;
626 struct rename_map_elt_s tmp;
627 PTR *x;
629 tmp.old_name = old_name;
630 x = htab_find_slot (res, &tmp, INSERT);
632 if (!*x)
633 *x = new_rename_map_elt (old_name, expr);
635 return 1;
638 /* Construct bb_pbb_def with BB and PBB. */
640 static bb_pbb_def *
641 new_bb_pbb_def (basic_block bb, poly_bb_p pbb)
643 bb_pbb_def *bb_pbb_p;
645 bb_pbb_p = XNEW (bb_pbb_def);
646 bb_pbb_p->bb = bb;
647 bb_pbb_p->pbb = pbb;
649 return bb_pbb_p;
652 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
654 static void
655 mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping)
657 bb_pbb_def tmp;
658 PTR *x;
660 tmp.bb = bb;
661 x = htab_find_slot (bb_pbb_mapping, &tmp, INSERT);
663 if (!*x)
664 *x = new_bb_pbb_def (bb, pbb);
667 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
669 static poly_bb_p
670 find_pbb_via_hash (htab_t bb_pbb_mapping, basic_block bb)
672 bb_pbb_def tmp;
673 PTR *slot;
675 tmp.bb = bb;
676 slot = htab_find_slot (bb_pbb_mapping, &tmp, NO_INSERT);
678 if (slot && *slot)
679 return ((bb_pbb_def *) *slot)->pbb;
681 return NULL;
684 /* Check data dependency in LOOP at scattering level LEVEL.
685 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p
686 mapping. */
688 static bool
689 dependency_in_loop_p (loop_p loop, htab_t bb_pbb_mapping, int level)
691 unsigned i,j;
692 basic_block *bbs = get_loop_body_in_dom_order (loop);
694 for (i = 0; i < loop->num_nodes; i++)
696 poly_bb_p pbb1 = find_pbb_via_hash (bb_pbb_mapping, bbs[i]);
698 if (pbb1 == NULL)
699 continue;
701 for (j = 0; j < loop->num_nodes; j++)
703 poly_bb_p pbb2 = find_pbb_via_hash (bb_pbb_mapping, bbs[j]);
705 if (pbb2 == NULL)
706 continue;
708 if (dependency_between_pbbs_p (pbb1, pbb2, level))
710 free (bbs);
711 return true;
716 free (bbs);
718 return false;
721 static edge
722 translate_clast (sese, struct clast_stmt *, edge, htab_t, VEC (tree, heap) **,
723 htab_t, htab_t, htab_t);
725 /* Translates a clast user statement STMT to gimple.
727 - REGION is the sese region we used to generate the scop.
728 - NEXT_E is the edge where new generated code should be attached.
729 - RENAME_MAP contains a set of tuples of new names associated to
730 the original variables names.
731 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
732 - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
733 the sese region. */
734 static edge
735 translate_clast_user (sese region, struct clast_user_stmt *stmt, edge next_e,
736 htab_t rename_map, VEC (tree, heap) **newivs,
737 htab_t newivs_index, htab_t bb_pbb_mapping,
738 htab_t params_index)
740 poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (stmt->statement);
741 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
743 if (GBB_BB (gbb) == ENTRY_BLOCK_PTR)
744 return next_e;
746 build_iv_mapping (rename_map, region, *newivs, newivs_index, stmt,
747 params_index);
748 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), region,
749 next_e, rename_map);
750 mark_bb_with_pbb (pbb, next_e->src, bb_pbb_mapping);
751 update_ssa (TODO_update_ssa);
753 return next_e;
756 /* Mark a loop parallel, if the graphite dependency check cannot find any
757 dependencies. This triggers parallel code generation in the autopar pass.
759 static void
760 try_mark_loop_parallel (sese region, loop_p loop, htab_t bb_pbb_mapping)
762 loop_p outermost_loop = SESE_ENTRY (region)->src->loop_father;
763 int level = loop_depth (loop) - loop_depth (outermost_loop);
765 if (flag_loop_parallelize_all
766 && !dependency_in_loop_p (loop, bb_pbb_mapping,
767 get_scattering_level (level)))
768 loop->can_be_parallel = true;
771 static tree gcc_type_for_iv_of_clast_loop (struct clast_for *);
774 /* Creates a new if region protecting the loop to be executed, if the execution
775 count is zero (lb > ub). */
776 static edge
777 graphite_create_new_loop_guard (sese region, edge entry_edge,
778 struct clast_for *stmt,
779 VEC (tree, heap) *newivs,
780 htab_t newivs_index, htab_t params_index)
782 tree cond_expr;
783 edge exit_edge;
784 tree type = gcc_type_for_iv_of_clast_loop (stmt);
785 tree lb = clast_to_gcc_expression (type, stmt->LB, region, newivs,
786 newivs_index, params_index);
787 tree ub = clast_to_gcc_expression (type, stmt->UB, region, newivs,
788 newivs_index, params_index);
790 /* XXX: Adding +1 and using LT_EXPR helps with loop latches that have a
791 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
792 2^{32|64}, and the condition lb <= ub is true, even if we do not want this.
793 However lb < ub + 1 is false, as expected.
794 There might be a problem with cases where ub is 2^32. */
795 tree one;
796 Value gmp_one;
797 value_init (gmp_one);
798 value_set_si (gmp_one, 1);
799 one = gmp_cst_to_tree (type, gmp_one);
800 value_clear (gmp_one);
802 ub = fold_build2 (PLUS_EXPR, type, ub, one);
803 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, lb, ub);
805 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
807 return exit_edge;
811 /* Create the loop for a clast for statement.
813 - REGION is the sese region we used to generate the scop.
814 - NEXT_E is the edge where new generated code should be attached.
815 - RENAME_MAP contains a set of tuples of new names associated to
816 the original variables names.
817 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
818 - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
819 the sese region. */
820 static edge
821 translate_clast_for_loop (sese region, struct clast_for *stmt, edge next_e,
822 htab_t rename_map, VEC (tree, heap) **newivs,
823 htab_t newivs_index, htab_t bb_pbb_mapping,
824 htab_t params_index)
826 loop_p context_loop = next_e->dest->loop_father;
827 loop_p loop = graphite_create_new_loop (region, next_e, stmt, context_loop,
828 newivs, newivs_index, params_index);
829 edge last_e = single_exit (loop);
830 edge body = single_succ_edge (loop->header);
832 next_e = translate_clast (region, stmt->body, body, rename_map, newivs,
833 newivs_index, bb_pbb_mapping, params_index);
835 /* Create a basic block for loop close phi nodes. */
836 last_e = single_succ_edge (split_edge (last_e));
837 insert_loop_close_phis (rename_map, loop);
839 try_mark_loop_parallel (region, loop, bb_pbb_mapping);
841 return last_e;
844 /* Translates a clast for statement STMT to gimple. First a guard is created
845 protecting the loop, if it is executed zero times. In this guard we create
846 the real loop structure.
848 - REGION is the sese region we used to generate the scop.
849 - NEXT_E is the edge where new generated code should be attached.
850 - RENAME_MAP contains a set of tuples of new names associated to
851 the original variables names.
852 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
853 - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
854 the sese region. */
855 static edge
856 translate_clast_for (sese region, struct clast_for *stmt, edge next_e,
857 htab_t rename_map, VEC (tree, heap) **newivs,
858 htab_t newivs_index, htab_t bb_pbb_mapping,
859 htab_t params_index)
861 edge last_e = graphite_create_new_loop_guard (region, next_e, stmt, *newivs,
862 newivs_index, params_index);
864 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
865 edge false_e = get_false_edge_from_guard_bb (next_e->dest);
866 edge exit_true_e = single_succ_edge (true_e->dest);
867 edge exit_false_e = single_succ_edge (false_e->dest);
869 htab_t before_guard = htab_create (10, rename_map_elt_info,
870 eq_rename_map_elts, free);
871 htab_traverse (rename_map, copy_renames, before_guard);
873 next_e = translate_clast_for_loop (region, stmt, true_e, rename_map, newivs,
874 newivs_index, bb_pbb_mapping,
875 params_index);
877 insert_guard_phis (last_e->src, exit_true_e, exit_false_e,
878 before_guard, rename_map);
880 htab_delete (before_guard);
882 return last_e;
885 /* Translates a clast guard statement STMT to gimple.
887 - REGION is the sese region we used to generate the scop.
888 - NEXT_E is the edge where new generated code should be attached.
889 - RENAME_MAP contains a set of tuples of new names associated to
890 the original variables names.
891 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
892 - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
893 the sese region. */
894 static edge
895 translate_clast_guard (sese region, struct clast_guard *stmt, edge next_e,
896 htab_t rename_map, VEC (tree, heap) **newivs,
897 htab_t newivs_index, htab_t bb_pbb_mapping,
898 htab_t params_index)
900 edge last_e = graphite_create_new_guard (region, next_e, stmt, *newivs,
901 newivs_index, params_index);
903 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
904 edge false_e = get_false_edge_from_guard_bb (next_e->dest);
905 edge exit_true_e = single_succ_edge (true_e->dest);
906 edge exit_false_e = single_succ_edge (false_e->dest);
908 htab_t before_guard = htab_create (10, rename_map_elt_info,
909 eq_rename_map_elts, free);
910 htab_traverse (rename_map, copy_renames, before_guard);
912 next_e = translate_clast (region, stmt->then, true_e,
913 rename_map, newivs, newivs_index, bb_pbb_mapping,
914 params_index);
916 insert_guard_phis (last_e->src, exit_true_e, exit_false_e,
917 before_guard, rename_map);
919 htab_delete (before_guard);
921 return last_e;
924 /* Translates a CLAST statement STMT to GCC representation in the
925 context of a SESE.
927 - NEXT_E is the edge where new generated code should be attached.
928 - RENAME_MAP contains a set of tuples of new names associated to
929 the original variables names.
930 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
931 static edge
932 translate_clast (sese region, struct clast_stmt *stmt,
933 edge next_e, htab_t rename_map, VEC (tree, heap) **newivs,
934 htab_t newivs_index, htab_t bb_pbb_mapping,
935 htab_t params_index)
937 if (!stmt)
938 return next_e;
940 if (CLAST_STMT_IS_A (stmt, stmt_root))
941 ; /* Do nothing. */
943 else if (CLAST_STMT_IS_A (stmt, stmt_user))
944 next_e = translate_clast_user (region, (struct clast_user_stmt *) stmt,
945 next_e, rename_map, newivs, newivs_index,
946 bb_pbb_mapping, params_index);
948 else if (CLAST_STMT_IS_A (stmt, stmt_for))
949 next_e = translate_clast_for (region,
950 (struct clast_for *) stmt, next_e, rename_map,
951 newivs, newivs_index, bb_pbb_mapping,
952 params_index);
954 else if (CLAST_STMT_IS_A (stmt, stmt_guard))
955 next_e = translate_clast_guard (region, (struct clast_guard *) stmt, next_e,
956 rename_map, newivs, newivs_index,
957 bb_pbb_mapping, params_index);
959 else if (CLAST_STMT_IS_A (stmt, stmt_block))
960 next_e = translate_clast (region, ((struct clast_block *) stmt)->body,
961 next_e, rename_map, newivs, newivs_index,
962 bb_pbb_mapping, params_index);
963 else
964 gcc_unreachable();
966 recompute_all_dominators ();
967 graphite_verify ();
969 return translate_clast (region, stmt->next, next_e, rename_map, newivs,
970 newivs_index, bb_pbb_mapping, params_index);
973 /* Returns the first cloog name used in EXPR. */
975 static const char *
976 find_cloog_iv_in_expr (struct clast_expr *expr)
978 struct clast_term *term = (struct clast_term *) expr;
980 if (expr->type == expr_term
981 && !term->var)
982 return NULL;
984 if (expr->type == expr_term)
985 return term->var;
987 if (expr->type == expr_red)
989 int i;
990 struct clast_reduction *red = (struct clast_reduction *) expr;
992 for (i = 0; i < red->n; i++)
994 const char *res = find_cloog_iv_in_expr ((red)->elts[i]);
996 if (res)
997 return res;
1001 return NULL;
1004 /* Build for a clast_user_stmt USER_STMT a map between the CLAST
1005 induction variables and the corresponding GCC old induction
1006 variables. This information is stored on each GRAPHITE_BB. */
1008 static void
1009 compute_cloog_iv_types_1 (poly_bb_p pbb, struct clast_user_stmt *user_stmt)
1011 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1012 struct clast_stmt *t;
1013 int index = 0;
1015 for (t = user_stmt->substitutions; t; t = t->next, index++)
1017 PTR *slot;
1018 struct ivtype_map_elt_s tmp;
1019 struct clast_expr *expr = (struct clast_expr *)
1020 ((struct clast_assignment *)t)->RHS;
1022 /* Create an entry (clast_var, type). */
1023 tmp.cloog_iv = find_cloog_iv_in_expr (expr);
1024 if (!tmp.cloog_iv)
1025 continue;
1027 slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, INSERT);
1029 if (!*slot)
1031 tree oldiv = pbb_to_depth_to_oldiv (pbb, index);
1032 tree type = oldiv ? TREE_TYPE (oldiv) : integer_type_node;
1033 *slot = new_ivtype_map_elt (tmp.cloog_iv, type);
1038 /* Walk the CLAST tree starting from STMT and build for each
1039 clast_user_stmt a map between the CLAST induction variables and the
1040 corresponding GCC old induction variables. This information is
1041 stored on each GRAPHITE_BB. */
1043 static void
1044 compute_cloog_iv_types (struct clast_stmt *stmt)
1046 if (!stmt)
1047 return;
1049 if (CLAST_STMT_IS_A (stmt, stmt_root))
1050 goto next;
1052 if (CLAST_STMT_IS_A (stmt, stmt_user))
1054 CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
1055 poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
1056 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1058 if (!GBB_CLOOG_IV_TYPES (gbb))
1059 GBB_CLOOG_IV_TYPES (gbb) = htab_create (10, ivtype_map_elt_info,
1060 eq_ivtype_map_elts, free);
1062 compute_cloog_iv_types_1 (pbb, (struct clast_user_stmt *) stmt);
1063 goto next;
1066 if (CLAST_STMT_IS_A (stmt, stmt_for))
1068 struct clast_stmt *s = ((struct clast_for *) stmt)->body;
1069 compute_cloog_iv_types (s);
1070 goto next;
1073 if (CLAST_STMT_IS_A (stmt, stmt_guard))
1075 struct clast_stmt *s = ((struct clast_guard *) stmt)->then;
1076 compute_cloog_iv_types (s);
1077 goto next;
1080 if (CLAST_STMT_IS_A (stmt, stmt_block))
1082 struct clast_stmt *s = ((struct clast_block *) stmt)->body;
1083 compute_cloog_iv_types (s);
1084 goto next;
1087 gcc_unreachable ();
1089 next:
1090 compute_cloog_iv_types (stmt->next);
1093 /* Free the SCATTERING domain list. */
1095 static void
1096 free_scattering (CloogDomainList *scattering)
1098 while (scattering)
1100 CloogDomain *dom = cloog_domain (scattering);
1101 CloogDomainList *next = cloog_next_domain (scattering);
1103 cloog_domain_free (dom);
1104 free (scattering);
1105 scattering = next;
1109 /* Initialize Cloog's parameter names from the names used in GIMPLE.
1110 Initialize Cloog's iterator names, using 'graphite_iterator_%d'
1111 from 0 to scop_nb_loops (scop). */
1113 static void
1114 initialize_cloog_names (scop_p scop, CloogProgram *prog)
1116 sese region = SCOP_REGION (scop);
1117 int i;
1118 int nb_iterators = scop_max_loop_depth (scop);
1119 int nb_scattering = cloog_program_nb_scattdims (prog);
1120 int nb_parameters = VEC_length (tree, SESE_PARAMS (region));
1121 char **iterators = XNEWVEC (char *, nb_iterators * 2);
1122 char **scattering = XNEWVEC (char *, nb_scattering);
1123 char **parameters= XNEWVEC (char *, nb_parameters);
1125 cloog_program_set_names (prog, cloog_names_malloc ());
1127 for (i = 0; i < nb_parameters; i++)
1129 tree param = VEC_index (tree, SESE_PARAMS(region), i);
1130 const char *name = get_name (param);
1131 int len;
1133 if (!name)
1134 name = "T";
1136 len = strlen (name);
1137 len += 17;
1138 parameters[i] = XNEWVEC (char, len + 1);
1139 snprintf (parameters[i], len, "%s_%d", name, SSA_NAME_VERSION (param));
1142 cloog_names_set_nb_parameters (cloog_program_names (prog), nb_parameters);
1143 cloog_names_set_parameters (cloog_program_names (prog), parameters);
1145 for (i = 0; i < nb_iterators; i++)
1147 int len = 4 + 16;
1148 iterators[i] = XNEWVEC (char, len);
1149 snprintf (iterators[i], len, "git_%d", i);
1152 cloog_names_set_nb_iterators (cloog_program_names (prog),
1153 nb_iterators);
1154 cloog_names_set_iterators (cloog_program_names (prog),
1155 iterators);
1157 for (i = 0; i < nb_scattering; i++)
1159 int len = 5 + 16;
1160 scattering[i] = XNEWVEC (char, len);
1161 snprintf (scattering[i], len, "scat_%d", i);
1164 cloog_names_set_nb_scattering (cloog_program_names (prog),
1165 nb_scattering);
1166 cloog_names_set_scattering (cloog_program_names (prog),
1167 scattering);
1170 /* Build cloog program for SCoP. */
1172 static void
1173 build_cloog_prog (scop_p scop, CloogProgram *prog)
1175 int i;
1176 int max_nb_loops = scop_max_loop_depth (scop);
1177 poly_bb_p pbb;
1178 CloogLoop *loop_list = NULL;
1179 CloogBlockList *block_list = NULL;
1180 CloogDomainList *scattering = NULL;
1181 int nbs = 2 * max_nb_loops + 1;
1182 int *scaldims;
1184 cloog_program_set_context
1185 (prog, new_Cloog_Domain_from_ppl_Pointset_Powerset (SCOP_CONTEXT (scop)));
1186 nbs = unify_scattering_dimensions (scop);
1187 scaldims = (int *) xmalloc (nbs * (sizeof (int)));
1188 cloog_program_set_nb_scattdims (prog, nbs);
1189 initialize_cloog_names (scop, prog);
1191 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1193 CloogStatement *stmt;
1194 CloogBlock *block;
1196 /* Dead code elimination: when the domain of a PBB is empty,
1197 don't generate code for the PBB. */
1198 if (ppl_Pointset_Powerset_C_Polyhedron_is_empty (PBB_DOMAIN (pbb)))
1199 continue;
1201 /* Build the new statement and its block. */
1202 stmt = cloog_statement_alloc (pbb_index (pbb));
1203 block = cloog_block_alloc (stmt, 0, NULL, pbb_dim_iter_domain (pbb));
1204 cloog_statement_set_usr (stmt, pbb);
1206 /* Build loop list. */
1208 CloogLoop *new_loop_list = cloog_loop_malloc ();
1209 cloog_loop_set_next (new_loop_list, loop_list);
1210 cloog_loop_set_domain
1211 (new_loop_list,
1212 new_Cloog_Domain_from_ppl_Pointset_Powerset (PBB_DOMAIN (pbb)));
1213 cloog_loop_set_block (new_loop_list, block);
1214 loop_list = new_loop_list;
1217 /* Build block list. */
1219 CloogBlockList *new_block_list = cloog_block_list_malloc ();
1221 cloog_block_list_set_next (new_block_list, block_list);
1222 cloog_block_list_set_block (new_block_list, block);
1223 block_list = new_block_list;
1226 /* Build scattering list. */
1228 /* XXX: Replace with cloog_domain_list_alloc(), when available. */
1229 CloogDomainList *new_scattering
1230 = (CloogDomainList *) xmalloc (sizeof (CloogDomainList));
1231 ppl_Polyhedron_t scat;
1232 CloogDomain *dom;
1234 scat = PBB_TRANSFORMED_SCATTERING (pbb);
1235 dom = new_Cloog_Domain_from_ppl_Polyhedron (scat);
1237 cloog_set_next_domain (new_scattering, scattering);
1238 cloog_set_domain (new_scattering, dom);
1239 scattering = new_scattering;
1243 cloog_program_set_loop (prog, loop_list);
1244 cloog_program_set_blocklist (prog, block_list);
1246 for (i = 0; i < nbs; i++)
1247 scaldims[i] = 0 ;
1249 cloog_program_set_scaldims (prog, scaldims);
1251 /* Extract scalar dimensions to simplify the code generation problem. */
1252 cloog_program_extract_scalars (prog, scattering);
1254 /* Apply scattering. */
1255 cloog_program_scatter (prog, scattering);
1256 free_scattering (scattering);
1258 /* Iterators corresponding to scalar dimensions have to be extracted. */
1259 cloog_names_scalarize (cloog_program_names (prog), nbs,
1260 cloog_program_scaldims (prog));
1262 /* Free blocklist. */
1264 CloogBlockList *next = cloog_program_blocklist (prog);
1266 while (next)
1268 CloogBlockList *toDelete = next;
1269 next = cloog_block_list_next (next);
1270 cloog_block_list_set_next (toDelete, NULL);
1271 cloog_block_list_set_block (toDelete, NULL);
1272 cloog_block_list_free (toDelete);
1274 cloog_program_set_blocklist (prog, NULL);
1278 /* Return the options that will be used in GLOOG. */
1280 static CloogOptions *
1281 set_cloog_options (void)
1283 CloogOptions *options = cloog_options_malloc ();
1285 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1286 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1287 we pass an incomplete program to cloog. */
1288 options->language = LANGUAGE_C;
1290 /* Enable complex equality spreading: removes dummy statements
1291 (assignments) in the generated code which repeats the
1292 substitution equations for statements. This is useless for
1293 GLooG. */
1294 options->esp = 1;
1296 /* Enable C pretty-printing mode: normalizes the substitution
1297 equations for statements. */
1298 options->cpp = 1;
1300 /* Allow cloog to build strides with a stride width different to one.
1301 This example has stride = 4:
1303 for (i = 0; i < 20; i += 4)
1304 A */
1305 options->strides = 1;
1307 /* Disable optimizations and make cloog generate source code closer to the
1308 input. This is useful for debugging, but later we want the optimized
1309 code.
1311 XXX: We can not disable optimizations, as loop blocking is not working
1312 without them. */
1313 if (0)
1315 options->f = -1;
1316 options->l = INT_MAX;
1319 return options;
1322 /* Prints STMT to STDERR. */
1324 void
1325 print_clast_stmt (FILE *file, struct clast_stmt *stmt)
1327 CloogOptions *options = set_cloog_options ();
1329 pprint (file, stmt, 0, options);
1330 cloog_options_free (options);
1333 /* Prints STMT to STDERR. */
1335 void
1336 debug_clast_stmt (struct clast_stmt *stmt)
1338 print_clast_stmt (stderr, stmt);
1341 /* Translate SCOP to a CLooG program and clast. These two
1342 representations should be freed together: a clast cannot be used
1343 without a program. */
1345 cloog_prog_clast
1346 scop_to_clast (scop_p scop)
1348 CloogOptions *options = set_cloog_options ();
1349 cloog_prog_clast pc;
1351 /* Connect new cloog prog generation to graphite. */
1352 pc.prog = cloog_program_malloc ();
1353 build_cloog_prog (scop, pc.prog);
1354 pc.prog = cloog_program_generate (pc.prog, options);
1355 pc.stmt = cloog_clast_create (pc.prog, options);
1357 cloog_options_free (options);
1358 return pc;
1361 /* Prints to FILE the code generated by CLooG for SCOP. */
1363 void
1364 print_generated_program (FILE *file, scop_p scop)
1366 CloogOptions *options = set_cloog_options ();
1367 cloog_prog_clast pc = scop_to_clast (scop);
1369 fprintf (file, " (prog: \n");
1370 cloog_program_print (file, pc.prog);
1371 fprintf (file, " )\n");
1373 fprintf (file, " (clast: \n");
1374 pprint (file, pc.stmt, 0, options);
1375 fprintf (file, " )\n");
1377 cloog_options_free (options);
1378 cloog_clast_free (pc.stmt);
1379 cloog_program_free (pc.prog);
1382 /* Prints to STDERR the code generated by CLooG for SCOP. */
1384 void
1385 debug_generated_program (scop_p scop)
1387 print_generated_program (stderr, scop);
1390 /* Add CLooG names to parameter index. The index is used to translate back from
1391 * CLooG names to GCC trees. */
1393 static void
1394 create_params_index (htab_t index_table, CloogProgram *prog) {
1395 CloogNames* names = cloog_program_names (prog);
1396 int nb_parameters = cloog_names_nb_parameters (names);
1397 char **parameters = cloog_names_parameters (names);
1398 int i;
1400 for (i = 0; i < nb_parameters; i++)
1401 save_clast_name_index (index_table, parameters[i], i);
1404 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1405 the given SCOP. Return true if code generation succeeded.
1406 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1409 bool
1410 gloog (scop_p scop, htab_t bb_pbb_mapping)
1412 edge new_scop_exit_edge = NULL;
1413 VEC (tree, heap) *newivs = VEC_alloc (tree, heap, 10);
1414 sese region = SCOP_REGION (scop);
1415 ifsese if_region = NULL;
1416 htab_t rename_map, newivs_index, params_index;
1417 cloog_prog_clast pc;
1419 timevar_push (TV_GRAPHITE_CODE_GEN);
1421 pc = scop_to_clast (scop);
1423 if (dump_file && (dump_flags & TDF_DETAILS))
1425 fprintf (dump_file, "\nCLAST generated by CLooG: \n");
1426 print_clast_stmt (dump_file, pc.stmt);
1427 fprintf (dump_file, "\n");
1430 recompute_all_dominators ();
1431 graphite_verify ();
1433 if_region = move_sese_in_condition (region);
1434 sese_insert_phis_for_liveouts (region,
1435 if_region->region->exit->src,
1436 if_region->false_region->exit,
1437 if_region->true_region->exit);
1438 recompute_all_dominators ();
1439 graphite_verify ();
1441 compute_cloog_iv_types (pc.stmt);
1442 rename_map = htab_create (10, rename_map_elt_info, eq_rename_map_elts, free);
1443 newivs_index = htab_create (10, clast_name_index_elt_info,
1444 eq_clast_name_indexes, free);
1445 params_index = htab_create (10, clast_name_index_elt_info,
1446 eq_clast_name_indexes, free);
1448 create_params_index (params_index, pc.prog);
1450 new_scop_exit_edge = translate_clast (region, pc.stmt,
1451 if_region->true_region->entry,
1452 rename_map, &newivs, newivs_index,
1453 bb_pbb_mapping, params_index);
1454 graphite_verify ();
1455 sese_adjust_liveout_phis (region, rename_map,
1456 if_region->region->exit->src,
1457 if_region->false_region->exit,
1458 if_region->true_region->exit);
1459 recompute_all_dominators ();
1460 graphite_verify ();
1462 free (if_region->true_region);
1463 free (if_region->region);
1464 free (if_region);
1466 htab_delete (rename_map);
1467 htab_delete (newivs_index);
1468 htab_delete (params_index);
1469 VEC_free (tree, heap, newivs);
1470 cloog_clast_free (pc.stmt);
1471 cloog_program_free (pc.prog);
1472 timevar_pop (TV_GRAPHITE_CODE_GEN);
1474 if (dump_file && (dump_flags & TDF_DETAILS))
1476 loop_p loop;
1477 loop_iterator li;
1478 int num_no_dependency = 0;
1480 FOR_EACH_LOOP (li, loop, 0)
1481 if (loop->can_be_parallel)
1482 num_no_dependency++;
1484 fprintf (dump_file, "\n%d loops carried no dependency.\n",
1485 num_no_dependency);
1488 return true;
1491 #endif