2009-01-03 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / graphite.c
blobeda09f89471b25b834ed3a01e6d9671d8328ec5d
1 /* Gimple Represented as Polyhedra.
2 Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <sebastian.pop@inria.fr>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This pass converts GIMPLE to GRAPHITE, performs some loop
22 transformations and then converts the resulting representation back
23 to GIMPLE.
25 An early description of this pass can be found in the GCC Summit'06
26 paper "GRAPHITE: Polyhedral Analyses and Optimizations for GCC".
27 The wiki page http://gcc.gnu.org/wiki/Graphite contains pointers to
28 the related work.
30 One important document to read is CLooG's internal manual:
31 http://repo.or.cz/w/cloog-ppl.git?a=blob_plain;f=doc/cloog.texi;hb=HEAD
32 that describes the data structure of loops used in this file, and
33 the functions that are used for transforming the code. */
35 #include "config.h"
36 #include "system.h"
37 #include "coretypes.h"
38 #include "tm.h"
39 #include "ggc.h"
40 #include "tree.h"
41 #include "rtl.h"
42 #include "basic-block.h"
43 #include "diagnostic.h"
44 #include "tree-flow.h"
45 #include "toplev.h"
46 #include "tree-dump.h"
47 #include "timevar.h"
48 #include "cfgloop.h"
49 #include "tree-chrec.h"
50 #include "tree-data-ref.h"
51 #include "tree-scalar-evolution.h"
52 #include "tree-pass.h"
53 #include "domwalk.h"
54 #include "value-prof.h"
55 #include "pointer-set.h"
56 #include "gimple.h"
58 #ifdef HAVE_cloog
59 #include "cloog/cloog.h"
60 #include "graphite.h"
62 static VEC (scop_p, heap) *current_scops;
64 /* Converts a GMP constant V to a tree and returns it. */
66 static tree
67 gmp_cst_to_tree (tree type, Value v)
69 return build_int_cst (type, value_get_si (v));
72 /* Debug the list of old induction variables for this SCOP. */
74 void
75 debug_oldivs (scop_p scop)
77 int i;
78 name_tree oldiv;
80 fprintf (stderr, "Old IVs:");
82 for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, oldiv); i++)
84 fprintf (stderr, "(");
85 print_generic_expr (stderr, oldiv->t, 0);
86 fprintf (stderr, ", %s, %d)\n", oldiv->name, oldiv->loop->num);
88 fprintf (stderr, "\n");
91 /* Debug the loops around basic block GB. */
93 void
94 debug_loop_vec (graphite_bb_p gb)
96 int i;
97 loop_p loop;
99 fprintf (stderr, "Loop Vec:");
101 for (i = 0; VEC_iterate (loop_p, GBB_LOOPS (gb), i, loop); i++)
102 fprintf (stderr, "%d: %d, ", i, loop ? loop->num : -1);
104 fprintf (stderr, "\n");
107 /* Returns true if stack ENTRY is a constant. */
109 static bool
110 iv_stack_entry_is_constant (iv_stack_entry *entry)
112 return entry->kind == iv_stack_entry_const;
115 /* Returns true if stack ENTRY is an induction variable. */
117 static bool
118 iv_stack_entry_is_iv (iv_stack_entry *entry)
120 return entry->kind == iv_stack_entry_iv;
123 /* Push (IV, NAME) on STACK. */
125 static void
126 loop_iv_stack_push_iv (loop_iv_stack stack, tree iv, const char *name)
128 iv_stack_entry *entry = XNEW (iv_stack_entry);
129 name_tree named_iv = XNEW (struct name_tree);
131 named_iv->t = iv;
132 named_iv->name = name;
134 entry->kind = iv_stack_entry_iv;
135 entry->data.iv = named_iv;
137 VEC_safe_push (iv_stack_entry_p, heap, *stack, entry);
140 /* Inserts a CONSTANT in STACK at INDEX. */
142 static void
143 loop_iv_stack_insert_constant (loop_iv_stack stack, int index,
144 tree constant)
146 iv_stack_entry *entry = XNEW (iv_stack_entry);
148 entry->kind = iv_stack_entry_const;
149 entry->data.constant = constant;
151 VEC_safe_insert (iv_stack_entry_p, heap, *stack, index, entry);
154 /* Pops and frees an element out of STACK. */
156 static void
157 loop_iv_stack_pop (loop_iv_stack stack)
159 iv_stack_entry_p entry = VEC_pop (iv_stack_entry_p, *stack);
161 free (entry->data.iv);
162 free (entry);
165 /* Get the IV at INDEX in STACK. */
167 static tree
168 loop_iv_stack_get_iv (loop_iv_stack stack, int index)
170 iv_stack_entry_p entry = VEC_index (iv_stack_entry_p, *stack, index);
171 iv_stack_entry_data data = entry->data;
173 return iv_stack_entry_is_iv (entry) ? data.iv->t : data.constant;
176 /* Get the IV from its NAME in STACK. */
178 static tree
179 loop_iv_stack_get_iv_from_name (loop_iv_stack stack, const char* name)
181 int i;
182 iv_stack_entry_p entry;
184 for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry); i++)
186 name_tree iv = entry->data.iv;
187 if (!strcmp (name, iv->name))
188 return iv->t;
191 return NULL;
194 /* Prints on stderr the contents of STACK. */
196 void
197 debug_loop_iv_stack (loop_iv_stack stack)
199 int i;
200 iv_stack_entry_p entry;
201 bool first = true;
203 fprintf (stderr, "(");
205 for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry); i++)
207 if (first)
208 first = false;
209 else
210 fprintf (stderr, " ");
212 if (iv_stack_entry_is_iv (entry))
214 name_tree iv = entry->data.iv;
215 fprintf (stderr, "%s:", iv->name);
216 print_generic_expr (stderr, iv->t, 0);
218 else
220 tree constant = entry->data.constant;
221 print_generic_expr (stderr, constant, 0);
222 fprintf (stderr, ":");
223 print_generic_expr (stderr, constant, 0);
227 fprintf (stderr, ")\n");
230 /* Frees STACK. */
232 static void
233 free_loop_iv_stack (loop_iv_stack stack)
235 int i;
236 iv_stack_entry_p entry;
238 for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry); i++)
240 free (entry->data.iv);
241 free (entry);
244 VEC_free (iv_stack_entry_p, heap, *stack);
249 /* Structure containing the mapping between the CLooG's induction
250 variable and the type of the old induction variable. */
251 typedef struct ivtype_map_elt
253 tree type;
254 const char *cloog_iv;
255 } *ivtype_map_elt;
257 /* Print to stderr the element ELT. */
259 static void
260 debug_ivtype_elt (ivtype_map_elt elt)
262 fprintf (stderr, "(%s, ", elt->cloog_iv);
263 print_generic_expr (stderr, elt->type, 0);
264 fprintf (stderr, ")\n");
267 /* Helper function for debug_ivtype_map. */
269 static int
270 debug_ivtype_map_1 (void **slot, void *s ATTRIBUTE_UNUSED)
272 struct ivtype_map_elt *entry = (struct ivtype_map_elt *) *slot;
273 debug_ivtype_elt (entry);
274 return 1;
277 /* Print to stderr all the elements of MAP. */
279 void
280 debug_ivtype_map (htab_t map)
282 htab_traverse (map, debug_ivtype_map_1, NULL);
285 /* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW. */
287 static inline ivtype_map_elt
288 new_ivtype_map_elt (const char *cloog_iv, tree type)
290 ivtype_map_elt res;
292 res = XNEW (struct ivtype_map_elt);
293 res->cloog_iv = cloog_iv;
294 res->type = type;
296 return res;
299 /* Computes a hash function for database element ELT. */
301 static hashval_t
302 ivtype_map_elt_info (const void *elt)
304 return htab_hash_pointer (((const struct ivtype_map_elt *) elt)->cloog_iv);
307 /* Compares database elements E1 and E2. */
309 static int
310 eq_ivtype_map_elts (const void *e1, const void *e2)
312 const struct ivtype_map_elt *elt1 = (const struct ivtype_map_elt *) e1;
313 const struct ivtype_map_elt *elt2 = (const struct ivtype_map_elt *) e2;
315 return (elt1->cloog_iv == elt2->cloog_iv);
320 /* Given a CLOOG_IV, returns the type that it should have in GCC land.
321 If the information is not available, i.e. in the case one of the
322 transforms created the loop, just return integer_type_node. */
324 static tree
325 gcc_type_for_cloog_iv (const char *cloog_iv, graphite_bb_p gbb)
327 struct ivtype_map_elt tmp;
328 PTR *slot;
330 tmp.cloog_iv = cloog_iv;
331 slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, NO_INSERT);
333 if (slot && *slot)
334 return ((ivtype_map_elt) *slot)->type;
336 return integer_type_node;
339 /* Inserts constants derived from the USER_STMT argument list into the
340 STACK. This is needed to map old ivs to constants when loops have
341 been eliminated. */
343 static void
344 loop_iv_stack_patch_for_consts (loop_iv_stack stack,
345 struct clast_user_stmt *user_stmt)
347 struct clast_stmt *t;
348 int index = 0;
349 CloogStatement *cs = user_stmt->statement;
350 graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
352 for (t = user_stmt->substitutions; t; t = t->next)
354 struct clast_expr *expr = (struct clast_expr *)
355 ((struct clast_assignment *)t)->RHS;
356 struct clast_term *term = (struct clast_term *) expr;
358 /* FIXME: What should be done with expr_bin, expr_red? */
359 if (expr->type == expr_term
360 && !term->var)
362 loop_p loop = gbb_loop_at_index (gbb, index);
363 tree oldiv = oldiv_for_loop (GBB_SCOP (gbb), loop);
364 tree type = oldiv ? TREE_TYPE (oldiv) : integer_type_node;
365 tree value = gmp_cst_to_tree (type, term->val);
366 loop_iv_stack_insert_constant (stack, index, value);
368 index = index + 1;
372 /* Removes all constants in the iv STACK. */
374 static void
375 loop_iv_stack_remove_constants (loop_iv_stack stack)
377 int i;
378 iv_stack_entry *entry;
380 for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry);)
382 if (iv_stack_entry_is_constant (entry))
384 free (VEC_index (iv_stack_entry_p, *stack, i));
385 VEC_ordered_remove (iv_stack_entry_p, *stack, i);
387 else
388 i++;
392 /* Returns a new loop_to_cloog_loop_str structure. */
394 static inline struct loop_to_cloog_loop_str *
395 new_loop_to_cloog_loop_str (int loop_num,
396 int loop_position,
397 CloogLoop *cloog_loop)
399 struct loop_to_cloog_loop_str *result;
401 result = XNEW (struct loop_to_cloog_loop_str);
402 result->loop_num = loop_num;
403 result->cloog_loop = cloog_loop;
404 result->loop_position = loop_position;
406 return result;
409 /* Hash function for SCOP_LOOP2CLOOG_LOOP hash table. */
411 static hashval_t
412 hash_loop_to_cloog_loop (const void *elt)
414 return ((const struct loop_to_cloog_loop_str *) elt)->loop_num;
417 /* Equality function for SCOP_LOOP2CLOOG_LOOP hash table. */
419 static int
420 eq_loop_to_cloog_loop (const void *el1, const void *el2)
422 const struct loop_to_cloog_loop_str *elt1, *elt2;
424 elt1 = (const struct loop_to_cloog_loop_str *) el1;
425 elt2 = (const struct loop_to_cloog_loop_str *) el2;
426 return elt1->loop_num == elt2->loop_num;
429 /* Compares two graphite bbs and returns an integer less than, equal to, or
430 greater than zero if the first argument is considered to be respectively
431 less than, equal to, or greater than the second.
432 We compare using the lexicographic order of the static schedules. */
434 static int
435 gbb_compare (const void *p_1, const void *p_2)
437 const struct graphite_bb *const gbb_1
438 = *(const struct graphite_bb *const*) p_1;
439 const struct graphite_bb *const gbb_2
440 = *(const struct graphite_bb *const*) p_2;
442 return lambda_vector_compare (GBB_STATIC_SCHEDULE (gbb_1),
443 gbb_nb_loops (gbb_1) + 1,
444 GBB_STATIC_SCHEDULE (gbb_2),
445 gbb_nb_loops (gbb_2) + 1);
448 /* Sort graphite bbs in SCOP. */
450 static void
451 graphite_sort_gbbs (scop_p scop)
453 VEC (graphite_bb_p, heap) *bbs = SCOP_BBS (scop);
455 qsort (VEC_address (graphite_bb_p, bbs),
456 VEC_length (graphite_bb_p, bbs),
457 sizeof (graphite_bb_p), gbb_compare);
460 /* Dump conditions of a graphite basic block GBB on FILE. */
462 static void
463 dump_gbb_conditions (FILE *file, graphite_bb_p gbb)
465 int i;
466 gimple stmt;
467 VEC (gimple, heap) *conditions = GBB_CONDITIONS (gbb);
469 if (VEC_empty (gimple, conditions))
470 return;
472 fprintf (file, "\tbb %d\t: cond = {", GBB_BB (gbb)->index);
474 for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
475 print_gimple_stmt (file, stmt, 0, 0);
477 fprintf (file, "}\n");
480 /* Converts the graphite scheduling function into a cloog scattering
481 matrix. This scattering matrix is used to limit the possible cloog
482 output to valid programs in respect to the scheduling function.
484 SCATTERING_DIMENSIONS specifies the dimensionality of the scattering
485 matrix. CLooG 0.14.0 and previous versions require, that all scattering
486 functions of one CloogProgram have the same dimensionality, therefore we
487 allow to specify it. (Should be removed in future versions) */
489 static CloogMatrix *
490 schedule_to_scattering (graphite_bb_p gb, int scattering_dimensions)
492 int i;
493 scop_p scop = GBB_SCOP (gb);
495 int nb_iterators = gbb_nb_loops (gb);
497 /* The cloog scattering matrix consists of these colums:
498 1 col = Eq/Inq,
499 scattering_dimensions cols = Scattering dimensions,
500 nb_iterators cols = bb's iterators,
501 scop_nb_params cols = Parameters,
502 1 col = Constant 1.
504 Example:
506 scattering_dimensions = 5
507 max_nb_iterators = 2
508 nb_iterators = 1
509 scop_nb_params = 2
511 Schedule:
515 Scattering Matrix:
516 s1 s2 s3 s4 s5 i p1 p2 1
517 1 0 0 0 0 0 0 0 -4 = 0
518 0 1 0 0 0 -1 0 0 0 = 0
519 0 0 1 0 0 0 0 0 -5 = 0 */
520 int nb_params = scop_nb_params (scop);
521 int nb_cols = 1 + scattering_dimensions + nb_iterators + nb_params + 1;
522 int col_const = nb_cols - 1;
523 int col_iter_offset = 1 + scattering_dimensions;
525 CloogMatrix *scat = cloog_matrix_alloc (scattering_dimensions, nb_cols);
527 gcc_assert (scattering_dimensions >= nb_iterators * 2 + 1);
529 /* Initialize the identity matrix. */
530 for (i = 0; i < scattering_dimensions; i++)
531 value_set_si (scat->p[i][i + 1], 1);
533 /* Textual order outside the first loop */
534 value_set_si (scat->p[0][col_const], -GBB_STATIC_SCHEDULE (gb)[0]);
536 /* For all surrounding loops. */
537 for (i = 0; i < nb_iterators; i++)
539 int schedule = GBB_STATIC_SCHEDULE (gb)[i + 1];
541 /* Iterations of this loop. */
542 value_set_si (scat->p[2 * i + 1][col_iter_offset + i], -1);
544 /* Textual order inside this loop. */
545 value_set_si (scat->p[2 * i + 2][col_const], -schedule);
548 return scat;
551 /* Print the schedules of GB to FILE with INDENT white spaces before.
552 VERBOSITY determines how verbose the code pretty printers are. */
554 void
555 print_graphite_bb (FILE *file, graphite_bb_p gb, int indent, int verbosity)
557 CloogMatrix *scattering;
558 int i;
559 loop_p loop;
560 fprintf (file, "\nGBB (\n");
562 print_loops_bb (file, GBB_BB (gb), indent+2, verbosity);
564 if (GBB_DOMAIN (gb))
566 fprintf (file, " (domain: \n");
567 cloog_matrix_print (file, GBB_DOMAIN (gb));
568 fprintf (file, " )\n");
571 if (GBB_STATIC_SCHEDULE (gb))
573 fprintf (file, " (static schedule: ");
574 print_lambda_vector (file, GBB_STATIC_SCHEDULE (gb),
575 gbb_nb_loops (gb) + 1);
576 fprintf (file, " )\n");
579 if (GBB_LOOPS (gb))
581 fprintf (file, " (contained loops: \n");
582 for (i = 0; VEC_iterate (loop_p, GBB_LOOPS (gb), i, loop); i++)
583 if (loop == NULL)
584 fprintf (file, " iterator %d => NULL \n", i);
585 else
586 fprintf (file, " iterator %d => loop %d \n", i,
587 loop->num);
588 fprintf (file, " )\n");
591 if (GBB_DATA_REFS (gb))
592 dump_data_references (file, GBB_DATA_REFS (gb));
594 if (GBB_CONDITIONS (gb))
596 fprintf (file, " (conditions: \n");
597 dump_gbb_conditions (file, gb);
598 fprintf (file, " )\n");
601 if (GBB_SCOP (gb)
602 && GBB_STATIC_SCHEDULE (gb))
604 fprintf (file, " (scattering: \n");
605 scattering = schedule_to_scattering (gb, 2 * gbb_nb_loops (gb) + 1);
606 cloog_matrix_print (file, scattering);
607 cloog_matrix_free (scattering);
608 fprintf (file, " )\n");
611 fprintf (file, ")\n");
614 /* Print to STDERR the schedules of GB with VERBOSITY level. */
616 void
617 debug_gbb (graphite_bb_p gb, int verbosity)
619 print_graphite_bb (stderr, gb, 0, verbosity);
623 /* Print SCOP to FILE. VERBOSITY determines how verbose the pretty
624 printers are. */
626 static void
627 print_scop (FILE *file, scop_p scop, int verbosity)
629 if (scop == NULL)
630 return;
632 fprintf (file, "\nSCoP_%d_%d (\n",
633 SCOP_ENTRY (scop)->index, SCOP_EXIT (scop)->index);
635 fprintf (file, " (cloog: \n");
636 cloog_program_print (file, SCOP_PROG (scop));
637 fprintf (file, " )\n");
639 if (SCOP_BBS (scop))
641 graphite_bb_p gb;
642 int i;
644 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
645 print_graphite_bb (file, gb, 0, verbosity);
648 fprintf (file, ")\n");
651 /* Print all the SCOPs to FILE. VERBOSITY determines how verbose the
652 code pretty printers are. */
654 static void
655 print_scops (FILE *file, int verbosity)
657 int i;
658 scop_p scop;
660 for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
661 print_scop (file, scop, verbosity);
664 /* Debug SCOP. VERBOSITY determines how verbose the code pretty
665 printers are. */
667 void
668 debug_scop (scop_p scop, int verbosity)
670 print_scop (stderr, scop, verbosity);
673 /* Debug all SCOPs from CURRENT_SCOPS. VERBOSITY determines how
674 verbose the code pretty printers are. */
676 void
677 debug_scops (int verbosity)
679 print_scops (stderr, verbosity);
682 /* Pretty print to FILE the SCOP in DOT format. */
684 static void
685 dot_scop_1 (FILE *file, scop_p scop)
687 edge e;
688 edge_iterator ei;
689 basic_block bb;
690 basic_block entry = SCOP_ENTRY (scop);
691 basic_block exit = SCOP_EXIT (scop);
693 fprintf (file, "digraph SCoP_%d_%d {\n", entry->index,
694 exit->index);
696 FOR_ALL_BB (bb)
698 if (bb == entry)
699 fprintf (file, "%d [shape=triangle];\n", bb->index);
701 if (bb == exit)
702 fprintf (file, "%d [shape=box];\n", bb->index);
704 if (bb_in_scop_p (bb, scop))
705 fprintf (file, "%d [color=red];\n", bb->index);
707 FOR_EACH_EDGE (e, ei, bb->succs)
708 fprintf (file, "%d -> %d;\n", bb->index, e->dest->index);
711 fputs ("}\n\n", file);
714 /* Display SCOP using dotty. */
716 void
717 dot_scop (scop_p scop)
719 dot_scop_1 (stderr, scop);
722 /* Pretty print all SCoPs in DOT format and mark them with different colors.
723 If there are not enough colors, paint later SCoPs gray.
724 Special nodes:
725 - "*" after the node number: entry of a SCoP,
726 - "#" after the node number: exit of a SCoP,
727 - "()" entry or exit not part of SCoP. */
729 static void
730 dot_all_scops_1 (FILE *file)
732 basic_block bb;
733 edge e;
734 edge_iterator ei;
735 scop_p scop;
736 const char* color;
737 int i;
739 /* Disable debugging while printing graph. */
740 int tmp_dump_flags = dump_flags;
741 dump_flags = 0;
743 fprintf (file, "digraph all {\n");
745 FOR_ALL_BB (bb)
747 int part_of_scop = false;
749 /* Use HTML for every bb label. So we are able to print bbs
750 which are part of two different SCoPs, with two different
751 background colors. */
752 fprintf (file, "%d [label=<\n <TABLE BORDER=\"0\" CELLBORDER=\"1\" ",
753 bb->index);
754 fprintf (file, "CELLSPACING=\"0\">\n");
756 /* Select color for SCoP. */
757 for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
758 if (bb_in_scop_p (bb, scop)
759 || (SCOP_EXIT (scop) == bb)
760 || (SCOP_ENTRY (scop) == bb))
762 switch (i % 17)
764 case 0: /* red */
765 color = "#e41a1c";
766 break;
767 case 1: /* blue */
768 color = "#377eb8";
769 break;
770 case 2: /* green */
771 color = "#4daf4a";
772 break;
773 case 3: /* purple */
774 color = "#984ea3";
775 break;
776 case 4: /* orange */
777 color = "#ff7f00";
778 break;
779 case 5: /* yellow */
780 color = "#ffff33";
781 break;
782 case 6: /* brown */
783 color = "#a65628";
784 break;
785 case 7: /* rose */
786 color = "#f781bf";
787 break;
788 case 8:
789 color = "#8dd3c7";
790 break;
791 case 9:
792 color = "#ffffb3";
793 break;
794 case 10:
795 color = "#bebada";
796 break;
797 case 11:
798 color = "#fb8072";
799 break;
800 case 12:
801 color = "#80b1d3";
802 break;
803 case 13:
804 color = "#fdb462";
805 break;
806 case 14:
807 color = "#b3de69";
808 break;
809 case 15:
810 color = "#fccde5";
811 break;
812 case 16:
813 color = "#bc80bd";
814 break;
815 default: /* gray */
816 color = "#999999";
819 fprintf (file, " <TR><TD WIDTH=\"50\" BGCOLOR=\"%s\">", color);
821 if (!bb_in_scop_p (bb, scop))
822 fprintf (file, " (");
824 if (bb == SCOP_ENTRY (scop)
825 && bb == SCOP_EXIT (scop))
826 fprintf (file, " %d*# ", bb->index);
827 else if (bb == SCOP_ENTRY (scop))
828 fprintf (file, " %d* ", bb->index);
829 else if (bb == SCOP_EXIT (scop))
830 fprintf (file, " %d# ", bb->index);
831 else
832 fprintf (file, " %d ", bb->index);
834 if (!bb_in_scop_p (bb, scop))
835 fprintf (file, ")");
837 fprintf (file, "</TD></TR>\n");
838 part_of_scop = true;
841 if (!part_of_scop)
843 fprintf (file, " <TR><TD WIDTH=\"50\" BGCOLOR=\"#ffffff\">");
844 fprintf (file, " %d </TD></TR>\n", bb->index);
847 fprintf (file, " </TABLE>>, shape=box, style=\"setlinewidth(0)\"]\n");
850 FOR_ALL_BB (bb)
852 FOR_EACH_EDGE (e, ei, bb->succs)
853 fprintf (file, "%d -> %d;\n", bb->index, e->dest->index);
856 fputs ("}\n\n", file);
858 /* Enable debugging again. */
859 dump_flags = tmp_dump_flags;
862 /* Display all SCoPs using dotty. */
864 void
865 dot_all_scops (void)
867 /* When debugging, enable the following code. This cannot be used
868 in production compilers because it calls "system". */
869 #if 0
870 FILE *stream = fopen ("/tmp/allscops.dot", "w");
871 gcc_assert (stream);
873 dot_all_scops_1 (stream);
874 fclose (stream);
876 system ("dotty /tmp/allscops.dot");
877 #else
878 dot_all_scops_1 (stderr);
879 #endif
882 /* Returns the outermost loop in SCOP that contains BB. */
884 static struct loop *
885 outermost_loop_in_scop (scop_p scop, basic_block bb)
887 struct loop *nest;
889 nest = bb->loop_father;
890 while (loop_outer (nest) && loop_in_scop_p (loop_outer (nest), scop))
891 nest = loop_outer (nest);
893 return nest;
896 /* Returns the block preceding the entry of SCOP. */
898 static basic_block
899 block_before_scop (scop_p scop)
901 return SESE_ENTRY (SCOP_REGION (scop))->src;
904 /* Return true when EXPR is an affine function in LOOP with parameters
905 instantiated relative to SCOP_ENTRY. */
907 static bool
908 loop_affine_expr (basic_block scop_entry, struct loop *loop, tree expr)
910 int n = loop->num;
911 tree scev = analyze_scalar_evolution (loop, expr);
913 scev = instantiate_scev (scop_entry, loop, scev);
915 return (evolution_function_is_invariant_p (scev, n)
916 || evolution_function_is_affine_multivariate_p (scev, n));
919 /* Return false if the tree_code of the operand OP or any of its operands
920 is component_ref. */
922 static bool
923 exclude_component_ref (tree op)
925 int i;
926 int len;
928 if (op)
930 if (TREE_CODE (op) == COMPONENT_REF)
931 return false;
932 else
934 len = TREE_OPERAND_LENGTH (op);
935 for (i = 0; i < len; ++i)
937 if (!exclude_component_ref (TREE_OPERAND (op, i)))
938 return false;
943 return true;
946 /* Return true if the operand OP is simple. */
948 static bool
949 is_simple_operand (loop_p loop, gimple stmt, tree op)
951 /* It is not a simple operand when it is a declaration, */
952 if (DECL_P (op)
953 /* or a structure, */
954 || AGGREGATE_TYPE_P (TREE_TYPE (op))
955 /* or a memory access that cannot be analyzed by the data
956 reference analysis. */
957 || ((handled_component_p (op) || INDIRECT_REF_P (op))
958 && !stmt_simple_memref_p (loop, stmt, op)))
959 return false;
961 return exclude_component_ref (op);
964 /* Return true only when STMT is simple enough for being handled by
965 Graphite. This depends on SCOP_ENTRY, as the parametetrs are
966 initialized relatively to this basic block. */
968 static bool
969 stmt_simple_for_scop_p (basic_block scop_entry, gimple stmt)
971 basic_block bb = gimple_bb (stmt);
972 struct loop *loop = bb->loop_father;
974 /* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects.
975 Calls have side-effects, except those to const or pure
976 functions. */
977 if (gimple_has_volatile_ops (stmt)
978 || (gimple_code (stmt) == GIMPLE_CALL
979 && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
980 || (gimple_code (stmt) == GIMPLE_ASM))
981 return false;
983 switch (gimple_code (stmt))
985 case GIMPLE_RETURN:
986 case GIMPLE_LABEL:
987 return true;
989 case GIMPLE_COND:
991 tree op;
992 ssa_op_iter op_iter;
993 enum tree_code code = gimple_cond_code (stmt);
995 /* We can only handle this kind of conditional expressions.
996 For inequalities like "if (i != 3 * k)" we need unions of
997 polyhedrons. Expressions like "if (a)" or "if (a == 15)" need
998 them for the else branch. */
999 if (!(code == LT_EXPR
1000 || code == GT_EXPR
1001 || code == LE_EXPR
1002 || code == GE_EXPR))
1003 return false;
1005 if (!scop_entry)
1006 return false;
1008 FOR_EACH_SSA_TREE_OPERAND (op, stmt, op_iter, SSA_OP_ALL_USES)
1009 if (!loop_affine_expr (scop_entry, loop, op))
1010 return false;
1012 return true;
1015 case GIMPLE_ASSIGN:
1017 enum tree_code code = gimple_assign_rhs_code (stmt);
1019 switch (get_gimple_rhs_class (code))
1021 case GIMPLE_UNARY_RHS:
1022 case GIMPLE_SINGLE_RHS:
1023 return (is_simple_operand (loop, stmt, gimple_assign_lhs (stmt))
1024 && is_simple_operand (loop, stmt, gimple_assign_rhs1 (stmt)));
1026 case GIMPLE_BINARY_RHS:
1027 return (is_simple_operand (loop, stmt, gimple_assign_lhs (stmt))
1028 && is_simple_operand (loop, stmt, gimple_assign_rhs1 (stmt))
1029 && is_simple_operand (loop, stmt, gimple_assign_rhs2 (stmt)));
1031 case GIMPLE_INVALID_RHS:
1032 default:
1033 gcc_unreachable ();
1037 case GIMPLE_CALL:
1039 size_t i;
1040 size_t n = gimple_call_num_args (stmt);
1041 tree lhs = gimple_call_lhs (stmt);
1043 for (i = 0; i < n; i++)
1045 tree arg = gimple_call_arg (stmt, i);
1047 if (!(is_simple_operand (loop, stmt, lhs)
1048 && is_simple_operand (loop, stmt, arg)))
1049 return false;
1052 return true;
1055 default:
1056 /* These nodes cut a new scope. */
1057 return false;
1060 return false;
1063 /* Returns the statement of BB that contains a harmful operation: that
1064 can be a function call with side effects, the induction variables
1065 are not linear with respect to SCOP_ENTRY, etc. The current open
1066 scop should end before this statement. */
1068 static gimple
1069 harmful_stmt_in_bb (basic_block scop_entry, basic_block bb)
1071 gimple_stmt_iterator gsi;
1073 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1074 if (!stmt_simple_for_scop_p (scop_entry, gsi_stmt (gsi)))
1075 return gsi_stmt (gsi);
1077 return NULL;
1080 /* Returns true when BB will be represented in graphite. Return false
1081 for the basic blocks that contain code eliminated in the code
1082 generation pass: i.e. induction variables and exit conditions. */
1084 static bool
1085 graphite_stmt_p (scop_p scop, basic_block bb,
1086 VEC (data_reference_p, heap) *drs)
1088 gimple_stmt_iterator gsi;
1089 loop_p loop = bb->loop_father;
1091 if (VEC_length (data_reference_p, drs) > 0)
1092 return true;
1094 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1096 gimple stmt = gsi_stmt (gsi);
1098 switch (gimple_code (stmt))
1100 /* Control flow expressions can be ignored, as they are
1101 represented in the iteration domains and will be
1102 regenerated by graphite. */
1103 case GIMPLE_COND:
1104 case GIMPLE_GOTO:
1105 case GIMPLE_SWITCH:
1106 break;
1108 case GIMPLE_ASSIGN:
1110 tree var = gimple_assign_lhs (stmt);
1111 var = analyze_scalar_evolution (loop, var);
1112 var = instantiate_scev (block_before_scop (scop), loop, var);
1114 if (chrec_contains_undetermined (var))
1115 return true;
1117 break;
1120 default:
1121 return true;
1125 return false;
1128 /* Store the GRAPHITE representation of BB. */
1130 static void
1131 new_graphite_bb (scop_p scop, basic_block bb)
1133 struct graphite_bb *gbb;
1134 VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
1135 struct loop *nest = outermost_loop_in_scop (scop, bb);
1136 gimple_stmt_iterator gsi;
1138 bitmap_set_bit (SCOP_BBS_B (scop), bb->index);
1140 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1141 find_data_references_in_stmt (nest, gsi_stmt (gsi), &drs);
1143 if (!graphite_stmt_p (scop, bb, drs))
1145 free_data_refs (drs);
1146 return;
1149 gbb = XNEW (struct graphite_bb);
1150 bb->aux = gbb;
1151 GBB_BB (gbb) = bb;
1152 GBB_SCOP (gbb) = scop;
1153 GBB_DATA_REFS (gbb) = drs;
1154 GBB_DOMAIN (gbb) = NULL;
1155 GBB_CONDITIONS (gbb) = NULL;
1156 GBB_CONDITION_CASES (gbb) = NULL;
1157 GBB_LOOPS (gbb) = NULL;
1158 GBB_STATIC_SCHEDULE (gbb) = NULL;
1159 GBB_CLOOG_IV_TYPES (gbb) = NULL;
1160 VEC_safe_push (graphite_bb_p, heap, SCOP_BBS (scop), gbb);
1163 /* Frees GBB. */
1165 static void
1166 free_graphite_bb (struct graphite_bb *gbb)
1168 if (GBB_DOMAIN (gbb))
1169 cloog_matrix_free (GBB_DOMAIN (gbb));
1171 if (GBB_CLOOG_IV_TYPES (gbb))
1172 htab_delete (GBB_CLOOG_IV_TYPES (gbb));
1174 /* FIXME: free_data_refs is disabled for the moment, but should be
1175 enabled.
1177 free_data_refs (GBB_DATA_REFS (gbb)); */
1179 VEC_free (gimple, heap, GBB_CONDITIONS (gbb));
1180 VEC_free (gimple, heap, GBB_CONDITION_CASES (gbb));
1181 VEC_free (loop_p, heap, GBB_LOOPS (gbb));
1182 GBB_BB (gbb)->aux = 0;
1183 XDELETE (gbb);
1186 /* Register basic blocks belonging to a region in a pointer set. */
1188 static void
1189 register_bb_in_sese (basic_block entry_bb, basic_block exit_bb, sese region)
1191 edge_iterator ei;
1192 edge e;
1193 basic_block bb = entry_bb;
1195 FOR_EACH_EDGE (e, ei, bb->succs)
1197 if (!pointer_set_contains (SESE_REGION_BBS (region), e->dest) &&
1198 e->dest->index != exit_bb->index)
1200 pointer_set_insert (SESE_REGION_BBS (region), e->dest);
1201 register_bb_in_sese (e->dest, exit_bb, region);
1206 /* Creates a new scop starting with ENTRY. */
1208 static scop_p
1209 new_scop (edge entry, edge exit)
1211 scop_p scop = XNEW (struct scop);
1213 gcc_assert (entry && exit);
1215 SCOP_REGION (scop) = XNEW (struct sese);
1216 SESE_ENTRY (SCOP_REGION (scop)) = entry;
1217 SESE_EXIT (SCOP_REGION (scop)) = exit;
1218 SESE_REGION_BBS (SCOP_REGION (scop)) = pointer_set_create ();
1219 register_bb_in_sese (SCOP_ENTRY (scop), SCOP_EXIT (scop),
1220 SCOP_REGION (scop));
1221 SCOP_BBS (scop) = VEC_alloc (graphite_bb_p, heap, 3);
1222 SCOP_OLDIVS (scop) = VEC_alloc (name_tree, heap, 3);
1223 SCOP_BBS_B (scop) = BITMAP_ALLOC (NULL);
1224 SCOP_LOOPS (scop) = BITMAP_ALLOC (NULL);
1225 SCOP_LOOP_NEST (scop) = VEC_alloc (loop_p, heap, 3);
1226 SCOP_ADD_PARAMS (scop) = true;
1227 SCOP_PARAMS (scop) = VEC_alloc (name_tree, heap, 3);
1228 SCOP_PROG (scop) = cloog_program_malloc ();
1229 cloog_program_set_names (SCOP_PROG (scop), cloog_names_malloc ());
1230 SCOP_LOOP2CLOOG_LOOP (scop) = htab_create (10, hash_loop_to_cloog_loop,
1231 eq_loop_to_cloog_loop,
1232 free);
1233 return scop;
1236 /* Deletes SCOP. */
1238 static void
1239 free_scop (scop_p scop)
1241 int i;
1242 name_tree p;
1243 struct graphite_bb *gb;
1244 name_tree iv;
1246 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
1247 free_graphite_bb (gb);
1249 VEC_free (graphite_bb_p, heap, SCOP_BBS (scop));
1250 BITMAP_FREE (SCOP_BBS_B (scop));
1251 BITMAP_FREE (SCOP_LOOPS (scop));
1252 VEC_free (loop_p, heap, SCOP_LOOP_NEST (scop));
1254 for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, iv); i++)
1255 free (iv);
1256 VEC_free (name_tree, heap, SCOP_OLDIVS (scop));
1258 for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++)
1259 free (p);
1261 VEC_free (name_tree, heap, SCOP_PARAMS (scop));
1262 cloog_program_free (SCOP_PROG (scop));
1263 htab_delete (SCOP_LOOP2CLOOG_LOOP (scop));
1264 XDELETE (SCOP_REGION (scop));
1265 XDELETE (scop);
1268 /* Deletes all scops in SCOPS. */
1270 static void
1271 free_scops (VEC (scop_p, heap) *scops)
1273 int i;
1274 scop_p scop;
1276 for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++)
1277 free_scop (scop);
1279 VEC_free (scop_p, heap, scops);
1282 typedef enum gbb_type {
1283 GBB_UNKNOWN,
1284 GBB_LOOP_SING_EXIT_HEADER,
1285 GBB_LOOP_MULT_EXIT_HEADER,
1286 GBB_LOOP_EXIT,
1287 GBB_COND_HEADER,
1288 GBB_SIMPLE,
1289 GBB_LAST
1290 } gbb_type;
1292 /* Detect the type of BB. Loop headers are only marked, if they are
1293 new. This means their loop_father is different to LAST_LOOP.
1294 Otherwise they are treated like any other bb and their type can be
1295 any other type. */
1297 static gbb_type
1298 get_bb_type (basic_block bb, struct loop *last_loop)
1300 VEC (basic_block, heap) *dom;
1301 int nb_dom, nb_suc;
1302 struct loop *loop = bb->loop_father;
1304 /* Check, if we entry into a new loop. */
1305 if (loop != last_loop)
1307 if (single_exit (loop) != NULL)
1308 return GBB_LOOP_SING_EXIT_HEADER;
1309 else if (loop->num != 0)
1310 return GBB_LOOP_MULT_EXIT_HEADER;
1311 else
1312 return GBB_COND_HEADER;
1315 dom = get_dominated_by (CDI_DOMINATORS, bb);
1316 nb_dom = VEC_length (basic_block, dom);
1317 VEC_free (basic_block, heap, dom);
1319 if (nb_dom == 0)
1320 return GBB_LAST;
1322 nb_suc = VEC_length (edge, bb->succs);
1324 if (nb_dom == 1 && nb_suc == 1)
1325 return GBB_SIMPLE;
1327 return GBB_COND_HEADER;
1330 /* A SCoP detection region, defined using bbs as borders.
1331 All control flow touching this region, comes in passing basic_block ENTRY and
1332 leaves passing basic_block EXIT. By using bbs instead of edges for the
1333 borders we are able to represent also regions that do not have a single
1334 entry or exit edge.
1335 But as they have a single entry basic_block and a single exit basic_block, we
1336 are able to generate for every sd_region a single entry and exit edge.
1340 3 <- entry
1343 / \ This region contains: {3, 4, 5, 6, 7, 8}
1348 9 <- exit */
1351 typedef struct sd_region_p
1353 /* The entry bb dominates all bbs in the sd_region. It is part of the
1354 region. */
1355 basic_block entry;
1357 /* The exit bb postdominates all bbs in the sd_region, but is not
1358 part of the region. */
1359 basic_block exit;
1360 } sd_region;
1362 DEF_VEC_O(sd_region);
1363 DEF_VEC_ALLOC_O(sd_region, heap);
1366 /* Moves the scops from SOURCE to TARGET and clean up SOURCE. */
1368 static void
1369 move_sd_regions (VEC (sd_region, heap) **source, VEC (sd_region, heap) **target)
1371 sd_region *s;
1372 int i;
1374 for (i = 0; VEC_iterate (sd_region, *source, i, s); i++)
1375 VEC_safe_push (sd_region, heap, *target, s);
1377 VEC_free (sd_region, heap, *source);
1380 /* Store information needed by scopdet_* functions. */
1382 struct scopdet_info
1384 /* Where the last open scop would stop if the current BB is harmful. */
1385 basic_block last;
1387 /* Where the next scop would start if the current BB is harmful. */
1388 basic_block next;
1390 /* The bb or one of its children contains open loop exits. That means
1391 loop exit nodes that are not surrounded by a loop dominated by bb. */
1392 bool exits;
1394 /* The bb or one of its children contains only structures we can handle. */
1395 bool difficult;
1399 static struct scopdet_info build_scops_1 (basic_block, VEC (sd_region, heap) **,
1400 loop_p);
1402 /* Calculates BB infos. If bb is difficult we add valid SCoPs dominated by BB
1403 to SCOPS. TYPE is the gbb_type of BB. */
1405 static struct scopdet_info
1406 scopdet_basic_block_info (basic_block bb, VEC (sd_region, heap) **scops,
1407 gbb_type type)
1409 struct loop *loop = bb->loop_father;
1410 struct scopdet_info result;
1411 gimple stmt;
1413 /* XXX: ENTRY_BLOCK_PTR could be optimized in later steps. */
1414 stmt = harmful_stmt_in_bb (ENTRY_BLOCK_PTR, bb);
1415 result.difficult = (stmt != NULL);
1416 result.last = NULL;
1418 switch (type)
1420 case GBB_LAST:
1421 result.next = NULL;
1422 result.exits = false;
1423 result.last = bb;
1424 break;
1426 case GBB_SIMPLE:
1427 result.next = single_succ (bb);
1428 result.exits = false;
1429 result.last = bb;
1430 break;
1432 case GBB_LOOP_SING_EXIT_HEADER:
1434 VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap,3);
1435 struct scopdet_info sinfo;
1437 sinfo = build_scops_1 (bb, &tmp_scops, loop);
1439 result.last = single_exit (bb->loop_father)->src;
1440 result.next = single_exit (bb->loop_father)->dest;
1442 /* If we do not dominate result.next, remove it. It's either
1443 the EXIT_BLOCK_PTR, or another bb dominates it and will
1444 call the scop detection for this bb. */
1445 if (!dominated_by_p (CDI_DOMINATORS, result.next, bb))
1446 result.next = NULL;
1448 if (result.last->loop_father != loop)
1449 result.next = NULL;
1451 if (TREE_CODE (number_of_latch_executions (loop))
1452 == SCEV_NOT_KNOWN)
1453 result.difficult = true;
1455 if (sinfo.difficult)
1456 move_sd_regions (&tmp_scops, scops);
1457 else
1458 VEC_free (sd_region, heap, tmp_scops);
1460 result.exits = false;
1461 result.difficult |= sinfo.difficult;
1462 break;
1465 case GBB_LOOP_MULT_EXIT_HEADER:
1467 /* XXX: For now we just do not join loops with multiple exits. If the
1468 exits lead to the same bb it may be possible to join the loop. */
1469 VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap, 3);
1470 VEC (edge, heap) *exits = get_loop_exit_edges (loop);
1471 edge e;
1472 int i;
1473 build_scops_1 (bb, &tmp_scops, loop);
1475 /* Scan the code dominated by this loop. This means all bbs, that are
1476 are dominated by a bb in this loop, but are not part of this loop.
1478 The easiest case:
1479 - The loop exit destination is dominated by the exit sources.
1481 TODO: We miss here the more complex cases:
1482 - The exit destinations are dominated by another bb inside the
1483 loop.
1484 - The loop dominates bbs, that are not exit destinations. */
1485 for (i = 0; VEC_iterate (edge, exits, i, e); i++)
1486 if (e->src->loop_father == loop
1487 && dominated_by_p (CDI_DOMINATORS, e->dest, e->src))
1489 /* Pass loop_outer to recognize e->dest as loop header in
1490 build_scops_1. */
1491 if (e->dest->loop_father->header == e->dest)
1492 build_scops_1 (e->dest, &tmp_scops,
1493 loop_outer (e->dest->loop_father));
1494 else
1495 build_scops_1 (e->dest, &tmp_scops, e->dest->loop_father);
1498 result.next = NULL;
1499 result.last = NULL;
1500 result.difficult = true;
1501 result.exits = false;
1502 move_sd_regions (&tmp_scops, scops);
1503 VEC_free (edge, heap, exits);
1504 break;
1506 case GBB_COND_HEADER:
1508 VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap, 3);
1509 struct scopdet_info sinfo;
1510 VEC (basic_block, heap) *dominated;
1511 int i;
1512 basic_block dom_bb;
1513 basic_block last_bb = NULL;
1514 edge e;
1515 result.exits = false;
1517 /* First check the successors of BB, and check if it is possible to join
1518 the different branches. */
1519 for (i = 0; VEC_iterate (edge, bb->succs, i, e); i++)
1521 /* Ignore loop exits. They will be handled after the loop body. */
1522 if (is_loop_exit (loop, e->dest))
1524 result.exits = true;
1525 continue;
1528 /* Do not follow edges that lead to the end of the
1529 conditions block. For example, in
1532 | /|\
1533 | 1 2 |
1534 | | | |
1535 | 3 4 |
1536 | \|/
1539 the edge from 0 => 6. Only check if all paths lead to
1540 the same node 6. */
1542 if (!single_pred_p (e->dest))
1544 /* Check, if edge leads directly to the end of this
1545 condition. */
1546 if (!last_bb)
1548 last_bb = e->dest;
1551 if (e->dest != last_bb)
1552 result.difficult = true;
1554 continue;
1557 if (!dominated_by_p (CDI_DOMINATORS, e->dest, bb))
1559 result.difficult = true;
1560 continue;
1563 sinfo = build_scops_1 (e->dest, &tmp_scops, loop);
1565 result.exits |= sinfo.exits;
1566 result.last = sinfo.last;
1567 result.difficult |= sinfo.difficult;
1569 /* Checks, if all branches end at the same point.
1570 If that is true, the condition stays joinable.
1571 Have a look at the example above. */
1572 if (sinfo.last && single_succ_p (sinfo.last))
1574 basic_block next_tmp = single_succ (sinfo.last);
1576 if (!last_bb)
1577 last_bb = next_tmp;
1579 if (next_tmp != last_bb)
1580 result.difficult = true;
1582 else
1583 result.difficult = true;
1586 /* If the condition is joinable. */
1587 if (!result.exits && !result.difficult)
1589 /* Only return a next pointer if we dominate this pointer.
1590 Otherwise it will be handled by the bb dominating it. */
1591 if (dominated_by_p (CDI_DOMINATORS, last_bb, bb) && last_bb != bb)
1592 result.next = last_bb;
1593 else
1594 result.next = NULL;
1596 VEC_free (sd_region, heap, tmp_scops);
1597 break;
1600 /* Scan remaining bbs dominated by BB. */
1601 dominated = get_dominated_by (CDI_DOMINATORS, bb);
1603 for (i = 0; VEC_iterate (basic_block, dominated, i, dom_bb); i++)
1605 /* Ignore loop exits: they will be handled after the loop body. */
1606 if (loop_depth (find_common_loop (loop, dom_bb->loop_father))
1607 < loop_depth (loop))
1609 result.exits = true;
1610 continue;
1613 /* Ignore the bbs processed above. */
1614 if (single_pred_p (dom_bb) && single_pred (dom_bb) == bb)
1615 continue;
1617 if (loop_depth (loop) > loop_depth (dom_bb->loop_father))
1618 sinfo = build_scops_1 (dom_bb, &tmp_scops, loop_outer (loop));
1619 else
1620 sinfo = build_scops_1 (dom_bb, &tmp_scops, loop);
1623 result.exits |= sinfo.exits;
1624 result.difficult = true;
1625 result.last = NULL;
1628 VEC_free (basic_block, heap, dominated);
1630 result.next = NULL;
1631 move_sd_regions (&tmp_scops, scops);
1633 break;
1636 default:
1637 gcc_unreachable ();
1640 return result;
1643 /* Creates the SCoPs and writes entry and exit points for every SCoP. */
1645 static struct scopdet_info
1646 build_scops_1 (basic_block current, VEC (sd_region, heap) **scops, loop_p loop)
1648 bool in_scop = false;
1649 sd_region open_scop;
1650 struct scopdet_info sinfo;
1652 /* Initialize result. */
1653 struct scopdet_info result;
1654 result.exits = false;
1655 result.difficult = false;
1656 result.next = NULL;
1657 result.last = NULL;
1658 open_scop.entry = NULL;
1659 open_scop.exit = NULL;
1660 sinfo.last = NULL;
1662 /* Loop over the dominance tree. If we meet a difficult bb, close
1663 the current SCoP. Loop and condition header start a new layer,
1664 and can only be added if all bbs in deeper layers are simple. */
1665 while (current != NULL)
1667 sinfo = scopdet_basic_block_info (current, scops, get_bb_type (current,
1668 loop));
1670 if (!in_scop && !(sinfo.exits || sinfo.difficult))
1672 open_scop.entry = current;
1673 open_scop.exit = NULL;
1674 in_scop = true;
1676 else if (in_scop && (sinfo.exits || sinfo.difficult))
1678 open_scop.exit = current;
1679 VEC_safe_push (sd_region, heap, *scops, &open_scop);
1680 in_scop = false;
1683 result.difficult |= sinfo.difficult;
1684 result.exits |= sinfo.exits;
1686 current = sinfo.next;
1689 /* Try to close open_scop, if we are still in an open SCoP. */
1690 if (in_scop)
1692 int i;
1693 edge e;
1695 for (i = 0; VEC_iterate (edge, sinfo.last->succs, i, e); i++)
1696 if (dominated_by_p (CDI_POST_DOMINATORS, sinfo.last, e->dest))
1697 open_scop.exit = e->dest;
1699 if (!open_scop.exit && open_scop.entry != sinfo.last)
1700 open_scop.exit = sinfo.last;
1702 if (open_scop.exit)
1703 VEC_safe_push (sd_region, heap, *scops, &open_scop);
1707 result.last = sinfo.last;
1708 return result;
1711 /* Checks if a bb is contained in REGION. */
1713 static bool
1714 bb_in_sd_region (basic_block bb, sd_region *region)
1716 return dominated_by_p (CDI_DOMINATORS, bb, region->entry)
1717 && !(dominated_by_p (CDI_DOMINATORS, bb, region->exit)
1718 && !dominated_by_p (CDI_DOMINATORS, region->entry,
1719 region->exit));
1722 /* Returns the single entry edge of REGION, if it does not exits NULL. */
1724 static edge
1725 find_single_entry_edge (sd_region *region)
1727 edge e;
1728 edge_iterator ei;
1729 edge entry = NULL;
1731 FOR_EACH_EDGE (e, ei, region->entry->preds)
1732 if (!bb_in_sd_region (e->src, region))
1734 if (entry)
1736 entry = NULL;
1737 break;
1740 else
1741 entry = e;
1744 return entry;
1747 /* Returns the single exit edge of REGION, if it does not exits NULL. */
1749 static edge
1750 find_single_exit_edge (sd_region *region)
1752 edge e;
1753 edge_iterator ei;
1754 edge exit = NULL;
1756 FOR_EACH_EDGE (e, ei, region->exit->preds)
1757 if (bb_in_sd_region (e->src, region))
1759 if (exit)
1761 exit = NULL;
1762 break;
1765 else
1766 exit = e;
1769 return exit;
1772 /* Create a single entry edge for REGION. */
1774 static void
1775 create_single_entry_edge (sd_region *region)
1777 if (find_single_entry_edge (region))
1778 return;
1780 /* There are multiple predecessors for bb_3
1782 | 1 2
1783 | | /
1784 | |/
1785 | 3 <- entry
1786 | |\
1787 | | |
1788 | 4 ^
1789 | | |
1790 | |/
1793 There are two edges (1->3, 2->3), that point from outside into the region,
1794 and another one (5->3), a loop latch, lead to bb_3.
1796 We split bb_3.
1798 | 1 2
1799 | | /
1800 | |/
1801 |3.0
1802 | |\ (3.0 -> 3.1) = single entry edge
1803 |3.1 | <- entry
1804 | | |
1805 | | |
1806 | 4 ^
1807 | | |
1808 | |/
1811 If the loop is part of the SCoP, we have to redirect the loop latches.
1813 | 1 2
1814 | | /
1815 | |/
1816 |3.0
1817 | | (3.0 -> 3.1) = entry edge
1818 |3.1 <- entry
1819 | |\
1820 | | |
1821 | 4 ^
1822 | | |
1823 | |/
1824 | 5 */
1826 if (region->entry->loop_father->header != region->entry
1827 || dominated_by_p (CDI_DOMINATORS,
1828 loop_latch_edge (region->entry->loop_father)->src,
1829 region->exit))
1831 edge forwarder = split_block_after_labels (region->entry);
1832 region->entry = forwarder->dest;
1834 else
1835 /* This case is never executed, as the loop headers seem always to have a
1836 single edge pointing from outside into the loop. */
1837 gcc_unreachable ();
1839 #ifdef ENABLE_CHECKING
1840 gcc_assert (find_single_entry_edge (region));
1841 #endif
1844 /* Check if the sd_region, mentioned in EDGE, has no exit bb. */
1846 static bool
1847 sd_region_without_exit (edge e)
1849 sd_region *r = (sd_region *) e->aux;
1851 if (r)
1852 return r->exit == NULL;
1853 else
1854 return false;
1857 /* Create a single exit edge for REGION. */
1859 static void
1860 create_single_exit_edge (sd_region *region)
1862 edge e;
1863 edge_iterator ei;
1864 edge forwarder = NULL;
1865 basic_block exit;
1867 if (find_single_exit_edge (region))
1868 return;
1870 /* We create a forwarder bb (5) for all edges leaving this region
1871 (3->5, 4->5). All other edges leading to the same bb, are moved
1872 to a new bb (6). If these edges where part of another region (2->5)
1873 we update the region->exit pointer, of this region.
1875 To identify which edge belongs to which region we depend on the e->aux
1876 pointer in every edge. It points to the region of the edge or to NULL,
1877 if the edge is not part of any region.
1879 1 2 3 4 1->5 no region, 2->5 region->exit = 5,
1880 \| |/ 3->5 region->exit = NULL, 4->5 region->exit = NULL
1881 5 <- exit
1883 changes to
1885 1 2 3 4 1->6 no region, 2->6 region->exit = 6,
1886 | | \/ 3->5 no region, 4->5 no region,
1887 | | 5
1888 \| / 5->6 region->exit = 6
1891 Now there is only a single exit edge (5->6). */
1892 exit = region->exit;
1893 region->exit = NULL;
1894 forwarder = make_forwarder_block (exit, &sd_region_without_exit, NULL);
1896 /* Unmark the edges, that are no longer exit edges. */
1897 FOR_EACH_EDGE (e, ei, forwarder->src->preds)
1898 if (e->aux)
1899 e->aux = NULL;
1901 /* Mark the new exit edge. */
1902 single_succ_edge (forwarder->src)->aux = region;
1904 /* Update the exit bb of all regions, where exit edges lead to
1905 forwarder->dest. */
1906 FOR_EACH_EDGE (e, ei, forwarder->dest->preds)
1907 if (e->aux)
1908 ((sd_region *) e->aux)->exit = forwarder->dest;
1910 #ifdef ENABLE_CHECKING
1911 gcc_assert (find_single_exit_edge (region));
1912 #endif
1915 /* Unmark the exit edges of all REGIONS.
1916 See comment in "create_single_exit_edge". */
1918 static void
1919 unmark_exit_edges (VEC (sd_region, heap) *regions)
1921 int i;
1922 sd_region *s;
1923 edge e;
1924 edge_iterator ei;
1926 for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
1927 FOR_EACH_EDGE (e, ei, s->exit->preds)
1928 e->aux = NULL;
1932 /* Mark the exit edges of all REGIONS.
1933 See comment in "create_single_exit_edge". */
1935 static void
1936 mark_exit_edges (VEC (sd_region, heap) *regions)
1938 int i;
1939 sd_region *s;
1940 edge e;
1941 edge_iterator ei;
1943 for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
1944 FOR_EACH_EDGE (e, ei, s->exit->preds)
1945 if (bb_in_sd_region (e->src, s))
1946 e->aux = s;
1949 /* Free and compute again all the dominators information. */
1951 static inline void
1952 recompute_all_dominators (void)
1954 free_dominance_info (CDI_DOMINATORS);
1955 free_dominance_info (CDI_POST_DOMINATORS);
1956 calculate_dominance_info (CDI_DOMINATORS);
1957 calculate_dominance_info (CDI_POST_DOMINATORS);
1960 /* Verifies properties that GRAPHITE should maintain during translation. */
1962 static inline void
1963 graphite_verify (void)
1965 #ifdef ENABLE_CHECKING
1966 verify_loop_structure ();
1967 verify_dominators (CDI_DOMINATORS);
1968 verify_dominators (CDI_POST_DOMINATORS);
1969 verify_ssa (false);
1970 #endif
1973 /* Create for all scop regions a single entry and a single exit edge. */
1975 static void
1976 create_sese_edges (VEC (sd_region, heap) *regions)
1978 int i;
1979 sd_region *s;
1981 for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
1982 create_single_entry_edge (s);
1984 mark_exit_edges (regions);
1986 for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
1987 create_single_exit_edge (s);
1989 unmark_exit_edges (regions);
1991 #ifdef ENABLE_CHECKING
1992 verify_loop_structure ();
1993 verify_dominators (CDI_DOMINATORS);
1994 verify_ssa (false);
1995 #endif
1998 /* Create graphite SCoPs from an array of scop detection regions. */
2000 static void
2001 build_graphite_scops (VEC (sd_region, heap) *scop_regions)
2003 int i;
2004 sd_region *s;
2006 for (i = 0; VEC_iterate (sd_region, scop_regions, i, s); i++)
2008 edge entry = find_single_entry_edge (s);
2009 edge exit = find_single_exit_edge (s);
2010 scop_p scop = new_scop (entry, exit);
2011 VEC_safe_push (scop_p, heap, current_scops, scop);
2013 /* Are there overlapping SCoPs? */
2014 #ifdef ENABLE_CHECKING
2016 int j;
2017 sd_region *s2;
2019 for (j = 0; VEC_iterate (sd_region, scop_regions, j, s2); j++)
2020 if (s != s2)
2021 gcc_assert (!bb_in_sd_region (s->entry, s2));
2023 #endif
2027 /* Find static control parts. */
2029 static void
2030 build_scops (void)
2032 struct loop *loop = current_loops->tree_root;
2033 VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap, 3);
2035 build_scops_1 (single_succ (ENTRY_BLOCK_PTR), &tmp_scops, loop);
2036 create_sese_edges (tmp_scops);
2037 build_graphite_scops (tmp_scops);
2038 VEC_free (sd_region, heap, tmp_scops);
2041 /* Gather the basic blocks belonging to the SCOP. */
2043 static void
2044 build_scop_bbs (scop_p scop)
2046 basic_block *stack = XNEWVEC (basic_block, n_basic_blocks + 1);
2047 sbitmap visited = sbitmap_alloc (last_basic_block);
2048 int sp = 0;
2050 sbitmap_zero (visited);
2051 stack[sp++] = SCOP_ENTRY (scop);
2053 while (sp)
2055 basic_block bb = stack[--sp];
2056 int depth = loop_depth (bb->loop_father);
2057 int num = bb->loop_father->num;
2058 edge_iterator ei;
2059 edge e;
2061 /* Scop's exit is not in the scop. Exclude also bbs, which are
2062 dominated by the SCoP exit. These are e.g. loop latches. */
2063 if (TEST_BIT (visited, bb->index)
2064 || dominated_by_p (CDI_DOMINATORS, bb, SCOP_EXIT (scop))
2065 /* Every block in the scop is dominated by scop's entry. */
2066 || !dominated_by_p (CDI_DOMINATORS, bb, SCOP_ENTRY (scop)))
2067 continue;
2069 new_graphite_bb (scop, bb);
2070 SET_BIT (visited, bb->index);
2072 /* First push the blocks that have to be processed last. Note
2073 that this means that the order in which the code is organized
2074 below is important: do not reorder the following code. */
2075 FOR_EACH_EDGE (e, ei, bb->succs)
2076 if (! TEST_BIT (visited, e->dest->index)
2077 && (int) loop_depth (e->dest->loop_father) < depth)
2078 stack[sp++] = e->dest;
2080 FOR_EACH_EDGE (e, ei, bb->succs)
2081 if (! TEST_BIT (visited, e->dest->index)
2082 && (int) loop_depth (e->dest->loop_father) == depth
2083 && e->dest->loop_father->num != num)
2084 stack[sp++] = e->dest;
2086 FOR_EACH_EDGE (e, ei, bb->succs)
2087 if (! TEST_BIT (visited, e->dest->index)
2088 && (int) loop_depth (e->dest->loop_father) == depth
2089 && e->dest->loop_father->num == num
2090 && EDGE_COUNT (e->dest->preds) > 1)
2091 stack[sp++] = e->dest;
2093 FOR_EACH_EDGE (e, ei, bb->succs)
2094 if (! TEST_BIT (visited, e->dest->index)
2095 && (int) loop_depth (e->dest->loop_father) == depth
2096 && e->dest->loop_father->num == num
2097 && EDGE_COUNT (e->dest->preds) == 1)
2098 stack[sp++] = e->dest;
2100 FOR_EACH_EDGE (e, ei, bb->succs)
2101 if (! TEST_BIT (visited, e->dest->index)
2102 && (int) loop_depth (e->dest->loop_father) > depth)
2103 stack[sp++] = e->dest;
2106 free (stack);
2107 sbitmap_free (visited);
2110 /* Returns the number of reduction phi nodes in LOOP. */
2112 static int
2113 nb_reductions_in_loop (loop_p loop)
2115 int res = 0;
2116 gimple_stmt_iterator gsi;
2118 for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
2120 gimple phi = gsi_stmt (gsi);
2121 tree scev;
2122 affine_iv iv;
2124 if (!is_gimple_reg (PHI_RESULT (phi)))
2125 continue;
2127 scev = analyze_scalar_evolution (loop, PHI_RESULT (phi));
2128 scev = instantiate_parameters (loop, scev);
2129 if (!simple_iv (loop, phi, PHI_RESULT (phi), &iv, true))
2130 res++;
2133 return res;
2136 /* A LOOP is in normal form when it contains only one scalar phi node
2137 that defines the main induction variable of the loop, only one
2138 increment of the IV, and only one exit condition. */
2140 static tree
2141 graphite_loop_normal_form (loop_p loop)
2143 struct tree_niter_desc niter;
2144 tree nit;
2145 gimple_seq stmts;
2146 edge exit = single_dom_exit (loop);
2148 if (!number_of_iterations_exit (loop, exit, &niter, false))
2149 gcc_unreachable ();
2151 nit = force_gimple_operand (unshare_expr (niter.niter), &stmts, true,
2152 NULL_TREE);
2153 if (stmts)
2154 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
2156 /* One IV per loop. */
2157 if (nb_reductions_in_loop (loop) > 0)
2158 return NULL_TREE;
2160 return canonicalize_loop_ivs (loop, NULL, nit);
2163 /* Record LOOP as occuring in SCOP. Returns true when the operation
2164 was successful. */
2166 static bool
2167 scop_record_loop (scop_p scop, loop_p loop)
2169 tree induction_var;
2170 name_tree oldiv;
2172 if (bitmap_bit_p (SCOP_LOOPS (scop), loop->num))
2173 return true;
2175 bitmap_set_bit (SCOP_LOOPS (scop), loop->num);
2176 VEC_safe_push (loop_p, heap, SCOP_LOOP_NEST (scop), loop);
2178 induction_var = graphite_loop_normal_form (loop);
2179 if (!induction_var)
2180 return false;
2182 oldiv = XNEW (struct name_tree);
2183 oldiv->t = induction_var;
2184 oldiv->name = get_name (SSA_NAME_VAR (oldiv->t));
2185 oldiv->loop = loop;
2186 VEC_safe_push (name_tree, heap, SCOP_OLDIVS (scop), oldiv);
2187 return true;
2190 /* Build the loop nests contained in SCOP. Returns true when the
2191 operation was successful. */
2193 static bool
2194 build_scop_loop_nests (scop_p scop)
2196 unsigned i;
2197 basic_block bb;
2198 struct loop *loop0, *loop1;
2200 FOR_EACH_BB (bb)
2201 if (bb_in_scop_p (bb, scop))
2203 struct loop *loop = bb->loop_father;
2205 /* Only add loops if they are completely contained in the SCoP. */
2206 if (loop->header == bb
2207 && bb_in_scop_p (loop->latch, scop))
2209 if (!scop_record_loop (scop, loop))
2210 return false;
2214 /* Make sure that the loops in the SCOP_LOOP_NEST are ordered. It
2215 can be the case that an inner loop is inserted before an outer
2216 loop. To avoid this, semi-sort once. */
2217 for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop0); i++)
2219 if (VEC_length (loop_p, SCOP_LOOP_NEST (scop)) == i + 1)
2220 break;
2222 loop1 = VEC_index (loop_p, SCOP_LOOP_NEST (scop), i + 1);
2223 if (loop0->num > loop1->num)
2225 VEC_replace (loop_p, SCOP_LOOP_NEST (scop), i, loop1);
2226 VEC_replace (loop_p, SCOP_LOOP_NEST (scop), i + 1, loop0);
2230 return true;
2233 /* Build dynamic schedules for all the BBs. */
2235 static void
2236 build_scop_dynamic_schedules (scop_p scop)
2238 int i, dim, loop_num, row, col;
2239 graphite_bb_p gb;
2241 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
2243 loop_num = GBB_BB (gb)->loop_father->num;
2245 if (loop_num != 0)
2247 dim = nb_loops_around_gb (gb);
2248 GBB_DYNAMIC_SCHEDULE (gb) = cloog_matrix_alloc (dim, dim);
2250 for (row = 0; row < GBB_DYNAMIC_SCHEDULE (gb)->NbRows; row++)
2251 for (col = 0; col < GBB_DYNAMIC_SCHEDULE (gb)->NbColumns; col++)
2252 if (row == col)
2253 value_set_si (GBB_DYNAMIC_SCHEDULE (gb)->p[row][col], 1);
2254 else
2255 value_set_si (GBB_DYNAMIC_SCHEDULE (gb)->p[row][col], 0);
2257 else
2258 GBB_DYNAMIC_SCHEDULE (gb) = NULL;
2262 /* Build for BB the static schedule.
2264 The STATIC_SCHEDULE is defined like this:
2267 for (i: ...)
2269 for (j: ...)
2275 for (k: ...)
2283 Static schedules for A to F:
2285 DEPTH
2286 0 1 2
2288 B 1 0 0
2289 C 1 0 1
2290 D 1 1 0
2291 E 1 1 1
2295 static void
2296 build_scop_canonical_schedules (scop_p scop)
2298 int i, j;
2299 graphite_bb_p gb;
2300 int nb = scop_nb_loops (scop) + 1;
2302 SCOP_STATIC_SCHEDULE (scop) = lambda_vector_new (nb);
2304 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
2306 int offset = nb_loops_around_gb (gb);
2308 /* After leaving a loop, it is possible that the schedule is not
2309 set at zero. This loop reinitializes components located
2310 after OFFSET. */
2312 for (j = offset + 1; j < nb; j++)
2313 if (SCOP_STATIC_SCHEDULE (scop)[j])
2315 memset (&(SCOP_STATIC_SCHEDULE (scop)[j]), 0,
2316 sizeof (int) * (nb - j));
2317 ++SCOP_STATIC_SCHEDULE (scop)[offset];
2318 break;
2321 GBB_STATIC_SCHEDULE (gb) = lambda_vector_new (offset + 1);
2322 lambda_vector_copy (SCOP_STATIC_SCHEDULE (scop),
2323 GBB_STATIC_SCHEDULE (gb), offset + 1);
2325 ++SCOP_STATIC_SCHEDULE (scop)[offset];
2329 /* Build the LOOPS vector for all bbs in SCOP. */
2331 static void
2332 build_bb_loops (scop_p scop)
2334 graphite_bb_p gb;
2335 int i;
2337 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
2339 loop_p loop;
2340 int depth;
2342 depth = nb_loops_around_gb (gb) - 1;
2344 GBB_LOOPS (gb) = VEC_alloc (loop_p, heap, 3);
2345 VEC_safe_grow_cleared (loop_p, heap, GBB_LOOPS (gb), depth + 1);
2347 loop = GBB_BB (gb)->loop_father;
2349 while (scop_contains_loop (scop, loop))
2351 VEC_replace (loop_p, GBB_LOOPS (gb), depth, loop);
2352 loop = loop_outer (loop);
2353 depth--;
2358 /* Get the index for parameter VAR in SCOP. */
2360 static int
2361 param_index (tree var, scop_p scop)
2363 int i;
2364 name_tree p;
2365 name_tree nvar;
2367 gcc_assert (TREE_CODE (var) == SSA_NAME);
2369 for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++)
2370 if (p->t == var)
2371 return i;
2373 gcc_assert (SCOP_ADD_PARAMS (scop));
2375 nvar = XNEW (struct name_tree);
2376 nvar->t = var;
2377 nvar->name = NULL;
2378 VEC_safe_push (name_tree, heap, SCOP_PARAMS (scop), nvar);
2379 return VEC_length (name_tree, SCOP_PARAMS (scop)) - 1;
2382 /* Scan EXPR and translate it to an inequality vector INEQ that will
2383 be added, or subtracted, in the constraint domain matrix C at row
2384 R. K is the number of columns for loop iterators in C. */
2386 static void
2387 scan_tree_for_params (scop_p s, tree e, CloogMatrix *c, int r, Value k,
2388 bool subtract)
2390 int cst_col, param_col;
2392 if (e == chrec_dont_know)
2393 return;
2395 switch (TREE_CODE (e))
2397 case POLYNOMIAL_CHREC:
2399 tree left = CHREC_LEFT (e);
2400 tree right = CHREC_RIGHT (e);
2401 int var = CHREC_VARIABLE (e);
2403 if (TREE_CODE (right) != INTEGER_CST)
2404 return;
2406 if (c)
2408 int loop_col = scop_gimple_loop_depth (s, get_loop (var)) + 1;
2410 if (subtract)
2411 value_sub_int (c->p[r][loop_col], c->p[r][loop_col],
2412 int_cst_value (right));
2413 else
2414 value_add_int (c->p[r][loop_col], c->p[r][loop_col],
2415 int_cst_value (right));
2418 switch (TREE_CODE (left))
2420 case POLYNOMIAL_CHREC:
2421 scan_tree_for_params (s, left, c, r, k, subtract);
2422 return;
2424 case INTEGER_CST:
2425 /* Constant part. */
2426 if (c)
2428 int v = int_cst_value (left);
2429 cst_col = c->NbColumns - 1;
2431 if (v < 0)
2433 v = -v;
2434 subtract = subtract ? false : true;
2437 if (subtract)
2438 value_sub_int (c->p[r][cst_col], c->p[r][cst_col], v);
2439 else
2440 value_add_int (c->p[r][cst_col], c->p[r][cst_col], v);
2442 return;
2444 default:
2445 scan_tree_for_params (s, left, c, r, k, subtract);
2446 return;
2449 break;
2451 case MULT_EXPR:
2452 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
2454 if (c)
2456 Value val;
2457 gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0));
2458 value_init (val);
2459 value_set_si (val, int_cst_value (TREE_OPERAND (e, 1)));
2460 value_multiply (k, k, val);
2461 value_clear (val);
2463 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
2465 else
2467 if (c)
2469 Value val;
2470 gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0));
2471 value_init (val);
2472 value_set_si (val, int_cst_value (TREE_OPERAND (e, 0)));
2473 value_multiply (k, k, val);
2474 value_clear (val);
2476 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, subtract);
2478 break;
2480 case PLUS_EXPR:
2481 case POINTER_PLUS_EXPR:
2482 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
2483 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, subtract);
2484 break;
2486 case MINUS_EXPR:
2487 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
2488 value_oppose (k, k);
2489 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, subtract);
2490 break;
2492 case NEGATE_EXPR:
2493 value_oppose (k, k);
2494 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
2495 break;
2497 case SSA_NAME:
2498 param_col = param_index (e, s);
2500 if (c)
2502 param_col += c->NbColumns - scop_nb_params (s) - 1;
2504 if (subtract)
2505 value_subtract (c->p[r][param_col], c->p[r][param_col], k);
2506 else
2507 value_addto (c->p[r][param_col], c->p[r][param_col], k);
2509 break;
2511 case INTEGER_CST:
2512 if (c)
2514 int v = int_cst_value (e);
2515 cst_col = c->NbColumns - 1;
2517 if (v < 0)
2519 v = -v;
2520 subtract = subtract ? false : true;
2523 if (subtract)
2524 value_sub_int (c->p[r][cst_col], c->p[r][cst_col], v);
2525 else
2526 value_add_int (c->p[r][cst_col], c->p[r][cst_col], v);
2528 break;
2530 case NOP_EXPR:
2531 case CONVERT_EXPR:
2532 case NON_LVALUE_EXPR:
2533 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
2534 break;
2536 default:
2537 gcc_unreachable ();
2538 break;
2542 /* Data structure for idx_record_params. */
2544 struct irp_data
2546 struct loop *loop;
2547 scop_p scop;
2550 /* For a data reference with an ARRAY_REF as its BASE, record the
2551 parameters occurring in IDX. DTA is passed in as complementary
2552 information, and is used by the automatic walker function. This
2553 function is a callback for for_each_index. */
2555 static bool
2556 idx_record_params (tree base, tree *idx, void *dta)
2558 struct irp_data *data = (struct irp_data *) dta;
2560 if (TREE_CODE (base) != ARRAY_REF)
2561 return true;
2563 if (TREE_CODE (*idx) == SSA_NAME)
2565 tree scev;
2566 scop_p scop = data->scop;
2567 struct loop *loop = data->loop;
2568 Value one;
2570 scev = analyze_scalar_evolution (loop, *idx);
2571 scev = instantiate_scev (block_before_scop (scop), loop, scev);
2573 value_init (one);
2574 value_set_si (one, 1);
2575 scan_tree_for_params (scop, scev, NULL, 0, one, false);
2576 value_clear (one);
2579 return true;
2582 /* Find parameters with respect to SCOP in BB. We are looking in memory
2583 access functions, conditions and loop bounds. */
2585 static void
2586 find_params_in_bb (scop_p scop, graphite_bb_p gb)
2588 int i;
2589 data_reference_p dr;
2590 gimple stmt;
2591 loop_p father = GBB_BB (gb)->loop_father;
2593 for (i = 0; VEC_iterate (data_reference_p, GBB_DATA_REFS (gb), i, dr); i++)
2595 struct irp_data irp;
2597 irp.loop = father;
2598 irp.scop = scop;
2599 for_each_index (&dr->ref, idx_record_params, &irp);
2602 /* Find parameters in conditional statements. */
2603 for (i = 0; VEC_iterate (gimple, GBB_CONDITIONS (gb), i, stmt); i++)
2605 Value one;
2606 loop_p loop = father;
2608 tree lhs, rhs;
2610 lhs = gimple_cond_lhs (stmt);
2611 lhs = analyze_scalar_evolution (loop, lhs);
2612 lhs = instantiate_scev (block_before_scop (scop), loop, lhs);
2614 rhs = gimple_cond_rhs (stmt);
2615 rhs = analyze_scalar_evolution (loop, rhs);
2616 rhs = instantiate_scev (block_before_scop (scop), loop, rhs);
2618 value_init (one);
2619 scan_tree_for_params (scop, lhs, NULL, 0, one, false);
2620 value_set_si (one, 1);
2621 scan_tree_for_params (scop, rhs, NULL, 0, one, false);
2622 value_clear (one);
2626 /* Saves in NV the name of variable P->T. */
2628 static void
2629 save_var_name (char **nv, int i, name_tree p)
2631 const char *name = get_name (SSA_NAME_VAR (p->t));
2633 if (name)
2635 int len = strlen (name) + 16;
2636 nv[i] = XNEWVEC (char, len);
2637 snprintf (nv[i], len, "%s_%d", name, SSA_NAME_VERSION (p->t));
2639 else
2641 nv[i] = XNEWVEC (char, 16);
2642 snprintf (nv[i], 2 + 16, "T_%d", SSA_NAME_VERSION (p->t));
2645 p->name = nv[i];
2648 /* Return the maximal loop depth in SCOP. */
2650 static int
2651 scop_max_loop_depth (scop_p scop)
2653 int i;
2654 graphite_bb_p gbb;
2655 int max_nb_loops = 0;
2657 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++)
2659 int nb_loops = gbb_nb_loops (gbb);
2660 if (max_nb_loops < nb_loops)
2661 max_nb_loops = nb_loops;
2664 return max_nb_loops;
2667 /* Initialize Cloog's parameter names from the names used in GIMPLE.
2668 Initialize Cloog's iterator names, using 'graphite_iterator_%d'
2669 from 0 to scop_nb_loops (scop). */
2671 static void
2672 initialize_cloog_names (scop_p scop)
2674 int i, nb_params = VEC_length (name_tree, SCOP_PARAMS (scop));
2675 char **params = XNEWVEC (char *, nb_params);
2676 int nb_iterators = scop_max_loop_depth (scop);
2677 int nb_scattering= cloog_program_nb_scattdims (SCOP_PROG (scop));
2678 char **iterators = XNEWVEC (char *, nb_iterators * 2);
2679 char **scattering = XNEWVEC (char *, nb_scattering);
2680 name_tree p;
2682 for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++)
2683 save_var_name (params, i, p);
2685 cloog_names_set_nb_parameters (cloog_program_names (SCOP_PROG (scop)),
2686 nb_params);
2687 cloog_names_set_parameters (cloog_program_names (SCOP_PROG (scop)),
2688 params);
2690 for (i = 0; i < nb_iterators; i++)
2692 int len = 18 + 16;
2693 iterators[i] = XNEWVEC (char, len);
2694 snprintf (iterators[i], len, "graphite_iterator_%d", i);
2697 cloog_names_set_nb_iterators (cloog_program_names (SCOP_PROG (scop)),
2698 nb_iterators);
2699 cloog_names_set_iterators (cloog_program_names (SCOP_PROG (scop)),
2700 iterators);
2702 for (i = 0; i < nb_scattering; i++)
2704 int len = 2 + 16;
2705 scattering[i] = XNEWVEC (char, len);
2706 snprintf (scattering[i], len, "s_%d", i);
2709 cloog_names_set_nb_scattering (cloog_program_names (SCOP_PROG (scop)),
2710 nb_scattering);
2711 cloog_names_set_scattering (cloog_program_names (SCOP_PROG (scop)),
2712 scattering);
2715 /* Record the parameters used in the SCOP. A variable is a parameter
2716 in a scop if it does not vary during the execution of that scop. */
2718 static void
2719 find_scop_parameters (scop_p scop)
2721 graphite_bb_p gb;
2722 unsigned i;
2723 struct loop *loop;
2724 Value one;
2726 value_init (one);
2727 value_set_si (one, 1);
2729 /* Find the parameters used in the loop bounds. */
2730 for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop); i++)
2732 tree nb_iters = number_of_latch_executions (loop);
2734 if (!chrec_contains_symbols (nb_iters))
2735 continue;
2737 nb_iters = analyze_scalar_evolution (loop, nb_iters);
2738 nb_iters = instantiate_scev (block_before_scop (scop), loop, nb_iters);
2739 scan_tree_for_params (scop, nb_iters, NULL, 0, one, false);
2742 value_clear (one);
2744 /* Find the parameters used in data accesses. */
2745 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
2746 find_params_in_bb (scop, gb);
2748 SCOP_ADD_PARAMS (scop) = false;
2751 /* Build the context constraints for SCOP: constraints and relations
2752 on parameters. */
2754 static void
2755 build_scop_context (scop_p scop)
2757 int nb_params = scop_nb_params (scop);
2758 CloogMatrix *matrix = cloog_matrix_alloc (1, nb_params + 2);
2760 /* Insert '0 >= 0' in the context matrix, as it is not allowed to be
2761 empty. */
2763 value_set_si (matrix->p[0][0], 1);
2765 value_set_si (matrix->p[0][nb_params + 1], 0);
2767 cloog_program_set_context (SCOP_PROG (scop),
2768 cloog_domain_matrix2domain (matrix));
2769 cloog_matrix_free (matrix);
2772 /* Returns a graphite_bb from BB. */
2774 static inline graphite_bb_p
2775 gbb_from_bb (basic_block bb)
2777 return (graphite_bb_p) bb->aux;
2780 /* Builds the constraint matrix for LOOP in SCOP. NB_OUTER_LOOPS is the
2781 number of loops surrounding LOOP in SCOP. OUTER_CSTR gives the
2782 constraints matrix for the surrounding loops. */
2784 static void
2785 build_loop_iteration_domains (scop_p scop, struct loop *loop,
2786 CloogMatrix *outer_cstr, int nb_outer_loops)
2788 int i, j, row;
2789 CloogMatrix *cstr;
2790 graphite_bb_p gb;
2792 int nb_rows = outer_cstr->NbRows + 1;
2793 int nb_cols = outer_cstr->NbColumns + 1;
2795 /* Last column of CSTR is the column of constants. */
2796 int cst_col = nb_cols - 1;
2798 /* The column for the current loop is just after the columns of
2799 other outer loops. */
2800 int loop_col = nb_outer_loops + 1;
2802 tree nb_iters = number_of_latch_executions (loop);
2804 /* When the number of iterations is a constant or a parameter, we
2805 add a constraint for the upper bound of the loop. So add a row
2806 to the constraint matrix before allocating it. */
2807 if (TREE_CODE (nb_iters) == INTEGER_CST
2808 || !chrec_contains_undetermined (nb_iters))
2809 nb_rows++;
2811 cstr = cloog_matrix_alloc (nb_rows, nb_cols);
2813 /* Copy the outer constraints. */
2814 for (i = 0; i < outer_cstr->NbRows; i++)
2816 /* Copy the eq/ineq and loops columns. */
2817 for (j = 0; j < loop_col; j++)
2818 value_assign (cstr->p[i][j], outer_cstr->p[i][j]);
2820 /* Leave an empty column in CSTR for the current loop, and then
2821 copy the parameter columns. */
2822 for (j = loop_col; j < outer_cstr->NbColumns; j++)
2823 value_assign (cstr->p[i][j + 1], outer_cstr->p[i][j]);
2826 /* 0 <= loop_i */
2827 row = outer_cstr->NbRows;
2828 value_set_si (cstr->p[row][0], 1);
2829 value_set_si (cstr->p[row][loop_col], 1);
2831 /* loop_i <= nb_iters */
2832 if (TREE_CODE (nb_iters) == INTEGER_CST)
2834 row++;
2835 value_set_si (cstr->p[row][0], 1);
2836 value_set_si (cstr->p[row][loop_col], -1);
2838 value_set_si (cstr->p[row][cst_col],
2839 int_cst_value (nb_iters));
2841 else if (!chrec_contains_undetermined (nb_iters))
2843 /* Otherwise nb_iters contains parameters: scan the nb_iters
2844 expression and build its matrix representation. */
2845 Value one;
2847 row++;
2848 value_set_si (cstr->p[row][0], 1);
2849 value_set_si (cstr->p[row][loop_col], -1);
2851 nb_iters = analyze_scalar_evolution (loop, nb_iters);
2852 nb_iters = instantiate_scev (block_before_scop (scop), loop, nb_iters);
2854 value_init (one);
2855 value_set_si (one, 1);
2856 scan_tree_for_params (scop, nb_iters, cstr, row, one, false);
2857 value_clear (one);
2859 else
2860 gcc_unreachable ();
2862 if (loop->inner && loop_in_scop_p (loop->inner, scop))
2863 build_loop_iteration_domains (scop, loop->inner, cstr, nb_outer_loops + 1);
2865 /* Only go to the next loops, if we are not at the outermost layer. These
2866 have to be handled seperately, as we can be sure, that the chain at this
2867 layer will be connected. */
2868 if (nb_outer_loops != 0 && loop->next && loop_in_scop_p (loop->next, scop))
2869 build_loop_iteration_domains (scop, loop->next, outer_cstr, nb_outer_loops);
2871 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
2872 if (gbb_loop (gb) == loop)
2873 GBB_DOMAIN (gb) = cloog_matrix_copy (cstr);
2875 cloog_matrix_free (cstr);
2878 /* Add conditions to the domain of GB. */
2880 static void
2881 add_conditions_to_domain (graphite_bb_p gb)
2883 unsigned int i,j;
2884 gimple stmt;
2885 VEC (gimple, heap) *conditions = GBB_CONDITIONS (gb);
2886 CloogMatrix *domain = GBB_DOMAIN (gb);
2887 scop_p scop = GBB_SCOP (gb);
2889 unsigned nb_rows;
2890 unsigned nb_cols;
2891 unsigned nb_new_rows = 0;
2892 unsigned row;
2894 if (VEC_empty (gimple, conditions))
2895 return;
2897 if (domain)
2899 nb_rows = domain->NbRows;
2900 nb_cols = domain->NbColumns;
2902 else
2904 nb_rows = 0;
2905 nb_cols = scop_nb_params (scop) + 2;
2908 /* Count number of necessary new rows to add the conditions to the
2909 domain. */
2910 for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
2912 switch (gimple_code (stmt))
2914 case GIMPLE_COND:
2916 enum tree_code code = gimple_cond_code (stmt);
2918 switch (code)
2920 case NE_EXPR:
2921 case EQ_EXPR:
2922 /* NE and EQ statements are not supported right know. */
2923 gcc_unreachable ();
2924 break;
2925 case LT_EXPR:
2926 case GT_EXPR:
2927 case LE_EXPR:
2928 case GE_EXPR:
2929 nb_new_rows++;
2930 break;
2931 default:
2932 gcc_unreachable ();
2933 break;
2935 break;
2937 case SWITCH_EXPR:
2938 /* Switch statements are not supported right know. */
2939 gcc_unreachable ();
2940 break;
2942 default:
2943 gcc_unreachable ();
2944 break;
2949 /* Enlarge the matrix. */
2951 CloogMatrix *new_domain;
2952 new_domain = cloog_matrix_alloc (nb_rows + nb_new_rows, nb_cols);
2954 for (i = 0; i < nb_rows; i++)
2955 for (j = 0; j < nb_cols; j++)
2956 value_assign (new_domain->p[i][j], domain->p[i][j]);
2958 cloog_matrix_free (domain);
2959 domain = new_domain;
2960 GBB_DOMAIN (gb) = new_domain;
2963 /* Add the conditions to the new enlarged domain matrix. */
2964 row = nb_rows;
2965 for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
2967 switch (gimple_code (stmt))
2969 case GIMPLE_COND:
2971 Value one;
2972 enum tree_code code;
2973 tree left;
2974 tree right;
2975 loop_p loop = GBB_BB (gb)->loop_father;
2977 left = gimple_cond_lhs (stmt);
2978 right = gimple_cond_rhs (stmt);
2980 left = analyze_scalar_evolution (loop, left);
2981 right = analyze_scalar_evolution (loop, right);
2983 left = instantiate_scev (block_before_scop (scop), loop, left);
2984 right = instantiate_scev (block_before_scop (scop), loop, right);
2986 code = gimple_cond_code (stmt);
2988 /* The conditions for ELSE-branches are inverted. */
2989 if (VEC_index (gimple, gb->condition_cases, i) == NULL)
2990 code = invert_tree_comparison (code, false);
2992 switch (code)
2994 case NE_EXPR:
2995 /* NE statements are not supported right know. */
2996 gcc_unreachable ();
2997 break;
2998 case EQ_EXPR:
2999 value_set_si (domain->p[row][0], 1);
3000 value_init (one);
3001 value_set_si (one, 1);
3002 scan_tree_for_params (scop, left, domain, row, one, true);
3003 value_set_si (one, 1);
3004 scan_tree_for_params (scop, right, domain, row, one, false);
3005 row++;
3006 value_set_si (domain->p[row][0], 1);
3007 value_set_si (one, 1);
3008 scan_tree_for_params (scop, left, domain, row, one, false);
3009 value_set_si (one, 1);
3010 scan_tree_for_params (scop, right, domain, row, one, true);
3011 value_clear (one);
3012 row++;
3013 break;
3014 case LT_EXPR:
3015 value_set_si (domain->p[row][0], 1);
3016 value_init (one);
3017 value_set_si (one, 1);
3018 scan_tree_for_params (scop, left, domain, row, one, true);
3019 value_set_si (one, 1);
3020 scan_tree_for_params (scop, right, domain, row, one, false);
3021 value_sub_int (domain->p[row][nb_cols - 1],
3022 domain->p[row][nb_cols - 1], 1);
3023 value_clear (one);
3024 row++;
3025 break;
3026 case GT_EXPR:
3027 value_set_si (domain->p[row][0], 1);
3028 value_init (one);
3029 value_set_si (one, 1);
3030 scan_tree_for_params (scop, left, domain, row, one, false);
3031 value_set_si (one, 1);
3032 scan_tree_for_params (scop, right, domain, row, one, true);
3033 value_sub_int (domain->p[row][nb_cols - 1],
3034 domain->p[row][nb_cols - 1], 1);
3035 value_clear (one);
3036 row++;
3037 break;
3038 case LE_EXPR:
3039 value_set_si (domain->p[row][0], 1);
3040 value_init (one);
3041 value_set_si (one, 1);
3042 scan_tree_for_params (scop, left, domain, row, one, true);
3043 value_set_si (one, 1);
3044 scan_tree_for_params (scop, right, domain, row, one, false);
3045 value_clear (one);
3046 row++;
3047 break;
3048 case GE_EXPR:
3049 value_set_si (domain->p[row][0], 1);
3050 value_init (one);
3051 value_set_si (one, 1);
3052 scan_tree_for_params (scop, left, domain, row, one, false);
3053 value_set_si (one, 1);
3054 scan_tree_for_params (scop, right, domain, row, one, true);
3055 value_clear (one);
3056 row++;
3057 break;
3058 default:
3059 gcc_unreachable ();
3060 break;
3062 break;
3064 case GIMPLE_SWITCH:
3065 /* Switch statements are not supported right know. */
3066 gcc_unreachable ();
3067 break;
3069 default:
3070 gcc_unreachable ();
3071 break;
3076 /* Helper recursive function. */
3078 static void
3079 build_scop_conditions_1 (VEC (gimple, heap) **conditions,
3080 VEC (gimple, heap) **cases, basic_block bb,
3081 scop_p scop)
3083 int i, j;
3084 graphite_bb_p gbb;
3085 gimple_stmt_iterator gsi;
3086 basic_block bb_child, bb_iter;
3087 VEC (basic_block, heap) *dom;
3089 /* Make sure we are in the SCoP. */
3090 if (!bb_in_scop_p (bb, scop))
3091 return;
3093 /* Record conditions in graphite_bb. */
3094 gbb = gbb_from_bb (bb);
3095 if (gbb)
3097 GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
3098 GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
3099 add_conditions_to_domain (gbb);
3102 dom = get_dominated_by (CDI_DOMINATORS, bb);
3104 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3106 gimple stmt = gsi_stmt (gsi);
3107 VEC (edge, gc) *edges;
3108 edge e;
3110 switch (gimple_code (stmt))
3112 case GIMPLE_COND:
3113 edges = bb->succs;
3114 for (i = 0; VEC_iterate (edge, edges, i, e); i++)
3115 if ((dominated_by_p (CDI_DOMINATORS, e->dest, bb))
3116 && VEC_length (edge, e->dest->preds) == 1)
3118 /* Remove the scanned block from the dominator successors. */
3119 for (j = 0; VEC_iterate (basic_block, dom, j, bb_iter); j++)
3120 if (bb_iter == e->dest)
3122 VEC_unordered_remove (basic_block, dom, j);
3123 break;
3126 /* Recursively scan the then or else part. */
3127 if (e->flags & EDGE_TRUE_VALUE)
3128 VEC_safe_push (gimple, heap, *cases, stmt);
3129 else if (e->flags & EDGE_FALSE_VALUE)
3130 VEC_safe_push (gimple, heap, *cases, NULL);
3131 else
3132 gcc_unreachable ();
3134 VEC_safe_push (gimple, heap, *conditions, stmt);
3135 build_scop_conditions_1 (conditions, cases, e->dest, scop);
3136 VEC_pop (gimple, *conditions);
3137 VEC_pop (gimple, *cases);
3139 break;
3141 case GIMPLE_SWITCH:
3143 unsigned i;
3144 gimple_stmt_iterator gsi_search_gimple_label;
3146 for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
3148 basic_block bb_iter;
3149 size_t k;
3150 size_t n_cases = VEC_length (gimple, *conditions);
3151 unsigned n = gimple_switch_num_labels (stmt);
3153 bb_child = label_to_block
3154 (CASE_LABEL (gimple_switch_label (stmt, i)));
3156 /* Do not handle multiple values for the same block. */
3157 for (k = 0; k < n; k++)
3158 if (i != k
3159 && label_to_block
3160 (CASE_LABEL (gimple_switch_label (stmt, k))) == bb_child)
3161 break;
3163 if (k != n)
3164 continue;
3166 /* Switch cases with more than one predecessor are not
3167 handled. */
3168 if (VEC_length (edge, bb_child->preds) != 1)
3169 continue;
3171 /* Recursively scan the corresponding 'case' block. */
3173 for (gsi_search_gimple_label = gsi_start_bb (bb_child);
3174 !gsi_end_p (gsi_search_gimple_label);
3175 gsi_next (&gsi_search_gimple_label))
3177 gimple stmt_gimple_label
3178 = gsi_stmt (gsi_search_gimple_label);
3180 if (gimple_code (stmt_gimple_label) == GIMPLE_LABEL)
3182 tree t = gimple_label_label (stmt_gimple_label);
3184 if (t == gimple_switch_label (stmt, i))
3185 VEC_replace (gimple, *cases, n_cases,
3186 stmt_gimple_label);
3187 else
3188 gcc_unreachable ();
3192 build_scop_conditions_1 (conditions, cases, bb_child, scop);
3194 /* Remove the scanned block from the dominator successors. */
3195 for (j = 0; VEC_iterate (basic_block, dom, j, bb_iter); j++)
3196 if (bb_iter == bb_child)
3198 VEC_unordered_remove (basic_block, dom, j);
3199 break;
3203 VEC_pop (gimple, *conditions);
3204 VEC_pop (gimple, *cases);
3205 break;
3207 default:
3208 break;
3212 /* Scan all immediate dominated successors. */
3213 for (i = 0; VEC_iterate (basic_block, dom, i, bb_child); i++)
3214 build_scop_conditions_1 (conditions, cases, bb_child, scop);
3216 VEC_free (basic_block, heap, dom);
3219 /* Record all 'if' and 'switch' conditions in each gbb of SCOP. */
3221 static void
3222 build_scop_conditions (scop_p scop)
3224 VEC (gimple, heap) *conditions = NULL;
3225 VEC (gimple, heap) *cases = NULL;
3227 build_scop_conditions_1 (&conditions, &cases, SCOP_ENTRY (scop), scop);
3229 VEC_free (gimple, heap, conditions);
3230 VEC_free (gimple, heap, cases);
3233 /* Build the current domain matrix: the loops belonging to the current
3234 SCOP, and that vary for the execution of the current basic block.
3235 Returns false if there is no loop in SCOP. */
3237 static bool
3238 build_scop_iteration_domain (scop_p scop)
3240 struct loop *loop;
3241 CloogMatrix *outer_cstr;
3242 int i;
3244 /* Build cloog loop for all loops, that are in the uppermost loop layer of
3245 this SCoP. */
3246 for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop); i++)
3247 if (!loop_in_scop_p (loop_outer (loop), scop))
3249 /* The outermost constraints is a matrix that has:
3250 -first column: eq/ineq boolean
3251 -last column: a constant
3252 -scop_nb_params columns for the parameters used in the scop. */
3253 outer_cstr = cloog_matrix_alloc (0, scop_nb_params (scop) + 2);
3254 build_loop_iteration_domains (scop, loop, outer_cstr, 0);
3255 cloog_matrix_free (outer_cstr);
3258 return (i != 0);
3261 /* Initializes an equation CY of the access matrix using the
3262 information for a subscript from AF, relatively to the loop
3263 indexes from LOOP_NEST and parameter indexes from PARAMS. NDIM is
3264 the dimension of the array access, i.e. the number of
3265 subscripts. Returns true when the operation succeeds. */
3267 static bool
3268 build_access_matrix_with_af (tree af, lambda_vector cy,
3269 scop_p scop, int ndim)
3271 int param_col;
3273 switch (TREE_CODE (af))
3275 case POLYNOMIAL_CHREC:
3277 struct loop *outer_loop;
3278 tree left = CHREC_LEFT (af);
3279 tree right = CHREC_RIGHT (af);
3280 int var;
3282 if (TREE_CODE (right) != INTEGER_CST)
3283 return false;
3285 outer_loop = get_loop (CHREC_VARIABLE (af));
3286 var = nb_loops_around_loop_in_scop (outer_loop, scop);
3287 cy[var] = int_cst_value (right);
3289 switch (TREE_CODE (left))
3291 case POLYNOMIAL_CHREC:
3292 return build_access_matrix_with_af (left, cy, scop, ndim);
3294 case INTEGER_CST:
3295 cy[ndim - 1] = int_cst_value (left);
3296 return true;
3298 default:
3299 return build_access_matrix_with_af (left, cy, scop, ndim);
3303 case PLUS_EXPR:
3304 build_access_matrix_with_af (TREE_OPERAND (af, 0), cy, scop, ndim);
3305 build_access_matrix_with_af (TREE_OPERAND (af, 1), cy, scop, ndim);
3306 return true;
3308 case MINUS_EXPR:
3309 build_access_matrix_with_af (TREE_OPERAND (af, 0), cy, scop, ndim);
3310 build_access_matrix_with_af (TREE_OPERAND (af, 1), cy, scop, ndim);
3311 return true;
3313 case INTEGER_CST:
3314 cy[ndim - 1] = int_cst_value (af);
3315 return true;
3317 case SSA_NAME:
3318 param_col = param_index (af, scop);
3319 cy [ndim - scop_nb_params (scop) + param_col - 1] = 1;
3320 return true;
3322 default:
3323 /* FIXME: access_fn can have parameters. */
3324 return false;
3328 /* Initialize the access matrix in the data reference REF with respect
3329 to the loop nesting LOOP_NEST. Return true when the operation
3330 succeeded. */
3332 static bool
3333 build_access_matrix (data_reference_p ref, graphite_bb_p gb)
3335 int i, ndim = DR_NUM_DIMENSIONS (ref);
3336 struct access_matrix *am = GGC_NEW (struct access_matrix);
3338 AM_MATRIX (am) = VEC_alloc (lambda_vector, heap, ndim);
3339 DR_SCOP (ref) = GBB_SCOP (gb);
3341 for (i = 0; i < ndim; i++)
3343 lambda_vector v = lambda_vector_new (ref_nb_loops (ref));
3344 scop_p scop = GBB_SCOP (gb);
3345 tree af = DR_ACCESS_FN (ref, i);
3347 if (!build_access_matrix_with_af (af, v, scop, ref_nb_loops (ref)))
3348 return false;
3350 VEC_safe_push (lambda_vector, heap, AM_MATRIX (am), v);
3353 DR_ACCESS_MATRIX (ref) = am;
3354 return true;
3357 /* Build the access matrices for the data references in the SCOP. */
3359 static void
3360 build_scop_data_accesses (scop_p scop)
3362 int i;
3363 graphite_bb_p gb;
3365 /* FIXME: Construction of access matrix is disabled until some
3366 pass, like the data dependence analysis, is using it. */
3367 return;
3369 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
3371 int j;
3372 data_reference_p dr;
3374 /* Construct the access matrix for each data ref, with respect to
3375 the loop nest of the current BB in the considered SCOP. */
3376 for (j = 0;
3377 VEC_iterate (data_reference_p, GBB_DATA_REFS (gb), j, dr);
3378 j++)
3380 bool res = build_access_matrix (dr, gb);
3382 /* FIXME: At this point the DRs should always have an affine
3383 form. For the moment this fails as build_access_matrix
3384 does not build matrices with parameters. */
3385 gcc_assert (res);
3390 /* Returns the tree variable from the name NAME that was given in
3391 Cloog representation. All the parameters are stored in PARAMS, and
3392 all the loop induction variables are stored in IVSTACK.
3394 FIXME: This is a hack, and Cloog should be fixed to not work with
3395 variable names represented as "char *string", but with void
3396 pointers that could be casted back to a tree. The only problem in
3397 doing that is that Cloog's pretty printer still assumes that
3398 variable names are char *strings. The solution would be to have a
3399 function pointer for pretty-printing that can be redirected to be
3400 print_generic_stmt in our case, or fprintf by default.
3401 ??? Too ugly to live. */
3403 static tree
3404 clast_name_to_gcc (const char *name, VEC (name_tree, heap) *params,
3405 loop_iv_stack ivstack)
3407 int i;
3408 name_tree t;
3409 tree iv;
3411 if (params)
3412 for (i = 0; VEC_iterate (name_tree, params, i, t); i++)
3413 if (!strcmp (name, t->name))
3414 return t->t;
3416 iv = loop_iv_stack_get_iv_from_name (ivstack, name);
3417 if (iv)
3418 return iv;
3420 gcc_unreachable ();
3423 /* Returns the maximal precision type for expressions E1 and E2. */
3425 static inline tree
3426 max_precision_type (tree e1, tree e2)
3428 tree type1 = TREE_TYPE (e1);
3429 tree type2 = TREE_TYPE (e2);
3430 return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
3433 /* Converts a Cloog AST expression E back to a GCC expression tree
3434 of type TYPE. */
3436 static tree
3437 clast_to_gcc_expression (tree type, struct clast_expr *e,
3438 VEC (name_tree, heap) *params,
3439 loop_iv_stack ivstack)
3441 switch (e->type)
3443 case expr_term:
3445 struct clast_term *t = (struct clast_term *) e;
3447 if (t->var)
3449 if (value_one_p (t->val))
3451 tree name = clast_name_to_gcc (t->var, params, ivstack);
3452 return fold_convert (type, name);
3455 else if (value_mone_p (t->val))
3457 tree name = clast_name_to_gcc (t->var, params, ivstack);
3458 name = fold_convert (type, name);
3459 return fold_build1 (NEGATE_EXPR, type, name);
3461 else
3463 tree name = clast_name_to_gcc (t->var, params, ivstack);
3464 tree cst = gmp_cst_to_tree (type, t->val);
3465 name = fold_convert (type, name);
3466 return fold_build2 (MULT_EXPR, type, cst, name);
3469 else
3470 return gmp_cst_to_tree (type, t->val);
3473 case expr_red:
3475 struct clast_reduction *r = (struct clast_reduction *) e;
3477 switch (r->type)
3479 case clast_red_sum:
3480 if (r->n == 1)
3481 return clast_to_gcc_expression (type, r->elts[0], params, ivstack);
3483 else
3485 tree tl = clast_to_gcc_expression (type, r->elts[0], params, ivstack);
3486 tree tr = clast_to_gcc_expression (type, r->elts[1], params, ivstack);
3488 gcc_assert (r->n >= 1
3489 && r->elts[0]->type == expr_term
3490 && r->elts[1]->type == expr_term);
3492 return fold_build2 (PLUS_EXPR, type, tl, tr);
3495 break;
3497 case clast_red_min:
3498 if (r->n == 1)
3499 return clast_to_gcc_expression (type, r->elts[0], params, ivstack);
3501 else if (r->n == 2)
3503 tree tl = clast_to_gcc_expression (type, r->elts[0], params, ivstack);
3504 tree tr = clast_to_gcc_expression (type, r->elts[1], params, ivstack);
3505 return fold_build2 (MIN_EXPR, type, tl, tr);
3508 else
3509 gcc_unreachable();
3511 break;
3513 case clast_red_max:
3514 if (r->n == 1)
3515 return clast_to_gcc_expression (type, r->elts[0], params, ivstack);
3517 else if (r->n == 2)
3519 tree tl = clast_to_gcc_expression (type, r->elts[0], params, ivstack);
3520 tree tr = clast_to_gcc_expression (type, r->elts[1], params, ivstack);
3521 return fold_build2 (MAX_EXPR, type, tl, tr);
3524 else
3525 gcc_unreachable();
3527 break;
3529 default:
3530 gcc_unreachable ();
3532 break;
3535 case expr_bin:
3537 struct clast_binary *b = (struct clast_binary *) e;
3538 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
3539 tree tl = clast_to_gcc_expression (type, lhs, params, ivstack);
3540 tree tr = gmp_cst_to_tree (type, b->RHS);
3542 switch (b->type)
3544 case clast_bin_fdiv:
3545 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
3547 case clast_bin_cdiv:
3548 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
3550 case clast_bin_div:
3551 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
3553 case clast_bin_mod:
3554 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
3556 default:
3557 gcc_unreachable ();
3561 default:
3562 gcc_unreachable ();
3565 return NULL_TREE;
3568 /* Returns the type for the expression E. */
3570 static tree
3571 gcc_type_for_clast_expr (struct clast_expr *e,
3572 VEC (name_tree, heap) *params,
3573 loop_iv_stack ivstack)
3575 switch (e->type)
3577 case expr_term:
3579 struct clast_term *t = (struct clast_term *) e;
3581 if (t->var)
3582 return TREE_TYPE (clast_name_to_gcc (t->var, params, ivstack));
3583 else
3584 return NULL_TREE;
3587 case expr_red:
3589 struct clast_reduction *r = (struct clast_reduction *) e;
3591 if (r->n == 1)
3592 return gcc_type_for_clast_expr (r->elts[0], params, ivstack);
3593 else
3595 int i;
3596 for (i = 0; i < r->n; i++)
3598 tree type = gcc_type_for_clast_expr (r->elts[i], params, ivstack);
3599 if (type)
3600 return type;
3602 return NULL_TREE;
3606 case expr_bin:
3608 struct clast_binary *b = (struct clast_binary *) e;
3609 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
3610 return gcc_type_for_clast_expr (lhs, params, ivstack);
3613 default:
3614 gcc_unreachable ();
3617 return NULL_TREE;
3620 /* Returns the type for the equation CLEQ. */
3622 static tree
3623 gcc_type_for_clast_eq (struct clast_equation *cleq,
3624 VEC (name_tree, heap) *params,
3625 loop_iv_stack ivstack)
3627 tree type = gcc_type_for_clast_expr (cleq->LHS, params, ivstack);
3628 if (type)
3629 return type;
3631 return gcc_type_for_clast_expr (cleq->RHS, params, ivstack);
3634 /* Translates a clast equation CLEQ to a tree. */
3636 static tree
3637 graphite_translate_clast_equation (scop_p scop,
3638 struct clast_equation *cleq,
3639 loop_iv_stack ivstack)
3641 enum tree_code comp;
3642 tree type = gcc_type_for_clast_eq (cleq, SCOP_PARAMS (scop), ivstack);
3643 tree lhs = clast_to_gcc_expression (type, cleq->LHS, SCOP_PARAMS (scop), ivstack);
3644 tree rhs = clast_to_gcc_expression (type, cleq->RHS, SCOP_PARAMS (scop), ivstack);
3646 if (cleq->sign == 0)
3647 comp = EQ_EXPR;
3649 else if (cleq->sign > 0)
3650 comp = GE_EXPR;
3652 else
3653 comp = LE_EXPR;
3655 return fold_build2 (comp, type, lhs, rhs);
3658 /* Creates the test for the condition in STMT. */
3660 static tree
3661 graphite_create_guard_cond_expr (scop_p scop, struct clast_guard *stmt,
3662 loop_iv_stack ivstack)
3664 tree cond = NULL;
3665 int i;
3667 for (i = 0; i < stmt->n; i++)
3669 tree eq = graphite_translate_clast_equation (scop, &stmt->eq[i], ivstack);
3671 if (cond)
3672 cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
3673 else
3674 cond = eq;
3677 return cond;
3680 /* Creates a new if region corresponding to Cloog's guard. */
3682 static edge
3683 graphite_create_new_guard (scop_p scop, edge entry_edge,
3684 struct clast_guard *stmt,
3685 loop_iv_stack ivstack)
3687 tree cond_expr = graphite_create_guard_cond_expr (scop, stmt, ivstack);
3688 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
3689 return exit_edge;
3692 /* Walks a CLAST and returns the first statement in the body of a
3693 loop. */
3695 static struct clast_user_stmt *
3696 clast_get_body_of_loop (struct clast_stmt *stmt)
3698 if (!stmt
3699 || CLAST_STMT_IS_A (stmt, stmt_user))
3700 return (struct clast_user_stmt *) stmt;
3702 if (CLAST_STMT_IS_A (stmt, stmt_for))
3703 return clast_get_body_of_loop (((struct clast_for *) stmt)->body);
3705 if (CLAST_STMT_IS_A (stmt, stmt_guard))
3706 return clast_get_body_of_loop (((struct clast_guard *) stmt)->then);
3708 if (CLAST_STMT_IS_A (stmt, stmt_block))
3709 return clast_get_body_of_loop (((struct clast_block *) stmt)->body);
3711 gcc_unreachable ();
3714 /* Returns the induction variable for the loop that gets translated to
3715 STMT. */
3717 static tree
3718 gcc_type_for_iv_of_clast_loop (struct clast_for *stmt_for)
3720 struct clast_user_stmt *stmt = clast_get_body_of_loop ((struct clast_stmt *) stmt_for);
3721 const char *cloog_iv = stmt_for->iterator;
3722 CloogStatement *cs = stmt->statement;
3723 graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
3725 return gcc_type_for_cloog_iv (cloog_iv, gbb);
3728 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an induction
3729 variable for the new LOOP. New LOOP is attached to CFG starting at
3730 ENTRY_EDGE. LOOP is inserted into the loop tree and becomes the child
3731 loop of the OUTER_LOOP. */
3733 static struct loop *
3734 graphite_create_new_loop (scop_p scop, edge entry_edge,
3735 struct clast_for *stmt, loop_iv_stack ivstack,
3736 loop_p outer)
3738 tree type = gcc_type_for_iv_of_clast_loop (stmt);
3739 VEC (name_tree, heap) *params = SCOP_PARAMS (scop);
3740 tree lb = clast_to_gcc_expression (type, stmt->LB, params, ivstack);
3741 tree ub = clast_to_gcc_expression (type, stmt->UB, params, ivstack);
3742 tree stride = gmp_cst_to_tree (type, stmt->stride);
3743 tree ivvar = create_tmp_var (type, "graphiteIV");
3744 tree iv_before;
3745 loop_p loop = create_empty_loop_on_edge
3746 (entry_edge, lb, stride, ub, ivvar, &iv_before,
3747 outer ? outer : entry_edge->src->loop_father);
3749 add_referenced_var (ivvar);
3750 loop_iv_stack_push_iv (ivstack, iv_before, stmt->iterator);
3751 return loop;
3754 /* Structure containing the mapping between the old names and the new
3755 names used after block copy in the new loop context. */
3756 typedef struct rename_map_elt
3758 tree old_name, new_name;
3759 } *rename_map_elt;
3762 /* Print to stderr the element ELT. */
3764 static void
3765 debug_rename_elt (rename_map_elt elt)
3767 fprintf (stderr, "(");
3768 print_generic_expr (stderr, elt->old_name, 0);
3769 fprintf (stderr, ", ");
3770 print_generic_expr (stderr, elt->new_name, 0);
3771 fprintf (stderr, ")\n");
3774 /* Helper function for debug_rename_map. */
3776 static int
3777 debug_rename_map_1 (void **slot, void *s ATTRIBUTE_UNUSED)
3779 struct rename_map_elt *entry = (struct rename_map_elt *) *slot;
3780 debug_rename_elt (entry);
3781 return 1;
3784 /* Print to stderr all the elements of MAP. */
3786 void
3787 debug_rename_map (htab_t map)
3789 htab_traverse (map, debug_rename_map_1, NULL);
3792 /* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW. */
3794 static inline rename_map_elt
3795 new_rename_map_elt (tree old_name, tree new_name)
3797 rename_map_elt res;
3799 res = XNEW (struct rename_map_elt);
3800 res->old_name = old_name;
3801 res->new_name = new_name;
3803 return res;
3806 /* Computes a hash function for database element ELT. */
3808 static hashval_t
3809 rename_map_elt_info (const void *elt)
3811 return htab_hash_pointer (((const struct rename_map_elt *) elt)->old_name);
3814 /* Compares database elements E1 and E2. */
3816 static int
3817 eq_rename_map_elts (const void *e1, const void *e2)
3819 const struct rename_map_elt *elt1 = (const struct rename_map_elt *) e1;
3820 const struct rename_map_elt *elt2 = (const struct rename_map_elt *) e2;
3822 return (elt1->old_name == elt2->old_name);
3825 /* Returns the new name associated to OLD_NAME in MAP. */
3827 static tree
3828 get_new_name_from_old_name (htab_t map, tree old_name)
3830 struct rename_map_elt tmp;
3831 PTR *slot;
3833 tmp.old_name = old_name;
3834 slot = htab_find_slot (map, &tmp, NO_INSERT);
3836 if (slot && *slot)
3837 return ((rename_map_elt) *slot)->new_name;
3839 return old_name;
3842 /* Rename the SSA_NAMEs used in STMT and that appear in IVSTACK. */
3844 static void
3845 rename_variables_in_stmt (gimple stmt, htab_t map)
3847 ssa_op_iter iter;
3848 use_operand_p use_p;
3850 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
3852 tree use = USE_FROM_PTR (use_p);
3853 tree new_name = get_new_name_from_old_name (map, use);
3855 replace_exp (use_p, new_name);
3858 update_stmt (stmt);
3861 /* Returns true if SSA_NAME is a parameter of SCOP. */
3863 static bool
3864 is_parameter (scop_p scop, tree ssa_name)
3866 int i;
3867 VEC (name_tree, heap) *params = SCOP_PARAMS (scop);
3868 name_tree param;
3870 for (i = 0; VEC_iterate (name_tree, params, i, param); i++)
3871 if (param->t == ssa_name)
3872 return true;
3874 return false;
3877 /* Returns true if NAME is an induction variable. */
3879 static bool
3880 is_iv (tree name)
3882 return gimple_code (SSA_NAME_DEF_STMT (name)) == GIMPLE_PHI;
3885 static void expand_scalar_variables_stmt (gimple, basic_block, scop_p,
3886 loop_p, htab_t);
3888 /* Constructs a tree which only contains old_ivs and parameters. Any
3889 other variables that are defined outside BB will be eliminated by
3890 using their definitions in the constructed tree. OLD_LOOP_FATHER
3891 is the original loop that contained BB. */
3893 static tree
3894 expand_scalar_variables_expr (tree type, tree op0, enum tree_code code,
3895 tree op1, basic_block bb, scop_p scop,
3896 loop_p old_loop_father, htab_t map)
3898 if ((TREE_CODE_CLASS (code) == tcc_constant
3899 && code == INTEGER_CST)
3900 || TREE_CODE_CLASS (code) == tcc_reference)
3901 return op0;
3903 if (TREE_CODE_CLASS (code) == tcc_unary)
3905 tree op0_type = TREE_TYPE (op0);
3906 enum tree_code op0_code = TREE_CODE (op0);
3907 tree op0_expr =
3908 expand_scalar_variables_expr (op0_type, op0, op0_code,
3909 NULL, bb, scop, old_loop_father, map);
3911 return fold_build1 (code, type, op0_expr);
3914 if (TREE_CODE_CLASS (code) == tcc_binary)
3916 tree op0_type = TREE_TYPE (op0);
3917 enum tree_code op0_code = TREE_CODE (op0);
3918 tree op0_expr =
3919 expand_scalar_variables_expr (op0_type, op0, op0_code,
3920 NULL, bb, scop, old_loop_father, map);
3921 tree op1_type = TREE_TYPE (op1);
3922 enum tree_code op1_code = TREE_CODE (op1);
3923 tree op1_expr =
3924 expand_scalar_variables_expr (op1_type, op1, op1_code,
3925 NULL, bb, scop, old_loop_father, map);
3927 return fold_build2 (code, type, op0_expr, op1_expr);
3930 if (code == SSA_NAME)
3932 tree var0, var1;
3933 gimple def_stmt;
3934 enum tree_code subcode;
3936 if (is_parameter (scop, op0)
3937 || is_iv (op0))
3938 return get_new_name_from_old_name (map, op0);
3940 def_stmt = SSA_NAME_DEF_STMT (op0);
3942 if (gimple_bb (def_stmt) == bb)
3944 /* If the defining statement is in the basic block already
3945 we do not need to create a new expression for it, we
3946 only need to ensure its operands are expanded. */
3947 expand_scalar_variables_stmt (def_stmt, bb, scop,
3948 old_loop_father, map);
3949 return get_new_name_from_old_name (map, op0);
3952 else
3954 if (gimple_code (def_stmt) != GIMPLE_ASSIGN
3955 || !bb_in_scop_p (gimple_bb (def_stmt), scop))
3956 return get_new_name_from_old_name (map, op0);
3958 var0 = gimple_assign_rhs1 (def_stmt);
3959 subcode = gimple_assign_rhs_code (def_stmt);
3960 var1 = gimple_assign_rhs2 (def_stmt);
3962 return expand_scalar_variables_expr (type, var0, subcode, var1,
3963 bb, scop, old_loop_father, map);
3967 gcc_unreachable ();
3968 return NULL;
3971 /* Replicates any uses of non-parameters and non-old-ivs variablesthat
3972 are defind outside BB with code that is inserted in BB.
3973 OLD_LOOP_FATHER is the original loop that contained STMT. */
3975 static void
3976 expand_scalar_variables_stmt (gimple stmt, basic_block bb, scop_p scop,
3977 loop_p old_loop_father, htab_t map)
3979 ssa_op_iter iter;
3980 use_operand_p use_p;
3982 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
3984 tree use = USE_FROM_PTR (use_p);
3985 tree type = TREE_TYPE (use);
3986 enum tree_code code = TREE_CODE (use);
3987 tree use_expr = expand_scalar_variables_expr (type, use, code, NULL, bb,
3988 scop, old_loop_father, map);
3989 if (use_expr != use)
3991 gimple_stmt_iterator gsi = gsi_after_labels (bb);
3992 tree new_use =
3993 force_gimple_operand_gsi (&gsi, use_expr, true, NULL,
3994 true, GSI_NEW_STMT);
3995 replace_exp (use_p, new_use);
3999 update_stmt (stmt);
4002 /* Copies the definitions outside of BB of variables that are not
4003 induction variables nor parameters. BB must only contain
4004 "external" references to these types of variables. OLD_LOOP_FATHER
4005 is the original loop that contained BB. */
4007 static void
4008 expand_scalar_variables (basic_block bb, scop_p scop,
4009 loop_p old_loop_father, htab_t map)
4011 gimple_stmt_iterator gsi;
4013 for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
4015 gimple stmt = gsi_stmt (gsi);
4016 expand_scalar_variables_stmt (stmt, bb, scop, old_loop_father, map);
4017 gsi_next (&gsi);
4021 /* Rename all the SSA_NAMEs from block BB according to the MAP. */
4023 static void
4024 rename_variables (basic_block bb, htab_t map)
4026 gimple_stmt_iterator gsi;
4028 for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4029 rename_variables_in_stmt (gsi_stmt (gsi), map);
4032 /* Rename following the information from MAP the PHI node argument
4033 corresponding to the edge E. In order to allow several renames of
4034 that argument, we match the original SSA_NAME on the argument
4035 coming from the edge different than E. */
4037 static void
4038 rename_variables_from_edge (edge e, gimple phi, htab_t map)
4040 int n = e->dest_idx == 0 ? 1 : 0;
4041 tree old_name = gimple_phi_arg_def (phi, n);
4042 tree new_name = get_new_name_from_old_name (map, old_name);
4044 gcc_assert (gimple_phi_num_args (phi) == 2
4045 && gimple_phi_arg_edge (phi, e->dest_idx) == e);
4047 SET_PHI_ARG_DEF (phi, n, new_name);
4050 /* Rename all the phi arguments for the edges comming from the scop
4051 according to the MAP. */
4053 static void
4054 rename_phis_end_scop (scop_p scop, htab_t map)
4056 basic_block after_scop = SCOP_EXIT (scop);
4057 edge e = SESE_EXIT (SCOP_REGION (scop));
4058 gimple_stmt_iterator gsi;
4060 for (gsi = gsi_start_phis (after_scop); !gsi_end_p (gsi); gsi_next (&gsi))
4061 rename_variables_from_edge (e, gsi_stmt (gsi), map);
4064 /* Remove condition from BB. */
4066 static void
4067 remove_condition (basic_block bb)
4069 gimple last = last_stmt (bb);
4071 if (last && gimple_code (last) == GIMPLE_COND)
4073 gimple_stmt_iterator gsi = gsi_last_bb (bb);
4074 gsi_remove (&gsi, true);
4078 /* Returns the first successor edge of BB with EDGE_TRUE_VALUE flag set. */
4080 static edge
4081 get_true_edge_from_guard_bb (basic_block bb)
4083 edge e;
4084 edge_iterator ei;
4086 FOR_EACH_EDGE (e, ei, bb->succs)
4087 if (e->flags & EDGE_TRUE_VALUE)
4088 return e;
4090 gcc_unreachable ();
4091 return NULL;
4094 /* Returns the first successor edge of BB with EDGE_TRUE_VALUE flag cleared. */
4096 static edge
4097 get_false_edge_from_guard_bb (basic_block bb)
4099 edge e;
4100 edge_iterator ei;
4102 FOR_EACH_EDGE (e, ei, bb->succs)
4103 if (!(e->flags & EDGE_TRUE_VALUE))
4104 return e;
4106 gcc_unreachable ();
4107 return NULL;
4110 /* Inserts in MAP a tuple (OLD_NAME, NEW_NAME) for the induction
4111 variables of the loops around GBB in SCOP, i.e. GBB_LOOPS.
4112 NEW_NAME is obtained from IVSTACK. IVSTACK has the same stack
4113 ordering as GBB_LOOPS. */
4115 static void
4116 build_iv_mapping (loop_iv_stack ivstack, htab_t map, gbb_p gbb, scop_p scop)
4118 int i;
4119 name_tree iv;
4120 PTR *slot;
4122 for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, iv); i++)
4124 struct rename_map_elt tmp;
4126 if (!flow_bb_inside_loop_p (iv->loop, GBB_BB (gbb)))
4127 continue;
4129 tmp.old_name = iv->t;
4130 slot = htab_find_slot (map, &tmp, INSERT);
4132 if (!*slot)
4134 tree new_name = loop_iv_stack_get_iv (ivstack,
4135 gbb_loop_index (gbb, iv->loop));
4136 *slot = new_rename_map_elt (iv->t, new_name);
4141 /* Register in MAP the tuple (old_name, new_name). */
4143 static void
4144 register_old_new_names (htab_t map, tree old_name, tree new_name)
4146 struct rename_map_elt tmp;
4147 PTR *slot;
4149 tmp.old_name = old_name;
4150 slot = htab_find_slot (map, &tmp, INSERT);
4152 if (!*slot)
4153 *slot = new_rename_map_elt (old_name, new_name);
4156 /* Create a duplicate of the basic block BB. NOTE: This does not
4157 preserve SSA form. */
4159 static void
4160 graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb, htab_t map)
4162 gimple_stmt_iterator gsi, gsi_tgt;
4164 gsi_tgt = gsi_start_bb (new_bb);
4165 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4167 def_operand_p def_p;
4168 ssa_op_iter op_iter;
4169 int region;
4170 gimple stmt = gsi_stmt (gsi);
4171 gimple copy;
4173 if (gimple_code (stmt) == GIMPLE_LABEL)
4174 continue;
4176 /* Create a new copy of STMT and duplicate STMT's virtual
4177 operands. */
4178 copy = gimple_copy (stmt);
4179 gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);
4180 mark_symbols_for_renaming (copy);
4182 region = lookup_stmt_eh_region (stmt);
4183 if (region >= 0)
4184 add_stmt_to_eh_region (copy, region);
4185 gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt);
4187 /* Create new names for all the definitions created by COPY and
4188 add replacement mappings for each new name. */
4189 FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_DEF)
4191 tree old_name = DEF_FROM_PTR (def_p);
4192 tree new_name = create_new_def_for (old_name, copy, def_p);
4193 register_old_new_names (map, old_name, new_name);
4198 /* Copies BB and includes in the copied BB all the statements that can
4199 be reached following the use-def chains from the memory accesses,
4200 and returns the next edge following this new block. */
4202 static edge
4203 copy_bb_and_scalar_dependences (basic_block bb, scop_p scop,
4204 loop_p context_loop,
4205 edge next_e, htab_t map)
4207 basic_block new_bb = split_edge (next_e);
4209 next_e = single_succ_edge (new_bb);
4210 graphite_copy_stmts_from_block (bb, new_bb, map);
4211 remove_condition (new_bb);
4212 rename_variables (new_bb, map);
4213 remove_phi_nodes (new_bb);
4214 expand_scalar_variables (new_bb, scop, context_loop, map);
4215 rename_phis_end_scop (scop, map);
4217 return next_e;
4220 /* Translates a CLAST statement STMT to GCC representation. NEXT_E is
4221 the edge where new generated code should be attached. BB_EXIT is the last
4222 basic block that defines the scope of code generation. CONTEXT_LOOP is the
4223 loop in which the generated code will be placed (might be NULL). */
4225 static edge
4226 translate_clast (scop_p scop, struct loop *context_loop,
4227 struct clast_stmt *stmt, edge next_e, loop_iv_stack ivstack)
4229 if (!stmt)
4230 return next_e;
4232 if (CLAST_STMT_IS_A (stmt, stmt_root))
4233 return translate_clast (scop, context_loop, stmt->next, next_e, ivstack);
4235 if (CLAST_STMT_IS_A (stmt, stmt_user))
4237 htab_t map;
4238 CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
4239 graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
4241 if (GBB_BB (gbb) == ENTRY_BLOCK_PTR)
4242 return next_e;
4244 map = htab_create (10, rename_map_elt_info, eq_rename_map_elts, free);
4245 loop_iv_stack_patch_for_consts (ivstack, (struct clast_user_stmt *) stmt);
4246 build_iv_mapping (ivstack, map, gbb, scop);
4247 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), scop,
4248 context_loop, next_e, map);
4249 htab_delete (map);
4250 loop_iv_stack_remove_constants (ivstack);
4251 update_ssa (TODO_update_ssa);
4252 recompute_all_dominators ();
4253 graphite_verify ();
4254 return translate_clast (scop, context_loop, stmt->next, next_e, ivstack);
4257 if (CLAST_STMT_IS_A (stmt, stmt_for))
4259 struct loop *loop
4260 = graphite_create_new_loop (scop, next_e, (struct clast_for *) stmt,
4261 ivstack, context_loop ? context_loop
4262 : get_loop (0));
4263 edge last_e = single_exit (loop);
4265 next_e = translate_clast (scop, loop, ((struct clast_for *) stmt)->body,
4266 single_pred_edge (loop->latch), ivstack);
4267 redirect_edge_succ_nodup (next_e, loop->latch);
4269 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
4270 loop_iv_stack_pop (ivstack);
4271 last_e = single_succ_edge (split_edge (last_e));
4272 recompute_all_dominators ();
4273 graphite_verify ();
4274 return translate_clast (scop, context_loop, stmt->next, last_e, ivstack);
4277 if (CLAST_STMT_IS_A (stmt, stmt_guard))
4279 edge last_e = graphite_create_new_guard (scop, next_e,
4280 ((struct clast_guard *) stmt),
4281 ivstack);
4282 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
4283 next_e = translate_clast (scop, context_loop,
4284 ((struct clast_guard *) stmt)->then,
4285 true_e, ivstack);
4286 graphite_verify ();
4287 return translate_clast (scop, context_loop, stmt->next, last_e, ivstack);
4290 if (CLAST_STMT_IS_A (stmt, stmt_block))
4292 next_e = translate_clast (scop, context_loop,
4293 ((struct clast_block *) stmt)->body,
4294 next_e, ivstack);
4295 graphite_verify ();
4296 return translate_clast (scop, context_loop, stmt->next, next_e, ivstack);
4299 gcc_unreachable ();
4302 /* Free the SCATTERING domain list. */
4304 static void
4305 free_scattering (CloogDomainList *scattering)
4307 while (scattering)
4309 CloogDomain *dom = cloog_domain (scattering);
4310 CloogDomainList *next = cloog_next_domain (scattering);
4312 cloog_domain_free (dom);
4313 free (scattering);
4314 scattering = next;
4318 /* Build cloog program for SCoP. */
4320 static void
4321 build_cloog_prog (scop_p scop)
4323 int i;
4324 int max_nb_loops = scop_max_loop_depth (scop);
4325 graphite_bb_p gbb;
4326 CloogLoop *loop_list = NULL;
4327 CloogBlockList *block_list = NULL;
4328 CloogDomainList *scattering = NULL;
4329 CloogProgram *prog = SCOP_PROG (scop);
4330 int nbs = 2 * max_nb_loops + 1;
4331 int *scaldims = (int *) xmalloc (nbs * (sizeof (int)));
4333 cloog_program_set_nb_scattdims (prog, nbs);
4334 initialize_cloog_names (scop);
4336 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++)
4338 /* Build new block. */
4339 CloogMatrix *domain = GBB_DOMAIN (gbb);
4340 CloogStatement *stmt = cloog_statement_alloc (GBB_BB (gbb)->index);
4341 CloogBlock *block = cloog_block_alloc (stmt, 0, NULL,
4342 nb_loops_around_gb (gbb));
4343 cloog_statement_set_usr (stmt, gbb);
4345 /* Add empty domain to all bbs, which do not yet have a domain, as they
4346 are not part of any loop. */
4347 if (domain == NULL)
4349 domain = cloog_matrix_alloc (0, scop_nb_params (scop) + 2);
4350 GBB_DOMAIN (gbb) = domain;
4353 /* Build loop list. */
4355 CloogLoop *new_loop_list = cloog_loop_malloc ();
4356 cloog_loop_set_next (new_loop_list, loop_list);
4357 cloog_loop_set_domain (new_loop_list,
4358 cloog_domain_matrix2domain (domain));
4359 cloog_loop_set_block (new_loop_list, block);
4360 loop_list = new_loop_list;
4363 /* Build block list. */
4365 CloogBlockList *new_block_list = cloog_block_list_malloc ();
4367 cloog_block_list_set_next (new_block_list, block_list);
4368 cloog_block_list_set_block (new_block_list, block);
4369 block_list = new_block_list;
4372 /* Build scattering list. */
4374 /* XXX: Replace with cloog_domain_list_alloc(), when available. */
4375 CloogDomainList *new_scattering
4376 = (CloogDomainList *) xmalloc (sizeof (CloogDomainList));
4377 CloogMatrix *scat_mat = schedule_to_scattering (gbb, nbs);
4379 cloog_set_next_domain (new_scattering, scattering);
4380 cloog_set_domain (new_scattering,
4381 cloog_domain_matrix2domain (scat_mat));
4382 scattering = new_scattering;
4383 cloog_matrix_free (scat_mat);
4387 cloog_program_set_loop (prog, loop_list);
4388 cloog_program_set_blocklist (prog, block_list);
4390 for (i = 0; i < nbs; i++)
4391 scaldims[i] = 0 ;
4393 cloog_program_set_scaldims (prog, scaldims);
4395 /* Extract scalar dimensions to simplify the code generation problem. */
4396 cloog_program_extract_scalars (prog, scattering);
4398 /* Apply scattering. */
4399 cloog_program_scatter (prog, scattering);
4400 free_scattering (scattering);
4402 /* Iterators corresponding to scalar dimensions have to be extracted. */
4403 cloog_names_scalarize (cloog_program_names (prog), nbs,
4404 cloog_program_scaldims (prog));
4406 /* Free blocklist. */
4408 CloogBlockList *next = cloog_program_blocklist (prog);
4410 while (next)
4412 CloogBlockList *toDelete = next;
4413 next = cloog_block_list_next (next);
4414 cloog_block_list_set_next (toDelete, NULL);
4415 cloog_block_list_set_block (toDelete, NULL);
4416 cloog_block_list_free (toDelete);
4418 cloog_program_set_blocklist (prog, NULL);
4422 /* Return the options that will be used in GLOOG. */
4424 static CloogOptions *
4425 set_cloog_options (void)
4427 CloogOptions *options = cloog_options_malloc ();
4429 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
4430 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
4431 we pass an incomplete program to cloog. */
4432 options->language = LANGUAGE_C;
4434 /* Enable complex equality spreading: removes dummy statements
4435 (assignments) in the generated code which repeats the
4436 substitution equations for statements. This is useless for
4437 GLooG. */
4438 options->esp = 1;
4440 /* Enable C pretty-printing mode: normalizes the substitution
4441 equations for statements. */
4442 options->cpp = 1;
4444 /* Allow cloog to build strides with a stride width different to one.
4445 This example has stride = 4:
4447 for (i = 0; i < 20; i += 4)
4448 A */
4449 options->strides = 1;
4451 /* Disable optimizations and make cloog generate source code closer to the
4452 input. This is useful for debugging, but later we want the optimized
4453 code.
4455 XXX: We can not disable optimizations, as loop blocking is not working
4456 without them. */
4457 if (0)
4459 options->f = -1;
4460 options->l = INT_MAX;
4463 return options;
4466 /* Prints STMT to STDERR. */
4468 void
4469 debug_clast_stmt (struct clast_stmt *stmt)
4471 CloogOptions *options = set_cloog_options ();
4473 pprint (stderr, stmt, 0, options);
4476 /* Find the right transform for the SCOP, and return a Cloog AST
4477 representing the new form of the program. */
4479 static struct clast_stmt *
4480 find_transform (scop_p scop)
4482 struct clast_stmt *stmt;
4483 CloogOptions *options = set_cloog_options ();
4485 /* Connect new cloog prog generation to graphite. */
4486 build_cloog_prog (scop);
4488 if (dump_file && (dump_flags & TDF_DETAILS))
4490 fprintf (dump_file, "Cloog Input [\n");
4491 cloog_program_print (dump_file, SCOP_PROG(scop));
4492 fprintf (dump_file, "]\n");
4495 SCOP_PROG (scop) = cloog_program_generate (SCOP_PROG (scop), options);
4496 stmt = cloog_clast_create (SCOP_PROG (scop), options);
4498 if (dump_file && (dump_flags & TDF_DETAILS))
4500 fprintf (dump_file, "Cloog Output[\n");
4501 pprint (dump_file, stmt, 0, options);
4502 cloog_program_dump_cloog (dump_file, SCOP_PROG (scop));
4503 fprintf (dump_file, "]\n");
4506 cloog_options_free (options);
4507 return stmt;
4510 /* Returns true when it is possible to generate code for this STMT.
4511 For the moment we cannot generate code when Cloog decides to
4512 duplicate a statement, as we do not do a copy, but a move.
4513 USED_BASIC_BLOCKS records the blocks that have already been seen.
4514 We return false if we have to generate code twice for the same
4515 block. */
4517 static bool
4518 can_generate_code_stmt (struct clast_stmt *stmt,
4519 struct pointer_set_t *used_basic_blocks)
4521 if (!stmt)
4522 return true;
4524 if (CLAST_STMT_IS_A (stmt, stmt_root))
4525 return can_generate_code_stmt (stmt->next, used_basic_blocks);
4527 if (CLAST_STMT_IS_A (stmt, stmt_user))
4529 CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
4530 graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
4532 if (pointer_set_contains (used_basic_blocks, gbb))
4533 return false;
4534 pointer_set_insert (used_basic_blocks, gbb);
4535 return can_generate_code_stmt (stmt->next, used_basic_blocks);
4538 if (CLAST_STMT_IS_A (stmt, stmt_for))
4539 return can_generate_code_stmt (((struct clast_for *) stmt)->body,
4540 used_basic_blocks)
4541 && can_generate_code_stmt (stmt->next, used_basic_blocks);
4543 if (CLAST_STMT_IS_A (stmt, stmt_guard))
4544 return can_generate_code_stmt (((struct clast_guard *) stmt)->then,
4545 used_basic_blocks);
4547 if (CLAST_STMT_IS_A (stmt, stmt_block))
4548 return can_generate_code_stmt (((struct clast_block *) stmt)->body,
4549 used_basic_blocks)
4550 && can_generate_code_stmt (stmt->next, used_basic_blocks);
4552 return false;
4555 /* Returns true when it is possible to generate code for this STMT. */
4557 static bool
4558 can_generate_code (struct clast_stmt *stmt)
4560 bool result;
4561 struct pointer_set_t *used_basic_blocks = pointer_set_create ();
4563 result = can_generate_code_stmt (stmt, used_basic_blocks);
4564 pointer_set_destroy (used_basic_blocks);
4565 return result;
4568 /* Remove from the CFG the REGION. */
4570 static inline void
4571 remove_sese_region (sese region)
4573 VEC (basic_block, heap) *bbs = NULL;
4574 basic_block entry_bb = SESE_ENTRY (region)->dest;
4575 basic_block exit_bb = SESE_EXIT (region)->dest;
4576 basic_block bb;
4577 int i;
4579 VEC_safe_push (basic_block, heap, bbs, entry_bb);
4580 gather_blocks_in_sese_region (entry_bb, exit_bb, &bbs);
4582 for (i = 0; VEC_iterate (basic_block, bbs, i, bb); i++)
4583 delete_basic_block (bb);
4585 VEC_free (basic_block, heap, bbs);
4588 typedef struct ifsese {
4589 sese region;
4590 sese true_region;
4591 sese false_region;
4592 } *ifsese;
4594 static inline edge
4595 if_region_entry (ifsese if_region)
4597 return SESE_ENTRY (if_region->region);
4600 static inline edge
4601 if_region_exit (ifsese if_region)
4603 return SESE_EXIT (if_region->region);
4606 static inline basic_block
4607 if_region_get_condition_block (ifsese if_region)
4609 return if_region_entry (if_region)->dest;
4612 static inline void
4613 if_region_set_false_region (ifsese if_region, sese region)
4615 basic_block condition = if_region_get_condition_block (if_region);
4616 edge false_edge = get_false_edge_from_guard_bb (condition);
4617 edge entry_region = SESE_ENTRY (region);
4618 edge exit_region = SESE_EXIT (region);
4619 basic_block before_region = entry_region->src;
4620 basic_block last_in_region = exit_region->src;
4621 void **slot = htab_find_slot_with_hash (current_loops->exits, exit_region,
4622 htab_hash_pointer (exit_region),
4623 NO_INSERT);
4625 entry_region->flags = false_edge->flags;
4626 false_edge->flags = exit_region->flags;
4628 redirect_edge_pred (entry_region, condition);
4629 redirect_edge_pred (exit_region, before_region);
4630 redirect_edge_pred (false_edge, last_in_region);
4632 exit_region->flags = EDGE_FALLTHRU;
4633 recompute_all_dominators ();
4635 SESE_EXIT (region) = single_succ_edge (false_edge->dest);
4636 if_region->false_region = region;
4638 if (slot)
4640 struct loop_exit *loop_exit = GGC_CNEW (struct loop_exit);
4642 memcpy (loop_exit, *((struct loop_exit **) slot), sizeof (struct loop_exit));
4643 htab_clear_slot (current_loops->exits, slot);
4645 slot = htab_find_slot_with_hash (current_loops->exits, false_edge,
4646 htab_hash_pointer (false_edge),
4647 INSERT);
4648 loop_exit->e = false_edge;
4649 *slot = loop_exit;
4650 false_edge->src->loop_father->exits->next = loop_exit;
4654 static ifsese
4655 create_if_region_on_edge (edge entry, tree condition)
4657 edge e;
4658 edge_iterator ei;
4659 sese sese_region = GGC_NEW (struct sese);
4660 sese true_region = GGC_NEW (struct sese);
4661 sese false_region = GGC_NEW (struct sese);
4662 ifsese if_region = GGC_NEW (struct ifsese);
4663 edge exit = create_empty_if_region_on_edge (entry, condition);
4665 if_region->region = sese_region;
4666 if_region->region->entry = entry;
4667 if_region->region->exit = exit;
4669 FOR_EACH_EDGE (e, ei, entry->dest->succs)
4671 if (e->flags & EDGE_TRUE_VALUE)
4673 true_region->entry = e;
4674 true_region->exit = single_succ_edge (e->dest);
4675 if_region->true_region = true_region;
4677 else if (e->flags & EDGE_FALSE_VALUE)
4679 false_region->entry = e;
4680 false_region->exit = single_succ_edge (e->dest);
4681 if_region->false_region = false_region;
4685 return if_region;
4688 /* Moves REGION in a condition expression:
4689 | if (1)
4691 | else
4692 | REGION;
4695 static ifsese
4696 move_sese_in_condition (sese region)
4698 basic_block pred_block = split_edge (SESE_ENTRY (region));
4699 ifsese if_region = NULL;
4701 SESE_ENTRY (region) = single_succ_edge (pred_block);
4702 if_region = create_if_region_on_edge (single_pred_edge (pred_block), integer_one_node);
4703 if_region_set_false_region (if_region, region);
4705 return if_region;
4708 /* Returns true when BB is in REGION. */
4710 static bool
4711 bb_in_sese_p (basic_block bb, sese region)
4713 return pointer_set_contains (SESE_REGION_BBS (region), bb);
4716 /* For USE in BB, if it is used outside of the REGION it is defined in,
4717 mark it for rewrite. Record basic block BB where it is used
4718 to USE_BLOCKS. Record the ssa name index to NEED_PHIS bitmap. */
4720 static void
4721 sese_find_uses_to_rename_use (sese region, basic_block bb, tree use,
4722 bitmap *use_blocks, bitmap need_phis)
4724 unsigned ver;
4725 basic_block def_bb;
4727 if (TREE_CODE (use) != SSA_NAME)
4728 return;
4730 ver = SSA_NAME_VERSION (use);
4731 def_bb = gimple_bb (SSA_NAME_DEF_STMT (use));
4732 if (!def_bb
4733 || !bb_in_sese_p (def_bb, region)
4734 || bb_in_sese_p (bb, region))
4735 return;
4737 if (!use_blocks[ver])
4738 use_blocks[ver] = BITMAP_ALLOC (NULL);
4739 bitmap_set_bit (use_blocks[ver], bb->index);
4741 bitmap_set_bit (need_phis, ver);
4744 /* Marks names that are used in BB and outside of the loop they are
4745 defined in for rewrite. Records the set of blocks in that the ssa
4746 names are defined to USE_BLOCKS. Record the SSA names that will
4747 need exit PHIs in NEED_PHIS. */
4749 static void
4750 sese_find_uses_to_rename_bb (sese region, basic_block bb,
4751 bitmap *use_blocks, bitmap need_phis)
4753 gimple_stmt_iterator bsi;
4754 edge e;
4755 edge_iterator ei;
4756 ssa_op_iter iter;
4757 tree var;
4759 FOR_EACH_EDGE (e, ei, bb->succs)
4760 for (bsi = gsi_start_phis (e->dest); !gsi_end_p (bsi); gsi_next (&bsi))
4761 sese_find_uses_to_rename_use (region, bb,
4762 PHI_ARG_DEF_FROM_EDGE (gsi_stmt (bsi), e),
4763 use_blocks, need_phis);
4765 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
4766 FOR_EACH_SSA_TREE_OPERAND (var, gsi_stmt (bsi), iter, SSA_OP_ALL_USES)
4767 sese_find_uses_to_rename_use (region, bb, var, use_blocks, need_phis);
4770 /* Add exit phis for USE on EXIT. */
4772 static void
4773 sese_add_exit_phis_edge (basic_block exit, tree use, edge false_e, edge true_e)
4775 gimple phi = create_phi_node (use, exit);
4777 create_new_def_for (gimple_phi_result (phi), phi,
4778 gimple_phi_result_ptr (phi));
4779 add_phi_arg (phi, use, false_e);
4780 add_phi_arg (phi, use, true_e);
4783 /* Add phi nodes for VAR that is used in LIVEIN. Phi nodes are
4784 inserted in block WHERE. */
4786 static void
4787 sese_add_exit_phis_var (basic_block where, tree var, bitmap livein,
4788 edge false_e, edge true_e)
4790 bitmap def;
4791 basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (var));
4793 if (is_gimple_reg (var))
4794 bitmap_clear_bit (livein, def_bb->index);
4795 else
4796 bitmap_set_bit (livein, def_bb->index);
4798 def = BITMAP_ALLOC (NULL);
4799 bitmap_set_bit (def, def_bb->index);
4800 compute_global_livein (livein, def);
4801 BITMAP_FREE (def);
4803 sese_add_exit_phis_edge (where, var, false_e, true_e);
4806 /* Insert in the block WHERE phi nodes for variables defined in REGION
4807 and used outside the REGION. */
4809 static void
4810 rewrite_into_sese_closed_ssa (sese region, basic_block where,
4811 edge false_e, edge true_e)
4813 unsigned i;
4814 basic_block bb;
4815 bitmap_iterator bi;
4816 bitmap names_to_rename = BITMAP_ALLOC (NULL);
4817 unsigned old_num_ssa_names = num_ssa_names;
4818 bitmap *use_blocks = XCNEWVEC (bitmap, old_num_ssa_names);
4820 update_ssa (TODO_update_ssa);
4822 FOR_EACH_BB (bb)
4823 sese_find_uses_to_rename_bb (region, bb, use_blocks, names_to_rename);
4825 EXECUTE_IF_SET_IN_BITMAP (names_to_rename, 0, i, bi)
4826 sese_add_exit_phis_var (where, ssa_name (i), use_blocks[i],
4827 false_e, true_e);
4829 update_ssa (TODO_update_ssa);
4831 for (i = 0; i < old_num_ssa_names; i++)
4832 BITMAP_FREE (use_blocks[i]);
4834 free (use_blocks);
4835 BITMAP_FREE (names_to_rename);
4838 /* Returns the first cloog name used in EXPR. */
4840 static const char *
4841 find_cloog_iv_in_expr (struct clast_expr *expr)
4843 struct clast_term *term = (struct clast_term *) expr;
4845 if (expr->type == expr_term
4846 && !term->var)
4847 return NULL;
4849 if (expr->type == expr_term)
4850 return term->var;
4852 if (expr->type == expr_red)
4854 int i;
4855 struct clast_reduction *red = (struct clast_reduction *) expr;
4857 for (i = 0; i < red->n; i++)
4859 const char *res = find_cloog_iv_in_expr ((red)->elts[i]);
4861 if (res)
4862 return res;
4866 return NULL;
4869 /* Build for a clast_user_stmt USER_STMT a map between the CLAST
4870 induction variables and the corresponding GCC old induction
4871 variables. This information is stored on each GRAPHITE_BB. */
4873 static void
4874 compute_cloog_iv_types_1 (graphite_bb_p gbb,
4875 struct clast_user_stmt *user_stmt)
4877 struct clast_stmt *t;
4878 int index = 0;
4880 for (t = user_stmt->substitutions; t; t = t->next, index++)
4882 PTR *slot;
4883 struct ivtype_map_elt tmp;
4884 struct clast_expr *expr = (struct clast_expr *)
4885 ((struct clast_assignment *)t)->RHS;
4887 /* Create an entry (clast_var, type). */
4888 tmp.cloog_iv = find_cloog_iv_in_expr (expr);
4889 if (!tmp.cloog_iv)
4890 continue;
4892 slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, INSERT);
4894 if (!*slot)
4896 loop_p loop = gbb_loop_at_index (gbb, index);
4897 tree oldiv = oldiv_for_loop (GBB_SCOP (gbb), loop);
4898 tree type = oldiv ? TREE_TYPE (oldiv) : integer_type_node;
4899 *slot = new_ivtype_map_elt (tmp.cloog_iv, type);
4904 /* Walk the CLAST tree starting from STMT and build for each
4905 clast_user_stmt a map between the CLAST induction variables and the
4906 corresponding GCC old induction variables. This information is
4907 stored on each GRAPHITE_BB. */
4909 static void
4910 compute_cloog_iv_types (struct clast_stmt *stmt)
4912 if (!stmt)
4913 return;
4915 if (CLAST_STMT_IS_A (stmt, stmt_root))
4916 goto next;
4918 if (CLAST_STMT_IS_A (stmt, stmt_user))
4920 CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
4921 graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
4922 GBB_CLOOG_IV_TYPES (gbb) = htab_create (10, ivtype_map_elt_info,
4923 eq_ivtype_map_elts, free);
4924 compute_cloog_iv_types_1 (gbb, (struct clast_user_stmt *) stmt);
4925 goto next;
4928 if (CLAST_STMT_IS_A (stmt, stmt_for))
4930 struct clast_stmt *s = ((struct clast_for *) stmt)->body;
4931 compute_cloog_iv_types (s);
4932 goto next;
4935 if (CLAST_STMT_IS_A (stmt, stmt_guard))
4937 struct clast_stmt *s = ((struct clast_guard *) stmt)->then;
4938 compute_cloog_iv_types (s);
4939 goto next;
4942 if (CLAST_STMT_IS_A (stmt, stmt_block))
4944 struct clast_stmt *s = ((struct clast_block *) stmt)->body;
4945 compute_cloog_iv_types (s);
4946 goto next;
4949 gcc_unreachable ();
4951 next:
4952 compute_cloog_iv_types (stmt->next);
4955 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
4956 the given SCOP. */
4958 static void
4959 gloog (scop_p scop, struct clast_stmt *stmt)
4961 edge new_scop_exit_edge = NULL;
4962 VEC (iv_stack_entry_p, heap) *ivstack = VEC_alloc (iv_stack_entry_p, heap,
4963 10);
4964 loop_p context_loop;
4965 ifsese if_region = NULL;
4967 if (!can_generate_code (stmt))
4969 cloog_clast_free (stmt);
4970 return;
4973 if_region = move_sese_in_condition (SCOP_REGION (scop));
4974 rewrite_into_sese_closed_ssa (SCOP_REGION (scop),
4975 if_region->region->exit->src,
4976 if_region->false_region->exit,
4977 if_region->true_region->exit);
4978 graphite_verify ();
4979 context_loop = SESE_ENTRY (SCOP_REGION (scop))->src->loop_father;
4980 compute_cloog_iv_types (stmt);
4981 new_scop_exit_edge = translate_clast (scop, context_loop,
4982 stmt, if_region->true_region->entry,
4983 &ivstack);
4984 graphite_verify ();
4985 cleanup_tree_cfg ();
4986 recompute_all_dominators ();
4987 graphite_verify ();
4988 free_loop_iv_stack (&ivstack);
4989 cloog_clast_free (stmt);
4992 /* Returns the number of data references in SCOP. */
4994 static int
4995 nb_data_refs_in_scop (scop_p scop)
4997 int i;
4998 graphite_bb_p gbb;
4999 int res = 0;
5001 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++)
5002 res += VEC_length (data_reference_p, GBB_DATA_REFS (gbb));
5004 return res;
5007 /* Move the loop at index LOOP and insert it before index NEW_LOOP_POS.
5008 This transformartion is only valid, if the loop nest between i and k is
5009 perfectly nested. Therefore we do not need to change the static schedule.
5011 Example:
5013 for (i = 0; i < 50; i++)
5014 for (j ...)
5015 for (k = 5; k < 100; k++)
5018 To move k before i use:
5020 graphite_trans_bb_move_loop (A, 2, 0)
5022 for (k = 5; k < 100; k++)
5023 for (i = 0; i < 50; i++)
5024 for (j ...)
5027 And to move k back:
5029 graphite_trans_bb_move_loop (A, 0, 2)
5031 This function does not check the validity of interchanging loops.
5032 This should be checked before calling this function. */
5034 static void
5035 graphite_trans_bb_move_loop (graphite_bb_p gb, int loop,
5036 int new_loop_pos)
5038 CloogMatrix *domain = GBB_DOMAIN (gb);
5039 int row, j;
5040 loop_p tmp_loop_p;
5042 gcc_assert (loop < gbb_nb_loops (gb)
5043 && new_loop_pos < gbb_nb_loops (gb));
5045 /* Update LOOPS vector. */
5046 tmp_loop_p = VEC_index (loop_p, GBB_LOOPS (gb), loop);
5047 VEC_ordered_remove (loop_p, GBB_LOOPS (gb), loop);
5048 VEC_safe_insert (loop_p, heap, GBB_LOOPS (gb), new_loop_pos, tmp_loop_p);
5050 /* Move the domain columns. */
5051 if (loop < new_loop_pos)
5052 for (row = 0; row < domain->NbRows; row++)
5054 Value tmp;
5055 value_init (tmp);
5056 value_assign (tmp, domain->p[row][loop + 1]);
5058 for (j = loop ; j < new_loop_pos - 1; j++)
5059 value_assign (domain->p[row][j + 1], domain->p[row][j + 2]);
5061 value_assign (domain->p[row][new_loop_pos], tmp);
5062 value_clear (tmp);
5064 else
5065 for (row = 0; row < domain->NbRows; row++)
5067 Value tmp;
5068 value_init (tmp);
5069 value_assign (tmp, domain->p[row][loop + 1]);
5071 for (j = loop ; j > new_loop_pos; j--)
5072 value_assign (domain->p[row][j + 1], domain->p[row][j]);
5074 value_assign (domain->p[row][new_loop_pos + 1], tmp);
5075 value_clear (tmp);
5079 /* Get the index of the column representing constants in the DOMAIN
5080 matrix. */
5082 static int
5083 const_column_index (CloogMatrix *domain)
5085 return domain->NbColumns - 1;
5089 /* Get the first index that is positive or negative, determined
5090 following the value of POSITIVE, in matrix DOMAIN in COLUMN. */
5092 static int
5093 get_first_matching_sign_row_index (CloogMatrix *domain, int column,
5094 bool positive)
5096 int row;
5098 for (row = 0; row < domain->NbRows; row++)
5100 int val = value_get_si (domain->p[row][column]);
5102 if (val > 0 && positive)
5103 return row;
5105 else if (val < 0 && !positive)
5106 return row;
5109 gcc_unreachable ();
5112 /* Get the lower bound of COLUMN in matrix DOMAIN. */
5114 static int
5115 get_lower_bound_row (CloogMatrix *domain, int column)
5117 return get_first_matching_sign_row_index (domain, column, true);
5120 /* Get the upper bound of COLUMN in matrix DOMAIN. */
5122 static int
5123 get_upper_bound_row (CloogMatrix *domain, int column)
5125 return get_first_matching_sign_row_index (domain, column, false);
5128 /* Get the lower bound of LOOP. */
5130 static void
5131 get_lower_bound (CloogMatrix *domain, int loop, Value lower_bound_result)
5133 int lower_bound_row = get_lower_bound_row (domain, loop);
5134 value_assign (lower_bound_result,
5135 domain->p[lower_bound_row][const_column_index(domain)]);
5138 /* Get the upper bound of LOOP. */
5140 static void
5141 get_upper_bound (CloogMatrix *domain, int loop, Value upper_bound_result)
5143 int upper_bound_row = get_upper_bound_row (domain, loop);
5144 value_assign (upper_bound_result,
5145 domain->p[upper_bound_row][const_column_index(domain)]);
5148 /* Strip mines the loop of BB at the position LOOP_DEPTH with STRIDE.
5149 Always valid, but not always a performance improvement. */
5151 static void
5152 graphite_trans_bb_strip_mine (graphite_bb_p gb, int loop_depth, int stride)
5154 int row, col;
5156 CloogMatrix *domain = GBB_DOMAIN (gb);
5157 CloogMatrix *new_domain = cloog_matrix_alloc (domain->NbRows + 3,
5158 domain->NbColumns + 1);
5160 int col_loop_old = loop_depth + 2;
5161 int col_loop_strip = col_loop_old - 1;
5163 Value old_lower_bound;
5164 Value old_upper_bound;
5166 gcc_assert (loop_depth <= gbb_nb_loops (gb) - 1);
5168 VEC_safe_insert (loop_p, heap, GBB_LOOPS (gb), loop_depth, NULL);
5170 GBB_DOMAIN (gb) = new_domain;
5173 nrows = 4, ncols = 4
5174 eq i j c
5175 1 1 0 0
5176 1 -1 0 99
5177 1 0 1 0
5178 1 0 -1 99
5181 /* Move domain. */
5182 for (row = 0; row < domain->NbRows; row++)
5183 for (col = 0; col < domain->NbColumns; col++)
5184 if (col <= loop_depth)
5185 value_assign (new_domain->p[row][col], domain->p[row][col]);
5186 else
5187 value_assign (new_domain->p[row][col + 1], domain->p[row][col]);
5191 nrows = 6, ncols = 5
5192 outer inner
5193 eq i jj j c
5194 1 1 0 0 0
5195 1 -1 0 0 99
5196 1 0 0 1 0
5197 1 0 0 -1 99
5198 0 0 0 0 0
5199 0 0 0 0 0
5200 0 0 0 0 0
5203 row = domain->NbRows;
5205 /* Add outer loop. */
5206 value_init (old_lower_bound);
5207 value_init (old_upper_bound);
5208 get_lower_bound (new_domain, col_loop_old, old_lower_bound);
5209 get_upper_bound (new_domain, col_loop_old, old_upper_bound);
5211 /* Set Lower Bound */
5212 value_set_si (new_domain->p[row][0], 1);
5213 value_set_si (new_domain->p[row][col_loop_strip], 1);
5214 value_assign (new_domain->p[row][const_column_index (new_domain)],
5215 old_lower_bound);
5216 value_clear (old_lower_bound);
5217 row++;
5222 eq i jj j c
5223 1 1 0 0 0
5224 1 -1 0 0 99
5225 1 0 0 1 0 -
5226 1 0 0 -1 99 | copy old lower bound
5227 1 0 1 0 0 <-
5228 0 0 0 0 0
5229 0 0 0 0 0
5233 Value new_upper_bound;
5234 Value strip_size_value;
5236 value_init (new_upper_bound);
5237 value_init (strip_size_value);
5238 value_set_si (strip_size_value, (int) stride);
5240 value_pdivision (new_upper_bound, old_upper_bound, strip_size_value);
5241 value_add_int (new_upper_bound, new_upper_bound, 1);
5243 /* Set Upper Bound */
5244 value_set_si (new_domain->p[row][0], 1);
5245 value_set_si (new_domain->p[row][col_loop_strip], -1);
5246 value_assign (new_domain->p[row][const_column_index (new_domain)],
5247 new_upper_bound);
5249 value_clear (strip_size_value);
5250 value_clear (old_upper_bound);
5251 value_clear (new_upper_bound);
5252 row++;
5256 eq i jj j c
5257 1 1 0 0 0
5258 1 -1 0 0 99
5259 1 0 0 1 0
5260 1 0 0 -1 99
5261 1 0 1 0 0
5262 1 0 -1 0 25 (divide old upper bound with stride)
5263 0 0 0 0 0
5267 row = get_lower_bound_row (new_domain, col_loop_old);
5268 /* Add local variable to keep linear representation. */
5269 value_set_si (new_domain->p[row][0], 1);
5270 value_set_si (new_domain->p[row][const_column_index (new_domain)],0);
5271 value_set_si (new_domain->p[row][col_loop_old], 1);
5272 value_set_si (new_domain->p[row][col_loop_strip], -1*((int)stride));
5277 eq i jj j c
5278 1 1 0 0 0
5279 1 -1 0 0 99
5280 1 0 -1 1 0
5281 1 0 0 -1 99
5282 1 0 1 0 0
5283 1 0 -1 0 25 (divide old upper bound with stride)
5284 0 0 0 0 0
5288 row = new_domain->NbRows-1;
5290 value_set_si (new_domain->p[row][0], 1);
5291 value_set_si (new_domain->p[row][col_loop_old], -1);
5292 value_set_si (new_domain->p[row][col_loop_strip], stride);
5293 value_set_si (new_domain->p[row][const_column_index (new_domain)],
5294 stride-1);
5299 eq i jj j c
5300 1 1 0 0 0 i >= 0
5301 1 -1 0 0 99 99 >= i
5302 1 0 -4 1 0 j >= 4*jj
5303 1 0 0 -1 99 99 >= j
5304 1 0 1 0 0 jj >= 0
5305 1 0 -1 0 25 25 >= jj
5306 0 0 4 -1 3 jj+3 >= j
5309 cloog_matrix_free (domain);
5311 /* Update static schedule. */
5313 int i;
5314 int nb_loops = gbb_nb_loops (gb);
5315 lambda_vector new_schedule = lambda_vector_new (nb_loops + 1);
5317 for (i = 0; i <= loop_depth; i++)
5318 new_schedule[i] = GBB_STATIC_SCHEDULE (gb)[i];
5320 for (i = loop_depth + 1; i <= nb_loops - 2; i++)
5321 new_schedule[i + 2] = GBB_STATIC_SCHEDULE (gb)[i];
5323 GBB_STATIC_SCHEDULE (gb) = new_schedule;
5327 /* Returns true when the strip mining of LOOP_INDEX by STRIDE is
5328 profitable or undecidable. GB is the statement around which the
5329 loops will be strip mined. */
5331 static bool
5332 strip_mine_profitable_p (graphite_bb_p gb, int stride,
5333 int loop_index)
5335 bool res = true;
5336 edge exit = NULL;
5337 tree niter;
5338 loop_p loop;
5339 long niter_val;
5341 loop = VEC_index (loop_p, GBB_LOOPS (gb), loop_index);
5342 exit = single_exit (loop);
5344 niter = find_loop_niter (loop, &exit);
5345 if (niter == chrec_dont_know
5346 || TREE_CODE (niter) != INTEGER_CST)
5347 return true;
5349 niter_val = int_cst_value (niter);
5351 if (niter_val < stride)
5353 res = false;
5354 if (dump_file && (dump_flags & TDF_DETAILS))
5356 fprintf (dump_file, "\nStrip Mining is not profitable for loop %d:",
5357 loop_index);
5358 fprintf (dump_file, "number of iterations is too low.\n");
5362 return res;
5365 /* Determines when the interchange of LOOP_A and LOOP_B belonging to
5366 SCOP is legal. */
5368 static bool
5369 is_interchange_valid (scop_p scop, int loop_a, int loop_b)
5371 bool res;
5372 VEC (ddr_p, heap) *dependence_relations;
5373 VEC (data_reference_p, heap) *datarefs;
5375 struct loop *nest = VEC_index (loop_p, SCOP_LOOP_NEST (scop), loop_a);
5376 int depth = perfect_loop_nest_depth (nest);
5377 lambda_trans_matrix trans;
5379 gcc_assert (loop_a < loop_b);
5381 dependence_relations = VEC_alloc (ddr_p, heap, 10 * 10);
5382 datarefs = VEC_alloc (data_reference_p, heap, 10);
5384 if (!compute_data_dependences_for_loop (nest, true, &datarefs,
5385 &dependence_relations))
5386 return false;
5388 if (dump_file && (dump_flags & TDF_DETAILS))
5389 dump_ddrs (dump_file, dependence_relations);
5391 trans = lambda_trans_matrix_new (depth, depth);
5392 lambda_matrix_id (LTM_MATRIX (trans), depth);
5394 lambda_matrix_row_exchange (LTM_MATRIX (trans), 0, loop_b - loop_a);
5396 if (!lambda_transform_legal_p (trans, depth, dependence_relations))
5398 lambda_matrix_row_exchange (LTM_MATRIX (trans), 0, loop_b - loop_a);
5399 res = false;
5401 else
5402 res = true;
5404 free_dependence_relations (dependence_relations);
5405 free_data_refs (datarefs);
5406 return res;
5409 /* Loop block the LOOPS innermost loops of GB with stride size STRIDE.
5411 Example
5413 for (i = 0; i <= 50; i++=4)
5414 for (k = 0; k <= 100; k++=4)
5415 for (l = 0; l <= 200; l++=4)
5418 To strip mine the two inner most loops with stride = 4 call:
5420 graphite_trans_bb_block (A, 4, 2)
5422 for (i = 0; i <= 50; i++)
5423 for (kk = 0; kk <= 100; kk+=4)
5424 for (ll = 0; ll <= 200; ll+=4)
5425 for (k = kk; k <= min (100, kk + 3); k++)
5426 for (l = ll; l <= min (200, ll + 3); l++)
5430 static bool
5431 graphite_trans_bb_block (graphite_bb_p gb, int stride, int loops)
5433 int i, j;
5434 int nb_loops = gbb_nb_loops (gb);
5435 int start = nb_loops - loops;
5436 scop_p scop = GBB_SCOP (gb);
5438 gcc_assert (scop_contains_loop (scop, gbb_loop (gb)));
5440 for (i = start ; i < nb_loops; i++)
5441 for (j = i + 1; j < nb_loops; j++)
5442 if (!is_interchange_valid (scop, i, j))
5444 if (dump_file && (dump_flags & TDF_DETAILS))
5445 fprintf (dump_file,
5446 "\nInterchange not valid for loops %d and %d:\n", i, j);
5447 return false;
5449 else if (dump_file && (dump_flags & TDF_DETAILS))
5450 fprintf (dump_file,
5451 "\nInterchange valid for loops %d and %d:\n", i, j);
5453 /* Check if strip mining is profitable for every loop. */
5454 for (i = 0; i < nb_loops - start; i++)
5455 if (!strip_mine_profitable_p (gb, stride, start + i))
5456 return false;
5458 /* Strip mine loops. */
5459 for (i = 0; i < nb_loops - start; i++)
5460 graphite_trans_bb_strip_mine (gb, start + 2 * i, stride);
5462 /* Interchange loops. */
5463 for (i = 1; i < nb_loops - start; i++)
5464 graphite_trans_bb_move_loop (gb, start + 2 * i, start + i);
5466 return true;
5469 /* Loop block LOOPS innermost loops of a loop nest. BBS represent the
5470 basic blocks that belong to the loop nest to be blocked. */
5472 static bool
5473 graphite_trans_loop_block (VEC (graphite_bb_p, heap) *bbs, int loops)
5475 graphite_bb_p gb;
5476 int i;
5477 bool transform_done = false;
5479 /* TODO: - Calculate the stride size automatically. */
5480 int stride_size = 64;
5482 for (i = 0; VEC_iterate (graphite_bb_p, bbs, i, gb); i++)
5483 transform_done |= graphite_trans_bb_block (gb, stride_size, loops);
5485 return transform_done;
5488 /* Loop block all basic blocks of SCOP. Return false when the
5489 transform is not performed. */
5491 static bool
5492 graphite_trans_scop_block (scop_p scop)
5494 graphite_bb_p gb;
5495 int i, j;
5496 int last_nb_loops;
5497 int nb_loops;
5498 bool perfect = true;
5499 bool transform_done = false;
5501 VEC (graphite_bb_p, heap) *bbs = VEC_alloc (graphite_bb_p, heap, 3);
5502 int max_schedule = scop_max_loop_depth (scop) + 1;
5503 lambda_vector last_schedule = lambda_vector_new (max_schedule);
5505 if (VEC_length (graphite_bb_p, SCOP_BBS (scop)) == 0)
5506 return false;
5508 /* Get the data of the first bb. */
5509 gb = VEC_index (graphite_bb_p, SCOP_BBS (scop), 0);
5510 last_nb_loops = gbb_nb_loops (gb);
5511 lambda_vector_copy (GBB_STATIC_SCHEDULE (gb), last_schedule,
5512 last_nb_loops + 1);
5513 VEC_safe_push (graphite_bb_p, heap, bbs, gb);
5515 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
5517 /* We did the first bb before. */
5518 if (i == 0)
5519 continue;
5521 nb_loops = gbb_nb_loops (gb);
5523 /* If the number of loops is unchanged and only the last element of the
5524 schedule changes, we stay in the loop nest. */
5525 if (nb_loops == last_nb_loops
5526 && (last_schedule [nb_loops + 1]
5527 != GBB_STATIC_SCHEDULE (gb)[nb_loops + 1]))
5529 VEC_safe_push (graphite_bb_p, heap, bbs, gb);
5530 continue;
5533 /* Otherwise, we left the innermost loop. So check, if the last bb was in
5534 a perfect loop nest and how many loops are contained in this perfect
5535 loop nest.
5537 Count the number of zeros from the end of the schedule. They are the
5538 number of surrounding loops.
5540 Example:
5541 last_bb 2 3 2 0 0 0 0 3
5542 bb 2 4 0
5543 <------ j = 4
5545 last_bb 2 3 2 0 0 0 0 3
5546 bb 2 3 2 0 1
5547 <-- j = 2
5549 If there is no zero, there were other bbs in outer loops and the loop
5550 nest is not perfect. */
5551 for (j = last_nb_loops - 1; j >= 0; j--)
5553 if (last_schedule [j] != 0
5554 || (j <= nb_loops && GBB_STATIC_SCHEDULE (gb)[j] == 1))
5556 j--;
5557 break;
5561 j++;
5563 /* Found perfect loop nest. */
5564 if (perfect && last_nb_loops - j >= 2)
5565 transform_done |= graphite_trans_loop_block (bbs, last_nb_loops - j);
5567 /* Check if we start with a new loop.
5569 Example:
5571 last_bb 2 3 2 0 0 0 0 3
5572 bb 2 3 2 0 0 1 0
5574 Here we start with the loop "2 3 2 0 0 1"
5576 last_bb 2 3 2 0 0 0 0 3
5577 bb 2 3 2 0 0 1
5579 But here not, so the loop nest can never be perfect. */
5581 perfect = (GBB_STATIC_SCHEDULE (gb)[nb_loops] == 0);
5583 /* Update the last_bb infos. We do not do that for the bbs in the same
5584 loop, as the data we use is not changed. */
5585 last_nb_loops = nb_loops;
5586 lambda_vector_copy (GBB_STATIC_SCHEDULE (gb), last_schedule,
5587 nb_loops + 1);
5588 VEC_truncate (graphite_bb_p, bbs, 0);
5589 VEC_safe_push (graphite_bb_p, heap, bbs, gb);
5592 /* Check if the last loop nest was perfect. It is the same check as above,
5593 but the comparison with the next bb is missing. */
5594 for (j = last_nb_loops - 1; j >= 0; j--)
5595 if (last_schedule [j] != 0)
5597 j--;
5598 break;
5601 j++;
5603 /* Found perfect loop nest. */
5604 if (last_nb_loops - j > 0)
5605 transform_done |= graphite_trans_loop_block (bbs, last_nb_loops - j);
5606 VEC_free (graphite_bb_p, heap, bbs);
5608 if (dump_file && (dump_flags & TDF_DETAILS))
5609 fprintf (dump_file, "\nLoop blocked.\n");
5611 return transform_done;
5614 /* Apply graphite transformations to all the basic blocks of SCOP. */
5616 static bool
5617 graphite_apply_transformations (scop_p scop)
5619 bool transform_done = false;
5621 /* Sort the list of bbs. Keep them always sorted. */
5622 graphite_sort_gbbs (scop);
5624 if (flag_loop_block)
5625 transform_done = graphite_trans_scop_block (scop);
5627 /* Generate code even if we did not apply any real transformation.
5628 This also allows to check the performance for the identity
5629 transformation: GIMPLE -> GRAPHITE -> GIMPLE
5630 Keep in mind that CLooG optimizes in control, so the loop structure
5631 may change, even if we only use -fgraphite-identity. */
5632 if (flag_graphite_identity)
5633 transform_done = true;
5635 return transform_done;
5638 /* We limit all SCoPs to SCoPs, that are completely surrounded by a loop.
5640 Example:
5642 for (i |
5644 for (j | SCoP 1
5645 for (k |
5648 * SCoP frontier, as this line is not surrounded by any loop. *
5650 for (l | SCoP 2
5652 This is necessary as scalar evolution and parameter detection need a
5653 outermost loop to initialize parameters correctly.
5655 TODO: FIX scalar evolution and parameter detection to allow more flexible
5656 SCoP frontiers. */
5658 static void
5659 limit_scops (void)
5661 VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap, 3);
5663 int i;
5664 scop_p scop;
5666 for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
5668 int j;
5669 loop_p loop;
5670 build_scop_bbs (scop);
5672 if (!build_scop_loop_nests (scop))
5673 continue;
5675 for (j = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), j, loop); j++)
5676 if (!loop_in_scop_p (loop_outer (loop), scop))
5678 sd_region open_scop;
5679 open_scop.entry = loop->header;
5680 open_scop.exit = single_exit (loop)->dest;
5681 VEC_safe_push (sd_region, heap, tmp_scops, &open_scop);
5685 free_scops (current_scops);
5686 current_scops = VEC_alloc (scop_p, heap, 3);
5688 create_sese_edges (tmp_scops);
5689 build_graphite_scops (tmp_scops);
5690 VEC_free (sd_region, heap, tmp_scops);
5693 /* Perform a set of linear transforms on the loops of the current
5694 function. */
5696 void
5697 graphite_transform_loops (void)
5699 int i;
5700 scop_p scop;
5702 if (number_of_loops () <= 1)
5703 return;
5705 current_scops = VEC_alloc (scop_p, heap, 3);
5706 recompute_all_dominators ();
5708 if (dump_file && (dump_flags & TDF_DETAILS))
5709 fprintf (dump_file, "Graphite loop transformations \n");
5711 initialize_original_copy_tables ();
5712 cloog_initialize ();
5713 build_scops ();
5714 limit_scops ();
5716 if (dump_file && (dump_flags & TDF_DETAILS))
5717 fprintf (dump_file, "\nnumber of SCoPs: %d\n",
5718 VEC_length (scop_p, current_scops));
5720 for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
5722 build_scop_bbs (scop);
5723 if (!build_scop_loop_nests (scop))
5724 continue;
5726 build_scop_canonical_schedules (scop);
5727 build_bb_loops (scop);
5728 build_scop_conditions (scop);
5729 find_scop_parameters (scop);
5730 build_scop_context (scop);
5732 if (dump_file && (dump_flags & TDF_DETAILS))
5734 fprintf (dump_file, "\n(In SCoP %d:\n", i);
5735 fprintf (dump_file, "\nnumber of bbs: %d\n",
5736 VEC_length (graphite_bb_p, SCOP_BBS (scop)));
5737 fprintf (dump_file, "\nnumber of loops: %d)\n",
5738 VEC_length (loop_p, SCOP_LOOP_NEST (scop)));
5741 if (!build_scop_iteration_domain (scop))
5742 continue;
5744 build_scop_data_accesses (scop);
5745 build_scop_dynamic_schedules (scop);
5747 if (dump_file && (dump_flags & TDF_DETAILS))
5749 int nbrefs = nb_data_refs_in_scop (scop);
5750 fprintf (dump_file, "\nnumber of data refs: %d\n", nbrefs);
5753 if (graphite_apply_transformations (scop))
5754 gloog (scop, find_transform (scop));
5755 #ifdef ENABLE_CHECKING
5756 else
5758 struct clast_stmt *stmt = find_transform (scop);
5759 cloog_clast_free (stmt);
5761 #endif
5764 /* Cleanup. */
5765 free_scops (current_scops);
5766 cloog_finalize ();
5767 free_original_copy_tables ();
5770 #else /* If Cloog is not available: #ifndef HAVE_cloog. */
5772 void
5773 graphite_transform_loops (void)
5775 sorry ("Graphite loop optimizations cannot be used");
5778 #endif