graphite-clast-to-gimple.c (build_cloog_prog): Use pbb_index.
[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 /* Verifies properties that GRAPHITE should maintain during translation. */
56
57 static inline void
58 graphite_verify (void)
59 {
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
67 }
68
69 /* For a given loop DEPTH in the loop nest of the original black box
70 PBB, return the old induction variable associated to that loop. */
71
72 static inline tree
73 pbb_to_depth_to_oldiv (poly_bb_p pbb, int depth)
74 {
75 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
76 sese region = SCOP_REGION (PBB_SCOP (pbb));
77 loop_p loop = gbb_loop_at_index (gbb, region, depth);
78
79 return (tree) loop->aux;
80 }
81
82 /* For a given scattering dimension, return the new induction variable
83 associated to it. */
84
85 static inline tree
86 newivs_to_depth_to_newiv (VEC (tree, heap) *newivs, int depth)
87 {
88 return VEC_index (tree, newivs, depth);
89 }
90
91 \f
92
93 /* Returns the tree variable from the name NAME that was given in
94 Cloog representation. */
95
96 static tree
97 clast_name_to_gcc (const char *name, sese region, VEC (tree, heap) *newivs,
98 htab_t newivs_index)
99 {
100 int index;
101 VEC (tree, heap) *params = SESE_PARAMS (region);
102 htab_t params_index = SESE_PARAMS_INDEX (region);
103
104 if (params && params_index)
105 {
106 index = clast_name_to_index (name, params_index);
107
108 if (index >= 0)
109 return VEC_index (tree, params, index);
110 }
111
112 gcc_assert (newivs && newivs_index);
113 index = clast_name_to_index (name, newivs_index);
114 gcc_assert (index >= 0);
115
116 return newivs_to_depth_to_newiv (newivs, index);
117 }
118
119 /* Returns the maximal precision type for expressions E1 and E2. */
120
121 static inline tree
122 max_precision_type (tree e1, tree e2)
123 {
124 tree type1 = TREE_TYPE (e1);
125 tree type2 = TREE_TYPE (e2);
126 return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
127 }
128
129 static tree
130 clast_to_gcc_expression (tree, struct clast_expr *, sese, VEC (tree, heap) *,
131 htab_t);
132
133 /* Converts a Cloog reduction expression R with reduction operation OP
134 to a GCC expression tree of type TYPE. */
135
136 static tree
137 clast_to_gcc_expression_red (tree type, enum tree_code op,
138 struct clast_reduction *r,
139 sese region, VEC (tree, heap) *newivs,
140 htab_t newivs_index)
141 {
142 int i;
143 tree res = clast_to_gcc_expression (type, r->elts[0], region, newivs,
144 newivs_index);
145 tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type;
146
147 for (i = 1; i < r->n; i++)
148 {
149 tree t = clast_to_gcc_expression (operand_type, r->elts[i], region,
150 newivs, newivs_index);
151 res = fold_build2 (op, type, res, t);
152 }
153
154 return res;
155 }
156
157 /* Converts a Cloog AST expression E back to a GCC expression tree of
158 type TYPE. */
159
160 static tree
161 clast_to_gcc_expression (tree type, struct clast_expr *e,
162 sese region, VEC (tree, heap) *newivs,
163 htab_t newivs_index)
164 {
165 switch (e->type)
166 {
167 case expr_term:
168 {
169 struct clast_term *t = (struct clast_term *) e;
170
171 if (t->var)
172 {
173 if (value_one_p (t->val))
174 {
175 tree name = clast_name_to_gcc (t->var, region, newivs,
176 newivs_index);
177 return fold_convert (type, name);
178 }
179
180 else if (value_mone_p (t->val))
181 {
182 tree name = clast_name_to_gcc (t->var, region, newivs,
183 newivs_index);
184 name = fold_convert (type, name);
185 return fold_build1 (NEGATE_EXPR, type, name);
186 }
187 else
188 {
189 tree name = clast_name_to_gcc (t->var, region, newivs,
190 newivs_index);
191 tree cst = gmp_cst_to_tree (type, t->val);
192 name = fold_convert (type, name);
193 return fold_build2 (MULT_EXPR, type, cst, name);
194 }
195 }
196 else
197 return gmp_cst_to_tree (type, t->val);
198 }
199
200 case expr_red:
201 {
202 struct clast_reduction *r = (struct clast_reduction *) e;
203
204 switch (r->type)
205 {
206 case clast_red_sum:
207 return clast_to_gcc_expression_red
208 (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
209 r, region, newivs, newivs_index);
210
211 case clast_red_min:
212 return clast_to_gcc_expression_red (type, MIN_EXPR, r, region,
213 newivs, newivs_index);
214
215 case clast_red_max:
216 return clast_to_gcc_expression_red (type, MAX_EXPR, r, region,
217 newivs, newivs_index);
218
219 default:
220 gcc_unreachable ();
221 }
222 break;
223 }
224
225 case expr_bin:
226 {
227 struct clast_binary *b = (struct clast_binary *) e;
228 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
229 tree tl = clast_to_gcc_expression (type, lhs, region, newivs,
230 newivs_index);
231 tree tr = gmp_cst_to_tree (type, b->RHS);
232
233 switch (b->type)
234 {
235 case clast_bin_fdiv:
236 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
237
238 case clast_bin_cdiv:
239 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
240
241 case clast_bin_div:
242 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
243
244 case clast_bin_mod:
245 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
246
247 default:
248 gcc_unreachable ();
249 }
250 }
251
252 default:
253 gcc_unreachable ();
254 }
255
256 return NULL_TREE;
257 }
258
259 /* Returns the type for the expression E. */
260
261 static tree
262 gcc_type_for_clast_expr (struct clast_expr *e,
263 sese region, VEC (tree, heap) *newivs,
264 htab_t newivs_index)
265 {
266 switch (e->type)
267 {
268 case expr_term:
269 {
270 struct clast_term *t = (struct clast_term *) e;
271
272 if (t->var)
273 return TREE_TYPE (clast_name_to_gcc (t->var, region, newivs,
274 newivs_index));
275 else
276 return NULL_TREE;
277 }
278
279 case expr_red:
280 {
281 struct clast_reduction *r = (struct clast_reduction *) e;
282
283 if (r->n == 1)
284 return gcc_type_for_clast_expr (r->elts[0], region, newivs,
285 newivs_index);
286 else
287 {
288 int i;
289 for (i = 0; i < r->n; i++)
290 {
291 tree type = gcc_type_for_clast_expr (r->elts[i], region,
292 newivs, newivs_index);
293 if (type)
294 return type;
295 }
296 return NULL_TREE;
297 }
298 }
299
300 case expr_bin:
301 {
302 struct clast_binary *b = (struct clast_binary *) e;
303 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
304 return gcc_type_for_clast_expr (lhs, region, newivs,
305 newivs_index);
306 }
307
308 default:
309 gcc_unreachable ();
310 }
311
312 return NULL_TREE;
313 }
314
315 /* Returns the type for the equation CLEQ. */
316
317 static tree
318 gcc_type_for_clast_eq (struct clast_equation *cleq,
319 sese region, VEC (tree, heap) *newivs,
320 htab_t newivs_index)
321 {
322 tree type = gcc_type_for_clast_expr (cleq->LHS, region, newivs,
323 newivs_index);
324 if (type)
325 return type;
326
327 return gcc_type_for_clast_expr (cleq->RHS, region, newivs, newivs_index);
328 }
329
330 /* Translates a clast equation CLEQ to a tree. */
331
332 static tree
333 graphite_translate_clast_equation (sese region,
334 struct clast_equation *cleq,
335 VEC (tree, heap) *newivs,
336 htab_t newivs_index)
337 {
338 enum tree_code comp;
339 tree type = gcc_type_for_clast_eq (cleq, region, newivs, newivs_index);
340 tree lhs = clast_to_gcc_expression (type, cleq->LHS, region, newivs,
341 newivs_index);
342 tree rhs = clast_to_gcc_expression (type, cleq->RHS, region, newivs,
343 newivs_index);
344
345 if (cleq->sign == 0)
346 comp = EQ_EXPR;
347
348 else if (cleq->sign > 0)
349 comp = GE_EXPR;
350
351 else
352 comp = LE_EXPR;
353
354 return fold_build2 (comp, boolean_type_node, lhs, rhs);
355 }
356
357 /* Creates the test for the condition in STMT. */
358
359 static tree
360 graphite_create_guard_cond_expr (sese region, struct clast_guard *stmt,
361 VEC (tree, heap) *newivs,
362 htab_t newivs_index)
363 {
364 tree cond = NULL;
365 int i;
366
367 for (i = 0; i < stmt->n; i++)
368 {
369 tree eq = graphite_translate_clast_equation (region, &stmt->eq[i],
370 newivs, newivs_index);
371
372 if (cond)
373 cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
374 else
375 cond = eq;
376 }
377
378 return cond;
379 }
380
381 /* Creates a new if region corresponding to Cloog's guard. */
382
383 static edge
384 graphite_create_new_guard (sese region, edge entry_edge,
385 struct clast_guard *stmt,
386 VEC (tree, heap) *newivs,
387 htab_t newivs_index)
388 {
389 tree cond_expr = graphite_create_guard_cond_expr (region, stmt, newivs,
390 newivs_index);
391 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
392 return exit_edge;
393 }
394
395 /* Walks a CLAST and returns the first statement in the body of a
396 loop. */
397
398 static struct clast_user_stmt *
399 clast_get_body_of_loop (struct clast_stmt *stmt)
400 {
401 if (!stmt
402 || CLAST_STMT_IS_A (stmt, stmt_user))
403 return (struct clast_user_stmt *) stmt;
404
405 if (CLAST_STMT_IS_A (stmt, stmt_for))
406 return clast_get_body_of_loop (((struct clast_for *) stmt)->body);
407
408 if (CLAST_STMT_IS_A (stmt, stmt_guard))
409 return clast_get_body_of_loop (((struct clast_guard *) stmt)->then);
410
411 if (CLAST_STMT_IS_A (stmt, stmt_block))
412 return clast_get_body_of_loop (((struct clast_block *) stmt)->body);
413
414 gcc_unreachable ();
415 }
416
417 /* Given a CLOOG_IV, returns the type that it should have in GCC land.
418 If the information is not available, i.e. in the case one of the
419 transforms created the loop, just return integer_type_node. */
420
421 static tree
422 gcc_type_for_cloog_iv (const char *cloog_iv, gimple_bb_p gbb)
423 {
424 struct ivtype_map_elt_s tmp;
425 PTR *slot;
426
427 tmp.cloog_iv = cloog_iv;
428 slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, NO_INSERT);
429
430 if (slot && *slot)
431 return ((ivtype_map_elt) *slot)->type;
432
433 return integer_type_node;
434 }
435
436 /* Returns the induction variable for the loop that gets translated to
437 STMT. */
438
439 static tree
440 gcc_type_for_iv_of_clast_loop (struct clast_for *stmt_for)
441 {
442 struct clast_stmt *stmt = (struct clast_stmt *) stmt_for;
443 struct clast_user_stmt *body = clast_get_body_of_loop (stmt);
444 const char *cloog_iv = stmt_for->iterator;
445 CloogStatement *cs = body->statement;
446 poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
447
448 return gcc_type_for_cloog_iv (cloog_iv, PBB_BLACK_BOX (pbb));
449 }
450
451 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
452 induction variable for the new LOOP. New LOOP is attached to CFG
453 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
454 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
455 CLooG's scattering name to the induction variable created for the
456 loop of STMT. The new induction variable is inserted in the NEWIVS
457 vector. */
458
459 static struct loop *
460 graphite_create_new_loop (sese region, edge entry_edge,
461 struct clast_for *stmt,
462 loop_p outer, VEC (tree, heap) **newivs,
463 htab_t newivs_index)
464 {
465 tree type = gcc_type_for_iv_of_clast_loop (stmt);
466 tree lb = clast_to_gcc_expression (type, stmt->LB, region, *newivs,
467 newivs_index);
468 tree ub = clast_to_gcc_expression (type, stmt->UB, region, *newivs,
469 newivs_index);
470 tree stride = gmp_cst_to_tree (type, stmt->stride);
471 tree ivvar = create_tmp_var (type, "graphite_IV");
472 tree iv, iv_after_increment;
473 loop_p loop = create_empty_loop_on_edge
474 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
475 outer ? outer : entry_edge->src->loop_father);
476
477 add_referenced_var (ivvar);
478
479 save_clast_name_index (newivs_index, stmt->iterator,
480 VEC_length (tree, *newivs));
481 VEC_safe_push (tree, heap, *newivs, iv);
482 return loop;
483 }
484
485 /* Inserts in MAP a tuple (OLD_NAME, NEW_NAME) for the induction
486 variables of the loops around GBB in SESE. */
487
488 static void
489 build_iv_mapping (htab_t map, sese region,
490 VEC (tree, heap) *newivs, htab_t newivs_index,
491 struct clast_user_stmt *user_stmt)
492 {
493 struct clast_stmt *t;
494 int index = 0;
495 CloogStatement *cs = user_stmt->statement;
496 poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
497
498 for (t = user_stmt->substitutions; t; t = t->next, index++)
499 {
500 struct clast_expr *expr = (struct clast_expr *)
501 ((struct clast_assignment *)t)->RHS;
502 tree type = gcc_type_for_clast_expr (expr, region, newivs,
503 newivs_index);
504 tree old_name = pbb_to_depth_to_oldiv (pbb, index);
505 tree e = clast_to_gcc_expression (type, expr, region, newivs,
506 newivs_index);
507 set_rename (map, old_name, e);
508 }
509 }
510
511 /* Helper function for htab_traverse. */
512
513 static int
514 copy_renames (void **slot, void *s)
515 {
516 struct rename_map_elt_s *entry = (struct rename_map_elt_s *) *slot;
517 htab_t res = (htab_t) s;
518 tree old_name = entry->old_name;
519 tree expr = entry->expr;
520 struct rename_map_elt_s tmp;
521 PTR *x;
522
523 tmp.old_name = old_name;
524 x = htab_find_slot (res, &tmp, INSERT);
525
526 if (!*x)
527 *x = new_rename_map_elt (old_name, expr);
528
529 return 1;
530 }
531
532 /* Construct bb_pbb_def with BB and PBB. */
533
534 static bb_pbb_def *
535 new_bb_pbb_def (basic_block bb, poly_bb_p pbb)
536 {
537 bb_pbb_def *bb_pbb_p;
538
539 bb_pbb_p = XNEW (bb_pbb_def);
540 bb_pbb_p->bb = bb;
541 bb_pbb_p->pbb = pbb;
542
543 return bb_pbb_p;
544 }
545
546 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
547
548 static void
549 mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping)
550 {
551 bb_pbb_def tmp;
552 PTR *x;
553
554 tmp.bb = bb;
555 x = htab_find_slot (bb_pbb_mapping, &tmp, INSERT);
556
557 if (!*x)
558 *x = new_bb_pbb_def (bb, pbb);
559 }
560
561 /* Returns the scattering dimension for STMTFOR.
562
563 FIXME: This is a hackish solution to locate the scattering
564 dimension in newly created loops. Here the hackish solush
565 assume that the stmt_for->iterator is always something like:
566 scat_1 , scat_3 etc., where after "scat_" is loop level in
567 scattering dimension.
568 */
569
570 static int get_stmtfor_depth (struct clast_for *stmtfor)
571 {
572 const char * iterator = stmtfor->iterator;
573 const char * depth;
574
575 depth = strchr (iterator, '_');
576 if (!strncmp (iterator, "scat_", 5))
577 return atoi (depth+1);
578
579 gcc_unreachable();
580 }
581
582 /* Translates a CLAST statement STMT to GCC representation in the
583 context of a SESE.
584
585 - NEXT_E is the edge where new generated code should be attached.
586 - CONTEXT_LOOP is the loop in which the generated code will be placed
587 - RENAME_MAP contains a set of tuples of new names associated to
588 the original variables names.
589 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
590 */
591
592 static edge
593 translate_clast (sese region, struct loop *context_loop,
594 struct clast_stmt *stmt, edge next_e,
595 htab_t rename_map, VEC (tree, heap) **newivs,
596 htab_t newivs_index, htab_t bb_pbb_mapping)
597 {
598 if (!stmt)
599 return next_e;
600
601 if (CLAST_STMT_IS_A (stmt, stmt_root))
602 return translate_clast (region, context_loop, stmt->next, next_e,
603 rename_map, newivs, newivs_index, bb_pbb_mapping);
604
605 if (CLAST_STMT_IS_A (stmt, stmt_user))
606 {
607 gimple_bb_p gbb;
608 basic_block new_bb;
609 CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
610 poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
611 gbb = PBB_BLACK_BOX (pbb);
612
613 if (GBB_BB (gbb) == ENTRY_BLOCK_PTR)
614 return next_e;
615
616 build_iv_mapping (rename_map, region, *newivs, newivs_index,
617 (struct clast_user_stmt *) stmt);
618 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), region,
619 next_e, rename_map);
620 new_bb = next_e->src;
621 mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
622 recompute_all_dominators ();
623 update_ssa (TODO_update_ssa);
624 graphite_verify ();
625 return translate_clast (region, context_loop, stmt->next, next_e,
626 rename_map, newivs, newivs_index,
627 bb_pbb_mapping);
628 }
629
630 if (CLAST_STMT_IS_A (stmt, stmt_for))
631 {
632 struct clast_for *stmtfor = (struct clast_for *)stmt;
633 struct loop *loop
634 = graphite_create_new_loop (region, next_e, stmtfor,
635 context_loop, newivs, newivs_index);
636 edge last_e = single_exit (loop);
637 edge to_body = single_succ_edge (loop->header);
638 basic_block after = to_body->dest;
639
640 loop->aux = XNEW (int);
641 /* Pass scattering level information of the new loop by LOOP->AUX. */
642 *((int *)(loop->aux)) = get_stmtfor_depth (stmtfor);
643
644 /* Create a basic block for loop close phi nodes. */
645 last_e = single_succ_edge (split_edge (last_e));
646
647 /* Translate the body of the loop. */
648 next_e = translate_clast
649 (region, loop, ((struct clast_for *) stmt)->body,
650 single_succ_edge (loop->header), rename_map, newivs,
651 newivs_index, bb_pbb_mapping);
652 redirect_edge_succ_nodup (next_e, after);
653 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
654
655 /* Remove from rename_map all the tuples containing variables
656 defined in loop's body. */
657 insert_loop_close_phis (rename_map, loop);
658
659 recompute_all_dominators ();
660 graphite_verify ();
661 return translate_clast (region, context_loop, stmt->next, last_e,
662 rename_map, newivs, newivs_index,
663 bb_pbb_mapping);
664 }
665
666 if (CLAST_STMT_IS_A (stmt, stmt_guard))
667 {
668 edge last_e = graphite_create_new_guard (region, next_e,
669 ((struct clast_guard *) stmt),
670 *newivs, newivs_index);
671 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
672 edge false_e = get_false_edge_from_guard_bb (next_e->dest);
673 edge exit_true_e = single_succ_edge (true_e->dest);
674 edge exit_false_e = single_succ_edge (false_e->dest);
675 htab_t before_guard = htab_create (10, rename_map_elt_info,
676 eq_rename_map_elts, free);
677
678 htab_traverse (rename_map, copy_renames, before_guard);
679 next_e = translate_clast (region, context_loop,
680 ((struct clast_guard *) stmt)->then,
681 true_e, rename_map, newivs, newivs_index,
682 bb_pbb_mapping);
683 insert_guard_phis (last_e->src, exit_true_e, exit_false_e,
684 before_guard, rename_map);
685
686 htab_delete (before_guard);
687 recompute_all_dominators ();
688 graphite_verify ();
689
690 return translate_clast (region, context_loop, stmt->next, last_e,
691 rename_map, newivs, newivs_index,
692 bb_pbb_mapping);
693 }
694
695 if (CLAST_STMT_IS_A (stmt, stmt_block))
696 {
697 next_e = translate_clast (region, context_loop,
698 ((struct clast_block *) stmt)->body,
699 next_e, rename_map, newivs, newivs_index,
700 bb_pbb_mapping);
701 recompute_all_dominators ();
702 graphite_verify ();
703 return translate_clast (region, context_loop, stmt->next, next_e,
704 rename_map, newivs, newivs_index,
705 bb_pbb_mapping);
706 }
707
708 gcc_unreachable ();
709 }
710
711 /* Returns the first cloog name used in EXPR. */
712
713 static const char *
714 find_cloog_iv_in_expr (struct clast_expr *expr)
715 {
716 struct clast_term *term = (struct clast_term *) expr;
717
718 if (expr->type == expr_term
719 && !term->var)
720 return NULL;
721
722 if (expr->type == expr_term)
723 return term->var;
724
725 if (expr->type == expr_red)
726 {
727 int i;
728 struct clast_reduction *red = (struct clast_reduction *) expr;
729
730 for (i = 0; i < red->n; i++)
731 {
732 const char *res = find_cloog_iv_in_expr ((red)->elts[i]);
733
734 if (res)
735 return res;
736 }
737 }
738
739 return NULL;
740 }
741
742 /* Build for a clast_user_stmt USER_STMT a map between the CLAST
743 induction variables and the corresponding GCC old induction
744 variables. This information is stored on each GRAPHITE_BB. */
745
746 static void
747 compute_cloog_iv_types_1 (poly_bb_p pbb, struct clast_user_stmt *user_stmt)
748 {
749 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
750 struct clast_stmt *t;
751 int index = 0;
752
753 for (t = user_stmt->substitutions; t; t = t->next, index++)
754 {
755 PTR *slot;
756 struct ivtype_map_elt_s tmp;
757 struct clast_expr *expr = (struct clast_expr *)
758 ((struct clast_assignment *)t)->RHS;
759
760 /* Create an entry (clast_var, type). */
761 tmp.cloog_iv = find_cloog_iv_in_expr (expr);
762 if (!tmp.cloog_iv)
763 continue;
764
765 slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, INSERT);
766
767 if (!*slot)
768 {
769 tree oldiv = pbb_to_depth_to_oldiv (pbb, index);
770 tree type = oldiv ? TREE_TYPE (oldiv) : integer_type_node;
771 *slot = new_ivtype_map_elt (tmp.cloog_iv, type);
772 }
773 }
774 }
775
776 /* Walk the CLAST tree starting from STMT and build for each
777 clast_user_stmt a map between the CLAST induction variables and the
778 corresponding GCC old induction variables. This information is
779 stored on each GRAPHITE_BB. */
780
781 static void
782 compute_cloog_iv_types (struct clast_stmt *stmt)
783 {
784 if (!stmt)
785 return;
786
787 if (CLAST_STMT_IS_A (stmt, stmt_root))
788 goto next;
789
790 if (CLAST_STMT_IS_A (stmt, stmt_user))
791 {
792 CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
793 poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
794 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
795
796 if (!GBB_CLOOG_IV_TYPES (gbb))
797 GBB_CLOOG_IV_TYPES (gbb) = htab_create (10, ivtype_map_elt_info,
798 eq_ivtype_map_elts, free);
799
800 compute_cloog_iv_types_1 (pbb, (struct clast_user_stmt *) stmt);
801 goto next;
802 }
803
804 if (CLAST_STMT_IS_A (stmt, stmt_for))
805 {
806 struct clast_stmt *s = ((struct clast_for *) stmt)->body;
807 compute_cloog_iv_types (s);
808 goto next;
809 }
810
811 if (CLAST_STMT_IS_A (stmt, stmt_guard))
812 {
813 struct clast_stmt *s = ((struct clast_guard *) stmt)->then;
814 compute_cloog_iv_types (s);
815 goto next;
816 }
817
818 if (CLAST_STMT_IS_A (stmt, stmt_block))
819 {
820 struct clast_stmt *s = ((struct clast_block *) stmt)->body;
821 compute_cloog_iv_types (s);
822 goto next;
823 }
824
825 gcc_unreachable ();
826
827 next:
828 compute_cloog_iv_types (stmt->next);
829 }
830
831 /* Free the SCATTERING domain list. */
832
833 static void
834 free_scattering (CloogDomainList *scattering)
835 {
836 while (scattering)
837 {
838 CloogDomain *dom = cloog_domain (scattering);
839 CloogDomainList *next = cloog_next_domain (scattering);
840
841 cloog_domain_free (dom);
842 free (scattering);
843 scattering = next;
844 }
845 }
846
847 /* Initialize Cloog's parameter names from the names used in GIMPLE.
848 Initialize Cloog's iterator names, using 'graphite_iterator_%d'
849 from 0 to scop_nb_loops (scop). */
850
851 static void
852 initialize_cloog_names (scop_p scop, CloogProgram *prog)
853 {
854 sese region = SCOP_REGION (scop);
855 int i;
856 int nb_iterators = scop_max_loop_depth (scop);
857 int nb_scattering = cloog_program_nb_scattdims (prog);
858 char **iterators = XNEWVEC (char *, nb_iterators * 2);
859 char **scattering = XNEWVEC (char *, nb_scattering);
860
861 cloog_program_set_names (prog, cloog_names_malloc ());
862 cloog_names_set_nb_parameters (cloog_program_names (prog),
863 VEC_length (tree, SESE_PARAMS (region)));
864 cloog_names_set_parameters (cloog_program_names (prog),
865 SESE_PARAMS_NAMES (region));
866
867 for (i = 0; i < nb_iterators; i++)
868 {
869 int len = 4 + 16;
870 iterators[i] = XNEWVEC (char, len);
871 snprintf (iterators[i], len, "git_%d", i);
872 }
873
874 cloog_names_set_nb_iterators (cloog_program_names (prog),
875 nb_iterators);
876 cloog_names_set_iterators (cloog_program_names (prog),
877 iterators);
878
879 for (i = 0; i < nb_scattering; i++)
880 {
881 int len = 5 + 16;
882 scattering[i] = XNEWVEC (char, len);
883 snprintf (scattering[i], len, "scat_%d", i);
884 }
885
886 cloog_names_set_nb_scattering (cloog_program_names (prog),
887 nb_scattering);
888 cloog_names_set_scattering (cloog_program_names (prog),
889 scattering);
890 }
891
892 /* Build cloog program for SCoP. */
893
894 static void
895 build_cloog_prog (scop_p scop, CloogProgram *prog)
896 {
897 int i;
898 int max_nb_loops = scop_max_loop_depth (scop);
899 poly_bb_p pbb;
900 CloogLoop *loop_list = NULL;
901 CloogBlockList *block_list = NULL;
902 CloogDomainList *scattering = NULL;
903 int nbs = 2 * max_nb_loops + 1;
904 int *scaldims;
905
906 cloog_program_set_context
907 (prog, new_Cloog_Domain_from_ppl_Pointset_Powerset (SCOP_CONTEXT (scop)));
908 nbs = unify_scattering_dimensions (scop);
909 scaldims = (int *) xmalloc (nbs * (sizeof (int)));
910 cloog_program_set_nb_scattdims (prog, nbs);
911 initialize_cloog_names (scop, prog);
912
913 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
914 {
915 CloogStatement *stmt;
916 CloogBlock *block;
917
918 /* Dead code elimination: when the domain of a PBB is empty,
919 don't generate code for the PBB. */
920 if (ppl_Pointset_Powerset_C_Polyhedron_is_empty (PBB_DOMAIN (pbb)))
921 continue;
922
923 /* Build the new statement and its block. */
924 stmt = cloog_statement_alloc (pbb_index (pbb));
925 block = cloog_block_alloc (stmt, 0, NULL, pbb_dim_iter_domain (pbb));
926 cloog_statement_set_usr (stmt, pbb);
927
928 /* Build loop list. */
929 {
930 CloogLoop *new_loop_list = cloog_loop_malloc ();
931 cloog_loop_set_next (new_loop_list, loop_list);
932 cloog_loop_set_domain
933 (new_loop_list,
934 new_Cloog_Domain_from_ppl_Pointset_Powerset (PBB_DOMAIN (pbb)));
935 cloog_loop_set_block (new_loop_list, block);
936 loop_list = new_loop_list;
937 }
938
939 /* Build block list. */
940 {
941 CloogBlockList *new_block_list = cloog_block_list_malloc ();
942
943 cloog_block_list_set_next (new_block_list, block_list);
944 cloog_block_list_set_block (new_block_list, block);
945 block_list = new_block_list;
946 }
947
948 /* Build scattering list. */
949 {
950 /* XXX: Replace with cloog_domain_list_alloc(), when available. */
951 CloogDomainList *new_scattering
952 = (CloogDomainList *) xmalloc (sizeof (CloogDomainList));
953 ppl_Polyhedron_t scat;
954 CloogDomain *dom;
955
956 scat = PBB_TRANSFORMED_SCATTERING (pbb);
957 dom = new_Cloog_Domain_from_ppl_Polyhedron (scat);
958
959 cloog_set_next_domain (new_scattering, scattering);
960 cloog_set_domain (new_scattering, dom);
961 scattering = new_scattering;
962 }
963 }
964
965 cloog_program_set_loop (prog, loop_list);
966 cloog_program_set_blocklist (prog, block_list);
967
968 for (i = 0; i < nbs; i++)
969 scaldims[i] = 0 ;
970
971 cloog_program_set_scaldims (prog, scaldims);
972
973 /* Extract scalar dimensions to simplify the code generation problem. */
974 cloog_program_extract_scalars (prog, scattering);
975
976 /* Apply scattering. */
977 cloog_program_scatter (prog, scattering);
978 free_scattering (scattering);
979
980 /* Iterators corresponding to scalar dimensions have to be extracted. */
981 cloog_names_scalarize (cloog_program_names (prog), nbs,
982 cloog_program_scaldims (prog));
983
984 /* Free blocklist. */
985 {
986 CloogBlockList *next = cloog_program_blocklist (prog);
987
988 while (next)
989 {
990 CloogBlockList *toDelete = next;
991 next = cloog_block_list_next (next);
992 cloog_block_list_set_next (toDelete, NULL);
993 cloog_block_list_set_block (toDelete, NULL);
994 cloog_block_list_free (toDelete);
995 }
996 cloog_program_set_blocklist (prog, NULL);
997 }
998 }
999
1000 /* Return the options that will be used in GLOOG. */
1001
1002 static CloogOptions *
1003 set_cloog_options (void)
1004 {
1005 CloogOptions *options = cloog_options_malloc ();
1006
1007 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1008 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1009 we pass an incomplete program to cloog. */
1010 options->language = LANGUAGE_C;
1011
1012 /* Enable complex equality spreading: removes dummy statements
1013 (assignments) in the generated code which repeats the
1014 substitution equations for statements. This is useless for
1015 GLooG. */
1016 options->esp = 1;
1017
1018 /* Enable C pretty-printing mode: normalizes the substitution
1019 equations for statements. */
1020 options->cpp = 1;
1021
1022 /* Allow cloog to build strides with a stride width different to one.
1023 This example has stride = 4:
1024
1025 for (i = 0; i < 20; i += 4)
1026 A */
1027 options->strides = 1;
1028
1029 /* Disable optimizations and make cloog generate source code closer to the
1030 input. This is useful for debugging, but later we want the optimized
1031 code.
1032
1033 XXX: We can not disable optimizations, as loop blocking is not working
1034 without them. */
1035 if (0)
1036 {
1037 options->f = -1;
1038 options->l = INT_MAX;
1039 }
1040
1041 return options;
1042 }
1043
1044 /* Prints STMT to STDERR. */
1045
1046 void
1047 print_clast_stmt (FILE *file, struct clast_stmt *stmt)
1048 {
1049 CloogOptions *options = set_cloog_options ();
1050
1051 pprint (file, stmt, 0, options);
1052 cloog_options_free (options);
1053 }
1054
1055 /* Prints STMT to STDERR. */
1056
1057 void
1058 debug_clast_stmt (struct clast_stmt *stmt)
1059 {
1060 print_clast_stmt (stderr, stmt);
1061 }
1062
1063 /* Translate SCOP to a CLooG program and clast. These two
1064 representations should be freed together: a clast cannot be used
1065 without a program. */
1066
1067 cloog_prog_clast
1068 scop_to_clast (scop_p scop)
1069 {
1070 CloogOptions *options = set_cloog_options ();
1071 cloog_prog_clast pc;
1072
1073 /* Connect new cloog prog generation to graphite. */
1074 pc.prog = cloog_program_malloc ();
1075 build_cloog_prog (scop, pc.prog);
1076 pc.prog = cloog_program_generate (pc.prog, options);
1077 pc.stmt = cloog_clast_create (pc.prog, options);
1078
1079 cloog_options_free (options);
1080 return pc;
1081 }
1082
1083 /* Prints to FILE the code generated by CLooG for SCOP. */
1084
1085 void
1086 print_generated_program (FILE *file, scop_p scop)
1087 {
1088 CloogOptions *options = set_cloog_options ();
1089 cloog_prog_clast pc = scop_to_clast (scop);
1090
1091 fprintf (file, " (prog: \n");
1092 cloog_program_print (file, pc.prog);
1093 fprintf (file, " )\n");
1094
1095 fprintf (file, " (clast: \n");
1096 pprint (file, pc.stmt, 0, options);
1097 fprintf (file, " )\n");
1098
1099 cloog_options_free (options);
1100 cloog_clast_free (pc.stmt);
1101 cloog_program_free (pc.prog);
1102 }
1103
1104 /* Prints to STDERR the code generated by CLooG for SCOP. */
1105
1106 void
1107 debug_generated_program (scop_p scop)
1108 {
1109 print_generated_program (stderr, scop);
1110 }
1111
1112 /* A LOOP is in normal form for Graphite when it contains only one
1113 scalar phi node that defines the main induction variable of the
1114 loop, only one increment of the IV, and only one exit condition. */
1115
1116 static void
1117 graphite_loop_normal_form (loop_p loop)
1118 {
1119 struct tree_niter_desc niter;
1120 tree nit;
1121 gimple_seq stmts;
1122 edge exit = single_dom_exit (loop);
1123
1124 bool known_niter = number_of_iterations_exit (loop, exit, &niter, false);
1125
1126 /* At this point we should know the number of iterations, */
1127 gcc_assert (known_niter);
1128
1129 nit = force_gimple_operand (unshare_expr (niter.niter), &stmts, true,
1130 NULL_TREE);
1131 if (stmts)
1132 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
1133
1134 loop->aux = canonicalize_loop_ivs (loop, &nit);
1135 }
1136
1137 /* Converts REGION to loop normal form: one induction variable per loop. */
1138
1139 static void
1140 build_graphite_loop_normal_form (sese region)
1141 {
1142 int i;
1143 loop_p loop;
1144
1145 for (i = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), i, loop); i++)
1146 graphite_loop_normal_form (loop);
1147 }
1148
1149 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1150 the given SCOP. Return true if code generation succeeded.
1151 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1152 */
1153
1154 bool
1155 gloog (scop_p scop, htab_t bb_pbb_mapping)
1156 {
1157 edge new_scop_exit_edge = NULL;
1158 VEC (tree, heap) *newivs = VEC_alloc (tree, heap, 10);
1159 loop_p context_loop;
1160 sese region = SCOP_REGION (scop);
1161 ifsese if_region = NULL;
1162 htab_t rename_map, newivs_index;
1163 cloog_prog_clast pc;
1164
1165 timevar_push (TV_GRAPHITE_CODE_GEN);
1166
1167 pc = scop_to_clast (scop);
1168
1169 if (dump_file && (dump_flags & TDF_DETAILS))
1170 {
1171 fprintf (dump_file, "\nCLAST generated by CLooG: \n");
1172 print_clast_stmt (dump_file, pc.stmt);
1173 fprintf (dump_file, "\n");
1174 }
1175
1176 build_graphite_loop_normal_form (region);
1177 recompute_all_dominators ();
1178 graphite_verify ();
1179
1180 if_region = move_sese_in_condition (region);
1181 sese_insert_phis_for_liveouts (region,
1182 if_region->region->exit->src,
1183 if_region->false_region->exit,
1184 if_region->true_region->exit);
1185
1186 recompute_all_dominators ();
1187 graphite_verify ();
1188 context_loop = SESE_ENTRY (region)->src->loop_father;
1189 compute_cloog_iv_types (pc.stmt);
1190
1191 rename_map = htab_create (10, rename_map_elt_info, eq_rename_map_elts, free);
1192 newivs_index = htab_create (10, clast_name_index_elt_info,
1193 eq_clast_name_indexes, free);
1194
1195 new_scop_exit_edge = translate_clast (region, context_loop, pc.stmt,
1196 if_region->true_region->entry,
1197 rename_map, &newivs, newivs_index,
1198 bb_pbb_mapping);
1199 sese_reset_aux_in_loops (region);
1200 graphite_verify ();
1201 sese_adjust_liveout_phis (region, rename_map,
1202 if_region->region->exit->src,
1203 if_region->false_region->exit,
1204 if_region->true_region->exit);
1205 recompute_all_dominators ();
1206 graphite_verify ();
1207
1208 htab_delete (rename_map);
1209 htab_delete (newivs_index);
1210 VEC_free (tree, heap, newivs);
1211 cloog_clast_free (pc.stmt);
1212 cloog_program_free (pc.prog);
1213 timevar_pop (TV_GRAPHITE_CODE_GEN);
1214
1215 return true;
1216 }
1217
1218 \f
1219
1220 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
1221
1222 static poly_bb_p
1223 find_pbb_via_hash (htab_t bb_pbb_mapping, basic_block bb)
1224 {
1225 bb_pbb_def tmp;
1226 PTR *slot;
1227
1228 tmp.bb = bb;
1229 slot = htab_find_slot (bb_pbb_mapping, &tmp, NO_INSERT);
1230
1231 if (slot && *slot)
1232 return ((bb_pbb_def *) *slot)->pbb;
1233
1234 return NULL;
1235 }
1236
1237 /* Free loop->aux in newly created loops by translate_clast. */
1238
1239 void
1240 free_aux_in_new_loops (void)
1241 {
1242 loop_p loop;
1243 loop_iterator li;
1244
1245 FOR_EACH_LOOP (li, loop, 0)
1246 {
1247 if (!loop->aux)
1248 continue;
1249 free(loop->aux);
1250 loop->aux = NULL;
1251 }
1252 }
1253
1254 /* Check data dependency in LOOP. BB_PBB_MAPPING is a basic_block and
1255 it's related poly_bb_p mapping.
1256 */
1257
1258 static bool
1259 dependency_in_loop_p (loop_p loop, htab_t bb_pbb_mapping)
1260 {
1261 unsigned i,j;
1262 int level = 0;
1263 basic_block *bbs = get_loop_body_in_dom_order (loop);
1264
1265 level = *((int *)(loop->aux));
1266
1267 for (i = 0; i < loop->num_nodes; i++)
1268 {
1269 poly_bb_p pbb1 = find_pbb_via_hash (bb_pbb_mapping, bbs[i]);
1270
1271 if (pbb1 == NULL)
1272 continue;
1273
1274 for (j = 0; j < loop->num_nodes; j++)
1275 {
1276 poly_bb_p pbb2 = find_pbb_via_hash (bb_pbb_mapping, bbs[j]);
1277
1278 if (pbb2 == NULL)
1279 continue;
1280
1281 if (dependency_between_pbbs_p (pbb1, pbb2, level))
1282 {
1283 free (bbs);
1284 return true;
1285 }
1286 }
1287 }
1288
1289 free (bbs);
1290
1291 return false;
1292 }
1293
1294 /* Mark loop as parallel if data dependency does not exist.
1295 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1296 */
1297
1298 void mark_loops_parallel (htab_t bb_pbb_mapping)
1299 {
1300 loop_p loop;
1301 loop_iterator li;
1302 int num_no_dependency = 0;
1303
1304 FOR_EACH_LOOP (li, loop, 0)
1305 {
1306 if (!loop->aux)
1307 continue;
1308
1309 if (!dependency_in_loop_p (loop, bb_pbb_mapping))
1310 {
1311 loop->can_be_parallel = true;
1312 num_no_dependency++;
1313 }
1314 }
1315
1316 if (dump_file && (dump_flags & TDF_DETAILS))
1317 {
1318 fprintf (dump_file, "\n%d loops carried no dependency.\n",
1319 num_no_dependency);
1320 }
1321 }
1322
1323 #endif