Mercurial > hg > CbC > CbC_gcc
comparison gcc/graphite-clast-to-gimple.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
19 <http://www.gnu.org/licenses/>. */ | 19 <http://www.gnu.org/licenses/>. */ |
20 | 20 |
21 #include "config.h" | 21 #include "config.h" |
22 #include "system.h" | 22 #include "system.h" |
23 #include "coretypes.h" | 23 #include "coretypes.h" |
24 #include "tm.h" | 24 #include "diagnostic-core.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" | 25 #include "tree-flow.h" |
31 #include "toplev.h" | |
32 #include "tree-dump.h" | 26 #include "tree-dump.h" |
33 #include "timevar.h" | |
34 #include "cfgloop.h" | 27 #include "cfgloop.h" |
35 #include "tree-chrec.h" | 28 #include "tree-chrec.h" |
36 #include "tree-data-ref.h" | 29 #include "tree-data-ref.h" |
37 #include "tree-scalar-evolution.h" | 30 #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 "langhooks.h" | |
44 #include "sese.h" | 31 #include "sese.h" |
45 | 32 |
46 #ifdef HAVE_cloog | 33 #ifdef HAVE_cloog |
47 #include "cloog/cloog.h" | 34 #include "cloog/cloog.h" |
48 #include "ppl_c.h" | 35 #include "ppl_c.h" |
36 #include "graphite-cloog-util.h" | |
49 #include "graphite-ppl.h" | 37 #include "graphite-ppl.h" |
50 #include "graphite.h" | |
51 #include "graphite-poly.h" | 38 #include "graphite-poly.h" |
52 #include "graphite-scop-detection.h" | |
53 #include "graphite-clast-to-gimple.h" | 39 #include "graphite-clast-to-gimple.h" |
54 #include "graphite-dependences.h" | 40 #include "graphite-dependences.h" |
41 #include "graphite-cloog-compat.h" | |
55 | 42 |
56 /* This flag is set when an error occurred during the translation of | 43 /* This flag is set when an error occurred during the translation of |
57 CLAST to Gimple. */ | 44 CLAST to Gimple. */ |
58 static bool gloog_error; | 45 static bool gloog_error; |
59 | 46 |
63 graphite_verify (void) | 50 graphite_verify (void) |
64 { | 51 { |
65 #ifdef ENABLE_CHECKING | 52 #ifdef ENABLE_CHECKING |
66 verify_loop_structure (); | 53 verify_loop_structure (); |
67 verify_dominators (CDI_DOMINATORS); | 54 verify_dominators (CDI_DOMINATORS); |
68 verify_dominators (CDI_POST_DOMINATORS); | |
69 verify_loop_closed_ssa (true); | 55 verify_loop_closed_ssa (true); |
70 #endif | 56 #endif |
71 } | 57 } |
72 | 58 |
73 /* Stores the INDEX in a vector for a given clast NAME. */ | 59 /* Stores the INDEX in a vector for a given clast NAME. */ |
93 /* For a given clast NAME, returns -1 if it does not correspond to any | 79 /* 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 | 80 parameter, or otherwise, returns the index in the PARAMS or |
95 SCATTERING_DIMENSIONS vector. */ | 81 SCATTERING_DIMENSIONS vector. */ |
96 | 82 |
97 static inline int | 83 static inline int |
98 clast_name_to_index (const char *name, htab_t index_table) | 84 clast_name_to_index (clast_name_p name, htab_t index_table) |
99 { | 85 { |
100 struct clast_name_index tmp; | 86 struct clast_name_index tmp; |
101 PTR *slot; | 87 PTR *slot; |
102 | 88 |
89 #ifdef CLOOG_ORG | |
90 gcc_assert (name->type == clast_expr_name); | |
91 tmp.name = ((const struct clast_name*) name)->name; | |
92 #else | |
103 tmp.name = name; | 93 tmp.name = name; |
94 #endif | |
95 | |
104 slot = htab_find_slot (index_table, &tmp, NO_INSERT); | 96 slot = htab_find_slot (index_table, &tmp, NO_INSERT); |
105 | 97 |
106 if (slot && *slot) | 98 if (slot && *slot) |
107 return ((struct clast_name_index *) *slot)->index; | 99 return ((struct clast_name_index *) *slot)->index; |
108 | 100 |
127 | 119 |
128 *slot = new_clast_name_index (name, index); | 120 *slot = new_clast_name_index (name, index); |
129 } | 121 } |
130 } | 122 } |
131 | 123 |
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. */ | 124 /* Computes a hash function for database element ELT. */ |
159 | 125 |
160 static inline hashval_t | 126 static inline hashval_t |
161 clast_name_index_elt_info (const void *elt) | 127 clast_name_index_elt_info (const void *elt) |
162 { | 128 { |
172 const struct clast_name_index *elt2 = (const struct clast_name_index *) e2; | 138 const struct clast_name_index *elt2 = (const struct clast_name_index *) e2; |
173 | 139 |
174 return (elt1->name == elt2->name); | 140 return (elt1->name == elt2->name); |
175 } | 141 } |
176 | 142 |
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 | 143 /* For a given scattering dimension, return the new induction variable |
192 associated to it. */ | 144 associated to it. */ |
193 | 145 |
194 static inline tree | 146 static inline tree |
195 newivs_to_depth_to_newiv (VEC (tree, heap) *newivs, int depth) | 147 newivs_to_depth_to_newiv (VEC (tree, heap) *newivs, int depth) |
201 | 153 |
202 /* Returns the tree variable from the name NAME that was given in | 154 /* Returns the tree variable from the name NAME that was given in |
203 Cloog representation. */ | 155 Cloog representation. */ |
204 | 156 |
205 static tree | 157 static tree |
206 clast_name_to_gcc (const char *name, sese region, VEC (tree, heap) *newivs, | 158 clast_name_to_gcc (clast_name_p name, sese region, VEC (tree, heap) *newivs, |
207 htab_t newivs_index, htab_t params_index) | 159 htab_t newivs_index, htab_t params_index) |
208 { | 160 { |
209 int index; | 161 int index; |
210 VEC (tree, heap) *params = SESE_PARAMS (region); | 162 VEC (tree, heap) *params = SESE_PARAMS (region); |
211 | 163 |
231 { | 183 { |
232 int p1 = TYPE_PRECISION (type1); | 184 int p1 = TYPE_PRECISION (type1); |
233 int p2 = TYPE_PRECISION (type2); | 185 int p2 = TYPE_PRECISION (type2); |
234 int precision; | 186 int precision; |
235 tree type; | 187 tree type; |
188 enum machine_mode mode; | |
236 | 189 |
237 if (p1 > p2) | 190 if (p1 > p2) |
238 precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1; | 191 precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1; |
239 else | 192 else |
240 precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2; | 193 precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2; |
241 | 194 |
242 type = lang_hooks.types.type_for_size (precision, false); | 195 if (precision > BITS_PER_WORD) |
243 | |
244 if (!type) | |
245 { | 196 { |
246 gloog_error = true; | 197 gloog_error = true; |
247 return integer_type_node; | 198 return integer_type_node; |
248 } | 199 } |
200 | |
201 mode = smallest_mode_for_size (precision, MODE_INT); | |
202 precision = GET_MODE_PRECISION (mode); | |
203 type = build_nonstandard_integer_type (precision, false); | |
204 | |
205 if (!type) | |
206 { | |
207 gloog_error = true; | |
208 return integer_type_node; | |
209 } | |
210 | |
249 return type; | 211 return type; |
250 } | 212 } |
251 | 213 |
252 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */ | 214 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */ |
253 | 215 |
303 sese region, VEC (tree, heap) *newivs, | 265 sese region, VEC (tree, heap) *newivs, |
304 htab_t newivs_index, htab_t params_index) | 266 htab_t newivs_index, htab_t params_index) |
305 { | 267 { |
306 switch (e->type) | 268 switch (e->type) |
307 { | 269 { |
308 case expr_term: | 270 case clast_expr_term: |
309 { | 271 { |
310 struct clast_term *t = (struct clast_term *) e; | 272 struct clast_term *t = (struct clast_term *) e; |
311 | 273 |
312 if (t->var) | 274 if (t->var) |
313 { | 275 { |
355 } | 317 } |
356 else | 318 else |
357 return gmp_cst_to_tree (type, t->val); | 319 return gmp_cst_to_tree (type, t->val); |
358 } | 320 } |
359 | 321 |
360 case expr_red: | 322 case clast_expr_red: |
361 { | 323 { |
362 struct clast_reduction *r = (struct clast_reduction *) e; | 324 struct clast_reduction *r = (struct clast_reduction *) e; |
363 | 325 |
364 switch (r->type) | 326 switch (r->type) |
365 { | 327 { |
382 gcc_unreachable (); | 344 gcc_unreachable (); |
383 } | 345 } |
384 break; | 346 break; |
385 } | 347 } |
386 | 348 |
387 case expr_bin: | 349 case clast_expr_bin: |
388 { | 350 { |
389 struct clast_binary *b = (struct clast_binary *) e; | 351 struct clast_binary *b = (struct clast_binary *) e; |
390 struct clast_expr *lhs = (struct clast_expr *) b->LHS; | 352 struct clast_expr *lhs = (struct clast_expr *) b->LHS; |
391 tree tl = clast_to_gcc_expression (type, lhs, region, newivs, | 353 tree tl = clast_to_gcc_expression (type, lhs, region, newivs, |
392 newivs_index, params_index); | 354 newivs_index, params_index); |
424 precision_for_value (mpz_t val) | 386 precision_for_value (mpz_t val) |
425 { | 387 { |
426 mpz_t x, y, two; | 388 mpz_t x, y, two; |
427 int precision; | 389 int precision; |
428 | 390 |
429 value_init (x); | 391 mpz_init (x); |
430 value_init (y); | 392 mpz_init (y); |
431 value_init (two); | 393 mpz_init (two); |
432 value_set_si (x, 2); | 394 mpz_set_si (x, 2); |
433 value_assign (y, val); | 395 mpz_set (y, val); |
434 value_set_si (two, 2); | 396 mpz_set_si (two, 2); |
435 precision = 1; | 397 precision = 1; |
436 | 398 |
437 if (value_neg_p (y)) | 399 if (mpz_sgn (y) < 0) |
438 value_oppose (y, y); | 400 mpz_neg (y, y); |
439 | 401 |
440 while (value_gt (y, x)) | 402 while (mpz_cmp (y, x) >= 0) |
441 { | 403 { |
442 value_multiply (x, x, two); | 404 mpz_mul (x, x, two); |
443 precision++; | 405 precision++; |
444 } | 406 } |
445 | 407 |
446 value_clear (x); | 408 mpz_clear (x); |
447 value_clear (y); | 409 mpz_clear (y); |
448 value_clear (two); | 410 mpz_clear (two); |
449 | 411 |
450 return precision; | 412 return precision; |
451 } | 413 } |
452 | 414 |
453 /* Return the precision needed to represent the values between LOW and | 415 /* Return the precision needed to represent the values between LOW and |
457 precision_for_interval (mpz_t low, mpz_t up) | 419 precision_for_interval (mpz_t low, mpz_t up) |
458 { | 420 { |
459 mpz_t diff; | 421 mpz_t diff; |
460 int precision; | 422 int precision; |
461 | 423 |
462 gcc_assert (value_le (low, up)); | 424 gcc_assert (mpz_cmp (low, up) <= 0); |
463 | 425 |
464 value_init (diff); | 426 mpz_init (diff); |
465 value_subtract (diff, up, low); | 427 mpz_sub (diff, up, low); |
466 precision = precision_for_value (diff); | 428 precision = precision_for_value (diff); |
467 value_clear (diff); | 429 mpz_clear (diff); |
468 | 430 |
469 return precision; | 431 return precision; |
470 } | 432 } |
471 | 433 |
472 /* Return a type that could represent the integer value VAL, or | 434 /* Return a type that could represent the integer value VAL. */ |
473 otherwise return NULL_TREE. */ | 435 |
474 | 436 static tree |
475 static tree | 437 gcc_type_for_interval (mpz_t low, mpz_t up) |
476 gcc_type_for_interval (mpz_t low, mpz_t up, tree old_type) | |
477 { | 438 { |
478 bool unsigned_p = true; | 439 bool unsigned_p = true; |
479 int precision, prec_up, prec_int; | 440 int precision, prec_up, prec_int; |
480 tree type; | 441 tree type; |
481 | 442 enum machine_mode mode; |
482 gcc_assert (value_le (low, up)); | 443 |
483 | 444 gcc_assert (mpz_cmp (low, up) <= 0); |
484 /* Preserve the signedness of the old IV. */ | |
485 if ((old_type && !TYPE_UNSIGNED (old_type)) | |
486 || value_neg_p (low)) | |
487 unsigned_p = false; | |
488 | 445 |
489 prec_up = precision_for_value (up); | 446 prec_up = precision_for_value (up); |
490 prec_int = precision_for_interval (low, up); | 447 prec_int = precision_for_interval (low, up); |
491 precision = prec_up > prec_int ? prec_up : prec_int; | 448 precision = MAX (prec_up, prec_int); |
492 | 449 |
493 type = lang_hooks.types.type_for_size (precision, unsigned_p); | 450 if (precision > BITS_PER_WORD) |
494 if (!type) | |
495 { | 451 { |
496 gloog_error = true; | 452 gloog_error = true; |
497 return integer_type_node; | 453 return integer_type_node; |
498 } | 454 } |
499 | 455 |
456 if (mpz_sgn (low) <= 0) | |
457 unsigned_p = false; | |
458 | |
459 else if (precision < BITS_PER_WORD) | |
460 { | |
461 unsigned_p = false; | |
462 precision++; | |
463 } | |
464 | |
465 mode = smallest_mode_for_size (precision, MODE_INT); | |
466 precision = GET_MODE_PRECISION (mode); | |
467 type = build_nonstandard_integer_type (precision, unsigned_p); | |
468 | |
469 if (!type) | |
470 { | |
471 gloog_error = true; | |
472 return integer_type_node; | |
473 } | |
474 | |
500 return type; | 475 return type; |
501 } | 476 } |
502 | 477 |
503 /* Return a type that could represent the integer value VAL, or | 478 /* Return a type that could represent the integer value VAL, or |
504 otherwise return NULL_TREE. */ | 479 otherwise return NULL_TREE. */ |
505 | 480 |
506 static tree | 481 static tree |
507 gcc_type_for_value (mpz_t val) | 482 gcc_type_for_value (mpz_t val) |
508 { | 483 { |
509 return gcc_type_for_interval (val, val, NULL_TREE); | 484 return gcc_type_for_interval (val, val); |
510 } | 485 } |
511 | 486 |
512 /* Return the type for the clast_term T used in STMT. */ | 487 /* Return the type for the clast_term T used in STMT. */ |
513 | 488 |
514 static tree | 489 static tree |
515 gcc_type_for_clast_term (struct clast_term *t, | 490 gcc_type_for_clast_term (struct clast_term *t, |
516 sese region, VEC (tree, heap) *newivs, | 491 sese region, VEC (tree, heap) *newivs, |
517 htab_t newivs_index, htab_t params_index) | 492 htab_t newivs_index, htab_t params_index) |
518 { | 493 { |
519 gcc_assert (t->expr.type == expr_term); | 494 gcc_assert (t->expr.type == clast_expr_term); |
520 | 495 |
521 if (!t->var) | 496 if (!t->var) |
522 return gcc_type_for_value (t->val); | 497 return gcc_type_for_value (t->val); |
523 | 498 |
524 return TREE_TYPE (clast_name_to_gcc (t->var, region, newivs, | 499 return TREE_TYPE (clast_name_to_gcc (t->var, region, newivs, |
586 sese region, VEC (tree, heap) *newivs, | 561 sese region, VEC (tree, heap) *newivs, |
587 htab_t newivs_index, htab_t params_index) | 562 htab_t newivs_index, htab_t params_index) |
588 { | 563 { |
589 switch (e->type) | 564 switch (e->type) |
590 { | 565 { |
591 case expr_term: | 566 case clast_expr_term: |
592 return gcc_type_for_clast_term ((struct clast_term *) e, region, | 567 return gcc_type_for_clast_term ((struct clast_term *) e, region, |
593 newivs, newivs_index, params_index); | 568 newivs, newivs_index, params_index); |
594 | 569 |
595 case expr_red: | 570 case clast_expr_red: |
596 return gcc_type_for_clast_red ((struct clast_reduction *) e, region, | 571 return gcc_type_for_clast_red ((struct clast_reduction *) e, region, |
597 newivs, newivs_index, params_index); | 572 newivs, newivs_index, params_index); |
598 | 573 |
599 case expr_bin: | 574 case clast_expr_bin: |
600 return gcc_type_for_clast_bin ((struct clast_binary *) e, region, | 575 return gcc_type_for_clast_bin ((struct clast_binary *) e, region, |
601 newivs, newivs_index, params_index); | 576 newivs, newivs_index, params_index); |
602 | 577 |
603 default: | 578 default: |
604 gcc_unreachable (); | 579 gcc_unreachable (); |
711 ppl_set_coef (le, 2 * level + 1, 1); | 686 ppl_set_coef (le, 2 * level + 1, 1); |
712 } | 687 } |
713 | 688 |
714 ppl_max_for_le_pointset (ps, le, up); | 689 ppl_max_for_le_pointset (ps, le, up); |
715 ppl_min_for_le_pointset (ps, le, low); | 690 ppl_min_for_le_pointset (ps, le, low); |
691 ppl_delete_Linear_Expression (le); | |
692 ppl_delete_Pointset_Powerset_C_Polyhedron (ps); | |
716 } | 693 } |
717 | 694 |
718 /* Compute the type for the induction variable at LEVEL for the | 695 /* Compute the type for the induction variable at LEVEL for the |
719 statement PBB, based on the transformed schedule of PBB. OLD_TYPE | 696 statement PBB, based on the transformed schedule of PBB. */ |
720 is the type of the old induction variable for that loop. */ | 697 |
721 | 698 static tree |
722 static tree | 699 compute_type_for_level (poly_bb_p pbb, int level) |
723 compute_type_for_level_1 (poly_bb_p pbb, int level, tree old_type) | |
724 { | 700 { |
725 mpz_t low, up; | 701 mpz_t low, up; |
726 tree type; | 702 tree type; |
727 | 703 |
728 value_init (low); | 704 mpz_init (low); |
729 value_init (up); | 705 mpz_init (up); |
730 | 706 |
731 compute_bounds_for_level (pbb, level, low, up); | 707 compute_bounds_for_level (pbb, level, low, up); |
732 type = gcc_type_for_interval (low, up, old_type); | 708 type = gcc_type_for_interval (low, up); |
733 | 709 |
734 value_clear (low); | 710 mpz_clear (low); |
735 value_clear (up); | 711 mpz_clear (up); |
736 return type; | 712 return type; |
737 } | |
738 | |
739 /* Compute the type for the induction variable at LEVEL for the | |
740 statement PBB, based on the transformed schedule of PBB. */ | |
741 | |
742 static tree | |
743 compute_type_for_level (poly_bb_p pbb, int level) | |
744 { | |
745 tree oldiv = pbb_to_depth_to_oldiv (pbb, level); | |
746 tree type = TREE_TYPE (oldiv); | |
747 | |
748 if (type && POINTER_TYPE_P (type)) | |
749 { | |
750 #ifdef ENABLE_CHECKING | |
751 tree ctype = compute_type_for_level_1 (pbb, level, type); | |
752 | |
753 /* In the case of a pointer type, check that after the loop | |
754 transform, the lower and the upper bounds of the type fit the | |
755 oldiv pointer type. */ | |
756 gcc_assert (TYPE_PRECISION (type) >= TYPE_PRECISION (ctype) | |
757 && integer_zerop (lower_bound_in_type (ctype, ctype))); | |
758 #endif | |
759 return type; | |
760 } | |
761 | |
762 return compute_type_for_level_1 (pbb, level, type); | |
763 } | 713 } |
764 | 714 |
765 /* Walks a CLAST and returns the first statement in the body of a | 715 /* Walks a CLAST and returns the first statement in the body of a |
766 loop. */ | 716 loop. */ |
767 | 717 |
837 VEC_length (tree, *newivs)); | 787 VEC_length (tree, *newivs)); |
838 VEC_safe_push (tree, heap, *newivs, iv); | 788 VEC_safe_push (tree, heap, *newivs, iv); |
839 return loop; | 789 return loop; |
840 } | 790 } |
841 | 791 |
842 /* Inserts in MAP a tuple (OLD_NAME, NEW_NAME) for the induction | 792 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the |
843 variables of the loops around GBB in SESE. */ | 793 induction variables of the loops around GBB in SESE. */ |
844 | 794 |
845 static void | 795 static void |
846 build_iv_mapping (htab_t map, sese region, | 796 build_iv_mapping (VEC (tree, heap) *iv_map, sese region, |
847 VEC (tree, heap) *newivs, htab_t newivs_index, | 797 VEC (tree, heap) *newivs, htab_t newivs_index, |
848 struct clast_user_stmt *user_stmt, | 798 struct clast_user_stmt *user_stmt, |
849 htab_t params_index) | 799 htab_t params_index) |
850 { | 800 { |
851 struct clast_stmt *t; | 801 struct clast_stmt *t; |
852 int index = 0; | 802 int depth = 0; |
853 CloogStatement *cs = user_stmt->statement; | 803 CloogStatement *cs = user_stmt->statement; |
854 poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs); | 804 poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs); |
855 | 805 gimple_bb_p gbb = PBB_BLACK_BOX (pbb); |
856 for (t = user_stmt->substitutions; t; t = t->next, index++) | 806 |
807 for (t = user_stmt->substitutions; t; t = t->next, depth++) | |
857 { | 808 { |
858 struct clast_expr *expr = (struct clast_expr *) | 809 struct clast_expr *expr = (struct clast_expr *) |
859 ((struct clast_assignment *)t)->RHS; | 810 ((struct clast_assignment *)t)->RHS; |
860 tree type = gcc_type_for_clast_expr (expr, region, newivs, | 811 tree type = gcc_type_for_clast_expr (expr, region, newivs, |
861 newivs_index, params_index); | 812 newivs_index, params_index); |
862 tree old_name = pbb_to_depth_to_oldiv (pbb, index); | 813 tree new_name = clast_to_gcc_expression (type, expr, region, newivs, |
863 tree e = clast_to_gcc_expression (type, expr, region, newivs, | 814 newivs_index, params_index); |
864 newivs_index, params_index); | 815 loop_p old_loop = gbb_loop_at_index (gbb, region, depth); |
865 set_rename (map, old_name, e); | 816 |
866 } | 817 VEC_replace (tree, iv_map, old_loop->num, new_name); |
867 } | 818 } |
868 | 819 } |
869 /* Helper function for htab_traverse. */ | 820 |
870 | 821 /* Construct bb_pbb_def with BB and PBB. */ |
871 static int | |
872 copy_renames (void **slot, void *s) | |
873 { | |
874 struct rename_map_elt_s *entry = (struct rename_map_elt_s *) *slot; | |
875 htab_t res = (htab_t) s; | |
876 tree old_name = entry->old_name; | |
877 tree expr = entry->expr; | |
878 struct rename_map_elt_s tmp; | |
879 PTR *x; | |
880 | |
881 tmp.old_name = old_name; | |
882 x = htab_find_slot (res, &tmp, INSERT); | |
883 | |
884 if (x && !*x) | |
885 *x = new_rename_map_elt (old_name, expr); | |
886 | |
887 return 1; | |
888 } | |
889 | |
890 /* Construct bb_pbb_def with BB and PBB. */ | |
891 | 822 |
892 static bb_pbb_def * | 823 static bb_pbb_def * |
893 new_bb_pbb_def (basic_block bb, poly_bb_p pbb) | 824 new_bb_pbb_def (basic_block bb, poly_bb_p pbb) |
894 { | 825 { |
895 bb_pbb_def *bb_pbb_p; | 826 bb_pbb_def *bb_pbb_p; |
968 free (bbs); | 899 free (bbs); |
969 | 900 |
970 return false; | 901 return false; |
971 } | 902 } |
972 | 903 |
973 static edge | |
974 translate_clast (sese, loop_p, struct clast_stmt *, edge, htab_t, | |
975 VEC (tree, heap) **, htab_t, htab_t, int, htab_t); | |
976 | |
977 /* Translates a clast user statement STMT to gimple. | 904 /* Translates a clast user statement STMT to gimple. |
978 | 905 |
979 - REGION is the sese region we used to generate the scop. | 906 - REGION is the sese region we used to generate the scop. |
980 - NEXT_E is the edge where new generated code should be attached. | 907 - NEXT_E is the edge where new generated code should be attached. |
981 - CONTEXT_LOOP is the loop in which the generated code will be placed | 908 - CONTEXT_LOOP is the loop in which the generated code will be placed |
982 - RENAME_MAP contains a set of tuples of new names associated to | |
983 the original variables names. | |
984 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. | 909 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. |
985 - PARAMS_INDEX connects the cloog parameters with the gimple parameters in | 910 - PARAMS_INDEX connects the cloog parameters with the gimple parameters in |
986 the sese region. */ | 911 the sese region. */ |
987 static edge | 912 static edge |
988 translate_clast_user (sese region, struct clast_user_stmt *stmt, edge next_e, | 913 translate_clast_user (sese region, struct clast_user_stmt *stmt, edge next_e, |
989 htab_t rename_map, VEC (tree, heap) **newivs, | 914 VEC (tree, heap) **newivs, |
990 htab_t newivs_index, htab_t bb_pbb_mapping, | 915 htab_t newivs_index, htab_t bb_pbb_mapping, |
991 htab_t params_index) | 916 htab_t params_index) |
992 { | 917 { |
993 gimple_bb_p gbb; | 918 int i, nb_loops; |
994 basic_block new_bb; | 919 basic_block new_bb; |
995 poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (stmt->statement); | 920 poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (stmt->statement); |
996 gbb = PBB_BLACK_BOX (pbb); | 921 gimple_bb_p gbb = PBB_BLACK_BOX (pbb); |
922 VEC (tree, heap) *iv_map; | |
997 | 923 |
998 if (GBB_BB (gbb) == ENTRY_BLOCK_PTR) | 924 if (GBB_BB (gbb) == ENTRY_BLOCK_PTR) |
999 return next_e; | 925 return next_e; |
1000 | 926 |
1001 build_iv_mapping (rename_map, region, *newivs, newivs_index, stmt, | 927 nb_loops = number_of_loops (); |
1002 params_index); | 928 iv_map = VEC_alloc (tree, heap, nb_loops); |
929 for (i = 0; i < nb_loops; i++) | |
930 VEC_quick_push (tree, iv_map, NULL_TREE); | |
931 | |
932 build_iv_mapping (iv_map, region, *newivs, newivs_index, stmt, params_index); | |
1003 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), region, | 933 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), region, |
1004 next_e, rename_map); | 934 next_e, iv_map); |
935 VEC_free (tree, heap, iv_map); | |
936 | |
1005 new_bb = next_e->src; | 937 new_bb = next_e->src; |
1006 mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping); | 938 mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping); |
1007 update_ssa (TODO_update_ssa); | 939 update_ssa (TODO_update_ssa); |
1008 | 940 |
1009 return next_e; | 941 return next_e; |
1010 } | 942 } |
1011 | 943 |
1012 /* Creates a new if region protecting the loop to be executed, if the execution | 944 /* Creates a new if region protecting the loop to be executed, if the execution |
1013 count is zero (lb > ub). */ | 945 count is zero (lb > ub). */ |
946 | |
1014 static edge | 947 static edge |
1015 graphite_create_new_loop_guard (sese region, edge entry_edge, | 948 graphite_create_new_loop_guard (sese region, edge entry_edge, |
1016 struct clast_for *stmt, | 949 struct clast_for *stmt, |
1017 VEC (tree, heap) *newivs, | 950 VEC (tree, heap) *newivs, |
1018 htab_t newivs_index, htab_t params_index) | 951 htab_t newivs_index, htab_t params_index) |
1026 tree type = max_precision_type (lb_type, ub_type); | 959 tree type = max_precision_type (lb_type, ub_type); |
1027 tree lb = clast_to_gcc_expression (type, stmt->LB, region, newivs, | 960 tree lb = clast_to_gcc_expression (type, stmt->LB, region, newivs, |
1028 newivs_index, params_index); | 961 newivs_index, params_index); |
1029 tree ub = clast_to_gcc_expression (type, stmt->UB, region, newivs, | 962 tree ub = clast_to_gcc_expression (type, stmt->UB, region, newivs, |
1030 newivs_index, params_index); | 963 newivs_index, params_index); |
1031 tree ub_one; | 964 /* When ub is simply a constant or a parameter, use lb <= ub. */ |
1032 | 965 if (TREE_CODE (ub) == INTEGER_CST || TREE_CODE (ub) == SSA_NAME) |
1033 /* Adding +1 and using LT_EXPR helps with loop latches that have a | |
1034 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes | |
1035 2^{32|64}, and the condition lb <= ub is true, even if we do not want this. | |
1036 However lb < ub + 1 is false, as expected. */ | |
1037 tree one; | |
1038 mpz_t gmp_one; | |
1039 | |
1040 mpz_init (gmp_one); | |
1041 mpz_set_si (gmp_one, 1); | |
1042 one = gmp_cst_to_tree (type, gmp_one); | |
1043 mpz_clear (gmp_one); | |
1044 | |
1045 ub_one = fold_build2 (POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR, | |
1046 type, ub, one); | |
1047 | |
1048 /* When ub + 1 wraps around, use lb <= ub. */ | |
1049 if (integer_zerop (ub_one)) | |
1050 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, lb, ub); | 966 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, lb, ub); |
1051 else | 967 else |
1052 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, lb, ub_one); | 968 { |
969 tree one = (POINTER_TYPE_P (type) | |
970 ? size_one_node | |
971 : fold_convert (type, integer_one_node)); | |
972 /* Adding +1 and using LT_EXPR helps with loop latches that have a | |
973 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes | |
974 2^k-1 due to integer overflow, and the condition lb <= ub is true, | |
975 even if we do not want this. However lb < ub + 1 is false, as | |
976 expected. */ | |
977 tree ub_one = fold_build2 (POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR | |
978 : PLUS_EXPR, type, ub, one); | |
979 | |
980 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, lb, ub_one); | |
981 } | |
1053 | 982 |
1054 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr); | 983 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr); |
1055 | 984 |
1056 return exit_edge; | 985 return exit_edge; |
1057 } | 986 } |
1058 | 987 |
988 static edge | |
989 translate_clast (sese, loop_p, struct clast_stmt *, edge, | |
990 VEC (tree, heap) **, htab_t, htab_t, int, htab_t); | |
1059 | 991 |
1060 /* Create the loop for a clast for statement. | 992 /* Create the loop for a clast for statement. |
1061 | 993 |
1062 - REGION is the sese region we used to generate the scop. | 994 - REGION is the sese region we used to generate the scop. |
1063 - NEXT_E is the edge where new generated code should be attached. | 995 - NEXT_E is the edge where new generated code should be attached. |
1064 - RENAME_MAP contains a set of tuples of new names associated to | |
1065 the original variables names. | |
1066 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. | 996 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. |
1067 - PARAMS_INDEX connects the cloog parameters with the gimple parameters in | 997 - PARAMS_INDEX connects the cloog parameters with the gimple parameters in |
1068 the sese region. */ | 998 the sese region. */ |
1069 static edge | 999 static edge |
1070 translate_clast_for_loop (sese region, loop_p context_loop, | 1000 translate_clast_for_loop (sese region, loop_p context_loop, |
1071 struct clast_for *stmt, edge next_e, | 1001 struct clast_for *stmt, edge next_e, |
1072 htab_t rename_map, VEC (tree, heap) **newivs, | 1002 VEC (tree, heap) **newivs, |
1073 htab_t newivs_index, htab_t bb_pbb_mapping, | 1003 htab_t newivs_index, htab_t bb_pbb_mapping, |
1074 int level, htab_t params_index) | 1004 int level, htab_t params_index) |
1075 { | 1005 { |
1076 struct loop *loop = graphite_create_new_loop (region, next_e, stmt, | 1006 struct loop *loop = graphite_create_new_loop (region, next_e, stmt, |
1077 context_loop, newivs, | 1007 context_loop, newivs, |
1083 | 1013 |
1084 /* Create a basic block for loop close phi nodes. */ | 1014 /* Create a basic block for loop close phi nodes. */ |
1085 last_e = single_succ_edge (split_edge (last_e)); | 1015 last_e = single_succ_edge (split_edge (last_e)); |
1086 | 1016 |
1087 /* Translate the body of the loop. */ | 1017 /* Translate the body of the loop. */ |
1088 next_e = translate_clast (region, loop, stmt->body, to_body, rename_map, | 1018 next_e = translate_clast (region, loop, stmt->body, to_body, |
1089 newivs, newivs_index, bb_pbb_mapping, level + 1, | 1019 newivs, newivs_index, bb_pbb_mapping, level + 1, |
1090 params_index); | 1020 params_index); |
1091 redirect_edge_succ_nodup (next_e, after); | 1021 redirect_edge_succ_nodup (next_e, after); |
1092 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src); | 1022 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src); |
1093 | 1023 |
1094 /* Remove from rename_map all the tuples containing variables | |
1095 defined in loop's body. */ | |
1096 insert_loop_close_phis (rename_map, loop); | |
1097 | |
1098 if (flag_loop_parallelize_all | 1024 if (flag_loop_parallelize_all |
1099 && !dependency_in_loop_p (loop, bb_pbb_mapping, | 1025 && !dependency_in_loop_p (loop, bb_pbb_mapping, |
1100 get_scattering_level (level))) | 1026 get_scattering_level (level))) |
1101 loop->can_be_parallel = true; | 1027 loop->can_be_parallel = true; |
1102 | 1028 |
1107 protecting the loop, if it is executed zero times. In this guard we create | 1033 protecting the loop, if it is executed zero times. In this guard we create |
1108 the real loop structure. | 1034 the real loop structure. |
1109 | 1035 |
1110 - REGION is the sese region we used to generate the scop. | 1036 - REGION is the sese region we used to generate the scop. |
1111 - NEXT_E is the edge where new generated code should be attached. | 1037 - NEXT_E is the edge where new generated code should be attached. |
1112 - RENAME_MAP contains a set of tuples of new names associated to | |
1113 the original variables names. | |
1114 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. | 1038 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. |
1115 - PARAMS_INDEX connects the cloog parameters with the gimple parameters in | 1039 - PARAMS_INDEX connects the cloog parameters with the gimple parameters in |
1116 the sese region. */ | 1040 the sese region. */ |
1117 static edge | 1041 static edge |
1118 translate_clast_for (sese region, loop_p context_loop, struct clast_for *stmt, | 1042 translate_clast_for (sese region, loop_p context_loop, struct clast_for *stmt, |
1119 edge next_e, htab_t rename_map, VEC (tree, heap) **newivs, | 1043 edge next_e, VEC (tree, heap) **newivs, |
1120 htab_t newivs_index, htab_t bb_pbb_mapping, int level, | 1044 htab_t newivs_index, htab_t bb_pbb_mapping, int level, |
1121 htab_t params_index) | 1045 htab_t params_index) |
1122 { | 1046 { |
1123 edge last_e = graphite_create_new_loop_guard (region, next_e, stmt, *newivs, | 1047 edge last_e = graphite_create_new_loop_guard (region, next_e, stmt, *newivs, |
1124 newivs_index, params_index); | 1048 newivs_index, params_index); |
1125 | |
1126 edge true_e = get_true_edge_from_guard_bb (next_e->dest); | 1049 edge true_e = get_true_edge_from_guard_bb (next_e->dest); |
1127 edge false_e = get_false_edge_from_guard_bb (next_e->dest); | 1050 |
1128 edge exit_true_e = single_succ_edge (true_e->dest); | 1051 translate_clast_for_loop (region, context_loop, stmt, true_e, newivs, |
1129 edge exit_false_e = single_succ_edge (false_e->dest); | 1052 newivs_index, bb_pbb_mapping, level, |
1130 | 1053 params_index); |
1131 htab_t before_guard = htab_create (10, rename_map_elt_info, | |
1132 eq_rename_map_elts, free); | |
1133 htab_traverse (rename_map, copy_renames, before_guard); | |
1134 | |
1135 next_e = translate_clast_for_loop (region, context_loop, stmt, true_e, | |
1136 rename_map, newivs, | |
1137 newivs_index, bb_pbb_mapping, level, | |
1138 params_index); | |
1139 | |
1140 insert_guard_phis (last_e->src, exit_true_e, exit_false_e, | |
1141 before_guard, rename_map); | |
1142 | |
1143 htab_delete (before_guard); | |
1144 | |
1145 return last_e; | 1054 return last_e; |
1146 } | 1055 } |
1147 | 1056 |
1148 /* Translates a clast guard statement STMT to gimple. | 1057 /* Translates a clast guard statement STMT to gimple. |
1149 | 1058 |
1150 - REGION is the sese region we used to generate the scop. | 1059 - REGION is the sese region we used to generate the scop. |
1151 - NEXT_E is the edge where new generated code should be attached. | 1060 - NEXT_E is the edge where new generated code should be attached. |
1152 - CONTEXT_LOOP is the loop in which the generated code will be placed | 1061 - CONTEXT_LOOP is the loop in which the generated code will be placed |
1153 - RENAME_MAP contains a set of tuples of new names associated to | |
1154 the original variables names. | |
1155 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. | 1062 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. |
1156 - PARAMS_INDEX connects the cloog parameters with the gimple parameters in | 1063 - PARAMS_INDEX connects the cloog parameters with the gimple parameters in |
1157 the sese region. */ | 1064 the sese region. */ |
1158 static edge | 1065 static edge |
1159 translate_clast_guard (sese region, loop_p context_loop, | 1066 translate_clast_guard (sese region, loop_p context_loop, |
1160 struct clast_guard *stmt, edge next_e, | 1067 struct clast_guard *stmt, edge next_e, |
1161 htab_t rename_map, VEC (tree, heap) **newivs, | 1068 VEC (tree, heap) **newivs, |
1162 htab_t newivs_index, htab_t bb_pbb_mapping, int level, | 1069 htab_t newivs_index, htab_t bb_pbb_mapping, int level, |
1163 htab_t params_index) | 1070 htab_t params_index) |
1164 { | 1071 { |
1165 edge last_e = graphite_create_new_guard (region, next_e, stmt, *newivs, | 1072 edge last_e = graphite_create_new_guard (region, next_e, stmt, *newivs, |
1166 newivs_index, params_index); | 1073 newivs_index, params_index); |
1167 | |
1168 edge true_e = get_true_edge_from_guard_bb (next_e->dest); | 1074 edge true_e = get_true_edge_from_guard_bb (next_e->dest); |
1169 edge false_e = get_false_edge_from_guard_bb (next_e->dest); | 1075 |
1170 edge exit_true_e = single_succ_edge (true_e->dest); | 1076 translate_clast (region, context_loop, stmt->then, true_e, |
1171 edge exit_false_e = single_succ_edge (false_e->dest); | 1077 newivs, newivs_index, bb_pbb_mapping, |
1172 | 1078 level, params_index); |
1173 htab_t before_guard = htab_create (10, rename_map_elt_info, | |
1174 eq_rename_map_elts, free); | |
1175 htab_traverse (rename_map, copy_renames, before_guard); | |
1176 | |
1177 next_e = translate_clast (region, context_loop, stmt->then, true_e, | |
1178 rename_map, newivs, newivs_index, bb_pbb_mapping, | |
1179 level, params_index); | |
1180 | |
1181 insert_guard_phis (last_e->src, exit_true_e, exit_false_e, | |
1182 before_guard, rename_map); | |
1183 | |
1184 htab_delete (before_guard); | |
1185 | |
1186 return last_e; | 1079 return last_e; |
1187 } | 1080 } |
1188 | 1081 |
1189 /* Translates a CLAST statement STMT to GCC representation in the | 1082 /* Translates a CLAST statement STMT to GCC representation in the |
1190 context of a SESE. | 1083 context of a SESE. |
1191 | 1084 |
1192 - NEXT_E is the edge where new generated code should be attached. | 1085 - NEXT_E is the edge where new generated code should be attached. |
1193 - CONTEXT_LOOP is the loop in which the generated code will be placed | 1086 - CONTEXT_LOOP is the loop in which the generated code will be placed |
1194 - RENAME_MAP contains a set of tuples of new names associated to | |
1195 the original variables names. | |
1196 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */ | 1087 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */ |
1197 static edge | 1088 static edge |
1198 translate_clast (sese region, loop_p context_loop, struct clast_stmt *stmt, | 1089 translate_clast (sese region, loop_p context_loop, struct clast_stmt *stmt, |
1199 edge next_e, htab_t rename_map, VEC (tree, heap) **newivs, | 1090 edge next_e, VEC (tree, heap) **newivs, |
1200 htab_t newivs_index, htab_t bb_pbb_mapping, int level, | 1091 htab_t newivs_index, htab_t bb_pbb_mapping, int level, |
1201 htab_t params_index) | 1092 htab_t params_index) |
1202 { | 1093 { |
1203 if (!stmt) | 1094 if (!stmt) |
1204 return next_e; | 1095 return next_e; |
1206 if (CLAST_STMT_IS_A (stmt, stmt_root)) | 1097 if (CLAST_STMT_IS_A (stmt, stmt_root)) |
1207 ; /* Do nothing. */ | 1098 ; /* Do nothing. */ |
1208 | 1099 |
1209 else if (CLAST_STMT_IS_A (stmt, stmt_user)) | 1100 else if (CLAST_STMT_IS_A (stmt, stmt_user)) |
1210 next_e = translate_clast_user (region, (struct clast_user_stmt *) stmt, | 1101 next_e = translate_clast_user (region, (struct clast_user_stmt *) stmt, |
1211 next_e, rename_map, newivs, newivs_index, | 1102 next_e, newivs, newivs_index, |
1212 bb_pbb_mapping, params_index); | 1103 bb_pbb_mapping, params_index); |
1213 | 1104 |
1214 else if (CLAST_STMT_IS_A (stmt, stmt_for)) | 1105 else if (CLAST_STMT_IS_A (stmt, stmt_for)) |
1215 next_e = translate_clast_for (region, context_loop, | 1106 next_e = translate_clast_for (region, context_loop, |
1216 (struct clast_for *) stmt, next_e, | 1107 (struct clast_for *) stmt, next_e, |
1217 rename_map, newivs, newivs_index, | 1108 newivs, newivs_index, |
1218 bb_pbb_mapping, level, params_index); | 1109 bb_pbb_mapping, level, params_index); |
1219 | 1110 |
1220 else if (CLAST_STMT_IS_A (stmt, stmt_guard)) | 1111 else if (CLAST_STMT_IS_A (stmt, stmt_guard)) |
1221 next_e = translate_clast_guard (region, context_loop, | 1112 next_e = translate_clast_guard (region, context_loop, |
1222 (struct clast_guard *) stmt, next_e, | 1113 (struct clast_guard *) stmt, next_e, |
1223 rename_map, newivs, newivs_index, | 1114 newivs, newivs_index, |
1224 bb_pbb_mapping, level, params_index); | 1115 bb_pbb_mapping, level, params_index); |
1225 | 1116 |
1226 else if (CLAST_STMT_IS_A (stmt, stmt_block)) | 1117 else if (CLAST_STMT_IS_A (stmt, stmt_block)) |
1227 next_e = translate_clast (region, context_loop, | 1118 next_e = translate_clast (region, context_loop, |
1228 ((struct clast_block *) stmt)->body, | 1119 ((struct clast_block *) stmt)->body, |
1229 next_e, rename_map, newivs, newivs_index, | 1120 next_e, newivs, newivs_index, |
1230 bb_pbb_mapping, level, params_index); | 1121 bb_pbb_mapping, level, params_index); |
1231 else | 1122 else |
1232 gcc_unreachable(); | 1123 gcc_unreachable(); |
1233 | 1124 |
1234 recompute_all_dominators (); | 1125 recompute_all_dominators (); |
1235 graphite_verify (); | 1126 graphite_verify (); |
1236 | 1127 |
1237 return translate_clast (region, context_loop, stmt->next, next_e, | 1128 return translate_clast (region, context_loop, stmt->next, next_e, |
1238 rename_map, newivs, newivs_index, | 1129 newivs, newivs_index, |
1239 bb_pbb_mapping, level, params_index); | 1130 bb_pbb_mapping, level, params_index); |
1240 } | 1131 } |
1241 | 1132 |
1242 /* Free the SCATTERING domain list. */ | 1133 /* Free the SCATTERING domain list. */ |
1243 | 1134 |
1244 static void | 1135 static void |
1245 free_scattering (CloogDomainList *scattering) | 1136 free_scattering (CloogScatteringList *scattering) |
1246 { | 1137 { |
1247 while (scattering) | 1138 while (scattering) |
1248 { | 1139 { |
1249 CloogDomain *dom = cloog_domain (scattering); | 1140 CloogScattering *dom = cloog_scattering (scattering); |
1250 CloogDomainList *next = cloog_next_domain (scattering); | 1141 CloogScatteringList *next = cloog_next_scattering (scattering); |
1251 | 1142 |
1252 cloog_domain_free (dom); | 1143 cloog_scattering_free (dom); |
1253 free (scattering); | 1144 free (scattering); |
1254 scattering = next; | 1145 scattering = next; |
1255 } | 1146 } |
1256 } | 1147 } |
1257 | 1148 |
1314 nb_scattering); | 1205 nb_scattering); |
1315 cloog_names_set_scattering (cloog_program_names (prog), | 1206 cloog_names_set_scattering (cloog_program_names (prog), |
1316 scattering); | 1207 scattering); |
1317 } | 1208 } |
1318 | 1209 |
1210 /* Initialize a CLooG input file. */ | |
1211 | |
1212 static FILE * | |
1213 init_cloog_input_file (int scop_number) | |
1214 { | |
1215 FILE *graphite_out_file; | |
1216 int len = strlen (dump_base_name); | |
1217 char *dumpname = XNEWVEC (char, len + 25); | |
1218 char *s_scop_number = XNEWVEC (char, 15); | |
1219 | |
1220 memcpy (dumpname, dump_base_name, len + 1); | |
1221 strip_off_ending (dumpname, len); | |
1222 sprintf (s_scop_number, ".%d", scop_number); | |
1223 strcat (dumpname, s_scop_number); | |
1224 strcat (dumpname, ".cloog"); | |
1225 graphite_out_file = fopen (dumpname, "w+b"); | |
1226 | |
1227 if (graphite_out_file == 0) | |
1228 fatal_error ("can%'t open %s for writing: %m", dumpname); | |
1229 | |
1230 free (dumpname); | |
1231 | |
1232 return graphite_out_file; | |
1233 } | |
1234 | |
1319 /* Build cloog program for SCoP. */ | 1235 /* Build cloog program for SCoP. */ |
1320 | 1236 |
1321 static void | 1237 static void |
1322 build_cloog_prog (scop_p scop, CloogProgram *prog) | 1238 build_cloog_prog (scop_p scop, CloogProgram *prog, |
1239 CloogOptions *options) | |
1323 { | 1240 { |
1324 int i; | 1241 int i; |
1325 int max_nb_loops = scop_max_loop_depth (scop); | 1242 int max_nb_loops = scop_max_loop_depth (scop); |
1326 poly_bb_p pbb; | 1243 poly_bb_p pbb; |
1327 CloogLoop *loop_list = NULL; | 1244 CloogLoop *loop_list = NULL; |
1328 CloogBlockList *block_list = NULL; | 1245 CloogBlockList *block_list = NULL; |
1329 CloogDomainList *scattering = NULL; | 1246 CloogScatteringList *scattering = NULL; |
1330 int nbs = 2 * max_nb_loops + 1; | 1247 int nbs = 2 * max_nb_loops + 1; |
1331 int *scaldims; | 1248 int *scaldims; |
1332 | 1249 |
1333 cloog_program_set_context | 1250 cloog_program_set_context |
1334 (prog, new_Cloog_Domain_from_ppl_Pointset_Powerset (SCOP_CONTEXT (scop))); | 1251 (prog, new_Cloog_Domain_from_ppl_Pointset_Powerset (SCOP_CONTEXT (scop), |
1252 scop_nb_params (scop), cloog_state)); | |
1335 nbs = unify_scattering_dimensions (scop); | 1253 nbs = unify_scattering_dimensions (scop); |
1336 scaldims = (int *) xmalloc (nbs * (sizeof (int))); | 1254 scaldims = (int *) xmalloc (nbs * (sizeof (int))); |
1337 cloog_program_set_nb_scattdims (prog, nbs); | 1255 cloog_program_set_nb_scattdims (prog, nbs); |
1338 initialize_cloog_names (scop, prog); | 1256 initialize_cloog_names (scop, prog); |
1339 | 1257 |
1340 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) | 1258 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb) |
1341 { | 1259 { |
1342 CloogStatement *stmt; | 1260 CloogStatement *stmt; |
1343 CloogBlock *block; | 1261 CloogBlock *block; |
1262 CloogDomain *dom; | |
1344 | 1263 |
1345 /* Dead code elimination: when the domain of a PBB is empty, | 1264 /* Dead code elimination: when the domain of a PBB is empty, |
1346 don't generate code for the PBB. */ | 1265 don't generate code for the PBB. */ |
1347 if (ppl_Pointset_Powerset_C_Polyhedron_is_empty (PBB_DOMAIN (pbb))) | 1266 if (ppl_Pointset_Powerset_C_Polyhedron_is_empty (PBB_DOMAIN (pbb))) |
1348 continue; | 1267 continue; |
1349 | 1268 |
1350 /* Build the new statement and its block. */ | 1269 /* Build the new statement and its block. */ |
1351 stmt = cloog_statement_alloc (pbb_index (pbb)); | 1270 stmt = cloog_statement_alloc (cloog_state, pbb_index (pbb)); |
1271 dom = new_Cloog_Domain_from_ppl_Pointset_Powerset (PBB_DOMAIN (pbb), | |
1272 scop_nb_params (scop), | |
1273 cloog_state); | |
1352 block = cloog_block_alloc (stmt, 0, NULL, pbb_dim_iter_domain (pbb)); | 1274 block = cloog_block_alloc (stmt, 0, NULL, pbb_dim_iter_domain (pbb)); |
1353 cloog_statement_set_usr (stmt, pbb); | 1275 cloog_statement_set_usr (stmt, pbb); |
1354 | 1276 |
1355 /* Build loop list. */ | 1277 /* Build loop list. */ |
1356 { | 1278 { |
1357 CloogLoop *new_loop_list = cloog_loop_malloc (); | 1279 CloogLoop *new_loop_list = cloog_loop_malloc (cloog_state); |
1358 cloog_loop_set_next (new_loop_list, loop_list); | 1280 cloog_loop_set_next (new_loop_list, loop_list); |
1359 cloog_loop_set_domain | 1281 cloog_loop_set_domain (new_loop_list, dom); |
1360 (new_loop_list, | |
1361 new_Cloog_Domain_from_ppl_Pointset_Powerset (PBB_DOMAIN (pbb))); | |
1362 cloog_loop_set_block (new_loop_list, block); | 1282 cloog_loop_set_block (new_loop_list, block); |
1363 loop_list = new_loop_list; | 1283 loop_list = new_loop_list; |
1364 } | 1284 } |
1365 | 1285 |
1366 /* Build block list. */ | 1286 /* Build block list. */ |
1373 } | 1293 } |
1374 | 1294 |
1375 /* Build scattering list. */ | 1295 /* Build scattering list. */ |
1376 { | 1296 { |
1377 /* XXX: Replace with cloog_domain_list_alloc(), when available. */ | 1297 /* XXX: Replace with cloog_domain_list_alloc(), when available. */ |
1378 CloogDomainList *new_scattering | 1298 CloogScatteringList *new_scattering |
1379 = (CloogDomainList *) xmalloc (sizeof (CloogDomainList)); | 1299 = (CloogScatteringList *) xmalloc (sizeof (CloogScatteringList)); |
1380 ppl_Polyhedron_t scat; | 1300 ppl_Polyhedron_t scat; |
1381 CloogDomain *dom; | 1301 CloogScattering *dom; |
1382 | 1302 |
1383 scat = PBB_TRANSFORMED_SCATTERING (pbb); | 1303 scat = PBB_TRANSFORMED_SCATTERING (pbb); |
1384 dom = new_Cloog_Domain_from_ppl_Polyhedron (scat); | 1304 dom = new_Cloog_Scattering_from_ppl_Polyhedron |
1385 | 1305 (scat, scop_nb_params (scop), pbb_nb_scattering_transform (pbb), |
1386 cloog_set_next_domain (new_scattering, scattering); | 1306 cloog_state); |
1387 cloog_set_domain (new_scattering, dom); | 1307 |
1308 cloog_set_next_scattering (new_scattering, scattering); | |
1309 cloog_set_scattering (new_scattering, dom); | |
1388 scattering = new_scattering; | 1310 scattering = new_scattering; |
1389 } | 1311 } |
1390 } | 1312 } |
1391 | 1313 |
1392 cloog_program_set_loop (prog, loop_list); | 1314 cloog_program_set_loop (prog, loop_list); |
1396 scaldims[i] = 0 ; | 1318 scaldims[i] = 0 ; |
1397 | 1319 |
1398 cloog_program_set_scaldims (prog, scaldims); | 1320 cloog_program_set_scaldims (prog, scaldims); |
1399 | 1321 |
1400 /* Extract scalar dimensions to simplify the code generation problem. */ | 1322 /* Extract scalar dimensions to simplify the code generation problem. */ |
1401 cloog_program_extract_scalars (prog, scattering); | 1323 cloog_program_extract_scalars (prog, scattering, options); |
1324 | |
1325 /* Dump a .cloog input file, if requested. This feature is only | |
1326 enabled in the Graphite branch. */ | |
1327 if (0) | |
1328 { | |
1329 static size_t file_scop_number = 0; | |
1330 FILE *cloog_file = init_cloog_input_file (file_scop_number); | |
1331 | |
1332 cloog_program_dump_cloog (cloog_file, prog, scattering); | |
1333 ++file_scop_number; | |
1334 } | |
1402 | 1335 |
1403 /* Apply scattering. */ | 1336 /* Apply scattering. */ |
1404 cloog_program_scatter (prog, scattering); | 1337 cloog_program_scatter (prog, scattering, options); |
1405 free_scattering (scattering); | 1338 free_scattering (scattering); |
1406 | 1339 |
1407 /* Iterators corresponding to scalar dimensions have to be extracted. */ | 1340 /* Iterators corresponding to scalar dimensions have to be extracted. */ |
1408 cloog_names_scalarize (cloog_program_names (prog), nbs, | 1341 cloog_names_scalarize (cloog_program_names (prog), nbs, |
1409 cloog_program_scaldims (prog)); | 1342 cloog_program_scaldims (prog)); |
1427 /* Return the options that will be used in GLOOG. */ | 1360 /* Return the options that will be used in GLOOG. */ |
1428 | 1361 |
1429 static CloogOptions * | 1362 static CloogOptions * |
1430 set_cloog_options (void) | 1363 set_cloog_options (void) |
1431 { | 1364 { |
1432 CloogOptions *options = cloog_options_malloc (); | 1365 CloogOptions *options = cloog_options_malloc (cloog_state); |
1433 | 1366 |
1434 /* Change cloog output language to C. If we do use FORTRAN instead, cloog | 1367 /* Change cloog output language to C. If we do use FORTRAN instead, cloog |
1435 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if | 1368 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if |
1436 we pass an incomplete program to cloog. */ | 1369 we pass an incomplete program to cloog. */ |
1437 options->language = LANGUAGE_C; | 1370 options->language = LANGUAGE_C; |
1440 (assignments) in the generated code which repeats the | 1373 (assignments) in the generated code which repeats the |
1441 substitution equations for statements. This is useless for | 1374 substitution equations for statements. This is useless for |
1442 GLooG. */ | 1375 GLooG. */ |
1443 options->esp = 1; | 1376 options->esp = 1; |
1444 | 1377 |
1378 #ifdef CLOOG_ORG | |
1379 /* Silence CLooG to avoid failing tests due to debug output to stderr. */ | |
1380 options->quiet = 1; | |
1381 #else | |
1445 /* Enable C pretty-printing mode: normalizes the substitution | 1382 /* Enable C pretty-printing mode: normalizes the substitution |
1446 equations for statements. */ | 1383 equations for statements. */ |
1447 options->cpp = 1; | 1384 options->cpp = 1; |
1385 #endif | |
1448 | 1386 |
1449 /* Allow cloog to build strides with a stride width different to one. | 1387 /* Allow cloog to build strides with a stride width different to one. |
1450 This example has stride = 4: | 1388 This example has stride = 4: |
1451 | 1389 |
1452 for (i = 0; i < 20; i += 4) | 1390 for (i = 0; i < 20; i += 4) |
1473 void | 1411 void |
1474 print_clast_stmt (FILE *file, struct clast_stmt *stmt) | 1412 print_clast_stmt (FILE *file, struct clast_stmt *stmt) |
1475 { | 1413 { |
1476 CloogOptions *options = set_cloog_options (); | 1414 CloogOptions *options = set_cloog_options (); |
1477 | 1415 |
1478 pprint (file, stmt, 0, options); | 1416 clast_pprint (file, stmt, 0, options); |
1479 cloog_options_free (options); | 1417 cloog_options_free (options); |
1480 } | 1418 } |
1481 | 1419 |
1482 /* Prints STMT to STDERR. */ | 1420 /* Prints STMT to STDERR. */ |
1483 | 1421 |
1484 void | 1422 DEBUG_FUNCTION void |
1485 debug_clast_stmt (struct clast_stmt *stmt) | 1423 debug_clast_stmt (struct clast_stmt *stmt) |
1486 { | 1424 { |
1487 print_clast_stmt (stderr, stmt); | 1425 print_clast_stmt (stderr, stmt); |
1488 } | 1426 } |
1489 | 1427 |
1497 CloogOptions *options = set_cloog_options (); | 1435 CloogOptions *options = set_cloog_options (); |
1498 cloog_prog_clast pc; | 1436 cloog_prog_clast pc; |
1499 | 1437 |
1500 /* Connect new cloog prog generation to graphite. */ | 1438 /* Connect new cloog prog generation to graphite. */ |
1501 pc.prog = cloog_program_malloc (); | 1439 pc.prog = cloog_program_malloc (); |
1502 build_cloog_prog (scop, pc.prog); | 1440 build_cloog_prog (scop, pc.prog, options); |
1503 pc.prog = cloog_program_generate (pc.prog, options); | 1441 pc.prog = cloog_program_generate (pc.prog, options); |
1504 pc.stmt = cloog_clast_create (pc.prog, options); | 1442 pc.stmt = cloog_clast_create (pc.prog, options); |
1505 | 1443 |
1506 cloog_options_free (options); | 1444 cloog_options_free (options); |
1507 return pc; | 1445 return pc; |
1511 | 1449 |
1512 void | 1450 void |
1513 print_generated_program (FILE *file, scop_p scop) | 1451 print_generated_program (FILE *file, scop_p scop) |
1514 { | 1452 { |
1515 CloogOptions *options = set_cloog_options (); | 1453 CloogOptions *options = set_cloog_options (); |
1454 | |
1516 cloog_prog_clast pc = scop_to_clast (scop); | 1455 cloog_prog_clast pc = scop_to_clast (scop); |
1517 | 1456 |
1518 fprintf (file, " (prog: \n"); | 1457 fprintf (file, " (prog: \n"); |
1519 cloog_program_print (file, pc.prog); | 1458 cloog_program_print (file, pc.prog); |
1520 fprintf (file, " )\n"); | 1459 fprintf (file, " )\n"); |
1521 | 1460 |
1522 fprintf (file, " (clast: \n"); | 1461 fprintf (file, " (clast: \n"); |
1523 pprint (file, pc.stmt, 0, options); | 1462 clast_pprint (file, pc.stmt, 0, options); |
1524 fprintf (file, " )\n"); | 1463 fprintf (file, " )\n"); |
1525 | 1464 |
1526 cloog_options_free (options); | 1465 cloog_options_free (options); |
1527 cloog_clast_free (pc.stmt); | 1466 cloog_clast_free (pc.stmt); |
1528 cloog_program_free (pc.prog); | 1467 cloog_program_free (pc.prog); |
1529 } | 1468 } |
1530 | 1469 |
1531 /* Prints to STDERR the code generated by CLooG for SCOP. */ | 1470 /* Prints to STDERR the code generated by CLooG for SCOP. */ |
1532 | 1471 |
1533 void | 1472 DEBUG_FUNCTION void |
1534 debug_generated_program (scop_p scop) | 1473 debug_generated_program (scop_p scop) |
1535 { | 1474 { |
1536 print_generated_program (stderr, scop); | 1475 print_generated_program (stderr, scop); |
1537 } | 1476 } |
1538 | 1477 |
1554 the given SCOP. Return true if code generation succeeded. | 1493 the given SCOP. Return true if code generation succeeded. |
1555 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping. | 1494 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping. |
1556 */ | 1495 */ |
1557 | 1496 |
1558 bool | 1497 bool |
1559 gloog (scop_p scop, VEC (scop_p, heap) *scops, htab_t bb_pbb_mapping) | 1498 gloog (scop_p scop, htab_t bb_pbb_mapping) |
1560 { | 1499 { |
1561 VEC (tree, heap) *newivs = VEC_alloc (tree, heap, 10); | 1500 VEC (tree, heap) *newivs = VEC_alloc (tree, heap, 10); |
1562 loop_p context_loop; | 1501 loop_p context_loop; |
1563 sese region = SCOP_REGION (scop); | 1502 sese region = SCOP_REGION (scop); |
1564 ifsese if_region = NULL; | 1503 ifsese if_region = NULL; |
1565 htab_t rename_map, newivs_index, params_index; | 1504 htab_t newivs_index, params_index; |
1566 cloog_prog_clast pc; | 1505 cloog_prog_clast pc; |
1567 int i; | |
1568 | 1506 |
1569 timevar_push (TV_GRAPHITE_CODE_GEN); | 1507 timevar_push (TV_GRAPHITE_CODE_GEN); |
1570 gloog_error = false; | 1508 gloog_error = false; |
1571 | 1509 |
1572 pc = scop_to_clast (scop); | 1510 pc = scop_to_clast (scop); |
1588 if_region->true_region->exit); | 1526 if_region->true_region->exit); |
1589 recompute_all_dominators (); | 1527 recompute_all_dominators (); |
1590 graphite_verify (); | 1528 graphite_verify (); |
1591 | 1529 |
1592 context_loop = SESE_ENTRY (region)->src->loop_father; | 1530 context_loop = SESE_ENTRY (region)->src->loop_father; |
1593 rename_map = htab_create (10, rename_map_elt_info, eq_rename_map_elts, free); | |
1594 newivs_index = htab_create (10, clast_name_index_elt_info, | 1531 newivs_index = htab_create (10, clast_name_index_elt_info, |
1595 eq_clast_name_indexes, free); | 1532 eq_clast_name_indexes, free); |
1596 params_index = htab_create (10, clast_name_index_elt_info, | 1533 params_index = htab_create (10, clast_name_index_elt_info, |
1597 eq_clast_name_indexes, free); | 1534 eq_clast_name_indexes, free); |
1598 | 1535 |
1599 create_params_index (params_index, pc.prog); | 1536 create_params_index (params_index, pc.prog); |
1600 | 1537 |
1601 translate_clast (region, context_loop, pc.stmt, | 1538 translate_clast (region, context_loop, pc.stmt, |
1602 if_region->true_region->entry, | 1539 if_region->true_region->entry, |
1603 rename_map, &newivs, newivs_index, | 1540 &newivs, newivs_index, |
1604 bb_pbb_mapping, 1, params_index); | 1541 bb_pbb_mapping, 1, params_index); |
1605 graphite_verify (); | 1542 graphite_verify (); |
1606 sese_adjust_liveout_phis (region, rename_map, | 1543 scev_reset (); |
1607 if_region->region->exit->src, | |
1608 if_region->false_region->exit, | |
1609 if_region->true_region->exit); | |
1610 scev_reset_htab (); | |
1611 rename_nb_iterations (rename_map); | |
1612 | |
1613 for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++) | |
1614 rename_sese_parameters (rename_map, SCOP_REGION (scop)); | |
1615 | |
1616 recompute_all_dominators (); | 1544 recompute_all_dominators (); |
1617 graphite_verify (); | 1545 graphite_verify (); |
1618 | 1546 |
1619 if (gloog_error) | 1547 if (gloog_error) |
1620 set_ifsese_condition (if_region, integer_zero_node); | 1548 set_ifsese_condition (if_region, integer_zero_node); |
1621 | 1549 |
1622 free (if_region->true_region); | 1550 free (if_region->true_region); |
1623 free (if_region->region); | 1551 free (if_region->region); |
1624 free (if_region); | 1552 free (if_region); |
1625 | 1553 |
1626 htab_delete (rename_map); | |
1627 htab_delete (newivs_index); | 1554 htab_delete (newivs_index); |
1628 htab_delete (params_index); | 1555 htab_delete (params_index); |
1629 VEC_free (tree, heap, newivs); | 1556 VEC_free (tree, heap, newivs); |
1630 cloog_clast_free (pc.stmt); | 1557 cloog_clast_free (pc.stmt); |
1631 cloog_program_free (pc.prog); | 1558 cloog_program_free (pc.prog); |
1645 num_no_dependency); | 1572 num_no_dependency); |
1646 } | 1573 } |
1647 | 1574 |
1648 return !gloog_error; | 1575 return !gloog_error; |
1649 } | 1576 } |
1650 | |
1651 #endif | 1577 #endif |