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)
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
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
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. */
37 #include "coretypes.h"
42 #include "basic-block.h"
43 #include "diagnostic.h"
44 #include "tree-flow.h"
46 #include "tree-dump.h"
49 #include "tree-chrec.h"
50 #include "tree-data-ref.h"
51 #include "tree-scalar-evolution.h"
52 #include "tree-pass.h"
54 #include "pointer-set.h"
58 #include "cloog/cloog.h"
61 static VEC (scop_p, heap) *current_scops;
63 /* Debug the list of old induction variables for this SCOP. */
66 debug_oldivs (scop_p scop)
71 fprintf (stderr, "Old IVs:");
73 for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, oldiv); i++)
75 fprintf (stderr, "(");
76 print_generic_expr (stderr, oldiv->t, 0);
77 fprintf (stderr, ", %s, %d)\n", oldiv->name, oldiv->loop->num);
79 fprintf (stderr, "\n");
82 /* Debug the loops around basic block GB. */
85 debug_loop_vec (graphite_bb_p gb)
90 fprintf (stderr, "Loop Vec:");
92 for (i = 0; VEC_iterate (loop_p, GBB_LOOPS (gb), i, loop); i++)
93 fprintf (stderr, "%d: %d, ", i, loop ? loop->num : -1);
95 fprintf (stderr, "\n");
98 /* Push (IV, NAME) on STACK. */
101 loop_iv_stack_push (loop_iv_stack stack, tree iv, const char *name)
103 name_tree named_iv = XNEW (struct name_tree);
106 named_iv->name = name;
107 VEC_safe_push (name_tree, heap, *stack, named_iv);
110 /* Pops an element out of STACK. */
113 loop_iv_stack_pop (loop_iv_stack stack)
115 VEC_pop (name_tree, *stack);
118 /* Get the IV at INDEX in STACK. */
121 loop_iv_stack_get_iv (loop_iv_stack stack, int index)
123 name_tree named_iv = VEC_index (name_tree, *stack, index);
128 /* Get the IV from its NAME in STACK. */
131 loop_iv_stack_get_iv_from_name (loop_iv_stack stack, const char* name)
136 for (i = 0; VEC_iterate (name_tree, *stack, i, iv); i++)
137 if (!strcmp (name, iv->name))
143 /* Prints on stderr the contents of STACK. */
146 loop_iv_stack_debug (loop_iv_stack stack)
152 fprintf (stderr, "(");
154 for (i = 0; VEC_iterate (name_tree, *stack, i, iv); i++)
159 fprintf (stderr, " ");
160 fprintf (stderr, "%s:", iv->name);
161 print_generic_expr (stderr, iv->t, 0);
164 fprintf (stderr, ")\n");
167 /* In SCOP, get the induction variable from NAME. OLD is the original
168 loop that contained the definition of NAME. */
171 get_old_iv_from_ssa_name (scop_p scop, loop_p old, tree name)
173 tree var = SSA_NAME_VAR (name);
177 for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, oldiv); i++)
179 loop_p current = old;
184 && oldiv->loop == current)
187 current = loop_outer (current);
194 /* Returns a new loop_to_cloog_loop_str structure. */
196 static inline struct loop_to_cloog_loop_str *
197 new_loop_to_cloog_loop_str (int loop_num,
199 CloogLoop *cloog_loop)
201 struct loop_to_cloog_loop_str *result;
203 result = XNEW (struct loop_to_cloog_loop_str);
204 result->loop_num = loop_num;
205 result->cloog_loop = cloog_loop;
206 result->loop_position = loop_position;
211 /* Hash function for SCOP_LOOP2CLOOG_LOOP hash table. */
214 hash_loop_to_cloog_loop (const void *elt)
216 return ((const struct loop_to_cloog_loop_str *) elt)->loop_num;
219 /* Equality function for SCOP_LOOP2CLOOG_LOOP hash table. */
222 eq_loop_to_cloog_loop (const void *el1, const void *el2)
224 const struct loop_to_cloog_loop_str *elt1, *elt2;
226 elt1 = (const struct loop_to_cloog_loop_str *) el1;
227 elt2 = (const struct loop_to_cloog_loop_str *) el2;
228 return elt1->loop_num == elt2->loop_num;
231 /* Compares two graphite bbs and returns an integer less than, equal to, or
232 greater than zero if the first argument is considered to be respectively
233 less than, equal to, or greater than the second.
234 We compare using the lexicographic order of the static schedules. */
237 gbb_compare (const void *p_1, const void *p_2)
239 const struct graphite_bb *const gbb_1
240 = *(const struct graphite_bb *const*) p_1;
241 const struct graphite_bb *const gbb_2
242 = *(const struct graphite_bb *const*) p_2;
244 return lambda_vector_compare (GBB_STATIC_SCHEDULE (gbb_1),
245 gbb_nb_loops (gbb_1) + 1,
246 GBB_STATIC_SCHEDULE (gbb_2),
247 gbb_nb_loops (gbb_2) + 1);
250 /* Sort graphite bbs in SCOP. */
253 graphite_sort_gbbs (scop_p scop)
255 VEC (graphite_bb_p, heap) *bbs = SCOP_BBS (scop);
257 qsort (VEC_address (graphite_bb_p, bbs),
258 VEC_length (graphite_bb_p, bbs),
259 sizeof (graphite_bb_p), gbb_compare);
262 /* Dump conditions of a graphite basic block GBB on FILE. */
265 dump_gbb_conditions (FILE *file, graphite_bb_p gbb)
269 VEC (gimple, heap) *conditions = GBB_CONDITIONS (gbb);
271 if (VEC_empty (gimple, conditions))
274 fprintf (file, "\tbb %d\t: cond = {", GBB_BB (gbb)->index);
276 for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
277 print_gimple_stmt (file, stmt, 0, 0);
279 fprintf (file, "}\n");
282 /* Converts the graphite scheduling function into a cloog scattering
283 matrix. This scattering matrix is used to limit the possible cloog
284 output to valid programs in respect to the scheduling function.
286 SCATTERING_DIMENSIONS specifies the dimensionality of the scattering
287 matrix. CLooG 0.14.0 and previous versions require, that all scattering
288 functions of one CloogProgram have the same dimensionality, therefore we
289 allow to specify it. (Should be removed in future versions) */
292 schedule_to_scattering (graphite_bb_p gb, int scattering_dimensions)
295 scop_p scop = GBB_SCOP (gb);
297 int nb_iterators = gbb_nb_loops (gb);
299 /* The cloog scattering matrix consists of these colums:
301 scattering_dimensions cols = Scattering dimensions,
302 nb_iterators cols = bb's iterators,
303 scop_nb_params cols = Parameters,
308 scattering_dimensions = 5
318 s1 s2 s3 s4 s5 i p1 p2 1
319 1 0 0 0 0 0 0 0 -4 = 0
320 0 1 0 0 0 -1 0 0 0 = 0
321 0 0 1 0 0 0 0 0 -5 = 0 */
322 int nb_params = scop_nb_params (scop);
323 int nb_cols = 1 + scattering_dimensions + nb_iterators + nb_params + 1;
324 int col_const = nb_cols - 1;
325 int col_iter_offset = 1 + scattering_dimensions;
327 CloogMatrix *scat = cloog_matrix_alloc (scattering_dimensions, nb_cols);
329 gcc_assert (scattering_dimensions >= nb_iterators * 2 + 1);
331 /* Initialize the identity matrix. */
332 for (i = 0; i < scattering_dimensions; i++)
333 value_set_si (scat->p[i][i + 1], 1);
335 /* Textual order outside the first loop */
336 value_set_si (scat->p[0][col_const], -GBB_STATIC_SCHEDULE (gb)[0]);
338 /* For all surrounding loops. */
339 for (i = 0; i < nb_iterators; i++)
341 int schedule = GBB_STATIC_SCHEDULE (gb)[i + 1];
343 /* Iterations of this loop. */
344 value_set_si (scat->p[2 * i + 1][col_iter_offset + i], -1);
346 /* Textual order inside this loop. */
347 value_set_si (scat->p[2 * i + 2][col_const], -schedule);
353 /* Print the schedules of GB to FILE with INDENT white spaces before.
354 VERBOSITY determines how verbose the code pretty printers are. */
357 print_graphite_bb (FILE *file, graphite_bb_p gb, int indent, int verbosity)
359 CloogMatrix *scattering;
362 fprintf (file, "\nGBB (\n");
364 print_loops_bb (file, GBB_BB (gb), indent+2, verbosity);
368 fprintf (file, " (domain: \n");
369 cloog_matrix_print (dump_file, GBB_DOMAIN (gb));
370 fprintf (file, " )\n");
373 if (GBB_STATIC_SCHEDULE (gb))
375 fprintf (file, " (static schedule: ");
376 print_lambda_vector (file, GBB_STATIC_SCHEDULE (gb),
377 gbb_nb_loops (gb) + 1);
378 fprintf (file, " )\n");
383 fprintf (file, " (contained loops: \n");
384 for (i = 0; VEC_iterate (loop_p, GBB_LOOPS (gb), i, loop); i++)
386 fprintf (file, " iterator %d => NULL \n", i);
388 fprintf (file, " iterator %d => loop %d \n", i,
390 fprintf (file, " )\n");
393 if (GBB_DATA_REFS (gb))
394 dump_data_references (file, GBB_DATA_REFS (gb));
396 if (GBB_CONDITIONS (gb))
398 fprintf (file, " (conditions: \n");
399 dump_gbb_conditions (dump_file, gb);
400 fprintf (file, " )\n");
404 && GBB_STATIC_SCHEDULE (gb))
406 fprintf (file, " (scattering: \n");
407 scattering = schedule_to_scattering (gb, 2 * gbb_nb_loops (gb) + 1);
408 cloog_matrix_print (file, scattering);
409 cloog_matrix_free (scattering);
410 fprintf (file, " )\n");
413 fprintf (file, ")\n");
416 /* Print to STDERR the schedules of GB with VERBOSITY level. */
419 debug_gbb (graphite_bb_p gb, int verbosity)
421 print_graphite_bb (stderr, gb, 0, verbosity);
425 /* Print SCOP to FILE. VERBOSITY determines how verbose the pretty
429 print_scop (FILE *file, scop_p scop, int verbosity)
434 fprintf (file, "\nSCoP_%d_%d (\n",
435 SCOP_ENTRY (scop)->index, SCOP_EXIT (scop)->index);
437 fprintf (file, " (cloog: \n");
438 cloog_program_print (file, SCOP_PROG (scop));
439 fprintf (file, " )\n");
446 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
447 print_graphite_bb (file, gb, 0, verbosity);
450 fprintf (file, ")\n");
453 /* Print all the SCOPs to FILE. VERBOSITY determines how verbose the
454 code pretty printers are. */
457 print_scops (FILE *file, int verbosity)
462 for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
463 print_scop (file, scop, verbosity);
466 /* Debug SCOP. VERBOSITY determines how verbose the code pretty
470 debug_scop (scop_p scop, int verbosity)
472 print_scop (stderr, scop, verbosity);
475 /* Debug all SCOPs from CURRENT_SCOPS. VERBOSITY determines how
476 verbose the code pretty printers are. */
479 debug_scops (int verbosity)
481 print_scops (stderr, verbosity);
484 /* Return true when BB is contained in SCOP. */
487 bb_in_scop_p (basic_block bb, scop_p scop)
489 return bitmap_bit_p (SCOP_BBS_B (scop), bb->index);
492 /* Pretty print to FILE the SCOP in DOT format. */
495 dot_scop_1 (FILE *file, scop_p scop)
500 basic_block entry = SCOP_ENTRY (scop);
501 basic_block exit = SCOP_EXIT (scop);
503 fprintf (file, "digraph SCoP_%d_%d {\n", entry->index,
509 fprintf (file, "%d [shape=triangle];\n", bb->index);
512 fprintf (file, "%d [shape=box];\n", bb->index);
514 if (bb_in_scop_p (bb, scop))
515 fprintf (file, "%d [color=red];\n", bb->index);
517 FOR_EACH_EDGE (e, ei, bb->succs)
518 fprintf (file, "%d -> %d;\n", bb->index, e->dest->index);
521 fputs ("}\n\n", file);
524 /* Display SCOP using dotty. */
527 dot_scop (scop_p scop)
529 dot_scop_1 (stderr, scop);
532 /* Pretty print all SCoPs in DOT format and mark them with different colors.
533 If there are not enough colors, paint later SCoPs gray.
535 - "*" after the node number: entry of a SCoP,
536 - "#" after the node number: exit of a SCoP,
537 - "()" entry or exit not part of SCoP. */
540 dot_all_scops_1 (FILE *file)
549 /* Disable debugging while printing graph. */
550 int tmp_dump_flags = dump_flags;
553 fprintf (file, "digraph all {\n");
557 int part_of_scop = false;
559 /* Use HTML for every bb label. So we are able to print bbs
560 which are part of two different SCoPs, with two different
561 background colors. */
562 fprintf (file, "%d [label=<\n <TABLE BORDER=\"0\" CELLBORDER=\"1\" ",
564 fprintf (file, "CELLSPACING=\"0\">\n");
566 /* Select color for SCoP. */
567 for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
568 if (bb_in_scop_p (bb, scop)
569 || (SESE_EXIT (SCOP_REGION (scop)) && SCOP_EXIT (scop) == bb)
570 || (SESE_ENTRY (SCOP_REGION (scop)) && SCOP_ENTRY (scop) == bb))
629 fprintf (file, " <TR><TD WIDTH=\"50\" BGCOLOR=\"%s\">", color);
631 if (!bb_in_scop_p (bb, scop))
632 fprintf (file, " (");
634 if (SESE_ENTRY (SCOP_REGION (scop))
635 && SESE_EXIT (SCOP_REGION (scop))
636 && bb == SCOP_ENTRY (scop)
637 && bb == SCOP_EXIT (scop))
638 fprintf (file, " %d*# ", bb->index);
639 else if (SESE_ENTRY (SCOP_REGION (scop))
640 && bb == SCOP_ENTRY (scop))
641 fprintf (file, " %d* ", bb->index);
642 else if (SESE_EXIT (SCOP_REGION (scop))
643 && bb == SCOP_EXIT (scop))
644 fprintf (file, " %d# ", bb->index);
646 fprintf (file, " %d ", bb->index);
648 if (!bb_in_scop_p (bb, scop))
651 fprintf (file, "</TD></TR>\n");
658 fprintf (file, " <TR><TD WIDTH=\"50\" BGCOLOR=\"#ffffff\">");
659 fprintf (file, " %d </TD></TR>\n", bb->index);
662 fprintf (file, " </TABLE>>, shape=box, style=\"setlinewidth(0)\"]\n");
667 FOR_EACH_EDGE (e, ei, bb->succs)
668 fprintf (file, "%d -> %d;\n", bb->index, e->dest->index);
671 fputs ("}\n\n", file);
673 /* Enable debugging again. */
674 dump_flags = tmp_dump_flags;
677 /* Display all SCoPs using dotty. */
682 /* When debugging, enable the following code. This cannot be used
683 in production compilers because it calls "system". */
685 FILE *stream = fopen ("/tmp/allscops.dot", "w");
688 dot_all_scops_1 (stream);
691 system ("dotty /tmp/allscops.dot");
693 dot_all_scops_1 (stderr);
697 /* Returns true when LOOP is in SCOP. */
700 loop_in_scop_p (struct loop *loop, scop_p scop)
702 return (bb_in_scop_p (loop->header, scop)
703 && bb_in_scop_p (loop->latch, scop));
706 /* Returns the outermost loop in SCOP that contains BB. */
709 outermost_loop_in_scop (scop_p scop, basic_block bb)
713 nest = bb->loop_father;
714 while (loop_outer (nest) && loop_in_scop_p (loop_outer (nest), scop))
715 nest = loop_outer (nest);
720 /* Return true when EXPR is an affine function in LOOP with parameters
721 instantiated relative to outermost_loop. */
724 loop_affine_expr (struct loop *outermost_loop, struct loop *loop, tree expr)
726 int n = outermost_loop->num;
727 tree scev = analyze_scalar_evolution (loop, expr);
729 scev = instantiate_scev (outermost_loop, loop, scev);
731 return (evolution_function_is_invariant_p (scev, n)
732 || evolution_function_is_affine_multivariate_p (scev, n));
735 /* Return true if the operand OP is simple. */
738 is_simple_operand (loop_p loop, gimple stmt, tree op)
740 /* It is not a simple operand when it is a declaration, */
742 /* or a structure, */
743 || AGGREGATE_TYPE_P (TREE_TYPE (op))
744 /* or a memory access that cannot be analyzed by the data
745 reference analysis. */
746 || ((handled_component_p (op) || INDIRECT_REF_P (op))
747 && !stmt_simple_memref_p (loop, stmt, op)))
753 /* Return true only when STMT is simple enough for being handled by
754 Graphite. This depends on OUTERMOST_LOOP, as the parametetrs are
755 initialized relative to this loop. */
758 stmt_simple_for_scop_p (struct loop *outermost_loop, gimple stmt)
760 basic_block bb = gimple_bb (stmt);
761 struct loop *loop = bb->loop_father;
763 /* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects.
764 Calls have side-effects, except those to const or pure
766 if (gimple_has_volatile_ops (stmt)
767 || (gimple_code (stmt) == GIMPLE_CALL
768 && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
769 || (gimple_code (stmt) == GIMPLE_ASM))
772 switch (gimple_code (stmt))
782 enum tree_code code = gimple_cond_code (stmt);
784 /* We can only handle this kind of conditional expressions.
785 For inequalities like "if (i != 3 * k)" we need unions of
786 polyhedrons. Expressions like "if (a)" or "if (a == 15)" need
787 them for the else branch. */
788 if (!(code == LT_EXPR
797 FOR_EACH_SSA_TREE_OPERAND (op, stmt, op_iter, SSA_OP_ALL_USES)
798 if (!loop_affine_expr (outermost_loop, loop, op))
806 enum tree_code code = gimple_assign_rhs_code (stmt);
808 switch (get_gimple_rhs_class (code))
810 case GIMPLE_UNARY_RHS:
811 case GIMPLE_SINGLE_RHS:
812 return (is_simple_operand (loop, stmt, gimple_assign_lhs (stmt))
813 && is_simple_operand (loop, stmt, gimple_assign_rhs1 (stmt)));
815 case GIMPLE_BINARY_RHS:
816 return (is_simple_operand (loop, stmt, gimple_assign_lhs (stmt))
817 && is_simple_operand (loop, stmt, gimple_assign_rhs1 (stmt))
818 && is_simple_operand (loop, stmt, gimple_assign_rhs2 (stmt)));
820 case GIMPLE_INVALID_RHS:
829 size_t n = gimple_call_num_args (stmt);
830 tree lhs = gimple_call_lhs (stmt);
832 for (i = 0; i < n; i++)
834 tree arg = gimple_call_arg (stmt, i);
836 if (!(is_simple_operand (loop, stmt, lhs)
837 && is_simple_operand (loop, stmt, arg)))
845 /* These nodes cut a new scope. */
852 /* Returns the statement of BB that contains a harmful operation: that
853 can be a function call with side effects, data dependences that
854 cannot be computed in OUTERMOST_LOOP, the induction variables are
855 not linear with respect to OUTERMOST_LOOP, etc. The current open
856 scop should end before this statement. */
859 harmful_stmt_in_bb (struct loop *outermost_loop, basic_block bb)
861 gimple_stmt_iterator gsi;
863 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
864 if (!stmt_simple_for_scop_p (outermost_loop, gsi_stmt (gsi)))
865 return gsi_stmt (gsi);
870 /* Store the GRAPHITE representation of BB. */
873 new_graphite_bb (scop_p scop, basic_block bb)
875 struct graphite_bb *gbb = XNEW (struct graphite_bb);
879 GBB_SCOP (gbb) = scop;
880 GBB_DATA_REFS (gbb) = NULL;
881 GBB_DOMAIN (gbb) = NULL;
882 GBB_CONDITIONS (gbb) = NULL;
883 GBB_CONDITION_CASES (gbb) = NULL;
884 GBB_LOOPS (gbb) = NULL;
885 VEC_safe_push (graphite_bb_p, heap, SCOP_BBS (scop), gbb);
886 bitmap_set_bit (SCOP_BBS_B (scop), bb->index);
892 free_graphite_bb (struct graphite_bb *gbb)
894 if (GBB_DOMAIN (gbb))
895 cloog_matrix_free (GBB_DOMAIN (gbb));
897 free_data_refs (GBB_DATA_REFS (gbb));
898 VEC_free (gimple, heap, GBB_CONDITIONS (gbb));
899 VEC_free (gimple, heap, GBB_CONDITION_CASES (gbb));
900 VEC_free (loop_p, heap, GBB_LOOPS (gbb));
902 GBB_BB (gbb)->aux = 0;
906 /* Creates a new scop starting with ENTRY. */
909 new_scop (edge entry)
911 scop_p scop = XNEW (struct scop);
913 SCOP_REGION (scop) = XNEW (struct sese);
914 SESE_ENTRY (SCOP_REGION (scop)) = entry;
915 SESE_EXIT (SCOP_REGION (scop)) = NULL;
916 SCOP_BBS (scop) = VEC_alloc (graphite_bb_p, heap, 3);
917 SCOP_OLDIVS (scop) = VEC_alloc (name_tree, heap, 3);
918 SCOP_BBS_B (scop) = BITMAP_ALLOC (NULL);
919 SCOP_LOOPS (scop) = BITMAP_ALLOC (NULL);
920 SCOP_LOOP_NEST (scop) = VEC_alloc (loop_p, heap, 3);
921 SCOP_PARAMS (scop) = VEC_alloc (name_tree, heap, 3);
922 SCOP_PROG (scop) = cloog_program_malloc ();
923 cloog_program_set_names (SCOP_PROG (scop), cloog_names_malloc ());
924 SCOP_LOOP2CLOOG_LOOP (scop) = htab_create (10, hash_loop_to_cloog_loop,
925 eq_loop_to_cloog_loop,
933 free_scop (scop_p scop)
937 struct graphite_bb *gb;
939 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
940 free_graphite_bb (gb);
942 VEC_free (graphite_bb_p, heap, SCOP_BBS (scop));
943 BITMAP_FREE (SCOP_BBS_B (scop));
944 BITMAP_FREE (SCOP_LOOPS (scop));
945 VEC_free (loop_p, heap, SCOP_LOOP_NEST (scop));
946 VEC_free (name_tree, heap, SCOP_OLDIVS (scop));
948 for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++)
951 VEC_free (name_tree, heap, SCOP_PARAMS (scop));
952 cloog_program_free (SCOP_PROG (scop));
953 htab_delete (SCOP_LOOP2CLOOG_LOOP (scop));
954 XDELETE (SCOP_REGION (scop));
958 /* Deletes all scops in SCOPS. */
961 free_scops (VEC (scop_p, heap) *scops)
966 for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++)
969 VEC_free (scop_p, heap, scops);
972 typedef enum gbb_type {
974 GBB_LOOP_SING_EXIT_HEADER,
975 GBB_LOOP_MULT_EXIT_HEADER,
982 /* Detect the type of BB. Loop headers are only marked, if they are
983 new. This means their loop_father is different to LAST_LOOP.
984 Otherwise they are treated like any other bb and their type can be
988 get_bb_type (basic_block bb, struct loop *last_loop)
990 VEC (basic_block, heap) *dom;
992 struct loop *loop = bb->loop_father;
994 /* Check, if we entry into a new loop. */
995 if (loop != last_loop)
997 if (single_exit (loop) != NULL)
998 return GBB_LOOP_SING_EXIT_HEADER;
999 else if (loop->num != 0)
1000 return GBB_LOOP_MULT_EXIT_HEADER;
1002 return GBB_COND_HEADER;
1005 dom = get_dominated_by (CDI_DOMINATORS, bb);
1006 nb_dom = VEC_length (basic_block, dom);
1007 VEC_free (basic_block, heap, dom);
1011 nb_suc = VEC_length (edge, bb->succs);
1012 if (nb_dom == 1 && nb_suc == 1)
1015 return GBB_COND_HEADER;
1018 /* Moves the scops from SOURCE to TARGET and clean up SOURCE. */
1021 move_scops (VEC (scop_p, heap) **source, VEC (scop_p, heap) **target)
1026 for (i = 0; VEC_iterate (scop_p, *source, i, s); i++)
1027 VEC_safe_push (scop_p, heap, *target, s);
1029 VEC_free (scop_p, heap, *source);
1032 /* Store information needed by scopdet_* functions. */
1036 /* Where the last open scop would stop if the current BB is harmful. */
1039 /* Where the next scop would start if the current BB is harmful. */
1042 /* The bb or one of its children contains open loop exits. That means
1043 loop exit nodes that are not surrounded by a loop dominated by bb. */
1046 /* The bb or one of its children contains only structures we can handle. */
1050 static struct scopdet_info build_scops_1 (edge, VEC (scop_p, heap) **,
1053 /* Checks, if a bb can be added to a SCoP. */
1055 static struct scopdet_info
1056 scopdet_edge_info (edge ee, loop_p outermost_loop,
1057 VEC (scop_p, heap) **scops, gbb_type type, gimple *stmt)
1060 basic_block bb = ee->dest;
1061 struct loop *loop = bb->loop_father;
1062 struct scopdet_info result;
1064 *stmt = harmful_stmt_in_bb (outermost_loop, bb);
1065 result.difficult = (*stmt != NULL);
1072 result.exits = false;
1077 result.next = single_succ_edge (bb);
1078 result.exits = false;
1082 case GBB_LOOP_SING_EXIT_HEADER:
1084 VEC (scop_p, heap) *tmp_scops = VEC_alloc (scop_p, heap, 3);
1085 struct scopdet_info sinfo;
1087 sinfo = build_scops_1 (ee, &tmp_scops, loop, outermost_loop);
1089 result.last = single_exit (bb->loop_father);
1091 if (single_succ_p (result.last->dest)
1092 && get_bb_type (result.last->dest, loop) == GBB_SIMPLE)
1093 result.next = single_succ_edge (result.last->dest);
1095 result.next = split_block (result.last->dest, NULL);
1097 /* If we do not dominate result.next, remove it. It's either
1098 the EXIT_BLOCK_PTR, or another bb dominates it and will
1099 call the scop detection for this bb. */
1100 if (!dominated_by_p (CDI_DOMINATORS, result.next->dest, bb))
1103 if (TREE_CODE (number_of_latch_executions (loop))
1105 result.difficult = true;
1107 if (sinfo.difficult)
1108 move_scops (&tmp_scops, scops);
1110 free_scops (tmp_scops);
1112 result.exits = false;
1113 result.difficult |= sinfo.difficult;
1117 case GBB_LOOP_MULT_EXIT_HEADER:
1119 /* XXX: Handle loop nests with the same header. */
1120 /* XXX: Handle iterative optimization of outermost_loop. */
1121 /* XXX: For now we just do not join loops with multiple exits. If the
1122 exits lead to the same bb it may be possible to join the loop. */
1123 VEC (scop_p, heap) *tmp_scops = VEC_alloc (scop_p, heap, 3);
1124 VEC (edge, heap) *exits = get_loop_exit_edges (loop);
1127 build_scops_1 (ee, &tmp_scops, loop, outermost_loop);
1129 for (i = 0; VEC_iterate (edge, exits, i, e); i++)
1130 if (dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
1131 && e->dest->loop_father == loop_outer (loop))
1132 build_scops_1 (e, &tmp_scops, e->dest->loop_father,
1137 result.difficult = true;
1138 result.exits = false;
1139 move_scops (&tmp_scops, scops);
1140 VEC_free (edge, heap, exits);
1143 case GBB_COND_HEADER:
1145 VEC (scop_p, heap) *tmp_scops = VEC_alloc (scop_p, heap, 3);
1146 struct scopdet_info sinfo;
1147 VEC (basic_block, heap) *dominated;
1150 basic_block last_bb = NULL;
1153 result.exits = false;
1155 /* First check the successors of BB, and check if it is possible to join
1156 the different branches. */
1157 for (i = 0; VEC_iterate (edge, bb->succs, i, e); i++)
1159 /* Ignore loop exits. They will be handled after the loop body. */
1160 if (is_loop_exit (loop, e->dest))
1162 result.exits = true;
1166 /* Do not follow edges that lead to the end of the
1167 conditions block. For example, in
1177 the edge from 0 => 6. Only check if all paths lead to
1180 if (!single_pred_p (e->dest))
1182 /* Check, if edge leads directly to the end of this
1190 if (e->dest != last_bb)
1191 result.difficult = true;
1196 if (!dominated_by_p (CDI_DOMINATORS, e->dest, bb))
1198 result.difficult = true;
1202 sinfo = build_scops_1 (e, &tmp_scops, loop, outermost_loop);
1204 result.exits |= sinfo.exits;
1205 result.last = sinfo.last;
1206 result.difficult |= sinfo.difficult;
1208 /* Checks, if all branches end at the same point.
1209 If that is true, the condition stays joinable.
1210 Have a look at the example above. */
1211 if (sinfo.last && single_succ_p (sinfo.last->dest))
1213 basic_block next_tmp = single_succ (sinfo.last->dest);
1218 last_e = single_succ_edge (sinfo.last->dest);
1221 if (next_tmp != last_bb)
1222 result.difficult = true;
1225 result.difficult = true;
1228 /* If the condition is joinable. */
1229 if (!result.exits && !result.difficult)
1231 /* Only return a next pointer if we dominate this pointer.
1232 Otherwise it will be handled by the bb dominating it. */
1233 if (dominated_by_p (CDI_DOMINATORS, last_bb, bb) && last_bb != bb)
1234 result.next = last_e;
1238 move_scops (&tmp_scops, scops);
1242 /* Scan remaining bbs dominated by BB. */
1243 dominated = get_dominated_by (CDI_DOMINATORS, bb);
1245 for (i = 0; VEC_iterate (basic_block, dominated, i, dom_bb); i++)
1247 /* Ignore loop exits: they will be handled after the loop body. */
1248 if (is_loop_exit (loop, dom_bb))
1250 result.exits = true;
1254 /* Ignore the bbs processed above. */
1255 if (single_pred_p (dom_bb) && single_pred (dom_bb) == bb)
1258 if (single_pred_p (dom_bb))
1259 e = single_pred_edge (dom_bb);
1261 e = split_block (dom_bb, NULL);
1263 if (loop_depth (loop) > loop_depth (dom_bb->loop_father))
1264 sinfo = build_scops_1 (e, &tmp_scops, loop_outer (loop),
1267 sinfo = build_scops_1 (e, &tmp_scops, loop, outermost_loop);
1270 result.exits |= sinfo.exits;
1271 result.difficult = true;
1275 VEC_free (basic_block, heap, dominated);
1278 move_scops (&tmp_scops, scops);
1290 /* Split EXIT before STMT when STMT is non NULL. */
1293 split_difficult_bb (basic_block exit, edge *last, gimple stmt)
1295 if (stmt && VEC_length (edge, exit->preds) == 1)
1299 if (stmt == gsi_stmt (gsi_after_labels (exit)))
1303 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
1305 stmt = gsi_stmt (gsi);
1308 e = split_block (exit, stmt);
1309 set_immediate_dominator (CDI_DOMINATORS, e->dest, e->src);
1310 set_immediate_dominator (CDI_POST_DOMINATORS, e->src, e->dest);
1322 /* End SCOP with edge EXIT. */
1325 end_scop (scop_p scop, edge exit, bool split_entry)
1328 && !single_pred_p (SCOP_ENTRY (scop))
1329 && exit->dest->loop_father == SCOP_ENTRY (scop)->loop_father)
1330 SESE_ENTRY (SCOP_REGION (scop)) = split_block (SCOP_ENTRY (scop), NULL);
1332 SESE_EXIT (SCOP_REGION (scop)) = exit;
1335 /* Creates the SCoPs and writes entry and exit points for every SCoP. */
1337 static struct scopdet_info
1338 build_scops_1 (edge start, VEC (scop_p, heap) **scops, loop_p loop,
1339 loop_p outermost_loop)
1341 edge current = start;
1343 bool in_scop = false;
1344 scop_p open_scop = NULL;
1346 struct scopdet_info sinfo;
1348 /* Initialize result. */
1349 struct scopdet_info result;
1350 result.exits = false;
1351 result.difficult = false;
1355 /* Loop over the dominance tree. If we meet a difficult bb, close
1356 the current SCoP. Loop and condition header start a new layer,
1357 and can only be added if all bbs in deeper layers are simple. */
1358 while (current != NULL)
1360 sinfo = scopdet_edge_info (current, outermost_loop, scops,
1361 get_bb_type (current->dest, loop), &stmt);
1363 if (!in_scop && !(sinfo.exits || sinfo.difficult))
1365 open_scop = new_scop (current);
1367 VEC_safe_push (scop_p, heap, *scops, open_scop);
1370 else if (in_scop && (sinfo.exits || sinfo.difficult))
1372 edge exit = split_difficult_bb (current->dest, &sinfo.last, stmt);
1377 end_scop (open_scop, exit, sinfo.difficult);
1381 result.difficult |= sinfo.difficult;
1382 result.exits |= sinfo.exits;
1384 current = sinfo.next;
1387 /* Finish the SCOP, if it is left open. The exit is the bb, that
1388 postdominates sinfo.last. If no such bb exists, we use info.last
1389 or delete the scop. */
1395 for (i = 0; VEC_iterate (edge, sinfo.last->dest->succs, i, e); i++)
1396 if (dominated_by_p (CDI_POST_DOMINATORS, sinfo.last->dest, e->dest))
1398 edge exit = split_difficult_bb (e->dest, &sinfo.last, stmt);
1401 end_scop (open_scop, exit, sinfo.difficult);
1403 end_scop (open_scop, e, sinfo.difficult);
1408 if (SCOP_ENTRY (open_scop) != sinfo.last->dest)
1410 edge exit = split_difficult_bb (sinfo.last->dest, NULL, stmt);
1413 end_scop (open_scop, exit, sinfo.difficult);
1415 end_scop (open_scop, sinfo.last, sinfo.difficult);
1419 VEC_pop (scop_p, *scops);
1420 free_scop (open_scop);
1425 result.last = sinfo.last;
1430 /* Find static control parts. */
1435 struct loop *loop = current_loops->tree_root;
1436 build_scops_1 (single_succ_edge (ENTRY_BLOCK_PTR), ¤t_scops, loop, loop);
1439 /* Gather the basic blocks belonging to the SCOP. */
1442 build_scop_bbs (scop_p scop)
1444 basic_block *stack = XNEWVEC (basic_block, n_basic_blocks + 1);
1445 sbitmap visited = sbitmap_alloc (last_basic_block);
1448 sbitmap_zero (visited);
1449 stack[sp++] = SCOP_ENTRY (scop);
1453 basic_block bb = stack[--sp];
1454 int depth = loop_depth (bb->loop_father);
1455 int num = bb->loop_father->num;
1459 /* Scop's exit is not in the scop. Exclude also bbs, which are
1460 dominated by the SCoP exit. These are e.g. loop latches. */
1461 if (TEST_BIT (visited, bb->index)
1462 || dominated_by_p (CDI_DOMINATORS, bb, SCOP_EXIT (scop))
1463 /* Every block in the scop is dominated by scop's entry. */
1464 || !dominated_by_p (CDI_DOMINATORS, bb, SCOP_ENTRY (scop)))
1467 new_graphite_bb (scop, bb);
1468 SET_BIT (visited, bb->index);
1470 /* First push the blocks that have to be processed last. Note
1471 that this means that the order in which the code is organized
1472 below is important: do not reorder the following code. */
1473 FOR_EACH_EDGE (e, ei, bb->succs)
1474 if (! TEST_BIT (visited, e->dest->index)
1475 && (int) loop_depth (e->dest->loop_father) < depth)
1476 stack[sp++] = e->dest;
1478 FOR_EACH_EDGE (e, ei, bb->succs)
1479 if (! TEST_BIT (visited, e->dest->index)
1480 && (int) loop_depth (e->dest->loop_father) == depth
1481 && e->dest->loop_father->num != num)
1482 stack[sp++] = e->dest;
1484 FOR_EACH_EDGE (e, ei, bb->succs)
1485 if (! TEST_BIT (visited, e->dest->index)
1486 && (int) loop_depth (e->dest->loop_father) == depth
1487 && e->dest->loop_father->num == num
1488 && EDGE_COUNT (e->dest->preds) > 1)
1489 stack[sp++] = e->dest;
1491 FOR_EACH_EDGE (e, ei, bb->succs)
1492 if (! TEST_BIT (visited, e->dest->index)
1493 && (int) loop_depth (e->dest->loop_father) == depth
1494 && e->dest->loop_father->num == num
1495 && EDGE_COUNT (e->dest->preds) == 1)
1496 stack[sp++] = e->dest;
1498 FOR_EACH_EDGE (e, ei, bb->succs)
1499 if (! TEST_BIT (visited, e->dest->index)
1500 && (int) loop_depth (e->dest->loop_father) > depth)
1501 stack[sp++] = e->dest;
1505 sbitmap_free (visited);
1509 /* Record LOOP as occuring in SCOP. */
1512 scop_record_loop (scop_p scop, struct loop *loop)
1517 if (bitmap_bit_p (SCOP_LOOPS (scop), loop->num))
1520 parent = loop_outer (loop);
1521 induction_var = find_induction_var_from_exit_cond (loop);
1523 if (!bb_in_scop_p (parent->latch, scop))
1526 if (induction_var != NULL_TREE)
1528 name_tree oldiv = XNEW (struct name_tree);
1529 oldiv->t = SSA_NAME_VAR (induction_var);
1530 if (DECL_NAME (oldiv->t))
1531 oldiv->name = IDENTIFIER_POINTER (DECL_NAME (oldiv->t));
1534 char *n = XNEWVEC (char, 16);
1535 sprintf (n, "D.%u", DECL_UID (oldiv->t));
1540 VEC_safe_push (name_tree, heap, SCOP_OLDIVS (scop), oldiv);
1543 bitmap_set_bit (SCOP_LOOPS (scop), loop->num);
1544 VEC_safe_push (loop_p, heap, SCOP_LOOP_NEST (scop), loop);
1547 /* Build the loop nests contained in SCOP. */
1550 build_scop_loop_nests (scop_p scop)
1554 struct loop *loop0, *loop1;
1556 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
1558 struct loop *loop = gbb_loop (gb);
1560 /* Only add loops, if they are completely contained in the SCoP. */
1561 if (loop->header == GBB_BB (gb)
1562 && bb_in_scop_p (loop->latch, scop))
1563 scop_record_loop (scop, gbb_loop (gb));
1566 /* Make sure that the loops in the SCOP_LOOP_NEST are ordered. It
1567 can be the case that an inner loop is inserted before an outer
1568 loop. To avoid this, semi-sort once. */
1569 for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop0); i++)
1571 if (VEC_length (loop_p, SCOP_LOOP_NEST (scop)) == i + 1)
1574 loop1 = VEC_index (loop_p, SCOP_LOOP_NEST (scop), i + 1);
1575 if (loop0->num > loop1->num)
1577 VEC_replace (loop_p, SCOP_LOOP_NEST (scop), i, loop1);
1578 VEC_replace (loop_p, SCOP_LOOP_NEST (scop), i + 1, loop0);
1583 /* Calculate the number of loops around GB in the current SCOP. */
1586 nb_loops_around_gb (graphite_bb_p gb)
1588 scop_p scop = GBB_SCOP (gb);
1589 struct loop *l = gbb_loop (gb);
1592 for (; loop_in_scop_p (l, scop); d++, l = loop_outer (l));
1597 /* Build for BB the static schedule.
1599 The STATIC_SCHEDULE is defined like this:
1618 Static schedules for A to F:
1631 build_scop_canonical_schedules (scop_p scop)
1635 int nb = scop_nb_loops (scop) + 1;
1637 SCOP_STATIC_SCHEDULE (scop) = lambda_vector_new (nb);
1639 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
1641 int offset = nb_loops_around_gb (gb);
1643 /* After leaving a loop, it is possible that the schedule is not
1644 set at zero. This loop reinitializes components located
1647 for (j = offset + 1; j < nb; j++)
1648 if (SCOP_STATIC_SCHEDULE (scop)[j])
1650 memset (&(SCOP_STATIC_SCHEDULE (scop)[j]), 0,
1651 sizeof (int) * (nb - j));
1652 ++SCOP_STATIC_SCHEDULE (scop)[offset];
1656 GBB_STATIC_SCHEDULE (gb) = lambda_vector_new (offset + 1);
1657 lambda_vector_copy (SCOP_STATIC_SCHEDULE (scop),
1658 GBB_STATIC_SCHEDULE (gb), offset + 1);
1660 ++SCOP_STATIC_SCHEDULE (scop)[offset];
1664 /* Build the LOOPS vector for all bbs in SCOP. */
1667 build_bb_loops (scop_p scop)
1672 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
1677 depth = nb_loops_around_gb (gb) - 1;
1679 GBB_LOOPS (gb) = VEC_alloc (loop_p, heap, 3);
1680 VEC_safe_grow_cleared (loop_p, heap, GBB_LOOPS (gb), depth + 1);
1682 loop = GBB_BB (gb)->loop_father;
1684 while (scop_contains_loop (scop, loop))
1686 VEC_replace (loop_p, GBB_LOOPS (gb), depth, loop);
1687 loop = loop_outer (loop);
1693 /* Get the index for parameter VAR in SCOP. */
1696 param_index (tree var, scop_p scop)
1702 gcc_assert (TREE_CODE (var) == SSA_NAME);
1704 for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++)
1708 nvar = XNEW (struct name_tree);
1711 VEC_safe_push (name_tree, heap, SCOP_PARAMS (scop), nvar);
1712 return VEC_length (name_tree, SCOP_PARAMS (scop)) - 1;
1715 /* Scan EXPR and translate it to an inequality vector INEQ that will
1716 be added, or subtracted, in the constraint domain matrix C at row
1717 R. K is the number of columns for loop iterators in C. */
1720 scan_tree_for_params (scop_p s, tree e, CloogMatrix *c, int r, Value k,
1723 int cst_col, param_col;
1725 if (e == chrec_dont_know)
1728 switch (TREE_CODE (e))
1730 case POLYNOMIAL_CHREC:
1732 tree left = CHREC_LEFT (e);
1733 tree right = CHREC_RIGHT (e);
1734 int var = CHREC_VARIABLE (e);
1736 if (TREE_CODE (right) != INTEGER_CST)
1741 int loop_col = scop_gimple_loop_depth (s, get_loop (var)) + 1;
1744 value_sub_int (c->p[r][loop_col], c->p[r][loop_col],
1745 int_cst_value (right));
1747 value_add_int (c->p[r][loop_col], c->p[r][loop_col],
1748 int_cst_value (right));
1751 switch (TREE_CODE (left))
1753 case POLYNOMIAL_CHREC:
1754 scan_tree_for_params (s, left, c, r, k, subtract);
1758 /* Constant part. */
1761 int v = int_cst_value (left);
1762 cst_col = c->NbColumns - 1;
1767 subtract = subtract ? false : true;
1771 value_sub_int (c->p[r][cst_col], c->p[r][cst_col], v);
1773 value_add_int (c->p[r][cst_col], c->p[r][cst_col], v);
1778 scan_tree_for_params (s, left, c, r, k, subtract);
1785 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
1789 gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0));
1792 value_set_si (val, int_cst_value (TREE_OPERAND (e, 1)));
1793 value_multiply (k, k, val);
1795 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
1801 gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0));
1804 value_set_si (val, int_cst_value (TREE_OPERAND (e, 0)));
1805 value_multiply (k, k, val);
1807 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, subtract);
1812 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
1813 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, subtract);
1817 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
1818 value_oppose (k, k);
1819 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, subtract);
1823 value_oppose (k, k);
1824 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
1828 param_col = param_index (e, s);
1832 param_col += c->NbColumns - scop_nb_params (s) - 1;
1835 value_subtract (c->p[r][param_col], c->p[r][param_col], k);
1837 value_addto (c->p[r][param_col], c->p[r][param_col], k);
1844 int v = int_cst_value (e);
1845 cst_col = c->NbColumns - 1;
1850 subtract = subtract ? false : true;
1854 value_sub_int (c->p[r][cst_col], c->p[r][cst_col], v);
1856 value_add_int (c->p[r][cst_col], c->p[r][cst_col], v);
1862 case NON_LVALUE_EXPR:
1863 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
1872 /* Data structure for idx_record_params. */
1880 /* For a data reference with an ARRAY_REF as its BASE, record the
1881 parameters occurring in IDX. DTA is passed in as complementary
1882 information, and is used by the automatic walker function. This
1883 function is a callback for for_each_index. */
1886 idx_record_params (tree base, tree *idx, void *dta)
1888 struct irp_data *data = (struct irp_data *) dta;
1890 if (TREE_CODE (base) != ARRAY_REF)
1893 if (TREE_CODE (*idx) == SSA_NAME)
1896 scop_p scop = data->scop;
1897 struct loop *loop = data->loop;
1899 scev = analyze_scalar_evolution (loop, *idx);
1900 scev = instantiate_scev (outermost_loop_in_scop (scop, loop->header),
1907 value_set_si (one, 1);
1908 scan_tree_for_params (scop, scev, NULL, 0, one, false);
1916 /* Find parameters with respect to SCOP in BB. We are looking in memory
1917 access functions, conditions and loop bounds. */
1920 find_params_in_bb (scop_p scop, basic_block bb)
1923 data_reference_p dr;
1924 VEC (data_reference_p, heap) *drs;
1925 gimple_stmt_iterator gsi;
1926 struct loop *nest = outermost_loop_in_scop (scop, bb);
1928 /* Find the parameters used in the memory access functions. */
1929 drs = VEC_alloc (data_reference_p, heap, 5);
1930 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1931 find_data_references_in_stmt (nest, gsi_stmt (gsi), &drs);
1933 for (i = 0; VEC_iterate (data_reference_p, drs, i, dr); i++)
1935 struct irp_data irp;
1937 irp.loop = bb->loop_father;
1939 for_each_index (&dr->ref, idx_record_params, &irp);
1943 VEC_free (data_reference_p, heap, drs);
1945 /* Find parameters in conditional statements. */
1946 gsi = gsi_last_bb (bb);
1947 if (!gsi_end_p (gsi))
1949 gimple stmt = gsi_stmt (gsi);
1951 if (gimple_code (stmt) == GIMPLE_COND)
1954 loop_p loop = bb->loop_father;
1958 lhs = gimple_cond_lhs (stmt);
1959 lhs = analyze_scalar_evolution (loop, lhs);
1960 lhs = instantiate_scev (nest, loop, lhs);
1962 rhs = gimple_cond_rhs (stmt);
1963 rhs = analyze_scalar_evolution (loop, rhs);
1964 rhs = instantiate_scev (nest, loop, rhs);
1967 scan_tree_for_params (scop, lhs, NULL, 0, one, false);
1968 value_set_si (one, 1);
1969 scan_tree_for_params (scop, rhs, NULL, 0, one, false);
1975 /* Saves in NV the name of variable P->T. */
1978 save_var_name (char **nv, int i, name_tree p)
1980 const char *name = get_name (SSA_NAME_VAR (p->t));
1984 nv[i] = XNEWVEC (char, strlen (name) + 12);
1985 sprintf (nv[i], "%s_%12d", name, SSA_NAME_VERSION (p->t));
1989 nv[i] = XNEWVEC (char, 12);
1990 sprintf (nv[i], "T_%12d", SSA_NAME_VERSION (p->t));
1996 /* Return the maximal loop depth in SCOP. */
1999 scop_max_loop_depth (scop_p scop)
2003 int max_nb_loops = 0;
2005 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++)
2007 int nb_loops = gbb_nb_loops (gbb);
2008 if (max_nb_loops < nb_loops)
2009 max_nb_loops = nb_loops;
2012 return max_nb_loops;
2015 /* Initialize Cloog's parameter names from the names used in GIMPLE.
2016 Initialize Cloog's iterator names, using 'graphite_iterator_%d'
2017 from 0 to scop_nb_loops (scop). */
2020 initialize_cloog_names (scop_p scop)
2022 int i, nb_params = VEC_length (name_tree, SCOP_PARAMS (scop));
2023 char **params = XNEWVEC (char *, nb_params);
2024 int nb_iterators = scop_max_loop_depth (scop);
2025 int nb_scattering= cloog_program_nb_scattdims (SCOP_PROG (scop));
2026 char **iterators = XNEWVEC (char *, nb_iterators * 2);
2027 char **scattering = XNEWVEC (char *, nb_scattering);
2030 for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++)
2031 save_var_name (params, i, p);
2033 cloog_names_set_nb_parameters (cloog_program_names (SCOP_PROG (scop)),
2035 cloog_names_set_parameters (cloog_program_names (SCOP_PROG (scop)),
2038 for (i = 0; i < nb_iterators; i++)
2040 iterators[i] = XNEWVEC (char, 18 + 12);
2041 sprintf (iterators[i], "graphite_iterator_%d", i);
2044 cloog_names_set_nb_iterators (cloog_program_names (SCOP_PROG (scop)),
2046 cloog_names_set_iterators (cloog_program_names (SCOP_PROG (scop)),
2049 for (i = 0; i < nb_scattering; i++)
2051 scattering[i] = XNEWVEC (char, 2 + 12);
2052 sprintf (scattering[i], "s_%d", i);
2055 cloog_names_set_nb_scattering (cloog_program_names (SCOP_PROG (scop)),
2057 cloog_names_set_scattering (cloog_program_names (SCOP_PROG (scop)),
2061 /* Record the parameters used in the SCOP. A variable is a parameter
2062 in a scop if it does not vary during the execution of that scop. */
2065 find_scop_parameters (scop_p scop)
2073 value_set_si (one, 1);
2075 /* Find the parameters used in the loop bounds. */
2076 for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop); i++)
2078 tree nb_iters = number_of_latch_executions (loop);
2080 if (!chrec_contains_symbols (nb_iters))
2083 nb_iters = analyze_scalar_evolution (loop, nb_iters);
2084 nb_iters = instantiate_scev (outermost_loop_in_scop (scop, loop->header),
2086 scan_tree_for_params (scop, nb_iters, NULL, 0, one, false);
2091 /* Find the parameters used in data accesses. */
2092 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
2093 find_params_in_bb (scop, GBB_BB (gb));
2096 /* Build the context constraints for SCOP: constraints and relations
2100 build_scop_context (scop_p scop)
2102 int nb_params = scop_nb_params (scop);
2103 CloogMatrix *matrix = cloog_matrix_alloc (1, nb_params + 2);
2105 /* Insert '0 >= 0' in the context matrix, as it is not allowed to be
2108 value_set_si (matrix->p[0][0], 1);
2110 value_set_si (matrix->p[0][nb_params + 1], 0);
2112 cloog_program_set_context (SCOP_PROG (scop),
2113 cloog_domain_matrix2domain (matrix));
2114 cloog_matrix_free (matrix);
2117 /* Returns a graphite_bb from BB. */
2119 static inline graphite_bb_p
2120 gbb_from_bb (basic_block bb)
2122 return (graphite_bb_p) bb->aux;
2125 /* Add DOMAIN to all the basic blocks in LOOP. */
2128 add_bb_domains (struct loop *loop, CloogMatrix *domain)
2130 basic_block *bbs = get_loop_body (loop);
2133 for (i = 0; i < loop->num_nodes; i++)
2134 if (bbs[i]->loop_father == loop)
2136 graphite_bb_p gbb = gbb_from_bb (bbs[i]);
2137 GBB_DOMAIN (gbb) = cloog_matrix_copy (domain);
2143 /* Builds the constraint matrix for LOOP in SCOP. NB_OUTER_LOOPS is the
2144 number of loops surrounding LOOP in SCOP. OUTER_CSTR gives the
2145 constraints matrix for the surrounding loops. */
2148 build_loop_iteration_domains (scop_p scop, struct loop *loop,
2149 CloogMatrix *outer_cstr, int nb_outer_loops)
2154 int nb_rows = outer_cstr->NbRows + 1;
2155 int nb_cols = outer_cstr->NbColumns + 1;
2157 /* Last column of CSTR is the column of constants. */
2158 int cst_col = nb_cols - 1;
2160 /* The column for the current loop is just after the columns of
2161 other outer loops. */
2162 int loop_col = nb_outer_loops + 1;
2164 tree nb_iters = number_of_latch_executions (loop);
2166 /* When the number of iterations is a constant or a parameter, we
2167 add a constraint for the upper bound of the loop. So add a row
2168 to the constraint matrix before allocating it. */
2169 if (TREE_CODE (nb_iters) == INTEGER_CST
2170 || !chrec_contains_undetermined (nb_iters))
2173 cstr = cloog_matrix_alloc (nb_rows, nb_cols);
2175 /* Copy the outer constraints. */
2176 for (i = 0; i < outer_cstr->NbRows; i++)
2178 /* Copy the eq/ineq and loops columns. */
2179 for (j = 0; j < loop_col; j++)
2180 value_assign (cstr->p[i][j], outer_cstr->p[i][j]);
2182 /* Leave an empty column in CSTR for the current loop, and then
2183 copy the parameter columns. */
2184 for (j = loop_col; j < outer_cstr->NbColumns; j++)
2185 value_assign (cstr->p[i][j + 1], outer_cstr->p[i][j]);
2189 row = outer_cstr->NbRows;
2190 value_set_si (cstr->p[row][0], 1);
2191 value_set_si (cstr->p[row][loop_col], 1);
2193 /* loop_i <= nb_iters */
2194 if (TREE_CODE (nb_iters) == INTEGER_CST)
2197 value_set_si (cstr->p[row][0], 1);
2198 value_set_si (cstr->p[row][loop_col], -1);
2200 value_set_si (cstr->p[row][cst_col],
2201 int_cst_value (nb_iters));
2203 else if (!chrec_contains_undetermined (nb_iters))
2205 /* Otherwise nb_iters contains parameters: scan the nb_iters
2206 expression and build its matrix representation. */
2210 value_set_si (cstr->p[row][0], 1);
2211 value_set_si (cstr->p[row][loop_col], -1);
2212 nb_iters = analyze_scalar_evolution (loop, nb_iters);
2214 instantiate_scev (outermost_loop_in_scop (scop, loop->header),
2217 value_set_si (one, 1);
2218 scan_tree_for_params (scop, nb_iters, cstr, row, one, false);
2224 if (loop->inner && loop_in_scop_p (loop->inner, scop))
2225 build_loop_iteration_domains (scop, loop->inner, cstr, nb_outer_loops + 1);
2227 /* Only go to the next loops, if we are not at the outermost layer. These
2228 have to be handled seperately, as we can be sure, that the chain at this
2229 layer will be connected. */
2230 if (nb_outer_loops != 0 && loop->next && loop_in_scop_p (loop->next, scop))
2231 build_loop_iteration_domains (scop, loop->next, outer_cstr, nb_outer_loops);
2233 add_bb_domains (loop, cstr);
2235 cloog_matrix_free (cstr);
2238 /* Add conditions to the domain of GB. */
2241 add_conditions_to_domain (graphite_bb_p gb)
2245 VEC (gimple, heap) *conditions = GBB_CONDITIONS (gb);
2246 CloogMatrix *domain = GBB_DOMAIN (gb);
2247 scop_p scop = GBB_SCOP (gb);
2251 unsigned nb_new_rows = 0;
2254 if (VEC_empty (gimple, conditions))
2259 nb_rows = domain->NbRows;
2260 nb_cols = domain->NbColumns;
2265 nb_cols = scop_nb_params (scop) + 2;
2268 /* Count number of necessary new rows to add the conditions to the
2270 for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
2272 switch (gimple_code (stmt))
2276 enum tree_code code = gimple_cond_code (stmt);
2282 /* NE and EQ statements are not supported right know. */
2298 /* Switch statements are not supported right know. */
2309 /* Enlarge the matrix. */
2311 CloogMatrix *new_domain;
2312 new_domain = cloog_matrix_alloc (nb_rows + nb_new_rows, nb_cols);
2314 for (i = 0; i < nb_rows; i++)
2315 for (j = 0; j < nb_cols; j++)
2316 value_assign (new_domain->p[i][j], domain->p[i][j]);
2318 cloog_matrix_free (domain);
2319 domain = new_domain;
2320 GBB_DOMAIN (gb) = new_domain;
2323 /* Add the conditions to the new enlarged domain matrix. */
2325 for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
2327 switch (gimple_code (stmt))
2332 enum tree_code code;
2335 loop_p loop = GBB_BB (gb)->loop_father;
2336 loop_p outermost = outermost_loop_in_scop (scop, GBB_BB (gb));
2338 left = gimple_cond_lhs (stmt);
2339 right = gimple_cond_rhs (stmt);
2341 left = analyze_scalar_evolution (loop, left);
2342 right = analyze_scalar_evolution (loop, right);
2343 left = instantiate_scev (outermost, loop, left);
2344 right = instantiate_scev (outermost, loop, right);
2346 code = gimple_cond_code (stmt);
2348 /* The conditions for ELSE-branches are inverted. */
2349 if (VEC_index (gimple, gb->condition_cases, i) == NULL)
2350 code = invert_tree_comparison (code, false);
2355 /* NE statements are not supported right know. */
2359 value_set_si (domain->p[row][0], 1);
2361 value_set_si (one, 1);
2362 scan_tree_for_params (scop, left, domain, row, one, true);
2363 value_set_si (one, 1);
2364 scan_tree_for_params (scop, right, domain, row, one, false);
2366 value_set_si (domain->p[row][0], 1);
2367 value_set_si (one, 1);
2368 scan_tree_for_params (scop, left, domain, row, one, false);
2369 value_set_si (one, 1);
2370 scan_tree_for_params (scop, right, domain, row, one, true);
2375 value_set_si (domain->p[row][0], 1);
2377 value_set_si (one, 1);
2378 scan_tree_for_params (scop, left, domain, row, one, true);
2379 value_set_si (one, 1);
2380 scan_tree_for_params (scop, right, domain, row, one, false);
2381 value_sub_int (domain->p[row][nb_cols - 1],
2382 domain->p[row][nb_cols - 1], 1);
2387 value_set_si (domain->p[row][0], 1);
2389 value_set_si (one, 1);
2390 scan_tree_for_params (scop, left, domain, row, one, false);
2391 value_set_si (one, 1);
2392 scan_tree_for_params (scop, right, domain, row, one, true);
2393 value_sub_int (domain->p[row][nb_cols - 1],
2394 domain->p[row][nb_cols - 1], 1);
2399 value_set_si (domain->p[row][0], 1);
2401 value_set_si (one, 1);
2402 scan_tree_for_params (scop, left, domain, row, one, true);
2403 value_set_si (one, 1);
2404 scan_tree_for_params (scop, right, domain, row, one, false);
2409 value_set_si (domain->p[row][0], 1);
2411 value_set_si (one, 1);
2412 scan_tree_for_params (scop, left, domain, row, one, false);
2413 value_set_si (one, 1);
2414 scan_tree_for_params (scop, right, domain, row, one, true);
2425 /* Switch statements are not supported right know. */
2436 /* Helper recursive function. */
2439 build_scop_conditions_1 (VEC (gimple, heap) **conditions,
2440 VEC (gimple, heap) **cases, basic_block bb,
2445 gimple_stmt_iterator gsi;
2446 basic_block bb_child, bb_iter;
2447 VEC (basic_block, heap) *dom;
2449 /* Make sure we are in the SCoP. */
2450 if (!bb_in_scop_p (bb, scop))
2453 /* Record conditions in graphite_bb. */
2454 gbb = gbb_from_bb (bb);
2455 GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
2456 GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
2458 add_conditions_to_domain (gbb);
2460 dom = get_dominated_by (CDI_DOMINATORS, bb);
2462 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2464 gimple stmt = gsi_stmt (gsi);
2465 VEC (edge, gc) *edges;
2468 switch (gimple_code (stmt))
2472 for (i = 0; VEC_iterate (edge, edges, i, e); i++)
2473 if ((dominated_by_p (CDI_DOMINATORS, e->dest, bb))
2474 && VEC_length (edge, e->dest->preds) == 1)
2476 /* Remove the scanned block from the dominator successors. */
2477 for (j = 0; VEC_iterate (basic_block, dom, j, bb_iter); j++)
2478 if (bb_iter == e->dest)
2480 VEC_unordered_remove (basic_block, dom, j);
2484 /* Recursively scan the then or else part. */
2485 if (e->flags & EDGE_TRUE_VALUE)
2486 VEC_safe_push (gimple, heap, *cases, stmt);
2487 else if (e->flags & EDGE_FALSE_VALUE)
2488 VEC_safe_push (gimple, heap, *cases, NULL);
2492 VEC_safe_push (gimple, heap, *conditions, stmt);
2493 build_scop_conditions_1 (conditions, cases, e->dest, scop);
2494 VEC_pop (gimple, *conditions);
2495 VEC_pop (gimple, *cases);
2502 gimple_stmt_iterator gsi_search_gimple_label;
2504 for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
2506 basic_block bb_iter;
2508 size_t n_cases = VEC_length (gimple, *conditions);
2509 unsigned n = gimple_switch_num_labels (stmt);
2511 bb_child = label_to_block
2512 (CASE_LABEL (gimple_switch_label (stmt, i)));
2514 /* Do not handle multiple values for the same block. */
2515 for (k = 0; k < n; k++)
2518 (CASE_LABEL (gimple_switch_label (stmt, k))) == bb_child)
2524 /* Switch cases with more than one predecessor are not
2526 if (VEC_length (edge, bb_child->preds) != 1)
2529 /* Recursively scan the corresponding 'case' block. */
2531 for (gsi_search_gimple_label = gsi_start_bb (bb_child);
2532 !gsi_end_p (gsi_search_gimple_label);
2533 gsi_next (&gsi_search_gimple_label))
2535 gimple stmt_gimple_label
2536 = gsi_stmt (gsi_search_gimple_label);
2538 if (gimple_code (stmt_gimple_label) == GIMPLE_LABEL)
2540 tree t = gimple_label_label (stmt_gimple_label);
2542 if (t == gimple_switch_label (stmt, i))
2543 VEC_replace (gimple, *cases, n_cases,
2550 build_scop_conditions_1 (conditions, cases, bb_child, scop);
2552 /* Remove the scanned block from the dominator successors. */
2553 for (j = 0; VEC_iterate (basic_block, dom, j, bb_iter); j++)
2554 if (bb_iter == bb_child)
2556 VEC_unordered_remove (basic_block, dom, j);
2561 VEC_pop (gimple, *conditions);
2562 VEC_pop (gimple, *cases);
2570 /* Scan all immediate dominated successors. */
2571 for (i = 0; VEC_iterate (basic_block, dom, i, bb_child); i++)
2572 build_scop_conditions_1 (conditions, cases, bb_child, scop);
2574 VEC_free (basic_block, heap, dom);
2577 /* Record all 'if' and 'switch' conditions in each gbb of SCOP. */
2580 build_scop_conditions (scop_p scop)
2582 VEC (gimple, heap) *conditions = NULL;
2583 VEC (gimple, heap) *cases = NULL;
2585 build_scop_conditions_1 (&conditions, &cases, SCOP_ENTRY (scop), scop);
2587 VEC_free (gimple, heap, conditions);
2588 VEC_free (gimple, heap, cases);
2591 /* Build the current domain matrix: the loops belonging to the current
2592 SCOP, and that vary for the execution of the current basic block.
2593 Returns false if there is no loop in SCOP. */
2596 build_scop_iteration_domain (scop_p scop)
2599 CloogMatrix *outer_cstr;
2602 /* Build cloog loop for all loops, that are in the uppermost loop layer of
2604 for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop); i++)
2605 if (!loop_in_scop_p (loop_outer (loop), scop))
2607 /* The outermost constraints is a matrix that has:
2608 -first column: eq/ineq boolean
2609 -last column: a constant
2610 -scop_nb_params columns for the parameters used in the scop. */
2611 outer_cstr = cloog_matrix_alloc (0, scop_nb_params (scop) + 2);
2612 build_loop_iteration_domains (scop, loop, outer_cstr, 0);
2613 cloog_matrix_free (outer_cstr);
2619 /* Initializes an equation CY of the access matrix using the
2620 information for a subscript from ACCESS_FUN, relatively to the loop
2621 indexes from LOOP_NEST and parameter indexes from PARAMS. NDIM is
2622 the dimension of the array access, i.e. the number of
2623 subscripts. Returns true when the operation succeeds. */
2626 build_access_matrix_with_af (tree access_fun, lambda_vector cy,
2627 scop_p scop, int ndim)
2629 switch (TREE_CODE (access_fun))
2631 case POLYNOMIAL_CHREC:
2633 tree left = CHREC_LEFT (access_fun);
2634 tree right = CHREC_RIGHT (access_fun);
2637 if (TREE_CODE (right) != INTEGER_CST)
2640 var = loop_iteration_vector_dim (CHREC_VARIABLE (access_fun), scop);
2641 cy[var] = int_cst_value (right);
2643 switch (TREE_CODE (left))
2645 case POLYNOMIAL_CHREC:
2646 return build_access_matrix_with_af (left, cy, scop, ndim);
2649 cy[ndim - 1] = int_cst_value (left);
2653 /* FIXME: access_fn can have parameters. */
2658 cy[ndim - 1] = int_cst_value (access_fun);
2662 /* FIXME: access_fn can have parameters. */
2667 /* Initialize the access matrix in the data reference REF with respect
2668 to the loop nesting LOOP_NEST. Return true when the operation
2672 build_access_matrix (data_reference_p ref, graphite_bb_p gb)
2674 int i, ndim = DR_NUM_DIMENSIONS (ref);
2675 struct access_matrix *am = GGC_NEW (struct access_matrix);
2677 AM_MATRIX (am) = VEC_alloc (lambda_vector, heap, ndim);
2678 DR_SCOP (ref) = GBB_SCOP (gb);
2680 for (i = 0; i < ndim; i++)
2682 lambda_vector v = lambda_vector_new (ref_nb_loops (ref));
2683 scop_p scop = GBB_SCOP (gb);
2684 tree af = DR_ACCESS_FN (ref, i);
2686 if (!build_access_matrix_with_af (af, v, scop, ref_nb_loops (ref)))
2689 VEC_safe_push (lambda_vector, heap, AM_MATRIX (am), v);
2692 DR_ACCESS_MATRIX (ref) = am;
2696 /* Build the access matrices for the data references in the SCOP. */
2699 build_scop_data_accesses (scop_p scop)
2704 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
2707 gimple_stmt_iterator gsi;
2708 data_reference_p dr;
2709 struct loop *nest = outermost_loop_in_scop (scop, GBB_BB (gb));
2711 /* On each statement of the basic block, gather all the occurences
2712 to read/write memory. */
2713 GBB_DATA_REFS (gb) = VEC_alloc (data_reference_p, heap, 5);
2714 for (gsi = gsi_start_bb (GBB_BB (gb)); !gsi_end_p (gsi); gsi_next (&gsi))
2715 find_data_references_in_stmt (nest, gsi_stmt (gsi),
2716 &GBB_DATA_REFS (gb));
2718 /* FIXME: Construction of access matrix is disabled until some
2719 pass, like the data dependence analysis, is using it. */
2722 /* Construct the access matrix for each data ref, with respect to
2723 the loop nest of the current BB in the considered SCOP. */
2725 VEC_iterate (data_reference_p, GBB_DATA_REFS (gb), j, dr);
2728 bool res = build_access_matrix (dr, gb);
2730 /* FIXME: At this point the DRs should always have an affine
2731 form. For the moment this fails as build_access_matrix
2732 does not build matrices with parameters. */
2738 /* Converts a GMP constant value to a tree and returns it. */
2741 gmp_cst_to_tree (Value v)
2743 return build_int_cst (integer_type_node, value_get_si (v));
2746 /* Returns the tree variable from the name NAME that was given in
2747 Cloog representation. All the parameters are stored in PARAMS, and
2748 all the loop induction variables are stored in IVSTACK.
2750 FIXME: This is a hack, and Cloog should be fixed to not work with
2751 variable names represented as "char *string", but with void
2752 pointers that could be casted back to a tree. The only problem in
2753 doing that is that Cloog's pretty printer still assumes that
2754 variable names are char *strings. The solution would be to have a
2755 function pointer for pretty-printing that can be redirected to be
2756 print_generic_stmt in our case, or fprintf by default.
2757 ??? Too ugly to live. */
2760 clast_name_to_gcc (const char *name, VEC (name_tree, heap) *params,
2761 loop_iv_stack ivstack)
2767 for (i = 0; VEC_iterate (name_tree, params, i, t); i++)
2768 if (!strcmp (name, t->name))
2771 iv = loop_iv_stack_get_iv_from_name (ivstack, name);
2778 /* Converts a Cloog AST expression E back to a GCC expression tree. */
2781 clast_to_gcc_expression (struct clast_expr *e,
2782 VEC (name_tree, heap) *params,
2783 loop_iv_stack ivstack)
2785 tree type = integer_type_node;
2793 struct clast_term *t = (struct clast_term *) e;
2797 if (value_one_p (t->val))
2798 return clast_name_to_gcc (t->var, params, ivstack);
2800 else if (value_mone_p (t->val))
2801 return fold_build1 (NEGATE_EXPR, type,
2802 clast_name_to_gcc (t->var, params, ivstack));
2804 return fold_build2 (MULT_EXPR, type,
2805 gmp_cst_to_tree (t->val),
2806 clast_name_to_gcc (t->var, params, ivstack));
2809 return gmp_cst_to_tree (t->val);
2814 struct clast_reduction *r = (struct clast_reduction *) e;
2821 return clast_to_gcc_expression (r->elts[0], params, ivstack);
2825 gcc_assert (r->n >= 1
2826 && r->elts[0]->type == expr_term
2827 && r->elts[1]->type == expr_term);
2829 left = clast_to_gcc_expression (r->elts[0], params, ivstack);
2830 right = clast_to_gcc_expression (r->elts[1], params, ivstack);
2831 return fold_build2 (PLUS_EXPR, type, left, right);
2838 return clast_to_gcc_expression (r->elts[0], params, ivstack);
2842 left = clast_to_gcc_expression (r->elts[0], params, ivstack);
2843 right = clast_to_gcc_expression (r->elts[1], params, ivstack);
2844 return fold_build2 (MIN_EXPR, type, left, right);
2854 return clast_to_gcc_expression (r->elts[0], params, ivstack);
2858 left = clast_to_gcc_expression (r->elts[0], params, ivstack);
2859 right = clast_to_gcc_expression (r->elts[1], params, ivstack);
2860 return fold_build2 (MAX_EXPR, type, left, right);
2876 struct clast_binary *b = (struct clast_binary *) e;
2877 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
2878 struct clast_expr *rhs = (struct clast_expr *) b->RHS;
2879 tree tl = clast_to_gcc_expression (lhs, params, ivstack);
2881 /* FIXME: The next statement produces a warning: Cloog assumes
2882 that the RHS is a constant, but this is a "void *" pointer
2883 that should be casted into a Value, but this cast cannot be
2884 done as Value is a GMP type, that is an array. Cloog must
2885 be fixed for removing this warning. */
2886 tree tr = gmp_cst_to_tree (rhs);
2890 case clast_bin_fdiv:
2891 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
2893 case clast_bin_cdiv:
2894 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
2897 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
2900 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
2914 /* Translates a clast equation CLEQ to a tree. */
2917 graphite_translate_clast_equation (scop_p scop,
2918 struct clast_equation *cleq,
2919 loop_iv_stack ivstack)
2921 enum tree_code comp;
2922 tree lhs = clast_to_gcc_expression (cleq->LHS, SCOP_PARAMS (scop), ivstack);
2923 tree rhs = clast_to_gcc_expression (cleq->RHS, SCOP_PARAMS (scop), ivstack);
2925 if (cleq->sign == 0)
2928 else if (cleq->sign > 0)
2934 return fold_build2 (comp, integer_type_node, lhs, rhs);
2937 /* Creates the test for the condition in STMT. */
2940 graphite_create_guard_cond_expr (scop_p scop, struct clast_guard *stmt,
2941 loop_iv_stack ivstack)
2946 for (i = 0; i < stmt->n; i++)
2948 tree eq = graphite_translate_clast_equation (scop, &stmt->eq[i], ivstack);
2951 cond = fold_build2 (TRUTH_AND_EXPR, integer_type_node, cond, eq);
2959 /* Creates a new if region corresponding to Cloog's guard. */
2962 graphite_create_new_guard (scop_p scop, edge entry_edge,
2963 struct clast_guard *stmt,
2964 loop_iv_stack ivstack)
2966 tree cond_expr = graphite_create_guard_cond_expr (scop, stmt, ivstack);
2967 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
2972 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an induction
2973 variable for the new LOOP. New LOOP is attached to CFG starting at
2974 ENTRY_EDGE. LOOP is inserted into the loop tree and becomes the child
2975 loop of the OUTER_LOOP. */
2977 static struct loop *
2978 graphite_create_new_loop (scop_p scop, edge entry_edge,
2979 struct clast_for *stmt, loop_iv_stack ivstack,
2984 tree stride, lowb, upb;
2987 gcc_assert (stmt->LB
2990 stride = gmp_cst_to_tree (stmt->stride);
2991 lowb = clast_to_gcc_expression (stmt->LB, SCOP_PARAMS (scop), ivstack);
2992 ivvar = create_tmp_var (integer_type_node, "graphiteIV");
2993 add_referenced_var (ivvar);
2995 upb = clast_to_gcc_expression (stmt->UB, SCOP_PARAMS (scop), ivstack);
2996 loop = create_empty_loop_on_edge (entry_edge, lowb, stride, upb, ivvar,
2997 &iv_before, outer ? outer
2998 : entry_edge->src->loop_father);
3000 loop_iv_stack_push (ivstack, iv_before, stmt->iterator);
3005 /* Remove all the edges from EDGES except the edge KEEP. */
3008 remove_all_edges_1 (VEC (edge, gc) *edges, edge keep)
3013 for (ei = ei_start (edges); (e = ei_safe_edge (ei)); )
3018 e = ei_safe_edge (ei);
3025 /* Remove all the edges from BB except the edge KEEP. */
3028 remove_all_edges (basic_block bb, edge keep)
3030 remove_all_edges_1 (bb->succs, keep);
3031 remove_all_edges_1 (bb->preds, keep);
3034 /* Rename the SSA_NAMEs used in STMT and that appear in IVSTACK. */
3037 graphite_rename_ivs_stmt (gimple stmt, graphite_bb_p gbb, scop_p scop,
3038 loop_p old, loop_iv_stack ivstack)
3041 use_operand_p use_p;
3043 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
3045 tree use = USE_FROM_PTR (use_p);
3047 name_tree old_iv = get_old_iv_from_ssa_name (scop, old, use);
3050 new_iv = loop_iv_stack_get_iv (ivstack,
3051 gbb_loop_index (gbb, old_iv->loop));
3054 SET_USE (use_p, new_iv);
3058 /* Returns true if SSA_NAME is a parameter of SCOP. */
3061 is_parameter (scop_p scop, tree ssa_name)
3064 VEC (name_tree, heap) *params = SCOP_PARAMS (scop);
3067 for (i = 0; VEC_iterate (name_tree, params, i, param); i++)
3068 if (param->t == ssa_name)
3074 /* Returns true if NAME is an old induction variable in SCOP. OLD is
3075 the original loop that contained the definition of NAME. */
3078 is_old_iv (scop_p scop, loop_p old, tree name)
3080 return get_old_iv_from_ssa_name (scop, old, name) != NULL;
3084 static void expand_scalar_variables_stmt (gimple, graphite_bb_p, scop_p, loop_p,
3087 /* Constructs a tree which only contains old_ivs and parameters. Any
3088 other variables that are defined outside GBB will be eliminated by
3089 using their definitions in the constructed tree. OLD_LOOP_FATHER
3090 is the original loop that contained GBB. */
3093 expand_scalar_variables_expr (tree type, tree op0, enum tree_code code,
3094 tree op1, graphite_bb_p gbb, scop_p scop,
3095 loop_p old_loop_father, loop_iv_stack ivstack)
3097 if (TREE_CODE_CLASS (code) == tcc_constant
3098 && code == INTEGER_CST)
3101 if (TREE_CODE_CLASS (code) == tcc_unary)
3103 tree op0_type = TREE_TYPE (op0);
3104 enum tree_code op0_code = TREE_CODE (op0);
3106 expand_scalar_variables_expr (op0_type, op0, op0_code,
3107 NULL, gbb, scop, old_loop_father,
3110 return fold_build1 (code, type, op0_expr);
3113 if (TREE_CODE_CLASS (code) == tcc_binary)
3115 tree op0_type = TREE_TYPE (op0);
3116 enum tree_code op0_code = TREE_CODE (op0);
3118 expand_scalar_variables_expr (op0_type, op0, op0_code,
3119 NULL, gbb, scop, old_loop_father,
3121 tree op1_type = TREE_TYPE (op1);
3122 enum tree_code op1_code = TREE_CODE (op1);
3124 expand_scalar_variables_expr (op1_type, op1, op1_code,
3125 NULL, gbb, scop, old_loop_father,
3128 return fold_build2 (code, type, op0_expr, op1_expr);
3131 if (code == SSA_NAME)
3135 enum tree_code subcode;
3137 if(is_parameter (scop, op0) ||
3138 is_old_iv (scop, old_loop_father, op0))
3141 def_stmt = SSA_NAME_DEF_STMT (op0);
3143 if (gimple_bb (def_stmt) == GBB_BB (gbb))
3145 /* If the defining statement is in the basic block already
3146 we do not need to create a new expression for it, we
3147 only need to ensure its operands are expanded. */
3148 expand_scalar_variables_stmt (def_stmt, gbb, scop,
3149 old_loop_father, ivstack);
3155 if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
3158 var0 = gimple_assign_rhs1 (def_stmt);
3159 subcode = gimple_assign_rhs_code (def_stmt);
3160 var1 = gimple_assign_rhs2 (def_stmt);
3162 return expand_scalar_variables_expr (type, var0, subcode, var1,
3163 gbb, scop, old_loop_father,
3172 /* Replicates any uses of non-parameters and non-old-ivs variablesthat
3173 are defind outside GBB with code that is inserted in GBB.
3174 OLD_LOOP_FATHER is the original loop that contained STMT. */
3177 expand_scalar_variables_stmt (gimple stmt, graphite_bb_p gbb, scop_p scop,
3178 loop_p old_loop_father, loop_iv_stack ivstack)
3181 use_operand_p use_p;
3182 basic_block bb = GBB_BB (gbb);
3184 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
3186 tree use = USE_FROM_PTR (use_p);
3187 tree type = TREE_TYPE (use);
3188 enum tree_code code = TREE_CODE (use);
3189 tree use_expr = expand_scalar_variables_expr (type, use, code, NULL,
3190 gbb, scop, old_loop_father,
3192 if (use_expr != use)
3194 gimple_stmt_iterator gsi = gsi_after_labels (bb);
3196 force_gimple_operand_gsi (&gsi, use_expr, true, NULL,
3197 true, GSI_NEW_STMT);
3198 SET_USE (use_p, new_use);
3203 /* Copies the definitions outside of GBB of variables that are not
3204 induction variables nor parameters. GBB must only contain
3205 "external" references to these types of variables. OLD_LOOP_FATHER
3206 is the original loop that contained GBB. */
3209 expand_scalar_variables (graphite_bb_p gbb, scop_p scop,
3210 loop_p old_loop_father, loop_iv_stack ivstack)
3212 basic_block bb = GBB_BB (gbb);
3213 gimple_stmt_iterator gsi;
3215 for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
3217 gimple stmt = gsi_stmt (gsi);
3218 expand_scalar_variables_stmt (stmt, gbb, scop, old_loop_father,
3224 /* Rename all the SSA_NAMEs from block GBB that appear in IVSTACK in
3225 terms of new induction variables. OLD_LOOP_FATHER is the original
3226 loop that contained GBB. */
3229 graphite_rename_ivs (graphite_bb_p gbb, scop_p scop, loop_p old_loop_father,
3230 loop_iv_stack ivstack)
3232 basic_block bb = GBB_BB (gbb);
3233 gimple_stmt_iterator gsi;
3235 for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
3237 gimple stmt = gsi_stmt (gsi);
3239 if (gimple_get_lhs (stmt)
3240 && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME
3241 && get_old_iv_from_ssa_name (scop, old_loop_father,
3242 gimple_get_lhs (stmt)))
3243 gsi_remove (&gsi, false);
3246 graphite_rename_ivs_stmt (stmt, gbb, scop, old_loop_father, ivstack);
3252 /* Move all the PHI nodes from block FROM to block TO.
3253 OLD_LOOP_FATHER is the original loop that contained FROM. */
3256 move_phi_nodes (scop_p scop, loop_p old_loop_father, basic_block from,
3259 gimple_stmt_iterator gsi;
3261 for (gsi = gsi_start_phis (from); !gsi_end_p (gsi);)
3263 gimple phi = gsi_stmt (gsi);
3264 tree op = gimple_phi_result (phi);
3266 if (get_old_iv_from_ssa_name (scop, old_loop_father, op) == NULL)
3268 gimple new_phi = make_phi_node (op, 0);
3269 add_phi_node_to_bb (new_phi, to);
3271 remove_phi_node (&gsi, false);
3275 /* Remove condition from BB. */
3278 remove_condition (basic_block bb)
3280 gimple last = last_stmt (bb);
3282 if (last && gimple_code (last) == GIMPLE_COND)
3284 gimple_stmt_iterator gsi = gsi_last_bb (bb);
3285 gsi_remove (&gsi, true);
3289 /* Returns the first successor edge of BB with EDGE_TRUE_VALUE flag set. */
3292 get_true_edge_from_guard_bb (basic_block bb)
3297 FOR_EACH_EDGE (e, ei, bb->succs)
3298 if (e->flags & EDGE_TRUE_VALUE)
3305 /* Translates a CLAST statement STMT to GCC representation. NEXT_E is
3306 the edge where new generated code should be attached. BB_EXIT is the last
3307 basic block that defines the scope of code generation. CONTEXT_LOOP is the
3308 loop in which the generated code will be placed (might be NULL). */
3311 translate_clast (scop_p scop, struct loop *context_loop,
3312 struct clast_stmt *stmt, edge next_e, loop_iv_stack ivstack)
3317 if (CLAST_STMT_IS_A (stmt, stmt_root))
3318 return translate_clast (scop, context_loop, stmt->next, next_e, ivstack);
3320 if (CLAST_STMT_IS_A (stmt, stmt_user))
3322 CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
3323 graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
3324 basic_block bb = gbb->bb;
3325 loop_p old_loop_father = bb->loop_father;
3327 if (bb == ENTRY_BLOCK_PTR)
3330 remove_condition (bb);
3331 expand_scalar_variables (gbb, scop, old_loop_father, ivstack);
3332 remove_all_edges (bb, next_e);
3333 move_phi_nodes (scop, old_loop_father, bb, next_e->src);
3334 redirect_edge_succ_nodup (next_e, bb);
3338 remove_bb_from_loops (bb);
3339 add_bb_to_loop (bb, context_loop);
3342 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
3343 mark_virtual_ops_in_bb (bb);
3344 next_e = make_edge (bb,
3345 context_loop ? context_loop->latch : EXIT_BLOCK_PTR,
3347 graphite_rename_ivs (gbb, scop, old_loop_father, ivstack);
3348 return translate_clast (scop, context_loop, stmt->next, next_e, ivstack);
3351 if (CLAST_STMT_IS_A (stmt, stmt_for))
3354 = graphite_create_new_loop (scop, next_e, (struct clast_for *) stmt,
3355 ivstack, context_loop ? context_loop
3357 edge last_e = single_exit (loop);
3359 next_e = translate_clast (scop, loop, ((struct clast_for *) stmt)->body,
3360 single_pred_edge (loop->latch), ivstack);
3361 redirect_edge_succ_nodup (next_e, loop->latch);
3363 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
3364 loop_iv_stack_pop (ivstack);
3366 return translate_clast (scop, context_loop, stmt->next, last_e, ivstack);
3369 if (CLAST_STMT_IS_A (stmt, stmt_guard))
3371 edge last_e = graphite_create_new_guard (scop, next_e,
3372 ((struct clast_guard *) stmt),
3374 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
3375 next_e = translate_clast (scop, context_loop,
3376 ((struct clast_guard *) stmt)->then,
3378 redirect_edge_succ_nodup (next_e, last_e->src);
3379 return translate_clast (scop, context_loop, stmt->next, last_e, ivstack);
3382 if (CLAST_STMT_IS_A (stmt, stmt_block))
3384 next_e = translate_clast (scop, context_loop,
3385 ((struct clast_block *) stmt)->body,
3387 return translate_clast (scop, context_loop, stmt->next, next_e, ivstack);
3393 /* Build cloog program for SCoP. */
3396 build_cloog_prog (scop_p scop)
3399 int max_nb_loops = scop_max_loop_depth (scop);
3401 CloogLoop *loop_list = NULL;
3402 CloogBlockList *block_list = NULL;
3403 CloogDomainList *scattering = NULL;
3404 CloogProgram *prog = SCOP_PROG (scop);
3405 int nbs = 2 * max_nb_loops + 1;
3406 int *scaldims = (int *) xmalloc (nbs * (sizeof (int)));
3408 cloog_program_set_nb_scattdims (prog, nbs);
3409 initialize_cloog_names (scop);
3411 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++)
3413 /* Build new block. */
3414 CloogMatrix *domain = GBB_DOMAIN (gbb);
3415 CloogStatement *stmt = cloog_statement_alloc (GBB_BB (gbb)->index);
3416 CloogBlock *block = cloog_block_alloc (stmt, 0, NULL,
3417 nb_loops_around_gb (gbb));
3418 cloog_statement_set_usr (stmt, gbb);
3420 /* Add empty domain to all bbs, which do not yet have a domain, as they
3421 are not part of any loop. */
3424 domain = cloog_matrix_alloc (0, scop_nb_params (scop) + 2);
3425 GBB_DOMAIN (gbb) = domain;
3428 /* Build loop list. */
3430 CloogLoop *new_loop_list = cloog_loop_malloc ();
3431 cloog_loop_set_next (new_loop_list, loop_list);
3432 cloog_loop_set_domain (new_loop_list,
3433 cloog_domain_matrix2domain (domain));
3434 cloog_loop_set_block (new_loop_list, block);
3435 loop_list = new_loop_list;
3438 /* Build block list. */
3440 CloogBlockList *new_block_list = cloog_block_list_malloc ();
3442 cloog_block_list_set_next (new_block_list, block_list);
3443 cloog_block_list_set_block (new_block_list, block);
3444 block_list = new_block_list;
3447 /* Build scattering list. */
3449 /* XXX: Replace with cloog_domain_list_alloc(), when available. */
3450 CloogDomainList *new_scattering
3451 = (CloogDomainList *) xmalloc (sizeof (CloogDomainList));
3452 CloogMatrix *scat_mat = schedule_to_scattering (gbb, nbs);
3454 cloog_set_next_domain (new_scattering, scattering);
3455 cloog_set_domain (new_scattering,
3456 cloog_domain_matrix2domain (scat_mat));
3457 scattering = new_scattering;
3458 cloog_matrix_free (scat_mat);
3462 cloog_program_set_loop (prog, loop_list);
3463 cloog_program_set_blocklist (prog, block_list);
3465 for (i = 0; i < nbs; i++)
3468 cloog_program_set_scaldims (prog, scaldims);
3470 /* Extract scalar dimensions to simplify the code generation problem. */
3471 cloog_program_extract_scalars (prog, scattering);
3473 /* Apply scattering. */
3474 cloog_program_scatter (prog, scattering);
3476 /* Iterators corresponding to scalar dimensions have to be extracted. */
3477 cloog_names_scalarize (cloog_program_names (prog), nbs,
3478 cloog_program_scaldims (prog));
3480 /* Free blocklist. */
3482 CloogBlockList *next = cloog_program_blocklist (prog);
3486 CloogBlockList *toDelete = next;
3487 next = cloog_block_list_next (next);
3488 cloog_block_list_set_next (toDelete, NULL);
3489 cloog_block_list_set_block (toDelete, NULL);
3490 cloog_block_list_free (toDelete);
3492 cloog_program_set_blocklist (prog, NULL);
3496 /* Return the options that will be used in GLOOG. */
3498 static CloogOptions *
3499 set_cloog_options (void)
3501 CloogOptions *options = cloog_options_malloc ();
3503 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
3504 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
3505 we pass an incomplete program to cloog. */
3506 options->language = LANGUAGE_C;
3508 /* Enable complex equality spreading: removes dummy statements
3509 (assignments) in the generated code which repeats the
3510 substitution equations for statements. This is useless for
3514 /* Enable C pretty-printing mode: normalizes the substitution
3515 equations for statements. */
3518 /* Allow cloog to build strides with a stride width different to one.
3519 This example has stride = 4:
3521 for (i = 0; i < 20; i += 4)
3523 options->strides = 1;
3525 /* Disable optimizations and make cloog generate source code closer to the
3526 input. This is useful for debugging, but later we want the optimized
3529 XXX: We can not disable optimizations, as loop blocking is not working
3534 options->l = INT_MAX;
3540 /* Prints STMT to STDERR. */
3543 debug_clast_stmt (struct clast_stmt *stmt)
3545 CloogOptions *options = set_cloog_options ();
3547 pprint (stderr, stmt, 0, options);
3550 /* Find the right transform for the SCOP, and return a Cloog AST
3551 representing the new form of the program. */
3553 static struct clast_stmt *
3554 find_transform (scop_p scop)
3557 struct clast_stmt *stmt;
3558 CloogOptions *options = set_cloog_options ();
3560 /* Connect new cloog prog generation to graphite. */
3561 build_cloog_prog (scop);
3563 if (dump_file && (dump_flags & TDF_DETAILS))
3565 fprintf (dump_file, "Cloog Input [\n");
3566 cloog_program_print (dump_file, SCOP_PROG(scop));
3567 fprintf (dump_file, "]\n");
3570 prog = cloog_program_generate (SCOP_PROG (scop), options);
3571 stmt = cloog_clast_create (prog, options);
3573 if (dump_file && (dump_flags & TDF_DETAILS))
3575 fprintf (dump_file, "Cloog Output[\n");
3576 pprint (dump_file, stmt, 0, options);
3577 cloog_program_dump_cloog (dump_file, prog);
3578 fprintf (dump_file, "]\n");
3581 cloog_options_free (options);
3585 /* Return a vector of all the virtual phi nodes in the current
3588 static VEC (gimple, heap) *
3589 collect_virtual_phis (void)
3591 gimple_stmt_iterator si;
3592 gimple_vec phis = VEC_alloc (gimple, heap, 3);
3596 for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
3597 /* The phis we moved will have 0 arguments because the
3598 original edges were removed. */
3599 if (gimple_phi_num_args (gsi_stmt (si)) == 0)
3600 VEC_safe_push (gimple, heap, phis, gsi_stmt (si));
3602 /* Deallocate if we did not find any. */
3603 if (VEC_length (gimple, phis) == 0)
3605 VEC_free (gimple, heap, phis);
3612 /* Find a virtual definition for variable VAR in BB. */
3615 find_vdef_for_var_in_bb (basic_block bb, tree var)
3617 gimple_stmt_iterator gsi;
3619 def_operand_p def_var;
3621 ssa_op_iter op_iter;
3623 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
3624 FOR_EACH_SSA_VDEF_OPERAND (def_var, vv, gsi_stmt (gsi), op_iter)
3625 if (SSA_NAME_VAR (*def_var) == var)
3628 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
3629 FOR_EACH_SSA_DEF_OPERAND (def_var, gsi_stmt (gsi), op_iter, SSA_OP_DEF)
3630 if (SSA_NAME_VAR (*def_var) == var)
3633 for (gsi = gsi_start_phis (bb); !gsi_end_p(gsi); gsi_next (&gsi))
3635 phi = gsi_stmt (gsi);
3636 if (SSA_NAME_VAR (PHI_RESULT (phi)) == var)
3637 return PHI_RESULT (phi);
3643 /* Recursive helper. */
3646 find_vdef_for_var_1 (basic_block bb, struct pointer_set_t *visited, tree var)
3652 if (pointer_set_contains (visited, bb))
3655 pointer_set_insert (visited, bb);
3656 result = find_vdef_for_var_in_bb (bb, var);
3659 FOR_EACH_EDGE (pred_edge, ei, bb->preds)
3661 result = find_vdef_for_var_1 (pred_edge->src, visited, var);
3666 /* Finds a virtual definition for variable VAR. */
3669 find_vdef_for_var (basic_block bb, tree var)
3671 struct pointer_set_t *visited = pointer_set_create ();
3672 tree def = find_vdef_for_var_1 (bb, visited, var);
3674 pointer_set_destroy (visited);
3678 /* Update the virtual phis after loop bodies are moved to new
3682 patch_phis_for_virtual_defs (void)
3686 VEC (gimple, heap) *virtual_phis = collect_virtual_phis ();
3688 for (i = 0; VEC_iterate (gimple, virtual_phis, i, phi); i++)
3690 basic_block bb = gimple_bb (phi);
3693 gimple_stmt_iterator gsi;
3695 tree phi_result = PHI_RESULT (phi);
3696 tree var = SSA_NAME_VAR (phi_result);
3698 new_phi = create_phi_node (phi_result, bb);
3699 SSA_NAME_DEF_STMT (phi_result) = new_phi;
3701 FOR_EACH_EDGE (pred_edge, ei, bb->preds)
3703 tree def = find_vdef_for_var (pred_edge->src, var);
3706 add_phi_arg (new_phi, def, pred_edge);
3708 add_phi_arg (new_phi, gimple_default_def (cfun, var), pred_edge);
3711 gsi = gsi_for_stmt (phi);
3712 remove_phi_node (&gsi, false);
3716 /* Mark the original loops of SCOP for removal, replacing their header
3720 mark_old_loops (scop_p scop)
3725 for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop); i++)
3727 loop->header = NULL;
3732 /* Scan the loops and remove the ones that have been marked for
3736 remove_dead_loops (void)
3738 struct loop *loop, *ploop;
3741 FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
3743 /* Remove only those loops that we marked to be removed with
3750 ploop = loop->inner;
3751 flow_loop_tree_node_remove (ploop);
3752 flow_loop_tree_node_add (loop_outer (loop), ploop);
3755 /* Remove the loop and free its data. */
3760 /* Returns true when it is possible to generate code for this STMT.
3761 For the moment we cannot generate code when Cloog decides to
3762 duplicate a statement, as we do not do a copy, but a move.
3763 USED_BASIC_BLOCKS records the blocks that have already been seen.
3764 We return false if we have to generate code twice for the same
3768 can_generate_code_stmt (struct clast_stmt *stmt,
3769 struct pointer_set_t *used_basic_blocks)
3774 if (CLAST_STMT_IS_A (stmt, stmt_root))
3775 return can_generate_code_stmt (stmt->next, used_basic_blocks);
3777 if (CLAST_STMT_IS_A (stmt, stmt_user))
3779 CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
3780 graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
3782 if (pointer_set_contains (used_basic_blocks, gbb))
3784 pointer_set_insert (used_basic_blocks, gbb);
3785 return can_generate_code_stmt (stmt->next, used_basic_blocks);
3788 if (CLAST_STMT_IS_A (stmt, stmt_for))
3789 return can_generate_code_stmt (((struct clast_for *) stmt)->body,
3791 && can_generate_code_stmt (stmt->next, used_basic_blocks);
3793 if (CLAST_STMT_IS_A (stmt, stmt_guard))
3794 return can_generate_code_stmt (((struct clast_guard *) stmt)->then,
3797 if (CLAST_STMT_IS_A (stmt, stmt_block))
3798 return can_generate_code_stmt (((struct clast_block *) stmt)->body,
3800 && can_generate_code_stmt (stmt->next, used_basic_blocks);
3805 /* Returns true when it is possible to generate code for this STMT. */
3808 can_generate_code (struct clast_stmt *stmt)
3811 struct pointer_set_t *used_basic_blocks = pointer_set_create ();
3813 result = can_generate_code_stmt (stmt, used_basic_blocks);
3814 pointer_set_destroy (used_basic_blocks);
3818 /* Skip any definition that is a phi node with a single phi def. */
3821 skip_phi_defs (tree ssa_name)
3823 tree result = ssa_name;
3824 gimple def_stmt = SSA_NAME_DEF_STMT (ssa_name);
3826 if (gimple_code (def_stmt) == GIMPLE_PHI
3827 && gimple_phi_num_args (def_stmt) == 1)
3828 result = skip_phi_defs (gimple_phi_arg(def_stmt,0)->def);
3833 /* Returns a VEC containing the phi-arg defs coming from SCOP_EXIT in
3834 the destination block of SCOP_EXIT. */
3836 static VEC (tree, heap) *
3837 collect_scop_exit_phi_args (edge scop_exit)
3839 VEC (tree, heap) *phi_args = VEC_alloc (tree, heap, 1);
3840 gimple_stmt_iterator gsi;
3842 for (gsi = gsi_start_phis (scop_exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
3844 gimple phi = gsi_stmt (gsi);
3845 tree phi_arg = skip_phi_defs(PHI_ARG_DEF_FROM_EDGE (phi, scop_exit));
3847 VEC_safe_push (tree, heap, phi_args, phi_arg);
3853 /* Patches (adds) PHI_ARGS to the phi nodes in SCOP_EXIT destination. */
3856 patch_scop_exit_phi_args (edge scop_exit,
3857 VEC (tree, heap) *phi_args)
3860 gimple_stmt_iterator gsi;
3862 for (gsi = gsi_start_phis (scop_exit->dest); !gsi_end_p (gsi);
3863 gsi_next (&gsi), i++)
3865 tree def = VEC_index (tree, phi_args, i);
3866 gimple phi = gsi_stmt (gsi);
3868 gcc_assert (PHI_ARG_DEF_FROM_EDGE (phi, scop_exit) == NULL);
3870 add_phi_arg (phi, def, scop_exit);
3874 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
3878 gloog (scop_p scop, struct clast_stmt *stmt)
3880 edge new_scop_exit_edge = NULL;
3881 basic_block scop_exit = SCOP_EXIT (scop);
3882 VEC (tree, heap)* phi_args =
3883 collect_scop_exit_phi_args (SESE_EXIT (SCOP_REGION (scop)));
3884 VEC (name_tree, heap) *ivstack = VEC_alloc (name_tree, heap, 10);
3885 edge construction_edge = SESE_ENTRY (SCOP_REGION (scop));
3886 basic_block old_scop_exit_idom = get_immediate_dominator (CDI_DOMINATORS,
3889 if (!can_generate_code (stmt))
3891 cloog_clast_free (stmt);
3895 new_scop_exit_edge = translate_clast (scop,
3896 construction_edge->src->loop_father,
3897 stmt, construction_edge, &ivstack);
3898 redirect_edge_succ (new_scop_exit_edge, scop_exit);
3899 if (!old_scop_exit_idom
3900 || !dominated_by_p (CDI_DOMINATORS, SCOP_ENTRY (scop),
3902 || SCOP_ENTRY (scop) == old_scop_exit_idom)
3903 set_immediate_dominator (CDI_DOMINATORS,
3904 new_scop_exit_edge->dest,
3905 new_scop_exit_edge->src);
3907 cloog_clast_free (stmt);
3909 if (new_scop_exit_edge->dest == EXIT_BLOCK_PTR)
3910 new_scop_exit_edge->flags = 0;
3912 find_unreachable_blocks ();
3913 delete_unreachable_blocks ();
3914 patch_phis_for_virtual_defs ();
3915 patch_scop_exit_phi_args (new_scop_exit_edge, phi_args);
3916 mark_old_loops (scop);
3917 remove_dead_loops ();
3918 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
3920 #ifdef ENABLE_CHECKING
3921 verify_loop_structure ();
3922 verify_dominators (CDI_DOMINATORS);
3927 /* Returns the number of data references in SCOP. */
3930 nb_data_refs_in_scop (scop_p scop)
3936 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++)
3937 res += VEC_length (data_reference_p, GBB_DATA_REFS (gbb));
3942 /* Check if a graphite bb can be ignored in graphite. We ignore all
3943 bbs, that only contain code, that will be eliminated later.
3945 TODO: - Move PHI nodes and scalar variables out of these bbs, that only
3946 remain conditions and induction variables. */
3949 gbb_can_be_ignored (graphite_bb_p gb)
3951 gimple_stmt_iterator gsi;
3952 scop_p scop = GBB_SCOP (gb);
3953 loop_p loop = GBB_BB (gb)->loop_father;
3955 if (VEC_length (data_reference_p, GBB_DATA_REFS(gb)))
3958 /* Check statements. */
3959 for (gsi = gsi_start_bb (GBB_BB (gb)); !gsi_end_p (gsi); gsi_next (&gsi))
3961 gimple stmt = gsi_stmt (gsi);
3962 switch (gimple_code (stmt))
3964 /* Control flow expressions can be ignored, as they are
3965 represented in the iteration domains and will be
3966 regenerated by graphite. */
3972 /* Scalar variables can be ignored, if we can regenerate
3973 them later using their scalar evolution function.
3974 XXX: Just a heuristic, that needs further investigation. */
3977 tree var = gimple_assign_lhs (stmt);
3978 var = analyze_scalar_evolution (loop, var);
3979 var = instantiate_scev (outermost_loop_in_scop (scop,
3982 if (TREE_CODE (var) == SCEV_NOT_KNOWN)
3986 /* Otherwise not ignoreable. */
3995 /* Remove all ignoreable gbbs from SCOP. */
3998 scop_remove_ignoreable_gbbs (scop_p scop)
4003 int max_schedule = scop_max_loop_depth (scop) + 1;
4004 lambda_vector last_schedule = lambda_vector_new (max_schedule);
4005 lambda_vector_clear (last_schedule, max_schedule);
4007 /* Update schedules. */
4008 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
4010 int nb_loops = gbb_nb_loops (gb);
4012 if (GBB_STATIC_SCHEDULE (gb) [nb_loops] == 0)
4013 last_schedule [nb_loops] = 0;
4015 if (gbb_can_be_ignored (gb))
4017 /* Mark gbb for remove. */
4018 bitmap_clear_bit (SCOP_BBS_B (scop), gb->bb->index);
4019 GBB_SCOP (gb) = NULL;
4020 last_schedule [nb_loops]--;
4023 lambda_vector_add (GBB_STATIC_SCHEDULE (gb), last_schedule,
4024 GBB_STATIC_SCHEDULE (gb), nb_loops + 1);
4028 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
4029 if (GBB_SCOP (gb) == NULL)
4031 VEC_unordered_remove (graphite_bb_p, SCOP_BBS (scop), i);
4032 free_graphite_bb (gb);
4033 /* XXX: Hackish? But working. */
4037 graphite_sort_gbbs (scop);
4040 /* Move the loop at index LOOP and insert it before index NEW_LOOP_POS.
4041 This transformartion is only valid, if the loop nest between i and k is
4042 perfectly nested. Therefore we do not need to change the static schedule.
4046 for (i = 0; i < 50; i++)
4048 for (k = 5; k < 100; k++)
4051 To move k before i use:
4053 graphite_trans_bb_move_loop (A, 2, 0)
4055 for (k = 5; k < 100; k++)
4056 for (i = 0; i < 50; i++)
4062 graphite_trans_bb_move_loop (A, 0, 2)
4064 This function does not check the validity of interchanging loops.
4065 This should be checked before calling this function. */
4068 graphite_trans_bb_move_loop (graphite_bb_p gb, int loop,
4071 CloogMatrix *domain = GBB_DOMAIN (gb);
4075 gcc_assert (loop < gbb_nb_loops (gb)
4076 && new_loop_pos < gbb_nb_loops (gb));
4078 /* Update LOOPS vector. */
4079 tmp_loop_p = VEC_index (loop_p, GBB_LOOPS (gb), loop);
4080 VEC_ordered_remove (loop_p, GBB_LOOPS (gb), loop);
4081 VEC_safe_insert (loop_p, heap, GBB_LOOPS (gb), new_loop_pos, tmp_loop_p);
4083 /* Move the domain columns. */
4084 if (loop < new_loop_pos)
4085 for (row = 0; row < domain->NbRows; row++)
4089 value_assign (tmp, domain->p[row][loop + 1]);
4091 for (j = loop ; j < new_loop_pos - 1; j++)
4092 value_assign (domain->p[row][j + 1], domain->p[row][j + 2]);
4094 value_assign (domain->p[row][new_loop_pos], tmp);
4098 for (row = 0; row < domain->NbRows; row++)
4102 value_assign (tmp, domain->p[row][loop + 1]);
4104 for (j = loop ; j > new_loop_pos; j--)
4105 value_assign (domain->p[row][j + 1], domain->p[row][j]);
4107 value_assign (domain->p[row][new_loop_pos + 1], tmp);
4112 /* Get the index of the column representing constants in the DOMAIN
4116 const_column_index (CloogMatrix *domain)
4118 return domain->NbColumns - 1;
4122 /* Get the first index that is positive or negative, determined
4123 following the value of POSITIVE, in matrix DOMAIN in COLUMN. */
4126 get_first_matching_sign_row_index (CloogMatrix *domain, int column,
4131 for (row = 0; row < domain->NbRows; row++)
4133 int val = value_get_si (domain->p[row][column]);
4135 if (val > 0 && positive)
4138 else if (val < 0 && !positive)
4145 /* Get the lower bound of COLUMN in matrix DOMAIN. */
4148 get_lower_bound_row (CloogMatrix *domain, int column)
4150 return get_first_matching_sign_row_index (domain, column, true);
4153 /* Get the upper bound of COLUMN in matrix DOMAIN. */
4156 get_upper_bound_row (CloogMatrix *domain, int column)
4158 return get_first_matching_sign_row_index (domain, column, false);
4161 /* Get the lower bound of LOOP. */
4164 get_lower_bound (CloogMatrix *domain, int loop, Value lower_bound_result)
4166 int lower_bound_row = get_lower_bound_row (domain, loop);
4167 value_init (lower_bound_result);
4168 value_assign (lower_bound_result,
4169 domain->p[lower_bound_row][const_column_index(domain)]);
4172 /* Get the upper bound of LOOP. */
4175 get_upper_bound (CloogMatrix *domain, int loop, Value upper_bound_result)
4177 int upper_bound_row = get_upper_bound_row (domain, loop);
4178 value_init (upper_bound_result);
4179 value_assign (upper_bound_result,
4180 domain->p[upper_bound_row][const_column_index(domain)]);
4183 /* Strip mines the loop of BB at the position LOOP_DEPTH with STRIDE.
4184 Always valid, but not always a performance improvement. */
4187 graphite_trans_bb_strip_mine (graphite_bb_p gb, int loop_depth, int stride)
4191 CloogMatrix *domain = GBB_DOMAIN (gb);
4192 CloogMatrix *new_domain = cloog_matrix_alloc (domain->NbRows + 3,
4193 domain->NbColumns + 1);
4195 int col_loop_old = loop_depth + 2;
4196 int col_loop_strip = col_loop_old - 1;
4198 Value old_lower_bound;
4199 Value old_upper_bound;
4202 gcc_assert (loop_depth <= gbb_nb_loops (gb) - 1);
4204 VEC_safe_insert (loop_p, heap, GBB_LOOPS (gb), loop_depth, NULL);
4206 GBB_DOMAIN (gb) = new_domain;
4209 nrows = 4, ncols = 4
4218 for (row = 0; row < domain->NbRows; row++)
4219 for (col = 0; col < domain->NbColumns; col++)
4220 if (col <= loop_depth)
4222 value_assign (new_domain->p[row][col], domain->p[row][col]);
4226 value_assign (new_domain->p[row][col + 1], domain->p[row][col]);
4231 nrows = 6, ncols = 5
4243 row = domain->NbRows;
4245 /* Add outer loop. */
4247 get_lower_bound (new_domain, col_loop_old, old_lower_bound);
4248 get_upper_bound (new_domain, col_loop_old, old_upper_bound);
4250 /* Set Lower Bound */
4251 value_set_si (new_domain->p[row][0], 1);
4252 value_set_si (new_domain->p[row][col_loop_strip], 1);
4253 value_assign (new_domain->p[row][const_column_index (new_domain)],
4264 1 0 0 -1 99 | copy old lower bound
4271 Value new_upper_bound;
4272 Value strip_size_value;
4274 value_init (new_upper_bound);
4276 value_init (strip_size_value);
4277 value_set_si (strip_size_value, (int) stride);
4280 value_pdivision(new_upper_bound,old_upper_bound,strip_size_value);
4281 value_add_int (new_upper_bound, new_upper_bound, 1);
4283 /* Set Upper Bound */
4284 value_set_si (new_domain->p[row][0], 1);
4285 value_set_si (new_domain->p[row][col_loop_strip], -1);
4286 value_assign (new_domain->p[row][const_column_index (new_domain)],
4298 1 0 -1 0 25 (divide old upper bound with stride)
4303 row = get_lower_bound_row (new_domain, col_loop_old);
4304 /* Add local variable to keep linear representation. */
4305 value_set_si (new_domain->p[row][0], 1);
4306 value_set_si (new_domain->p[row][const_column_index (new_domain)],0);
4307 value_set_si (new_domain->p[row][col_loop_old], 1);
4308 value_set_si (new_domain->p[row][col_loop_strip], -1*((int)stride));
4319 1 0 -1 0 25 (divide old upper bound with stride)
4324 row = new_domain->NbRows-1;
4326 value_set_si (new_domain->p[row][0], 1);
4327 value_set_si (new_domain->p[row][col_loop_old], -1);
4328 value_set_si (new_domain->p[row][col_loop_strip], stride);
4329 value_set_si (new_domain->p[row][const_column_index (new_domain)],
4338 1 0 -4 1 0 j >= 4*jj
4341 1 0 -1 0 25 25 >= jj
4342 0 0 4 -1 3 jj+3 >= j
4345 cloog_matrix_free (domain);
4347 /* Update static schedule. */
4350 int nb_loops = gbb_nb_loops (gb);
4351 lambda_vector new_schedule = lambda_vector_new (nb_loops + 1);
4353 for (i = 0; i <= loop_depth; i++)
4354 new_schedule[i] = GBB_STATIC_SCHEDULE (gb)[i];
4356 for (i = loop_depth + 1; i <= nb_loops - 2; i++)
4357 new_schedule[i + 2] = GBB_STATIC_SCHEDULE (gb)[i];
4359 GBB_STATIC_SCHEDULE (gb) = new_schedule;
4363 /* Returns true when the strip mining of LOOP_INDEX by STRIDE is
4364 profitable or undecidable. GB is the statement around which the
4365 loops will be strip mined. */
4368 strip_mine_profitable_p (graphite_bb_p gb, int stride,
4377 loop = VEC_index (loop_p, GBB_LOOPS (gb), loop_index);
4378 exit = single_exit (loop);
4380 niter = find_loop_niter (loop, &exit);
4381 if (niter == chrec_dont_know
4382 || TREE_CODE (niter) != INTEGER_CST)
4385 niter_val = int_cst_value (niter);
4387 if (niter_val < stride)
4390 if (dump_file && (dump_flags & TDF_DETAILS))
4392 fprintf (dump_file, "\nStrip Mining is not profitable for loop %d:",
4394 fprintf (dump_file, "number of iterations is too low.\n");
4401 /* Determines when the interchange of LOOP_A and LOOP_B belonging to
4405 is_interchange_valid (scop_p scop, int loop_a, int loop_b)
4408 VEC (ddr_p, heap) *dependence_relations;
4409 VEC (data_reference_p, heap) *datarefs;
4411 struct loop *nest = VEC_index (loop_p, SCOP_LOOP_NEST (scop), loop_a);
4412 int depth = perfect_loop_nest_depth (nest);
4413 lambda_trans_matrix trans;
4415 gcc_assert (loop_a < loop_b);
4417 dependence_relations = VEC_alloc (ddr_p, heap, 10 * 10);
4418 datarefs = VEC_alloc (data_reference_p, heap, 10);
4420 if (!compute_data_dependences_for_loop (nest, true, &datarefs,
4421 &dependence_relations))
4424 if (dump_file && (dump_flags & TDF_DETAILS))
4425 dump_ddrs (dump_file, dependence_relations);
4427 trans = lambda_trans_matrix_new (depth, depth);
4428 lambda_matrix_id (LTM_MATRIX (trans), depth);
4430 lambda_matrix_row_exchange (LTM_MATRIX (trans), 0, loop_b - loop_a);
4432 if (!lambda_transform_legal_p (trans, depth, dependence_relations))
4434 lambda_matrix_row_exchange (LTM_MATRIX (trans), 0, loop_b - loop_a);
4440 free_dependence_relations (dependence_relations);
4441 free_data_refs (datarefs);
4445 /* Loop block the LOOPS innermost loops of GB with stride size STRIDE.
4449 for (i = 0; i <= 50; i++=4)
4450 for (k = 0; k <= 100; k++=4)
4451 for (l = 0; l <= 200; l++=4)
4454 To strip mine the two inner most loops with stride = 4 call:
4456 graphite_trans_bb_block (A, 4, 2)
4458 for (i = 0; i <= 50; i++)
4459 for (kk = 0; kk <= 100; kk+=4)
4460 for (ll = 0; ll <= 200; ll+=4)
4461 for (k = kk; k <= min (100, kk + 3); k++)
4462 for (l = ll; l <= min (200, ll + 3); l++)
4467 graphite_trans_bb_block (graphite_bb_p gb, int stride, int loops)
4470 int nb_loops = gbb_nb_loops (gb);
4471 int start = nb_loops - loops;
4472 scop_p scop = GBB_SCOP (gb);
4474 gcc_assert (scop_contains_loop (scop, gbb_loop (gb)));
4476 for (i = start ; i < nb_loops; i++)
4477 for (j = i + 1; j < nb_loops; j++)
4478 if (!is_interchange_valid (scop, i, j))
4480 if (dump_file && (dump_flags & TDF_DETAILS))
4482 "\nInterchange not valid for loops %d and %d:\n", i, j);
4485 else if (dump_file && (dump_flags & TDF_DETAILS))
4487 "\nInterchange valid for loops %d and %d:\n", i, j);
4489 /* Check if strip mining is profitable for every loop. */
4490 for (i = 0; i < nb_loops - start; i++)
4491 if (!strip_mine_profitable_p (gb, stride, start + i))
4494 /* Strip mine loops. */
4495 for (i = 0; i < nb_loops - start; i++)
4496 graphite_trans_bb_strip_mine (gb, start + 2 * i, stride);
4498 /* Interchange loops. */
4499 for (i = 1; i < nb_loops - start; i++)
4500 graphite_trans_bb_move_loop (gb, start + 2 * i, start + i);
4505 /* Loop block LOOPS innermost loops of a loop nest. BBS represent the
4506 basic blocks that belong to the loop nest to be blocked. */
4509 graphite_trans_loop_block (VEC (graphite_bb_p, heap) *bbs, int loops)
4513 bool transform_done = false;
4515 /* TODO: - Calculate the stride size automatically. */
4516 int stride_size = 64;
4518 for (i = 0; VEC_iterate (graphite_bb_p, bbs, i, gb); i++)
4519 transform_done |= graphite_trans_bb_block (gb, stride_size, loops);
4521 return transform_done;
4524 /* Loop block all basic blocks of SCOP. */
4527 graphite_trans_scop_block (scop_p scop)
4533 bool perfect = true;
4534 bool transform_done = false;
4536 VEC (graphite_bb_p, heap) *bbs = VEC_alloc (graphite_bb_p, heap, 3);
4537 int max_schedule = scop_max_loop_depth (scop) + 1;
4538 lambda_vector last_schedule = lambda_vector_new (max_schedule);
4540 if (VEC_length (graphite_bb_p, SCOP_BBS (scop)) == 0)
4541 return transform_done;
4543 /* Get the data of the first bb. */
4544 gb = VEC_index (graphite_bb_p, SCOP_BBS (scop), 0);
4545 last_nb_loops = gbb_nb_loops (gb);
4546 lambda_vector_copy (GBB_STATIC_SCHEDULE (gb), last_schedule,
4548 VEC_safe_push (graphite_bb_p, heap, bbs, gb);
4550 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
4552 /* We did the first bb before. */
4556 nb_loops = gbb_nb_loops (gb);
4558 /* If the number of loops is unchanged and only the last element of the
4559 schedule changes, we stay in the loop nest. */
4560 if (nb_loops == last_nb_loops
4561 && (last_schedule [nb_loops + 1]
4562 != GBB_STATIC_SCHEDULE (gb)[nb_loops + 1]))
4564 VEC_safe_push (graphite_bb_p, heap, bbs, gb);
4568 /* Otherwise, we left the innermost loop. So check, if the last bb was in
4569 a perfect loop nest and how many loops are contained in this perfect
4572 Count the number of zeros from the end of the schedule. They are the
4573 number of surrounding loops.
4576 last_bb 2 3 2 0 0 0 0 3
4580 last_bb 2 3 2 0 0 0 0 3
4584 If there is no zero, there were other bbs in outer loops and the loop
4585 nest is not perfect. */
4586 for (j = last_nb_loops - 1; j >= 0; j--)
4588 if (last_schedule [j] != 0
4589 || (j <= nb_loops && GBB_STATIC_SCHEDULE (gb)[j] == 1))
4598 /* Found perfect loop nest. */
4599 if (perfect && last_nb_loops - j > 0)
4600 transform_done |= graphite_trans_loop_block (bbs, last_nb_loops - j);
4602 /* Check if we start with a new loop.
4606 last_bb 2 3 2 0 0 0 0 3
4609 Here we start with the loop "2 3 2 0 0 1"
4611 last_bb 2 3 2 0 0 0 0 3
4614 But here not, so the loop nest can never be perfect. */
4616 perfect = (GBB_STATIC_SCHEDULE (gb)[nb_loops] == 0);
4618 /* Update the last_bb infos. We do not do that for the bbs in the same
4619 loop, as the data we use is not changed. */
4620 last_nb_loops = nb_loops;
4621 lambda_vector_copy (GBB_STATIC_SCHEDULE (gb), last_schedule,
4623 VEC_truncate (graphite_bb_p, bbs, 0);
4624 VEC_safe_push (graphite_bb_p, heap, bbs, gb);
4627 /* Check if the last loop nest was perfect. It is the same check as above,
4628 but the comparison with the next bb is missing. */
4629 for (j = last_nb_loops - 1; j >= 0; j--)
4630 if (last_schedule [j] != 0)
4638 /* Found perfect loop nest. */
4639 if (last_nb_loops - j > 0)
4640 transform_done |= graphite_trans_loop_block (bbs, last_nb_loops - j);
4641 VEC_free (graphite_bb_p, heap, bbs);
4643 if (dump_file && (dump_flags & TDF_DETAILS))
4644 fprintf (dump_file, "\nLoop blocked.\n");
4646 return transform_done;
4649 /* Apply graphite transformations to all the basic blocks of SCOP. */
4652 graphite_apply_transformations (scop_p scop)
4654 bool transform_done = false;
4656 /* Sort the list of bbs. Keep them always sorted. */
4657 graphite_sort_gbbs (scop);
4658 scop_remove_ignoreable_gbbs (scop);
4660 if (flag_loop_block)
4661 transform_done = graphite_trans_scop_block (scop);
4663 #if 0 && ENABLE_CHECKING
4664 /* When the compiler is configured with ENABLE_CHECKING, always
4665 generate code, even if we did not apply any transformation. This
4666 provides better code coverage of the backend code generator.
4668 This also allows to check the performance for an identity
4669 transform: GIMPLE -> GRAPHITE -> GIMPLE; and the output of CLooG
4670 is never an identity: if CLooG optimizations are not disabled,
4671 the CLooG output is always optimized in control flow. */
4672 transform_done = true;
4675 return transform_done;
4678 /* We limit all SCoPs to SCoPs, that are completely surrounded by a loop.
4688 * SCoP frontier, as this line is not surrounded by any loop. *
4692 This is necessary as scalar evolution and parameter detection need a
4693 outermost loop to initialize parameters correctly.
4695 TODO: FIX scalar evolution and parameter detection to allow mor flexible
4701 VEC (scop_p, heap) *new_scops = VEC_alloc (scop_p, heap, 3);
4705 for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
4709 build_scop_bbs (scop);
4710 build_scop_loop_nests (scop);
4712 for (j = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), j, loop); j++)
4713 if (!loop_in_scop_p (loop_outer (loop), scop))
4715 scop_p n_scop = new_scop (loop_preheader_edge (loop));
4716 end_scop (n_scop, single_exit (loop), false);
4717 VEC_safe_push (scop_p, heap, new_scops, n_scop);
4721 free_scops (current_scops);
4722 current_scops = new_scops;
4725 /* Perform a set of linear transforms on the loops of the current
4729 graphite_transform_loops (void)
4734 if (number_of_loops () <= 1)
4737 current_scops = VEC_alloc (scop_p, heap, 3);
4739 calculate_dominance_info (CDI_DOMINATORS);
4740 calculate_dominance_info (CDI_POST_DOMINATORS);
4742 if (dump_file && (dump_flags & TDF_DETAILS))
4743 fprintf (dump_file, "Graphite loop transformations \n");
4745 cloog_initialize ();
4749 if (dump_file && (dump_flags & TDF_DETAILS))
4750 fprintf (dump_file, "\nnumber of SCoPs: %d\n",
4751 VEC_length (scop_p, current_scops));
4753 for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
4755 build_scop_bbs (scop);
4756 build_scop_loop_nests (scop);
4757 build_scop_canonical_schedules (scop);
4758 build_bb_loops (scop);
4759 find_scop_parameters (scop);
4760 build_scop_context (scop);
4762 if (dump_file && (dump_flags & TDF_DETAILS))
4764 fprintf (dump_file, "\n(In SCoP %d:\n", i);
4765 fprintf (dump_file, "\nnumber of bbs: %d\n",
4766 VEC_length (graphite_bb_p, SCOP_BBS (scop)));
4767 fprintf (dump_file, "\nnumber of loops: %d)\n",
4768 VEC_length (loop_p, SCOP_LOOP_NEST (scop)));
4771 if (!build_scop_iteration_domain (scop))
4774 build_scop_conditions (scop);
4775 build_scop_data_accesses (scop);
4777 if (dump_file && (dump_flags & TDF_DETAILS))
4779 int nbrefs = nb_data_refs_in_scop (scop);
4780 fprintf (dump_file, "\nnumber of data refs: %d\n", nbrefs);
4783 if (graphite_apply_transformations (scop))
4784 gloog (scop, find_transform (scop));
4788 free_scops (current_scops);
4792 #else /* If Cloog is not available: #ifndef HAVE_cloog. */
4795 graphite_transform_loops (void)
4797 if (dump_file && (dump_flags & TDF_DETAILS))
4799 fprintf (dump_file, "Graphite loop optimizations cannot be used.\n");
4800 fprintf (dump_file, "GCC has not been configured with the required "
4801 "libraries for Graphite loop optimizations.");
4803 sorry ("Graphite loop optimizations cannot be used");