configure: Regenerate for new libtool.
[official-gcc.git] / gcc / graphite.c
blob4e1a969dab2bae526de554b0aacebe0e8faea5ea
1 /* Gimple Represented as Polyhedra.
2 Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <sebastian.pop@inria.fr>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This pass converts GIMPLE to GRAPHITE, performs some loop
22 transformations and then converts the resulting representation back
23 to GIMPLE.
25 An early description of this pass can be found in the GCC Summit'06
26 paper "GRAPHITE: Polyhedral Analyses and Optimizations for GCC".
27 The wiki page http://gcc.gnu.org/wiki/Graphite contains pointers to
28 the related work.
30 One important document to read is CLooG's internal manual:
31 http://repo.or.cz/w/cloog-ppl.git?a=blob_plain;f=doc/cloog.texi;hb=HEAD
32 that describes the data structure of loops used in this file, and
33 the functions that are used for transforming the code. */
35 #include "config.h"
36 #include "system.h"
37 #include "coretypes.h"
38 #include "tm.h"
39 #include "ggc.h"
40 #include "tree.h"
41 #include "rtl.h"
42 #include "basic-block.h"
43 #include "diagnostic.h"
44 #include "tree-flow.h"
45 #include "toplev.h"
46 #include "tree-dump.h"
47 #include "timevar.h"
48 #include "cfgloop.h"
49 #include "tree-chrec.h"
50 #include "tree-data-ref.h"
51 #include "tree-scalar-evolution.h"
52 #include "tree-pass.h"
53 #include "domwalk.h"
54 #include "pointer-set.h"
55 #include "gimple.h"
57 #ifdef HAVE_cloog
58 #include "cloog/cloog.h"
59 #include "graphite.h"
61 static VEC (scop_p, heap) *current_scops;
63 /* Debug the list of old induction variables for this SCOP. */
65 void
66 debug_oldivs (scop_p scop)
68 int i;
69 name_tree oldiv;
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. */
84 void
85 debug_loop_vec (graphite_bb_p gb)
87 int i;
88 loop_p loop;
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. */
100 static void
101 loop_iv_stack_push (loop_iv_stack stack, tree iv, const char *name)
103 name_tree named_iv = XNEW (struct name_tree);
105 named_iv->t = iv;
106 named_iv->name = name;
107 VEC_safe_push (name_tree, heap, *stack, named_iv);
110 /* Pops an element out of STACK. */
112 static void
113 loop_iv_stack_pop (loop_iv_stack stack)
115 VEC_pop (name_tree, *stack);
118 /* Get the IV at INDEX in STACK. */
120 static tree
121 loop_iv_stack_get_iv (loop_iv_stack stack, int index)
123 name_tree named_iv = VEC_index (name_tree, *stack, index);
125 return named_iv->t;
128 /* Get the IV from its NAME in STACK. */
130 static tree
131 loop_iv_stack_get_iv_from_name (loop_iv_stack stack, const char* name)
133 int i;
134 name_tree iv;
136 for (i = 0; VEC_iterate (name_tree, *stack, i, iv); i++)
137 if (!strcmp (name, iv->name))
138 return iv->t;
140 return NULL;
143 /* Prints on stderr the contents of STACK. */
145 void
146 loop_iv_stack_debug (loop_iv_stack stack)
148 int i;
149 name_tree iv;
150 bool first = true;
152 fprintf (stderr, "(");
154 for (i = 0; VEC_iterate (name_tree, *stack, i, iv); i++)
156 if (first)
157 first = false;
158 else
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. */
170 static name_tree
171 get_old_iv_from_ssa_name (scop_p scop, loop_p old, tree name)
173 tree var = SSA_NAME_VAR (name);
174 int i;
175 name_tree oldiv;
177 for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, oldiv); i++)
179 loop_p current = old;
181 while (current)
183 if (var == oldiv->t
184 && oldiv->loop == current)
185 return oldiv;
187 current = loop_outer (current);
190 return NULL;
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,
198 int loop_position,
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;
208 return result;
211 /* Hash function for SCOP_LOOP2CLOOG_LOOP hash table. */
213 static hashval_t
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. */
221 static int
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. */
236 static int
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. */
252 static void
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. */
264 static void
265 dump_gbb_conditions (FILE *file, graphite_bb_p gbb)
267 int i;
268 gimple stmt;
269 VEC (gimple, heap) *conditions = GBB_CONDITIONS (gbb);
271 if (VEC_empty (gimple, conditions))
272 return;
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) */
291 static CloogMatrix *
292 schedule_to_scattering (graphite_bb_p gb, int scattering_dimensions)
294 int i;
295 scop_p scop = GBB_SCOP (gb);
297 int nb_iterators = gbb_nb_loops (gb);
299 /* The cloog scattering matrix consists of these colums:
300 1 col = Eq/Inq,
301 scattering_dimensions cols = Scattering dimensions,
302 nb_iterators cols = bb's iterators,
303 scop_nb_params cols = Parameters,
304 1 col = Constant 1.
306 Example:
308 scattering_dimensions = 5
309 max_nb_iterators = 2
310 nb_iterators = 1
311 scop_nb_params = 2
313 Schedule:
317 Scattering Matrix:
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);
350 return scat;
353 /* Print the schedules of GB to FILE with INDENT white spaces before.
354 VERBOSITY determines how verbose the code pretty printers are. */
356 void
357 print_graphite_bb (FILE *file, graphite_bb_p gb, int indent, int verbosity)
359 CloogMatrix *scattering;
360 int i;
361 loop_p loop;
362 fprintf (file, "\nGBB (\n");
364 print_loops_bb (file, GBB_BB (gb), indent+2, verbosity);
366 if (GBB_DOMAIN (gb))
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");
381 if (GBB_LOOPS (gb))
383 fprintf (file, " (contained loops: \n");
384 for (i = 0; VEC_iterate (loop_p, GBB_LOOPS (gb), i, loop); i++)
385 if (loop == NULL)
386 fprintf (file, " iterator %d => NULL \n", i);
387 else
388 fprintf (file, " iterator %d => loop %d \n", i,
389 loop->num);
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");
403 if (GBB_SCOP (gb)
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. */
418 void
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
426 printers are. */
428 static void
429 print_scop (FILE *file, scop_p scop, int verbosity)
431 if (scop == NULL)
432 return;
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");
441 if (SCOP_BBS (scop))
443 graphite_bb_p gb;
444 int i;
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. */
456 static void
457 print_scops (FILE *file, int verbosity)
459 int i;
460 scop_p scop;
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
467 printers are. */
469 void
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. */
478 void
479 debug_scops (int verbosity)
481 print_scops (stderr, verbosity);
484 /* Return true when BB is contained in SCOP. */
486 static inline bool
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. */
494 static void
495 dot_scop_1 (FILE *file, scop_p scop)
497 edge e;
498 edge_iterator ei;
499 basic_block bb;
500 basic_block entry = SCOP_ENTRY (scop);
501 basic_block exit = SCOP_EXIT (scop);
503 fprintf (file, "digraph SCoP_%d_%d {\n", entry->index,
504 exit->index);
506 FOR_ALL_BB (bb)
508 if (bb == entry)
509 fprintf (file, "%d [shape=triangle];\n", bb->index);
511 if (bb == exit)
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. */
526 void
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.
534 Special nodes:
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. */
539 static void
540 dot_all_scops_1 (FILE *file)
542 basic_block bb;
543 edge e;
544 edge_iterator ei;
545 scop_p scop;
546 const char* color;
547 int i;
549 /* Disable debugging while printing graph. */
550 int tmp_dump_flags = dump_flags;
551 dump_flags = 0;
553 fprintf (file, "digraph all {\n");
555 FOR_ALL_BB (bb)
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\" ",
563 bb->index);
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))
572 switch (i % 17)
574 case 0: /* red */
575 color = "#e41a1c";
576 break;
577 case 1: /* blue */
578 color = "#377eb8";
579 break;
580 case 2: /* green */
581 color = "#4daf4a";
582 break;
583 case 3: /* purple */
584 color = "#984ea3";
585 break;
586 case 4: /* orange */
587 color = "#ff7f00";
588 break;
589 case 5: /* yellow */
590 color = "#ffff33";
591 break;
592 case 6: /* brown */
593 color = "#a65628";
594 break;
595 case 7: /* rose */
596 color = "#f781bf";
597 break;
598 case 8:
599 color = "#8dd3c7";
600 break;
601 case 9:
602 color = "#ffffb3";
603 break;
604 case 10:
605 color = "#bebada";
606 break;
607 case 11:
608 color = "#fb8072";
609 break;
610 case 12:
611 color = "#80b1d3";
612 break;
613 case 13:
614 color = "#fdb462";
615 break;
616 case 14:
617 color = "#b3de69";
618 break;
619 case 15:
620 color = "#fccde5";
621 break;
622 case 16:
623 color = "#bc80bd";
624 break;
625 default: /* gray */
626 color = "#999999";
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);
645 else
646 fprintf (file, " %d ", bb->index);
648 if (!bb_in_scop_p (bb, scop))
649 fprintf (file, ")");
651 fprintf (file, "</TD></TR>\n");
653 part_of_scop = true;
656 if (!part_of_scop)
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");
665 FOR_ALL_BB (bb)
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. */
679 void
680 dot_all_scops (void)
682 /* When debugging, enable the following code. This cannot be used
683 in production compilers because it calls "system". */
684 #if 0
685 FILE *stream = fopen ("/tmp/allscops.dot", "w");
686 gcc_assert (stream);
688 dot_all_scops_1 (stream);
689 fclose (stream);
691 system ("dotty /tmp/allscops.dot");
692 #else
693 dot_all_scops_1 (stderr);
694 #endif
697 /* Returns true when LOOP is in SCOP. */
699 static inline bool
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. */
708 static struct loop *
709 outermost_loop_in_scop (scop_p scop, basic_block bb)
711 struct loop *nest;
713 nest = bb->loop_father;
714 while (loop_outer (nest) && loop_in_scop_p (loop_outer (nest), scop))
715 nest = loop_outer (nest);
717 return nest;
720 /* Returns the block preceding the entry of SCOP. */
722 static basic_block
723 block_before_scop (scop_p scop)
725 return SESE_ENTRY (SCOP_REGION (scop))->src;
728 /* Return true when EXPR is an affine function in LOOP with parameters
729 instantiated relative to SCOP_ENTRY. */
731 static bool
732 loop_affine_expr (basic_block scop_entry, struct loop *loop, tree expr)
734 int n = scop_entry->loop_father->num;
735 tree scev = analyze_scalar_evolution (loop, expr);
737 scev = instantiate_scev (scop_entry, loop, scev);
739 return (evolution_function_is_invariant_p (scev, n)
740 || evolution_function_is_affine_multivariate_p (scev, n));
743 /* Return true if the operand OP is simple. */
745 static bool
746 is_simple_operand (loop_p loop, gimple stmt, tree op)
748 /* It is not a simple operand when it is a declaration, */
749 if (DECL_P (op)
750 /* or a structure, */
751 || AGGREGATE_TYPE_P (TREE_TYPE (op))
752 /* or a memory access that cannot be analyzed by the data
753 reference analysis. */
754 || ((handled_component_p (op) || INDIRECT_REF_P (op))
755 && !stmt_simple_memref_p (loop, stmt, op)))
756 return false;
758 return true;
761 /* Return true only when STMT is simple enough for being handled by
762 Graphite. This depends on SCOP_ENTRY, as the parametetrs are
763 initialized relatively to this basic block. */
765 static bool
766 stmt_simple_for_scop_p (basic_block scop_entry, gimple stmt)
768 basic_block bb = gimple_bb (stmt);
769 struct loop *loop = bb->loop_father;
771 /* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects.
772 Calls have side-effects, except those to const or pure
773 functions. */
774 if (gimple_has_volatile_ops (stmt)
775 || (gimple_code (stmt) == GIMPLE_CALL
776 && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
777 || (gimple_code (stmt) == GIMPLE_ASM))
778 return false;
780 switch (gimple_code (stmt))
782 case GIMPLE_RETURN:
783 case GIMPLE_LABEL:
784 return true;
786 case GIMPLE_COND:
788 tree op;
789 ssa_op_iter op_iter;
790 enum tree_code code = gimple_cond_code (stmt);
792 /* We can only handle this kind of conditional expressions.
793 For inequalities like "if (i != 3 * k)" we need unions of
794 polyhedrons. Expressions like "if (a)" or "if (a == 15)" need
795 them for the else branch. */
796 if (!(code == LT_EXPR
797 || code == GT_EXPR
798 || code == LE_EXPR
799 || code == GE_EXPR))
800 return false;
802 if (!scop_entry)
803 return false;
805 FOR_EACH_SSA_TREE_OPERAND (op, stmt, op_iter, SSA_OP_ALL_USES)
806 if (!loop_affine_expr (scop_entry, loop, op))
807 return false;
809 return true;
812 case GIMPLE_ASSIGN:
814 enum tree_code code = gimple_assign_rhs_code (stmt);
816 switch (get_gimple_rhs_class (code))
818 case GIMPLE_UNARY_RHS:
819 case GIMPLE_SINGLE_RHS:
820 return (is_simple_operand (loop, stmt, gimple_assign_lhs (stmt))
821 && is_simple_operand (loop, stmt, gimple_assign_rhs1 (stmt)));
823 case GIMPLE_BINARY_RHS:
824 return (is_simple_operand (loop, stmt, gimple_assign_lhs (stmt))
825 && is_simple_operand (loop, stmt, gimple_assign_rhs1 (stmt))
826 && is_simple_operand (loop, stmt, gimple_assign_rhs2 (stmt)));
828 case GIMPLE_INVALID_RHS:
829 default:
830 gcc_unreachable ();
834 case GIMPLE_CALL:
836 size_t i;
837 size_t n = gimple_call_num_args (stmt);
838 tree lhs = gimple_call_lhs (stmt);
840 for (i = 0; i < n; i++)
842 tree arg = gimple_call_arg (stmt, i);
844 if (!(is_simple_operand (loop, stmt, lhs)
845 && is_simple_operand (loop, stmt, arg)))
846 return false;
849 return true;
852 default:
853 /* These nodes cut a new scope. */
854 return false;
857 return false;
860 /* Returns the statement of BB that contains a harmful operation: that
861 can be a function call with side effects, the induction variables
862 are not linear with respect to SCOP_ENTRY, etc. The current open
863 scop should end before this statement. */
865 static gimple
866 harmful_stmt_in_bb (basic_block scop_entry, basic_block bb)
868 gimple_stmt_iterator gsi;
870 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
871 if (!stmt_simple_for_scop_p (scop_entry, gsi_stmt (gsi)))
872 return gsi_stmt (gsi);
874 return NULL;
877 /* Store the GRAPHITE representation of BB. */
879 static void
880 new_graphite_bb (scop_p scop, basic_block bb)
882 struct graphite_bb *gbb = XNEW (struct graphite_bb);
884 bb->aux = gbb;
885 GBB_BB (gbb) = bb;
886 GBB_SCOP (gbb) = scop;
887 GBB_DATA_REFS (gbb) = NULL;
888 GBB_DOMAIN (gbb) = NULL;
889 GBB_CONDITIONS (gbb) = NULL;
890 GBB_CONDITION_CASES (gbb) = NULL;
891 GBB_LOOPS (gbb) = NULL;
892 VEC_safe_push (graphite_bb_p, heap, SCOP_BBS (scop), gbb);
893 bitmap_set_bit (SCOP_BBS_B (scop), bb->index);
896 /* Frees GBB. */
898 static void
899 free_graphite_bb (struct graphite_bb *gbb)
901 if (GBB_DOMAIN (gbb))
902 cloog_matrix_free (GBB_DOMAIN (gbb));
904 free_data_refs (GBB_DATA_REFS (gbb));
905 VEC_free (gimple, heap, GBB_CONDITIONS (gbb));
906 VEC_free (gimple, heap, GBB_CONDITION_CASES (gbb));
907 VEC_free (loop_p, heap, GBB_LOOPS (gbb));
909 GBB_BB (gbb)->aux = 0;
910 XDELETE (gbb);
913 /* Creates a new scop starting with ENTRY. */
915 static scop_p
916 new_scop (edge entry)
918 scop_p scop = XNEW (struct scop);
920 SCOP_REGION (scop) = XNEW (struct sese);
921 SESE_ENTRY (SCOP_REGION (scop)) = entry;
922 SESE_EXIT (SCOP_REGION (scop)) = NULL;
923 SCOP_BBS (scop) = VEC_alloc (graphite_bb_p, heap, 3);
924 SCOP_OLDIVS (scop) = VEC_alloc (name_tree, heap, 3);
925 SCOP_BBS_B (scop) = BITMAP_ALLOC (NULL);
926 SCOP_LOOPS (scop) = BITMAP_ALLOC (NULL);
927 SCOP_LOOP_NEST (scop) = VEC_alloc (loop_p, heap, 3);
928 SCOP_PARAMS (scop) = VEC_alloc (name_tree, heap, 3);
929 SCOP_PROG (scop) = cloog_program_malloc ();
930 cloog_program_set_names (SCOP_PROG (scop), cloog_names_malloc ());
931 SCOP_LOOP2CLOOG_LOOP (scop) = htab_create (10, hash_loop_to_cloog_loop,
932 eq_loop_to_cloog_loop,
933 free);
934 return scop;
937 /* Deletes SCOP. */
939 static void
940 free_scop (scop_p scop)
942 int i;
943 name_tree p;
944 struct graphite_bb *gb;
946 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
947 free_graphite_bb (gb);
949 VEC_free (graphite_bb_p, heap, SCOP_BBS (scop));
950 BITMAP_FREE (SCOP_BBS_B (scop));
951 BITMAP_FREE (SCOP_LOOPS (scop));
952 VEC_free (loop_p, heap, SCOP_LOOP_NEST (scop));
953 VEC_free (name_tree, heap, SCOP_OLDIVS (scop));
955 for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++)
956 free (p);
958 VEC_free (name_tree, heap, SCOP_PARAMS (scop));
959 cloog_program_free (SCOP_PROG (scop));
960 htab_delete (SCOP_LOOP2CLOOG_LOOP (scop));
961 XDELETE (SCOP_REGION (scop));
962 XDELETE (scop);
965 /* Deletes all scops in SCOPS. */
967 static void
968 free_scops (VEC (scop_p, heap) *scops)
970 int i;
971 scop_p scop;
973 for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++)
974 free_scop (scop);
976 VEC_free (scop_p, heap, scops);
979 typedef enum gbb_type {
980 GBB_UNKNOWN,
981 GBB_LOOP_SING_EXIT_HEADER,
982 GBB_LOOP_MULT_EXIT_HEADER,
983 GBB_LOOP_EXIT,
984 GBB_COND_HEADER,
985 GBB_SIMPLE,
986 GBB_LAST
987 } gbb_type;
989 /* Detect the type of BB. Loop headers are only marked, if they are
990 new. This means their loop_father is different to LAST_LOOP.
991 Otherwise they are treated like any other bb and their type can be
992 any other type. */
994 static gbb_type
995 get_bb_type (basic_block bb, struct loop *last_loop)
997 VEC (basic_block, heap) *dom;
998 int nb_dom, nb_suc;
999 struct loop *loop = bb->loop_father;
1001 /* Check, if we entry into a new loop. */
1002 if (loop != last_loop)
1004 if (single_exit (loop) != NULL)
1005 return GBB_LOOP_SING_EXIT_HEADER;
1006 else if (loop->num != 0)
1007 return GBB_LOOP_MULT_EXIT_HEADER;
1008 else
1009 return GBB_COND_HEADER;
1012 dom = get_dominated_by (CDI_DOMINATORS, bb);
1013 nb_dom = VEC_length (basic_block, dom);
1014 VEC_free (basic_block, heap, dom);
1015 if (nb_dom == 0)
1016 return GBB_LAST;
1018 nb_suc = VEC_length (edge, bb->succs);
1019 if (nb_dom == 1 && nb_suc == 1)
1020 return GBB_SIMPLE;
1022 return GBB_COND_HEADER;
1025 /* Moves the scops from SOURCE to TARGET and clean up SOURCE. */
1027 static void
1028 move_scops (VEC (scop_p, heap) **source, VEC (scop_p, heap) **target)
1030 scop_p s;
1031 int i;
1033 for (i = 0; VEC_iterate (scop_p, *source, i, s); i++)
1034 VEC_safe_push (scop_p, heap, *target, s);
1036 VEC_free (scop_p, heap, *source);
1039 /* Store information needed by scopdet_* functions. */
1041 struct scopdet_info
1043 /* Where the last open scop would stop if the current BB is harmful. */
1044 edge last;
1046 /* Where the next scop would start if the current BB is harmful. */
1047 edge next;
1049 /* The bb or one of its children contains open loop exits. That means
1050 loop exit nodes that are not surrounded by a loop dominated by bb. */
1051 bool exits;
1053 /* The bb or one of its children contains only structures we can handle. */
1054 bool difficult;
1057 static struct scopdet_info build_scops_1 (edge, VEC (scop_p, heap) **,
1058 loop_p);
1060 /* Checks, if a bb can be added to a SCoP. */
1062 static struct scopdet_info
1063 scopdet_edge_info (edge ee,
1064 VEC (scop_p, heap) **scops, gbb_type type, gimple *stmt)
1067 basic_block bb = ee->dest;
1068 struct loop *loop = bb->loop_father;
1069 struct scopdet_info result;
1070 basic_block scop_entry;
1072 if (VEC_length (scop_p, *scops) != 0)
1073 scop_entry = block_before_scop (VEC_last (scop_p, *scops));
1074 else if (loop->header)
1075 scop_entry = loop->header;
1076 else
1077 scop_entry = ENTRY_BLOCK_PTR;
1079 *stmt = harmful_stmt_in_bb (scop_entry, bb);
1080 result.difficult = (*stmt != NULL);
1081 result.last = NULL;
1083 switch (type)
1085 case GBB_LAST:
1086 result.next = NULL;
1087 result.exits = false;
1088 result.last = ee;
1089 break;
1091 case GBB_SIMPLE:
1092 result.next = single_succ_edge (bb);
1093 result.exits = false;
1094 result.last = ee;
1095 break;
1097 case GBB_LOOP_SING_EXIT_HEADER:
1099 VEC (scop_p, heap) *tmp_scops = VEC_alloc (scop_p, heap, 3);
1100 struct scopdet_info sinfo;
1102 sinfo = build_scops_1 (ee, &tmp_scops, loop);
1104 result.last = single_exit (bb->loop_father);
1106 if (single_succ_p (result.last->dest)
1107 && get_bb_type (result.last->dest, loop) == GBB_SIMPLE)
1108 result.next = single_succ_edge (result.last->dest);
1109 else
1110 result.next = split_block (result.last->dest, NULL);
1112 /* If we do not dominate result.next, remove it. It's either
1113 the EXIT_BLOCK_PTR, or another bb dominates it and will
1114 call the scop detection for this bb. */
1115 if (!dominated_by_p (CDI_DOMINATORS, result.next->dest, bb))
1116 result.next = NULL;
1118 if (TREE_CODE (number_of_latch_executions (loop))
1119 == SCEV_NOT_KNOWN)
1120 result.difficult = true;
1122 if (sinfo.difficult)
1123 move_scops (&tmp_scops, scops);
1124 else
1125 free_scops (tmp_scops);
1127 result.exits = false;
1128 result.difficult |= sinfo.difficult;
1129 break;
1132 case GBB_LOOP_MULT_EXIT_HEADER:
1134 /* XXX: Handle loop nests with the same header. */
1135 /* XXX: For now we just do not join loops with multiple exits. If the
1136 exits lead to the same bb it may be possible to join the loop. */
1137 VEC (scop_p, heap) *tmp_scops = VEC_alloc (scop_p, heap, 3);
1138 VEC (edge, heap) *exits = get_loop_exit_edges (loop);
1139 edge e;
1140 int i;
1141 build_scops_1 (ee, &tmp_scops, loop);
1143 for (i = 0; VEC_iterate (edge, exits, i, e); i++)
1144 if (dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
1145 && e->dest->loop_father == loop_outer (loop))
1146 build_scops_1 (e, &tmp_scops, e->dest->loop_father);
1148 result.next = NULL;
1149 result.last = NULL;
1150 result.difficult = true;
1151 result.exits = false;
1152 move_scops (&tmp_scops, scops);
1153 VEC_free (edge, heap, exits);
1154 break;
1156 case GBB_COND_HEADER:
1158 VEC (scop_p, heap) *tmp_scops = VEC_alloc (scop_p, heap, 3);
1159 struct scopdet_info sinfo;
1160 VEC (basic_block, heap) *dominated;
1161 int i;
1162 basic_block dom_bb;
1163 basic_block last_bb = NULL;
1164 edge last_e = NULL;
1165 edge e;
1166 result.exits = false;
1168 /* First check the successors of BB, and check if it is possible to join
1169 the different branches. */
1170 for (i = 0; VEC_iterate (edge, bb->succs, i, e); i++)
1172 /* Ignore loop exits. They will be handled after the loop body. */
1173 if (is_loop_exit (loop, e->dest))
1175 result.exits = true;
1176 continue;
1179 /* Do not follow edges that lead to the end of the
1180 conditions block. For example, in
1183 | /|\
1184 | 1 2 |
1185 | | | |
1186 | 3 4 |
1187 | \|/
1190 the edge from 0 => 6. Only check if all paths lead to
1191 the same node 6. */
1193 if (!single_pred_p (e->dest))
1195 /* Check, if edge leads directly to the end of this
1196 condition. */
1197 if (!last_bb)
1199 last_bb = e->dest;
1200 last_e = e;
1203 if (e->dest != last_bb)
1204 result.difficult = true;
1206 continue;
1209 if (!dominated_by_p (CDI_DOMINATORS, e->dest, bb))
1211 result.difficult = true;
1212 continue;
1215 sinfo = build_scops_1 (e, &tmp_scops, loop);
1217 result.exits |= sinfo.exits;
1218 result.last = sinfo.last;
1219 result.difficult |= sinfo.difficult;
1221 /* Checks, if all branches end at the same point.
1222 If that is true, the condition stays joinable.
1223 Have a look at the example above. */
1224 if (sinfo.last && single_succ_p (sinfo.last->dest))
1226 basic_block next_tmp = single_succ (sinfo.last->dest);
1228 if (!last_bb)
1230 last_bb = next_tmp;
1231 last_e = single_succ_edge (sinfo.last->dest);
1234 if (next_tmp != last_bb)
1235 result.difficult = true;
1237 else
1238 result.difficult = true;
1241 /* If the condition is joinable. */
1242 if (!result.exits && !result.difficult)
1244 /* Only return a next pointer if we dominate this pointer.
1245 Otherwise it will be handled by the bb dominating it. */
1246 if (dominated_by_p (CDI_DOMINATORS, last_bb, bb) && last_bb != bb)
1247 result.next = last_e;
1248 else
1249 result.next = NULL;
1251 move_scops (&tmp_scops, scops);
1252 break;
1255 /* Scan remaining bbs dominated by BB. */
1256 dominated = get_dominated_by (CDI_DOMINATORS, bb);
1258 for (i = 0; VEC_iterate (basic_block, dominated, i, dom_bb); i++)
1260 /* Ignore loop exits: they will be handled after the loop body. */
1261 if (is_loop_exit (loop, dom_bb))
1263 result.exits = true;
1264 continue;
1267 /* Ignore the bbs processed above. */
1268 if (single_pred_p (dom_bb) && single_pred (dom_bb) == bb)
1269 continue;
1271 if (single_pred_p (dom_bb))
1272 e = single_pred_edge (dom_bb);
1273 else
1274 e = split_block (dom_bb, NULL);
1276 if (loop_depth (loop) > loop_depth (dom_bb->loop_father))
1277 sinfo = build_scops_1 (e, &tmp_scops, loop_outer (loop));
1278 else
1279 sinfo = build_scops_1 (e, &tmp_scops, loop);
1282 result.exits |= sinfo.exits;
1283 result.difficult = true;
1284 result.last = NULL;
1287 VEC_free (basic_block, heap, dominated);
1289 result.next = NULL;
1290 move_scops (&tmp_scops, scops);
1292 break;
1295 default:
1296 gcc_unreachable ();
1299 return result;
1302 /* Split EXIT before STMT when STMT is non NULL. */
1304 static edge
1305 split_difficult_bb (basic_block exit, edge *last, gimple stmt)
1307 if (stmt && VEC_length (edge, exit->preds) == 1)
1309 edge e;
1311 if (stmt == gsi_stmt (gsi_after_labels (exit)))
1312 stmt = NULL;
1313 else
1315 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
1316 gsi_prev (&gsi);
1317 stmt = gsi_stmt (gsi);
1320 e = split_block (exit, stmt);
1321 set_immediate_dominator (CDI_DOMINATORS, e->dest, e->src);
1322 set_immediate_dominator (CDI_POST_DOMINATORS, e->src, e->dest);
1323 exit = e->dest;
1325 if (last)
1326 *last = e;
1328 return e;
1331 return NULL;
1334 /* End SCOP with edge EXIT. */
1336 static void
1337 end_scop (scop_p scop, edge exit, bool split_entry)
1339 if (split_entry
1340 && !single_pred_p (SCOP_ENTRY (scop))
1341 && exit->dest->loop_father == SCOP_ENTRY (scop)->loop_father)
1342 SESE_ENTRY (SCOP_REGION (scop)) = split_block (SCOP_ENTRY (scop), NULL);
1344 SESE_EXIT (SCOP_REGION (scop)) = exit;
1347 /* Creates the SCoPs and writes entry and exit points for every SCoP. */
1349 static struct scopdet_info
1350 build_scops_1 (edge start, VEC (scop_p, heap) **scops, loop_p loop)
1352 edge current = start;
1354 bool in_scop = false;
1355 scop_p open_scop = NULL;
1356 gimple stmt;
1357 struct scopdet_info sinfo;
1359 /* Initialize result. */
1360 struct scopdet_info result;
1361 result.exits = false;
1362 result.difficult = false;
1363 result.next = NULL;
1364 result.last = NULL;
1366 /* Loop over the dominance tree. If we meet a difficult bb, close
1367 the current SCoP. Loop and condition header start a new layer,
1368 and can only be added if all bbs in deeper layers are simple. */
1369 while (current != NULL)
1371 sinfo = scopdet_edge_info (current, scops,
1372 get_bb_type (current->dest, loop), &stmt);
1374 if (!in_scop && !(sinfo.exits || sinfo.difficult))
1376 open_scop = new_scop (current);
1378 VEC_safe_push (scop_p, heap, *scops, open_scop);
1379 in_scop = true;
1381 else if (in_scop && (sinfo.exits || sinfo.difficult))
1383 edge exit = split_difficult_bb (current->dest, &sinfo.last, stmt);
1385 if (!exit)
1386 exit = current;
1388 end_scop (open_scop, exit, sinfo.difficult);
1389 in_scop = false;
1392 result.difficult |= sinfo.difficult;
1393 result.exits |= sinfo.exits;
1395 current = sinfo.next;
1398 /* Finish the SCOP, if it is left open. The exit is the bb, that
1399 postdominates sinfo.last. If no such bb exists, we use info.last
1400 or delete the scop. */
1401 if (in_scop)
1403 int i;
1404 edge e;
1406 for (i = 0; VEC_iterate (edge, sinfo.last->dest->succs, i, e); i++)
1407 if (dominated_by_p (CDI_POST_DOMINATORS, sinfo.last->dest, e->dest))
1409 edge exit = split_difficult_bb (e->dest, &sinfo.last, stmt);
1411 if (exit)
1412 end_scop (open_scop, exit, sinfo.difficult);
1413 else
1414 end_scop (open_scop, e, sinfo.difficult);
1416 goto done;
1419 if (SCOP_ENTRY (open_scop) != sinfo.last->dest)
1421 edge exit = split_difficult_bb (sinfo.last->dest, NULL, stmt);
1423 if (exit)
1424 end_scop (open_scop, exit, sinfo.difficult);
1425 else
1426 end_scop (open_scop, sinfo.last, sinfo.difficult);
1428 else
1430 VEC_pop (scop_p, *scops);
1431 free_scop (open_scop);
1435 done:
1436 result.last = sinfo.last;
1438 return result;
1441 /* Find static control parts. */
1443 static void
1444 build_scops (void)
1446 struct loop *loop = current_loops->tree_root;
1447 build_scops_1 (single_succ_edge (ENTRY_BLOCK_PTR), &current_scops, loop);
1450 /* Gather the basic blocks belonging to the SCOP. */
1452 static void
1453 build_scop_bbs (scop_p scop)
1455 basic_block *stack = XNEWVEC (basic_block, n_basic_blocks + 1);
1456 sbitmap visited = sbitmap_alloc (last_basic_block);
1457 int sp = 0;
1459 sbitmap_zero (visited);
1460 stack[sp++] = SCOP_ENTRY (scop);
1462 while (sp)
1464 basic_block bb = stack[--sp];
1465 int depth = loop_depth (bb->loop_father);
1466 int num = bb->loop_father->num;
1467 edge_iterator ei;
1468 edge e;
1470 /* Scop's exit is not in the scop. Exclude also bbs, which are
1471 dominated by the SCoP exit. These are e.g. loop latches. */
1472 if (TEST_BIT (visited, bb->index)
1473 || dominated_by_p (CDI_DOMINATORS, bb, SCOP_EXIT (scop))
1474 /* Every block in the scop is dominated by scop's entry. */
1475 || !dominated_by_p (CDI_DOMINATORS, bb, SCOP_ENTRY (scop)))
1476 continue;
1478 new_graphite_bb (scop, bb);
1479 SET_BIT (visited, bb->index);
1481 /* First push the blocks that have to be processed last. Note
1482 that this means that the order in which the code is organized
1483 below is important: do not reorder the following code. */
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 stack[sp++] = e->dest;
1489 FOR_EACH_EDGE (e, ei, bb->succs)
1490 if (! TEST_BIT (visited, e->dest->index)
1491 && (int) loop_depth (e->dest->loop_father) == depth
1492 && e->dest->loop_father->num != num)
1493 stack[sp++] = e->dest;
1495 FOR_EACH_EDGE (e, ei, bb->succs)
1496 if (! TEST_BIT (visited, e->dest->index)
1497 && (int) loop_depth (e->dest->loop_father) == depth
1498 && e->dest->loop_father->num == num
1499 && EDGE_COUNT (e->dest->preds) > 1)
1500 stack[sp++] = e->dest;
1502 FOR_EACH_EDGE (e, ei, bb->succs)
1503 if (! TEST_BIT (visited, e->dest->index)
1504 && (int) loop_depth (e->dest->loop_father) == depth
1505 && e->dest->loop_father->num == num
1506 && EDGE_COUNT (e->dest->preds) == 1)
1507 stack[sp++] = e->dest;
1509 FOR_EACH_EDGE (e, ei, bb->succs)
1510 if (! TEST_BIT (visited, e->dest->index)
1511 && (int) loop_depth (e->dest->loop_father) > depth)
1512 stack[sp++] = e->dest;
1515 free (stack);
1516 sbitmap_free (visited);
1520 /* Record LOOP as occuring in SCOP. */
1522 static void
1523 scop_record_loop (scop_p scop, struct loop *loop)
1525 loop_p parent;
1526 tree induction_var;
1528 if (bitmap_bit_p (SCOP_LOOPS (scop), loop->num))
1529 return;
1531 parent = loop_outer (loop);
1532 induction_var = find_induction_var_from_exit_cond (loop);
1534 if (!bb_in_scop_p (parent->latch, scop))
1535 parent = NULL;
1537 if (induction_var != NULL_TREE)
1539 name_tree oldiv = XNEW (struct name_tree);
1540 oldiv->t = SSA_NAME_VAR (induction_var);
1541 if (DECL_NAME (oldiv->t))
1542 oldiv->name = IDENTIFIER_POINTER (DECL_NAME (oldiv->t));
1543 else
1545 int len = 2 + 16;
1546 char *n = XNEWVEC (char, len);
1547 snprintf (n, len, "D.%u", DECL_UID (oldiv->t));
1548 oldiv->name = n;
1550 oldiv->loop = loop;
1552 VEC_safe_push (name_tree, heap, SCOP_OLDIVS (scop), oldiv);
1555 bitmap_set_bit (SCOP_LOOPS (scop), loop->num);
1556 VEC_safe_push (loop_p, heap, SCOP_LOOP_NEST (scop), loop);
1559 /* Build the loop nests contained in SCOP. */
1561 static void
1562 build_scop_loop_nests (scop_p scop)
1564 unsigned i;
1565 graphite_bb_p gb;
1566 struct loop *loop0, *loop1;
1568 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
1570 struct loop *loop = gbb_loop (gb);
1572 /* Only add loops, if they are completely contained in the SCoP. */
1573 if (loop->header == GBB_BB (gb)
1574 && bb_in_scop_p (loop->latch, scop))
1575 scop_record_loop (scop, gbb_loop (gb));
1578 /* Make sure that the loops in the SCOP_LOOP_NEST are ordered. It
1579 can be the case that an inner loop is inserted before an outer
1580 loop. To avoid this, semi-sort once. */
1581 for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop0); i++)
1583 if (VEC_length (loop_p, SCOP_LOOP_NEST (scop)) == i + 1)
1584 break;
1586 loop1 = VEC_index (loop_p, SCOP_LOOP_NEST (scop), i + 1);
1587 if (loop0->num > loop1->num)
1589 VEC_replace (loop_p, SCOP_LOOP_NEST (scop), i, loop1);
1590 VEC_replace (loop_p, SCOP_LOOP_NEST (scop), i + 1, loop0);
1595 /* Calculate the number of loops around GB in the current SCOP. */
1597 static inline int
1598 nb_loops_around_gb (graphite_bb_p gb)
1600 scop_p scop = GBB_SCOP (gb);
1601 struct loop *l = gbb_loop (gb);
1602 int d = 0;
1604 for (; loop_in_scop_p (l, scop); d++, l = loop_outer (l));
1606 return d;
1609 /* Build for BB the static schedule.
1611 The STATIC_SCHEDULE is defined like this:
1614 for (i: ...)
1616 for (j: ...)
1622 for (k: ...)
1630 Static schedules for A to F:
1632 DEPTH
1633 0 1 2
1635 B 1 0 0
1636 C 1 0 1
1637 D 1 1 0
1638 E 1 1 1
1642 static void
1643 build_scop_canonical_schedules (scop_p scop)
1645 int i, j;
1646 graphite_bb_p gb;
1647 int nb = scop_nb_loops (scop) + 1;
1649 SCOP_STATIC_SCHEDULE (scop) = lambda_vector_new (nb);
1651 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
1653 int offset = nb_loops_around_gb (gb);
1655 /* After leaving a loop, it is possible that the schedule is not
1656 set at zero. This loop reinitializes components located
1657 after OFFSET. */
1659 for (j = offset + 1; j < nb; j++)
1660 if (SCOP_STATIC_SCHEDULE (scop)[j])
1662 memset (&(SCOP_STATIC_SCHEDULE (scop)[j]), 0,
1663 sizeof (int) * (nb - j));
1664 ++SCOP_STATIC_SCHEDULE (scop)[offset];
1665 break;
1668 GBB_STATIC_SCHEDULE (gb) = lambda_vector_new (offset + 1);
1669 lambda_vector_copy (SCOP_STATIC_SCHEDULE (scop),
1670 GBB_STATIC_SCHEDULE (gb), offset + 1);
1672 ++SCOP_STATIC_SCHEDULE (scop)[offset];
1676 /* Build the LOOPS vector for all bbs in SCOP. */
1678 static void
1679 build_bb_loops (scop_p scop)
1681 graphite_bb_p gb;
1682 int i;
1684 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
1686 loop_p loop;
1687 int depth;
1689 depth = nb_loops_around_gb (gb) - 1;
1691 GBB_LOOPS (gb) = VEC_alloc (loop_p, heap, 3);
1692 VEC_safe_grow_cleared (loop_p, heap, GBB_LOOPS (gb), depth + 1);
1694 loop = GBB_BB (gb)->loop_father;
1696 while (scop_contains_loop (scop, loop))
1698 VEC_replace (loop_p, GBB_LOOPS (gb), depth, loop);
1699 loop = loop_outer (loop);
1700 depth--;
1705 /* Get the index for parameter VAR in SCOP. */
1707 static int
1708 param_index (tree var, scop_p scop)
1710 int i;
1711 name_tree p;
1712 name_tree nvar;
1714 gcc_assert (TREE_CODE (var) == SSA_NAME);
1716 for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++)
1717 if (p->t == var)
1718 return i;
1720 nvar = XNEW (struct name_tree);
1721 nvar->t = var;
1722 nvar->name = NULL;
1723 VEC_safe_push (name_tree, heap, SCOP_PARAMS (scop), nvar);
1724 return VEC_length (name_tree, SCOP_PARAMS (scop)) - 1;
1727 /* Scan EXPR and translate it to an inequality vector INEQ that will
1728 be added, or subtracted, in the constraint domain matrix C at row
1729 R. K is the number of columns for loop iterators in C. */
1731 static void
1732 scan_tree_for_params (scop_p s, tree e, CloogMatrix *c, int r, Value k,
1733 bool subtract)
1735 int cst_col, param_col;
1737 if (e == chrec_dont_know)
1738 return;
1740 switch (TREE_CODE (e))
1742 case POLYNOMIAL_CHREC:
1744 tree left = CHREC_LEFT (e);
1745 tree right = CHREC_RIGHT (e);
1746 int var = CHREC_VARIABLE (e);
1748 if (TREE_CODE (right) != INTEGER_CST)
1749 return;
1751 if (c)
1753 int loop_col = scop_gimple_loop_depth (s, get_loop (var)) + 1;
1755 if (subtract)
1756 value_sub_int (c->p[r][loop_col], c->p[r][loop_col],
1757 int_cst_value (right));
1758 else
1759 value_add_int (c->p[r][loop_col], c->p[r][loop_col],
1760 int_cst_value (right));
1763 switch (TREE_CODE (left))
1765 case POLYNOMIAL_CHREC:
1766 scan_tree_for_params (s, left, c, r, k, subtract);
1767 return;
1769 case INTEGER_CST:
1770 /* Constant part. */
1771 if (c)
1773 int v = int_cst_value (left);
1774 cst_col = c->NbColumns - 1;
1776 if (v < 0)
1778 v = -v;
1779 subtract = subtract ? false : true;
1782 if (subtract)
1783 value_sub_int (c->p[r][cst_col], c->p[r][cst_col], v);
1784 else
1785 value_add_int (c->p[r][cst_col], c->p[r][cst_col], v);
1787 return;
1789 default:
1790 scan_tree_for_params (s, left, c, r, k, subtract);
1791 return;
1794 break;
1796 case MULT_EXPR:
1797 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
1799 Value val;
1801 gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0));
1803 value_init (val);
1804 value_set_si (val, int_cst_value (TREE_OPERAND (e, 1)));
1805 value_multiply (k, k, val);
1806 value_clear (val);
1807 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
1809 else
1811 Value val;
1813 gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0));
1815 value_init (val);
1816 value_set_si (val, int_cst_value (TREE_OPERAND (e, 0)));
1817 value_multiply (k, k, val);
1818 value_clear (val);
1819 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, subtract);
1821 break;
1823 case PLUS_EXPR:
1824 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
1825 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, subtract);
1826 break;
1828 case MINUS_EXPR:
1829 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
1830 value_oppose (k, k);
1831 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, subtract);
1832 break;
1834 case NEGATE_EXPR:
1835 value_oppose (k, k);
1836 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
1837 break;
1839 case SSA_NAME:
1840 param_col = param_index (e, s);
1842 if (c)
1844 param_col += c->NbColumns - scop_nb_params (s) - 1;
1846 if (subtract)
1847 value_subtract (c->p[r][param_col], c->p[r][param_col], k);
1848 else
1849 value_addto (c->p[r][param_col], c->p[r][param_col], k);
1851 break;
1853 case INTEGER_CST:
1854 if (c)
1856 int v = int_cst_value (e);
1857 cst_col = c->NbColumns - 1;
1859 if (v < 0)
1861 v = -v;
1862 subtract = subtract ? false : true;
1865 if (subtract)
1866 value_sub_int (c->p[r][cst_col], c->p[r][cst_col], v);
1867 else
1868 value_add_int (c->p[r][cst_col], c->p[r][cst_col], v);
1870 break;
1872 case NOP_EXPR:
1873 case CONVERT_EXPR:
1874 case NON_LVALUE_EXPR:
1875 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
1876 break;
1878 default:
1879 gcc_unreachable ();
1880 break;
1884 /* Data structure for idx_record_params. */
1886 struct irp_data
1888 struct loop *loop;
1889 scop_p scop;
1892 /* For a data reference with an ARRAY_REF as its BASE, record the
1893 parameters occurring in IDX. DTA is passed in as complementary
1894 information, and is used by the automatic walker function. This
1895 function is a callback for for_each_index. */
1897 static bool
1898 idx_record_params (tree base, tree *idx, void *dta)
1900 struct irp_data *data = (struct irp_data *) dta;
1902 if (TREE_CODE (base) != ARRAY_REF)
1903 return true;
1905 if (TREE_CODE (*idx) == SSA_NAME)
1907 tree scev;
1908 scop_p scop = data->scop;
1909 struct loop *loop = data->loop;
1910 Value one;
1912 scev = analyze_scalar_evolution (loop, *idx);
1913 scev = instantiate_scev (block_before_scop (scop), loop, scev);
1915 value_init (one);
1916 value_set_si (one, 1);
1917 scan_tree_for_params (scop, scev, NULL, 0, one, false);
1918 value_clear (one);
1921 return true;
1924 /* Find parameters with respect to SCOP in BB. We are looking in memory
1925 access functions, conditions and loop bounds. */
1927 static void
1928 find_params_in_bb (scop_p scop, basic_block bb)
1930 int i;
1931 data_reference_p dr;
1932 VEC (data_reference_p, heap) *drs;
1933 gimple_stmt_iterator gsi;
1934 struct loop *nest = outermost_loop_in_scop (scop, bb);
1936 /* Find the parameters used in the memory access functions. */
1937 drs = VEC_alloc (data_reference_p, heap, 5);
1938 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1939 find_data_references_in_stmt (nest, gsi_stmt (gsi), &drs);
1941 for (i = 0; VEC_iterate (data_reference_p, drs, i, dr); i++)
1943 struct irp_data irp;
1945 irp.loop = bb->loop_father;
1946 irp.scop = scop;
1947 for_each_index (&dr->ref, idx_record_params, &irp);
1948 free_data_ref (dr);
1951 VEC_free (data_reference_p, heap, drs);
1953 /* Find parameters in conditional statements. */
1954 gsi = gsi_last_bb (bb);
1955 if (!gsi_end_p (gsi))
1957 gimple stmt = gsi_stmt (gsi);
1959 if (gimple_code (stmt) == GIMPLE_COND)
1961 Value one;
1962 loop_p loop = bb->loop_father;
1964 tree lhs, rhs;
1966 lhs = gimple_cond_lhs (stmt);
1967 lhs = analyze_scalar_evolution (loop, lhs);
1968 lhs = instantiate_scev (block_before_scop (scop), loop, lhs);
1970 rhs = gimple_cond_rhs (stmt);
1971 rhs = analyze_scalar_evolution (loop, rhs);
1972 rhs = instantiate_scev (block_before_scop (scop), loop, rhs);
1974 value_init (one);
1975 scan_tree_for_params (scop, lhs, NULL, 0, one, false);
1976 value_set_si (one, 1);
1977 scan_tree_for_params (scop, rhs, NULL, 0, one, false);
1978 value_clear (one);
1983 /* Saves in NV the name of variable P->T. */
1985 static void
1986 save_var_name (char **nv, int i, name_tree p)
1988 const char *name = get_name (SSA_NAME_VAR (p->t));
1990 if (name)
1992 int len = strlen (name) + 16;
1993 nv[i] = XNEWVEC (char, len);
1994 snprintf (nv[i], len, "%s_%d", name, SSA_NAME_VERSION (p->t));
1996 else
1998 nv[i] = XNEWVEC (char, 16);
1999 snprintf (nv[i], 2 + 16, "T_%d", SSA_NAME_VERSION (p->t));
2002 p->name = nv[i];
2005 /* Return the maximal loop depth in SCOP. */
2007 static int
2008 scop_max_loop_depth (scop_p scop)
2010 int i;
2011 graphite_bb_p gbb;
2012 int max_nb_loops = 0;
2014 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++)
2016 int nb_loops = gbb_nb_loops (gbb);
2017 if (max_nb_loops < nb_loops)
2018 max_nb_loops = nb_loops;
2021 return max_nb_loops;
2024 /* Initialize Cloog's parameter names from the names used in GIMPLE.
2025 Initialize Cloog's iterator names, using 'graphite_iterator_%d'
2026 from 0 to scop_nb_loops (scop). */
2028 static void
2029 initialize_cloog_names (scop_p scop)
2031 int i, nb_params = VEC_length (name_tree, SCOP_PARAMS (scop));
2032 char **params = XNEWVEC (char *, nb_params);
2033 int nb_iterators = scop_max_loop_depth (scop);
2034 int nb_scattering= cloog_program_nb_scattdims (SCOP_PROG (scop));
2035 char **iterators = XNEWVEC (char *, nb_iterators * 2);
2036 char **scattering = XNEWVEC (char *, nb_scattering);
2037 name_tree p;
2039 for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++)
2040 save_var_name (params, i, p);
2042 cloog_names_set_nb_parameters (cloog_program_names (SCOP_PROG (scop)),
2043 nb_params);
2044 cloog_names_set_parameters (cloog_program_names (SCOP_PROG (scop)),
2045 params);
2047 for (i = 0; i < nb_iterators; i++)
2049 int len = 18 + 16;
2050 iterators[i] = XNEWVEC (char, len);
2051 snprintf (iterators[i], len, "graphite_iterator_%d", i);
2054 cloog_names_set_nb_iterators (cloog_program_names (SCOP_PROG (scop)),
2055 nb_iterators);
2056 cloog_names_set_iterators (cloog_program_names (SCOP_PROG (scop)),
2057 iterators);
2059 for (i = 0; i < nb_scattering; i++)
2061 int len = 2 + 16;
2062 scattering[i] = XNEWVEC (char, len);
2063 snprintf (scattering[i], len, "s_%d", i);
2066 cloog_names_set_nb_scattering (cloog_program_names (SCOP_PROG (scop)),
2067 nb_scattering);
2068 cloog_names_set_scattering (cloog_program_names (SCOP_PROG (scop)),
2069 scattering);
2072 /* Record the parameters used in the SCOP. A variable is a parameter
2073 in a scop if it does not vary during the execution of that scop. */
2075 static void
2076 find_scop_parameters (scop_p scop)
2078 graphite_bb_p gb;
2079 unsigned i;
2080 struct loop *loop;
2081 Value one;
2083 value_init (one);
2084 value_set_si (one, 1);
2086 /* Find the parameters used in the loop bounds. */
2087 for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop); i++)
2089 tree nb_iters = number_of_latch_executions (loop);
2091 if (!chrec_contains_symbols (nb_iters))
2092 continue;
2094 nb_iters = analyze_scalar_evolution (loop, nb_iters);
2095 nb_iters = instantiate_scev (block_before_scop (scop), loop, nb_iters);
2096 scan_tree_for_params (scop, nb_iters, NULL, 0, one, false);
2099 value_clear (one);
2101 /* Find the parameters used in data accesses. */
2102 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
2103 find_params_in_bb (scop, GBB_BB (gb));
2106 /* Build the context constraints for SCOP: constraints and relations
2107 on parameters. */
2109 static void
2110 build_scop_context (scop_p scop)
2112 int nb_params = scop_nb_params (scop);
2113 CloogMatrix *matrix = cloog_matrix_alloc (1, nb_params + 2);
2115 /* Insert '0 >= 0' in the context matrix, as it is not allowed to be
2116 empty. */
2118 value_set_si (matrix->p[0][0], 1);
2120 value_set_si (matrix->p[0][nb_params + 1], 0);
2122 cloog_program_set_context (SCOP_PROG (scop),
2123 cloog_domain_matrix2domain (matrix));
2124 cloog_matrix_free (matrix);
2127 /* Returns a graphite_bb from BB. */
2129 static inline graphite_bb_p
2130 gbb_from_bb (basic_block bb)
2132 return (graphite_bb_p) bb->aux;
2135 /* Add DOMAIN to all the basic blocks in LOOP. */
2137 static void
2138 add_bb_domains (struct loop *loop, CloogMatrix *domain)
2140 basic_block *bbs = get_loop_body (loop);
2141 unsigned i;
2143 for (i = 0; i < loop->num_nodes; i++)
2144 if (bbs[i]->loop_father == loop)
2146 graphite_bb_p gbb = gbb_from_bb (bbs[i]);
2147 GBB_DOMAIN (gbb) = cloog_matrix_copy (domain);
2150 free (bbs);
2153 /* Builds the constraint matrix for LOOP in SCOP. NB_OUTER_LOOPS is the
2154 number of loops surrounding LOOP in SCOP. OUTER_CSTR gives the
2155 constraints matrix for the surrounding loops. */
2157 static void
2158 build_loop_iteration_domains (scop_p scop, struct loop *loop,
2159 CloogMatrix *outer_cstr, int nb_outer_loops)
2161 int i, j, row;
2162 CloogMatrix *cstr;
2164 int nb_rows = outer_cstr->NbRows + 1;
2165 int nb_cols = outer_cstr->NbColumns + 1;
2167 /* Last column of CSTR is the column of constants. */
2168 int cst_col = nb_cols - 1;
2170 /* The column for the current loop is just after the columns of
2171 other outer loops. */
2172 int loop_col = nb_outer_loops + 1;
2174 tree nb_iters = number_of_latch_executions (loop);
2176 /* When the number of iterations is a constant or a parameter, we
2177 add a constraint for the upper bound of the loop. So add a row
2178 to the constraint matrix before allocating it. */
2179 if (TREE_CODE (nb_iters) == INTEGER_CST
2180 || !chrec_contains_undetermined (nb_iters))
2181 nb_rows++;
2183 cstr = cloog_matrix_alloc (nb_rows, nb_cols);
2185 /* Copy the outer constraints. */
2186 for (i = 0; i < outer_cstr->NbRows; i++)
2188 /* Copy the eq/ineq and loops columns. */
2189 for (j = 0; j < loop_col; j++)
2190 value_assign (cstr->p[i][j], outer_cstr->p[i][j]);
2192 /* Leave an empty column in CSTR for the current loop, and then
2193 copy the parameter columns. */
2194 for (j = loop_col; j < outer_cstr->NbColumns; j++)
2195 value_assign (cstr->p[i][j + 1], outer_cstr->p[i][j]);
2198 /* 0 <= loop_i */
2199 row = outer_cstr->NbRows;
2200 value_set_si (cstr->p[row][0], 1);
2201 value_set_si (cstr->p[row][loop_col], 1);
2203 /* loop_i <= nb_iters */
2204 if (TREE_CODE (nb_iters) == INTEGER_CST)
2206 row++;
2207 value_set_si (cstr->p[row][0], 1);
2208 value_set_si (cstr->p[row][loop_col], -1);
2210 value_set_si (cstr->p[row][cst_col],
2211 int_cst_value (nb_iters));
2213 else if (!chrec_contains_undetermined (nb_iters))
2215 /* Otherwise nb_iters contains parameters: scan the nb_iters
2216 expression and build its matrix representation. */
2217 Value one;
2219 row++;
2220 value_set_si (cstr->p[row][0], 1);
2221 value_set_si (cstr->p[row][loop_col], -1);
2223 nb_iters = analyze_scalar_evolution (loop, nb_iters);
2224 nb_iters = instantiate_scev (block_before_scop (scop), loop, nb_iters);
2226 value_init (one);
2227 value_set_si (one, 1);
2228 scan_tree_for_params (scop, nb_iters, cstr, row, one, false);
2229 value_clear (one);
2231 else
2232 gcc_unreachable ();
2234 if (loop->inner && loop_in_scop_p (loop->inner, scop))
2235 build_loop_iteration_domains (scop, loop->inner, cstr, nb_outer_loops + 1);
2237 /* Only go to the next loops, if we are not at the outermost layer. These
2238 have to be handled seperately, as we can be sure, that the chain at this
2239 layer will be connected. */
2240 if (nb_outer_loops != 0 && loop->next && loop_in_scop_p (loop->next, scop))
2241 build_loop_iteration_domains (scop, loop->next, outer_cstr, nb_outer_loops);
2243 add_bb_domains (loop, cstr);
2245 cloog_matrix_free (cstr);
2248 /* Add conditions to the domain of GB. */
2250 static void
2251 add_conditions_to_domain (graphite_bb_p gb)
2253 unsigned int i,j;
2254 gimple stmt;
2255 VEC (gimple, heap) *conditions = GBB_CONDITIONS (gb);
2256 CloogMatrix *domain = GBB_DOMAIN (gb);
2257 scop_p scop = GBB_SCOP (gb);
2259 unsigned nb_rows;
2260 unsigned nb_cols;
2261 unsigned nb_new_rows = 0;
2262 unsigned row;
2264 if (VEC_empty (gimple, conditions))
2265 return;
2267 if (domain)
2269 nb_rows = domain->NbRows;
2270 nb_cols = domain->NbColumns;
2272 else
2274 nb_rows = 0;
2275 nb_cols = scop_nb_params (scop) + 2;
2278 /* Count number of necessary new rows to add the conditions to the
2279 domain. */
2280 for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
2282 switch (gimple_code (stmt))
2284 case GIMPLE_COND:
2286 enum tree_code code = gimple_cond_code (stmt);
2288 switch (code)
2290 case NE_EXPR:
2291 case EQ_EXPR:
2292 /* NE and EQ statements are not supported right know. */
2293 gcc_unreachable ();
2294 break;
2295 case LT_EXPR:
2296 case GT_EXPR:
2297 case LE_EXPR:
2298 case GE_EXPR:
2299 nb_new_rows++;
2300 break;
2301 default:
2302 gcc_unreachable ();
2303 break;
2305 break;
2307 case SWITCH_EXPR:
2308 /* Switch statements are not supported right know. */
2309 gcc_unreachable ();
2310 break;
2312 default:
2313 gcc_unreachable ();
2314 break;
2319 /* Enlarge the matrix. */
2321 CloogMatrix *new_domain;
2322 new_domain = cloog_matrix_alloc (nb_rows + nb_new_rows, nb_cols);
2324 for (i = 0; i < nb_rows; i++)
2325 for (j = 0; j < nb_cols; j++)
2326 value_assign (new_domain->p[i][j], domain->p[i][j]);
2328 cloog_matrix_free (domain);
2329 domain = new_domain;
2330 GBB_DOMAIN (gb) = new_domain;
2333 /* Add the conditions to the new enlarged domain matrix. */
2334 row = nb_rows;
2335 for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
2337 switch (gimple_code (stmt))
2339 case GIMPLE_COND:
2341 Value one;
2342 enum tree_code code;
2343 tree left;
2344 tree right;
2345 loop_p loop = GBB_BB (gb)->loop_father;
2347 left = gimple_cond_lhs (stmt);
2348 right = gimple_cond_rhs (stmt);
2350 left = analyze_scalar_evolution (loop, left);
2351 right = analyze_scalar_evolution (loop, right);
2353 left = instantiate_scev (block_before_scop (scop), loop, left);
2354 right = instantiate_scev (block_before_scop (scop), loop, right);
2356 code = gimple_cond_code (stmt);
2358 /* The conditions for ELSE-branches are inverted. */
2359 if (VEC_index (gimple, gb->condition_cases, i) == NULL)
2360 code = invert_tree_comparison (code, false);
2362 switch (code)
2364 case NE_EXPR:
2365 /* NE statements are not supported right know. */
2366 gcc_unreachable ();
2367 break;
2368 case EQ_EXPR:
2369 value_set_si (domain->p[row][0], 1);
2370 value_init (one);
2371 value_set_si (one, 1);
2372 scan_tree_for_params (scop, left, domain, row, one, true);
2373 value_set_si (one, 1);
2374 scan_tree_for_params (scop, right, domain, row, one, false);
2375 row++;
2376 value_set_si (domain->p[row][0], 1);
2377 value_set_si (one, 1);
2378 scan_tree_for_params (scop, left, domain, row, one, false);
2379 value_set_si (one, 1);
2380 scan_tree_for_params (scop, right, domain, row, one, true);
2381 value_clear (one);
2382 row++;
2383 break;
2384 case LT_EXPR:
2385 value_set_si (domain->p[row][0], 1);
2386 value_init (one);
2387 value_set_si (one, 1);
2388 scan_tree_for_params (scop, left, domain, row, one, true);
2389 value_set_si (one, 1);
2390 scan_tree_for_params (scop, right, domain, row, one, false);
2391 value_sub_int (domain->p[row][nb_cols - 1],
2392 domain->p[row][nb_cols - 1], 1);
2393 value_clear (one);
2394 row++;
2395 break;
2396 case GT_EXPR:
2397 value_set_si (domain->p[row][0], 1);
2398 value_init (one);
2399 value_set_si (one, 1);
2400 scan_tree_for_params (scop, left, domain, row, one, false);
2401 value_set_si (one, 1);
2402 scan_tree_for_params (scop, right, domain, row, one, true);
2403 value_sub_int (domain->p[row][nb_cols - 1],
2404 domain->p[row][nb_cols - 1], 1);
2405 value_clear (one);
2406 row++;
2407 break;
2408 case LE_EXPR:
2409 value_set_si (domain->p[row][0], 1);
2410 value_init (one);
2411 value_set_si (one, 1);
2412 scan_tree_for_params (scop, left, domain, row, one, true);
2413 value_set_si (one, 1);
2414 scan_tree_for_params (scop, right, domain, row, one, false);
2415 value_clear (one);
2416 row++;
2417 break;
2418 case GE_EXPR:
2419 value_set_si (domain->p[row][0], 1);
2420 value_init (one);
2421 value_set_si (one, 1);
2422 scan_tree_for_params (scop, left, domain, row, one, false);
2423 value_set_si (one, 1);
2424 scan_tree_for_params (scop, right, domain, row, one, true);
2425 value_clear (one);
2426 row++;
2427 break;
2428 default:
2429 gcc_unreachable ();
2430 break;
2432 break;
2434 case GIMPLE_SWITCH:
2435 /* Switch statements are not supported right know. */
2436 gcc_unreachable ();
2437 break;
2439 default:
2440 gcc_unreachable ();
2441 break;
2446 /* Helper recursive function. */
2448 static void
2449 build_scop_conditions_1 (VEC (gimple, heap) **conditions,
2450 VEC (gimple, heap) **cases, basic_block bb,
2451 scop_p scop)
2453 int i, j;
2454 graphite_bb_p gbb;
2455 gimple_stmt_iterator gsi;
2456 basic_block bb_child, bb_iter;
2457 VEC (basic_block, heap) *dom;
2459 /* Make sure we are in the SCoP. */
2460 if (!bb_in_scop_p (bb, scop))
2461 return;
2463 /* Record conditions in graphite_bb. */
2464 gbb = gbb_from_bb (bb);
2465 GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
2466 GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
2468 add_conditions_to_domain (gbb);
2470 dom = get_dominated_by (CDI_DOMINATORS, bb);
2472 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2474 gimple stmt = gsi_stmt (gsi);
2475 VEC (edge, gc) *edges;
2476 edge e;
2478 switch (gimple_code (stmt))
2480 case GIMPLE_COND:
2481 edges = bb->succs;
2482 for (i = 0; VEC_iterate (edge, edges, i, e); i++)
2483 if ((dominated_by_p (CDI_DOMINATORS, e->dest, bb))
2484 && VEC_length (edge, e->dest->preds) == 1)
2486 /* Remove the scanned block from the dominator successors. */
2487 for (j = 0; VEC_iterate (basic_block, dom, j, bb_iter); j++)
2488 if (bb_iter == e->dest)
2490 VEC_unordered_remove (basic_block, dom, j);
2491 break;
2494 /* Recursively scan the then or else part. */
2495 if (e->flags & EDGE_TRUE_VALUE)
2496 VEC_safe_push (gimple, heap, *cases, stmt);
2497 else if (e->flags & EDGE_FALSE_VALUE)
2498 VEC_safe_push (gimple, heap, *cases, NULL);
2499 else
2500 gcc_unreachable ();
2502 VEC_safe_push (gimple, heap, *conditions, stmt);
2503 build_scop_conditions_1 (conditions, cases, e->dest, scop);
2504 VEC_pop (gimple, *conditions);
2505 VEC_pop (gimple, *cases);
2507 break;
2509 case GIMPLE_SWITCH:
2511 unsigned i;
2512 gimple_stmt_iterator gsi_search_gimple_label;
2514 for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
2516 basic_block bb_iter;
2517 size_t k;
2518 size_t n_cases = VEC_length (gimple, *conditions);
2519 unsigned n = gimple_switch_num_labels (stmt);
2521 bb_child = label_to_block
2522 (CASE_LABEL (gimple_switch_label (stmt, i)));
2524 /* Do not handle multiple values for the same block. */
2525 for (k = 0; k < n; k++)
2526 if (i != k
2527 && label_to_block
2528 (CASE_LABEL (gimple_switch_label (stmt, k))) == bb_child)
2529 break;
2531 if (k != n)
2532 continue;
2534 /* Switch cases with more than one predecessor are not
2535 handled. */
2536 if (VEC_length (edge, bb_child->preds) != 1)
2537 continue;
2539 /* Recursively scan the corresponding 'case' block. */
2541 for (gsi_search_gimple_label = gsi_start_bb (bb_child);
2542 !gsi_end_p (gsi_search_gimple_label);
2543 gsi_next (&gsi_search_gimple_label))
2545 gimple stmt_gimple_label
2546 = gsi_stmt (gsi_search_gimple_label);
2548 if (gimple_code (stmt_gimple_label) == GIMPLE_LABEL)
2550 tree t = gimple_label_label (stmt_gimple_label);
2552 if (t == gimple_switch_label (stmt, i))
2553 VEC_replace (gimple, *cases, n_cases,
2554 stmt_gimple_label);
2555 else
2556 gcc_unreachable ();
2560 build_scop_conditions_1 (conditions, cases, bb_child, scop);
2562 /* Remove the scanned block from the dominator successors. */
2563 for (j = 0; VEC_iterate (basic_block, dom, j, bb_iter); j++)
2564 if (bb_iter == bb_child)
2566 VEC_unordered_remove (basic_block, dom, j);
2567 break;
2571 VEC_pop (gimple, *conditions);
2572 VEC_pop (gimple, *cases);
2573 break;
2575 default:
2576 break;
2580 /* Scan all immediate dominated successors. */
2581 for (i = 0; VEC_iterate (basic_block, dom, i, bb_child); i++)
2582 build_scop_conditions_1 (conditions, cases, bb_child, scop);
2584 VEC_free (basic_block, heap, dom);
2587 /* Record all 'if' and 'switch' conditions in each gbb of SCOP. */
2589 static void
2590 build_scop_conditions (scop_p scop)
2592 VEC (gimple, heap) *conditions = NULL;
2593 VEC (gimple, heap) *cases = NULL;
2595 build_scop_conditions_1 (&conditions, &cases, SCOP_ENTRY (scop), scop);
2597 VEC_free (gimple, heap, conditions);
2598 VEC_free (gimple, heap, cases);
2601 /* Build the current domain matrix: the loops belonging to the current
2602 SCOP, and that vary for the execution of the current basic block.
2603 Returns false if there is no loop in SCOP. */
2605 static bool
2606 build_scop_iteration_domain (scop_p scop)
2608 struct loop *loop;
2609 CloogMatrix *outer_cstr;
2610 int i;
2612 /* Build cloog loop for all loops, that are in the uppermost loop layer of
2613 this SCoP. */
2614 for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop); i++)
2615 if (!loop_in_scop_p (loop_outer (loop), scop))
2617 /* The outermost constraints is a matrix that has:
2618 -first column: eq/ineq boolean
2619 -last column: a constant
2620 -scop_nb_params columns for the parameters used in the scop. */
2621 outer_cstr = cloog_matrix_alloc (0, scop_nb_params (scop) + 2);
2622 build_loop_iteration_domains (scop, loop, outer_cstr, 0);
2623 cloog_matrix_free (outer_cstr);
2626 return (i != 0);
2629 /* Initializes an equation CY of the access matrix using the
2630 information for a subscript from ACCESS_FUN, relatively to the loop
2631 indexes from LOOP_NEST and parameter indexes from PARAMS. NDIM is
2632 the dimension of the array access, i.e. the number of
2633 subscripts. Returns true when the operation succeeds. */
2635 static bool
2636 build_access_matrix_with_af (tree access_fun, lambda_vector cy,
2637 scop_p scop, int ndim)
2639 switch (TREE_CODE (access_fun))
2641 case POLYNOMIAL_CHREC:
2643 tree left = CHREC_LEFT (access_fun);
2644 tree right = CHREC_RIGHT (access_fun);
2645 int var;
2647 if (TREE_CODE (right) != INTEGER_CST)
2648 return false;
2650 var = loop_iteration_vector_dim (CHREC_VARIABLE (access_fun), scop);
2651 cy[var] = int_cst_value (right);
2653 switch (TREE_CODE (left))
2655 case POLYNOMIAL_CHREC:
2656 return build_access_matrix_with_af (left, cy, scop, ndim);
2658 case INTEGER_CST:
2659 cy[ndim - 1] = int_cst_value (left);
2660 return true;
2662 default:
2663 /* FIXME: access_fn can have parameters. */
2664 return false;
2667 case INTEGER_CST:
2668 cy[ndim - 1] = int_cst_value (access_fun);
2669 return true;
2671 default:
2672 /* FIXME: access_fn can have parameters. */
2673 return false;
2677 /* Initialize the access matrix in the data reference REF with respect
2678 to the loop nesting LOOP_NEST. Return true when the operation
2679 succeeded. */
2681 static bool
2682 build_access_matrix (data_reference_p ref, graphite_bb_p gb)
2684 int i, ndim = DR_NUM_DIMENSIONS (ref);
2685 struct access_matrix *am = GGC_NEW (struct access_matrix);
2687 AM_MATRIX (am) = VEC_alloc (lambda_vector, heap, ndim);
2688 DR_SCOP (ref) = GBB_SCOP (gb);
2690 for (i = 0; i < ndim; i++)
2692 lambda_vector v = lambda_vector_new (ref_nb_loops (ref));
2693 scop_p scop = GBB_SCOP (gb);
2694 tree af = DR_ACCESS_FN (ref, i);
2696 if (!build_access_matrix_with_af (af, v, scop, ref_nb_loops (ref)))
2697 return false;
2699 VEC_safe_push (lambda_vector, heap, AM_MATRIX (am), v);
2702 DR_ACCESS_MATRIX (ref) = am;
2703 return true;
2706 /* Build the access matrices for the data references in the SCOP. */
2708 static void
2709 build_scop_data_accesses (scop_p scop)
2711 int i;
2712 graphite_bb_p gb;
2714 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
2716 int j;
2717 gimple_stmt_iterator gsi;
2718 data_reference_p dr;
2719 struct loop *nest = outermost_loop_in_scop (scop, GBB_BB (gb));
2721 /* On each statement of the basic block, gather all the occurences
2722 to read/write memory. */
2723 GBB_DATA_REFS (gb) = VEC_alloc (data_reference_p, heap, 5);
2724 for (gsi = gsi_start_bb (GBB_BB (gb)); !gsi_end_p (gsi); gsi_next (&gsi))
2725 find_data_references_in_stmt (nest, gsi_stmt (gsi),
2726 &GBB_DATA_REFS (gb));
2728 /* FIXME: Construction of access matrix is disabled until some
2729 pass, like the data dependence analysis, is using it. */
2730 continue;
2732 /* Construct the access matrix for each data ref, with respect to
2733 the loop nest of the current BB in the considered SCOP. */
2734 for (j = 0;
2735 VEC_iterate (data_reference_p, GBB_DATA_REFS (gb), j, dr);
2736 j++)
2738 bool res = build_access_matrix (dr, gb);
2740 /* FIXME: At this point the DRs should always have an affine
2741 form. For the moment this fails as build_access_matrix
2742 does not build matrices with parameters. */
2743 gcc_assert (res);
2748 /* Converts a GMP constant value to a tree and returns it. */
2750 static tree
2751 gmp_cst_to_tree (Value v)
2753 return build_int_cst (integer_type_node, value_get_si (v));
2756 /* Returns the tree variable from the name NAME that was given in
2757 Cloog representation. All the parameters are stored in PARAMS, and
2758 all the loop induction variables are stored in IVSTACK.
2760 FIXME: This is a hack, and Cloog should be fixed to not work with
2761 variable names represented as "char *string", but with void
2762 pointers that could be casted back to a tree. The only problem in
2763 doing that is that Cloog's pretty printer still assumes that
2764 variable names are char *strings. The solution would be to have a
2765 function pointer for pretty-printing that can be redirected to be
2766 print_generic_stmt in our case, or fprintf by default.
2767 ??? Too ugly to live. */
2769 static tree
2770 clast_name_to_gcc (const char *name, VEC (name_tree, heap) *params,
2771 loop_iv_stack ivstack)
2773 int i;
2774 name_tree t;
2775 tree iv;
2777 for (i = 0; VEC_iterate (name_tree, params, i, t); i++)
2778 if (!strcmp (name, t->name))
2779 return t->t;
2781 iv = loop_iv_stack_get_iv_from_name (ivstack, name);
2782 if (iv)
2783 return iv;
2785 gcc_unreachable ();
2788 /* Converts a Cloog AST expression E back to a GCC expression tree. */
2790 static tree
2791 clast_to_gcc_expression (struct clast_expr *e,
2792 VEC (name_tree, heap) *params,
2793 loop_iv_stack ivstack)
2795 tree type = integer_type_node;
2797 gcc_assert (e);
2799 switch (e->type)
2801 case expr_term:
2803 struct clast_term *t = (struct clast_term *) e;
2805 if (t->var)
2807 if (value_one_p (t->val))
2808 return clast_name_to_gcc (t->var, params, ivstack);
2810 else if (value_mone_p (t->val))
2811 return fold_build1 (NEGATE_EXPR, type,
2812 clast_name_to_gcc (t->var, params, ivstack));
2813 else
2814 return fold_build2 (MULT_EXPR, type,
2815 gmp_cst_to_tree (t->val),
2816 clast_name_to_gcc (t->var, params, ivstack));
2818 else
2819 return gmp_cst_to_tree (t->val);
2822 case expr_red:
2824 struct clast_reduction *r = (struct clast_reduction *) e;
2825 tree left, right;
2827 switch (r->type)
2829 case clast_red_sum:
2830 if (r->n == 1)
2831 return clast_to_gcc_expression (r->elts[0], params, ivstack);
2833 else
2835 gcc_assert (r->n >= 1
2836 && r->elts[0]->type == expr_term
2837 && r->elts[1]->type == expr_term);
2839 left = clast_to_gcc_expression (r->elts[0], params, ivstack);
2840 right = clast_to_gcc_expression (r->elts[1], params, ivstack);
2841 return fold_build2 (PLUS_EXPR, type, left, right);
2844 break;
2846 case clast_red_min:
2847 if (r->n == 1)
2848 return clast_to_gcc_expression (r->elts[0], params, ivstack);
2850 else if (r->n == 2)
2852 left = clast_to_gcc_expression (r->elts[0], params, ivstack);
2853 right = clast_to_gcc_expression (r->elts[1], params, ivstack);
2854 return fold_build2 (MIN_EXPR, type, left, right);
2857 else
2858 gcc_unreachable();
2860 break;
2862 case clast_red_max:
2863 if (r->n == 1)
2864 return clast_to_gcc_expression (r->elts[0], params, ivstack);
2866 else if (r->n == 2)
2868 left = clast_to_gcc_expression (r->elts[0], params, ivstack);
2869 right = clast_to_gcc_expression (r->elts[1], params, ivstack);
2870 return fold_build2 (MAX_EXPR, type, left, right);
2873 else
2874 gcc_unreachable();
2876 break;
2878 default:
2879 gcc_unreachable ();
2881 break;
2884 case expr_bin:
2886 struct clast_binary *b = (struct clast_binary *) e;
2887 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
2888 struct clast_expr *rhs = (struct clast_expr *) b->RHS;
2889 tree tl = clast_to_gcc_expression (lhs, params, ivstack);
2891 /* FIXME: The next statement produces a warning: Cloog assumes
2892 that the RHS is a constant, but this is a "void *" pointer
2893 that should be casted into a Value, but this cast cannot be
2894 done as Value is a GMP type, that is an array. Cloog must
2895 be fixed for removing this warning. */
2896 tree tr = gmp_cst_to_tree (rhs);
2898 switch (b->type)
2900 case clast_bin_fdiv:
2901 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
2903 case clast_bin_cdiv:
2904 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
2906 case clast_bin_div:
2907 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
2909 case clast_bin_mod:
2910 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
2912 default:
2913 gcc_unreachable ();
2917 default:
2918 gcc_unreachable ();
2921 return NULL_TREE;
2924 /* Translates a clast equation CLEQ to a tree. */
2926 static tree
2927 graphite_translate_clast_equation (scop_p scop,
2928 struct clast_equation *cleq,
2929 loop_iv_stack ivstack)
2931 enum tree_code comp;
2932 tree lhs = clast_to_gcc_expression (cleq->LHS, SCOP_PARAMS (scop), ivstack);
2933 tree rhs = clast_to_gcc_expression (cleq->RHS, SCOP_PARAMS (scop), ivstack);
2935 if (cleq->sign == 0)
2936 comp = EQ_EXPR;
2938 else if (cleq->sign > 0)
2939 comp = GE_EXPR;
2941 else
2942 comp = LE_EXPR;
2944 return fold_build2 (comp, integer_type_node, lhs, rhs);
2947 /* Creates the test for the condition in STMT. */
2949 static tree
2950 graphite_create_guard_cond_expr (scop_p scop, struct clast_guard *stmt,
2951 loop_iv_stack ivstack)
2953 tree cond = NULL;
2954 int i;
2956 for (i = 0; i < stmt->n; i++)
2958 tree eq = graphite_translate_clast_equation (scop, &stmt->eq[i], ivstack);
2960 if (cond)
2961 cond = fold_build2 (TRUTH_AND_EXPR, integer_type_node, cond, eq);
2962 else
2963 cond = eq;
2966 return cond;
2969 /* Creates a new if region corresponding to Cloog's guard. */
2971 static edge
2972 graphite_create_new_guard (scop_p scop, edge entry_edge,
2973 struct clast_guard *stmt,
2974 loop_iv_stack ivstack)
2976 tree cond_expr = graphite_create_guard_cond_expr (scop, stmt, ivstack);
2977 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
2978 return exit_edge;
2982 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an induction
2983 variable for the new LOOP. New LOOP is attached to CFG starting at
2984 ENTRY_EDGE. LOOP is inserted into the loop tree and becomes the child
2985 loop of the OUTER_LOOP. */
2987 static struct loop *
2988 graphite_create_new_loop (scop_p scop, edge entry_edge,
2989 struct clast_for *stmt, loop_iv_stack ivstack,
2990 loop_p outer)
2992 struct loop *loop;
2993 tree ivvar;
2994 tree stride, lowb, upb;
2995 tree iv_before;
2997 gcc_assert (stmt->LB
2998 && stmt->UB);
3000 stride = gmp_cst_to_tree (stmt->stride);
3001 lowb = clast_to_gcc_expression (stmt->LB, SCOP_PARAMS (scop), ivstack);
3002 ivvar = create_tmp_var (integer_type_node, "graphiteIV");
3003 add_referenced_var (ivvar);
3005 upb = clast_to_gcc_expression (stmt->UB, SCOP_PARAMS (scop), ivstack);
3006 loop = create_empty_loop_on_edge (entry_edge, lowb, stride, upb, ivvar,
3007 &iv_before, outer ? outer
3008 : entry_edge->src->loop_father);
3010 loop_iv_stack_push (ivstack, iv_before, stmt->iterator);
3012 return loop;
3015 /* Remove all the edges from EDGES except the edge KEEP. */
3017 static void
3018 remove_all_edges_1 (VEC (edge, gc) *edges, edge keep)
3020 edge e;
3021 edge_iterator ei;
3023 for (ei = ei_start (edges); (e = ei_safe_edge (ei)); )
3025 if (e != keep)
3027 remove_edge (e);
3028 e = ei_safe_edge (ei);
3030 else
3031 ei_next (&ei);
3035 /* Remove all the edges from BB except the edge KEEP. */
3037 static void
3038 remove_all_edges (basic_block bb, edge keep)
3040 remove_all_edges_1 (bb->succs, keep);
3041 remove_all_edges_1 (bb->preds, keep);
3044 /* Rename the SSA_NAMEs used in STMT and that appear in IVSTACK. */
3046 static void
3047 graphite_rename_ivs_stmt (gimple stmt, graphite_bb_p gbb, scop_p scop,
3048 loop_p old, loop_iv_stack ivstack)
3050 ssa_op_iter iter;
3051 use_operand_p use_p;
3053 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
3055 tree use = USE_FROM_PTR (use_p);
3056 tree new_iv = NULL;
3057 name_tree old_iv = get_old_iv_from_ssa_name (scop, old, use);
3059 if (old_iv)
3060 new_iv = loop_iv_stack_get_iv (ivstack,
3061 gbb_loop_index (gbb, old_iv->loop));
3063 if (new_iv)
3064 SET_USE (use_p, new_iv);
3068 /* Returns true if SSA_NAME is a parameter of SCOP. */
3070 static bool
3071 is_parameter (scop_p scop, tree ssa_name)
3073 int i;
3074 VEC (name_tree, heap) *params = SCOP_PARAMS (scop);
3075 name_tree param;
3077 for (i = 0; VEC_iterate (name_tree, params, i, param); i++)
3078 if (param->t == ssa_name)
3079 return true;
3081 return false;
3084 /* Returns true if NAME is an old induction variable in SCOP. OLD is
3085 the original loop that contained the definition of NAME. */
3087 static bool
3088 is_old_iv (scop_p scop, loop_p old, tree name)
3090 return get_old_iv_from_ssa_name (scop, old, name) != NULL;
3094 static void expand_scalar_variables_stmt (gimple, graphite_bb_p, scop_p, loop_p,
3095 loop_iv_stack);
3097 /* Constructs a tree which only contains old_ivs and parameters. Any
3098 other variables that are defined outside GBB will be eliminated by
3099 using their definitions in the constructed tree. OLD_LOOP_FATHER
3100 is the original loop that contained GBB. */
3102 static tree
3103 expand_scalar_variables_expr (tree type, tree op0, enum tree_code code,
3104 tree op1, graphite_bb_p gbb, scop_p scop,
3105 loop_p old_loop_father, loop_iv_stack ivstack)
3107 if (TREE_CODE_CLASS (code) == tcc_constant
3108 && code == INTEGER_CST)
3109 return op0;
3111 if (TREE_CODE_CLASS (code) == tcc_unary)
3113 tree op0_type = TREE_TYPE (op0);
3114 enum tree_code op0_code = TREE_CODE (op0);
3115 tree op0_expr =
3116 expand_scalar_variables_expr (op0_type, op0, op0_code,
3117 NULL, gbb, scop, old_loop_father,
3118 ivstack);
3120 return fold_build1 (code, type, op0_expr);
3123 if (TREE_CODE_CLASS (code) == tcc_binary)
3125 tree op0_type = TREE_TYPE (op0);
3126 enum tree_code op0_code = TREE_CODE (op0);
3127 tree op0_expr =
3128 expand_scalar_variables_expr (op0_type, op0, op0_code,
3129 NULL, gbb, scop, old_loop_father,
3130 ivstack);
3131 tree op1_type = TREE_TYPE (op1);
3132 enum tree_code op1_code = TREE_CODE (op1);
3133 tree op1_expr =
3134 expand_scalar_variables_expr (op1_type, op1, op1_code,
3135 NULL, gbb, scop, old_loop_father,
3136 ivstack);
3138 return fold_build2 (code, type, op0_expr, op1_expr);
3141 if (code == SSA_NAME)
3143 tree var0, var1;
3144 gimple def_stmt;
3145 enum tree_code subcode;
3147 if(is_parameter (scop, op0) ||
3148 is_old_iv (scop, old_loop_father, op0))
3149 return op0;
3151 def_stmt = SSA_NAME_DEF_STMT (op0);
3153 if (gimple_bb (def_stmt) == GBB_BB (gbb))
3155 /* If the defining statement is in the basic block already
3156 we do not need to create a new expression for it, we
3157 only need to ensure its operands are expanded. */
3158 expand_scalar_variables_stmt (def_stmt, gbb, scop,
3159 old_loop_father, ivstack);
3160 return op0;
3163 else
3165 if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
3166 return op0;
3168 var0 = gimple_assign_rhs1 (def_stmt);
3169 subcode = gimple_assign_rhs_code (def_stmt);
3170 var1 = gimple_assign_rhs2 (def_stmt);
3172 return expand_scalar_variables_expr (type, var0, subcode, var1,
3173 gbb, scop, old_loop_father,
3174 ivstack);
3178 gcc_unreachable ();
3179 return NULL;
3182 /* Replicates any uses of non-parameters and non-old-ivs variablesthat
3183 are defind outside GBB with code that is inserted in GBB.
3184 OLD_LOOP_FATHER is the original loop that contained STMT. */
3186 static void
3187 expand_scalar_variables_stmt (gimple stmt, graphite_bb_p gbb, scop_p scop,
3188 loop_p old_loop_father, loop_iv_stack ivstack)
3190 ssa_op_iter iter;
3191 use_operand_p use_p;
3192 basic_block bb = GBB_BB (gbb);
3194 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
3196 tree use = USE_FROM_PTR (use_p);
3197 tree type = TREE_TYPE (use);
3198 enum tree_code code = TREE_CODE (use);
3199 tree use_expr = expand_scalar_variables_expr (type, use, code, NULL,
3200 gbb, scop, old_loop_father,
3201 ivstack);
3202 if (use_expr != use)
3204 gimple_stmt_iterator gsi = gsi_after_labels (bb);
3205 tree new_use =
3206 force_gimple_operand_gsi (&gsi, use_expr, true, NULL,
3207 true, GSI_NEW_STMT);
3208 SET_USE (use_p, new_use);
3213 /* Copies the definitions outside of GBB of variables that are not
3214 induction variables nor parameters. GBB must only contain
3215 "external" references to these types of variables. OLD_LOOP_FATHER
3216 is the original loop that contained GBB. */
3218 static void
3219 expand_scalar_variables (graphite_bb_p gbb, scop_p scop,
3220 loop_p old_loop_father, loop_iv_stack ivstack)
3222 basic_block bb = GBB_BB (gbb);
3223 gimple_stmt_iterator gsi;
3225 for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
3227 gimple stmt = gsi_stmt (gsi);
3228 expand_scalar_variables_stmt (stmt, gbb, scop, old_loop_father,
3229 ivstack);
3230 gsi_next (&gsi);
3234 /* Rename all the SSA_NAMEs from block GBB that appear in IVSTACK in
3235 terms of new induction variables. OLD_LOOP_FATHER is the original
3236 loop that contained GBB. */
3238 static void
3239 graphite_rename_ivs (graphite_bb_p gbb, scop_p scop, loop_p old_loop_father,
3240 loop_iv_stack ivstack)
3242 basic_block bb = GBB_BB (gbb);
3243 gimple_stmt_iterator gsi;
3245 for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
3247 gimple stmt = gsi_stmt (gsi);
3249 if (gimple_get_lhs (stmt)
3250 && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME
3251 && get_old_iv_from_ssa_name (scop, old_loop_father,
3252 gimple_get_lhs (stmt)))
3253 gsi_remove (&gsi, false);
3254 else
3256 graphite_rename_ivs_stmt (stmt, gbb, scop, old_loop_father, ivstack);
3257 gsi_next (&gsi);
3262 /* Move all the PHI nodes from block FROM to block TO.
3263 OLD_LOOP_FATHER is the original loop that contained FROM. */
3265 static void
3266 move_phi_nodes (scop_p scop, loop_p old_loop_father, basic_block from,
3267 basic_block to)
3269 gimple_stmt_iterator gsi;
3271 for (gsi = gsi_start_phis (from); !gsi_end_p (gsi);)
3273 gimple phi = gsi_stmt (gsi);
3274 tree op = gimple_phi_result (phi);
3276 if (get_old_iv_from_ssa_name (scop, old_loop_father, op) == NULL)
3278 gimple new_phi = make_phi_node (op, 0);
3279 add_phi_node_to_bb (new_phi, to);
3281 remove_phi_node (&gsi, false);
3285 /* Remove condition from BB. */
3287 static void
3288 remove_condition (basic_block bb)
3290 gimple last = last_stmt (bb);
3292 if (last && gimple_code (last) == GIMPLE_COND)
3294 gimple_stmt_iterator gsi = gsi_last_bb (bb);
3295 gsi_remove (&gsi, true);
3299 /* Returns the first successor edge of BB with EDGE_TRUE_VALUE flag set. */
3301 static edge
3302 get_true_edge_from_guard_bb (basic_block bb)
3304 edge e;
3305 edge_iterator ei;
3307 FOR_EACH_EDGE (e, ei, bb->succs)
3308 if (e->flags & EDGE_TRUE_VALUE)
3309 return e;
3311 gcc_unreachable ();
3312 return NULL;
3315 /* Translates a CLAST statement STMT to GCC representation. NEXT_E is
3316 the edge where new generated code should be attached. BB_EXIT is the last
3317 basic block that defines the scope of code generation. CONTEXT_LOOP is the
3318 loop in which the generated code will be placed (might be NULL). */
3320 static edge
3321 translate_clast (scop_p scop, struct loop *context_loop,
3322 struct clast_stmt *stmt, edge next_e, loop_iv_stack ivstack)
3324 if (!stmt)
3325 return next_e;
3327 if (CLAST_STMT_IS_A (stmt, stmt_root))
3328 return translate_clast (scop, context_loop, stmt->next, next_e, ivstack);
3330 if (CLAST_STMT_IS_A (stmt, stmt_user))
3332 CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
3333 graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
3334 basic_block bb = gbb->bb;
3335 loop_p old_loop_father = bb->loop_father;
3337 if (bb == ENTRY_BLOCK_PTR)
3338 return next_e;
3340 remove_condition (bb);
3341 expand_scalar_variables (gbb, scop, old_loop_father, ivstack);
3342 remove_all_edges (bb, next_e);
3343 move_phi_nodes (scop, old_loop_father, bb, next_e->src);
3344 redirect_edge_succ_nodup (next_e, bb);
3346 if (context_loop)
3348 remove_bb_from_loops (bb);
3349 add_bb_to_loop (bb, context_loop);
3352 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
3353 mark_virtual_ops_in_bb (bb);
3354 next_e = make_edge (bb,
3355 context_loop ? context_loop->latch : EXIT_BLOCK_PTR,
3356 EDGE_FALLTHRU);;
3357 graphite_rename_ivs (gbb, scop, old_loop_father, ivstack);
3358 return translate_clast (scop, context_loop, stmt->next, next_e, ivstack);
3361 if (CLAST_STMT_IS_A (stmt, stmt_for))
3363 struct loop *loop
3364 = graphite_create_new_loop (scop, next_e, (struct clast_for *) stmt,
3365 ivstack, context_loop ? context_loop
3366 : get_loop (0));
3367 edge last_e = single_exit (loop);
3369 next_e = translate_clast (scop, loop, ((struct clast_for *) stmt)->body,
3370 single_pred_edge (loop->latch), ivstack);
3371 redirect_edge_succ_nodup (next_e, loop->latch);
3373 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
3374 loop_iv_stack_pop (ivstack);
3376 return translate_clast (scop, context_loop, stmt->next, last_e, ivstack);
3379 if (CLAST_STMT_IS_A (stmt, stmt_guard))
3381 edge last_e = graphite_create_new_guard (scop, next_e,
3382 ((struct clast_guard *) stmt),
3383 ivstack);
3384 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
3385 next_e = translate_clast (scop, context_loop,
3386 ((struct clast_guard *) stmt)->then,
3387 true_e, ivstack);
3388 redirect_edge_succ_nodup (next_e, last_e->src);
3389 return translate_clast (scop, context_loop, stmt->next, last_e, ivstack);
3392 if (CLAST_STMT_IS_A (stmt, stmt_block))
3394 next_e = translate_clast (scop, context_loop,
3395 ((struct clast_block *) stmt)->body,
3396 next_e, ivstack);
3397 return translate_clast (scop, context_loop, stmt->next, next_e, ivstack);
3400 gcc_unreachable ();
3403 /* Build cloog program for SCoP. */
3405 static void
3406 build_cloog_prog (scop_p scop)
3408 int i;
3409 int max_nb_loops = scop_max_loop_depth (scop);
3410 graphite_bb_p gbb;
3411 CloogLoop *loop_list = NULL;
3412 CloogBlockList *block_list = NULL;
3413 CloogDomainList *scattering = NULL;
3414 CloogProgram *prog = SCOP_PROG (scop);
3415 int nbs = 2 * max_nb_loops + 1;
3416 int *scaldims = (int *) xmalloc (nbs * (sizeof (int)));
3418 cloog_program_set_nb_scattdims (prog, nbs);
3419 initialize_cloog_names (scop);
3421 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++)
3423 /* Build new block. */
3424 CloogMatrix *domain = GBB_DOMAIN (gbb);
3425 CloogStatement *stmt = cloog_statement_alloc (GBB_BB (gbb)->index);
3426 CloogBlock *block = cloog_block_alloc (stmt, 0, NULL,
3427 nb_loops_around_gb (gbb));
3428 cloog_statement_set_usr (stmt, gbb);
3430 /* Add empty domain to all bbs, which do not yet have a domain, as they
3431 are not part of any loop. */
3432 if (domain == NULL)
3434 domain = cloog_matrix_alloc (0, scop_nb_params (scop) + 2);
3435 GBB_DOMAIN (gbb) = domain;
3438 /* Build loop list. */
3440 CloogLoop *new_loop_list = cloog_loop_malloc ();
3441 cloog_loop_set_next (new_loop_list, loop_list);
3442 cloog_loop_set_domain (new_loop_list,
3443 cloog_domain_matrix2domain (domain));
3444 cloog_loop_set_block (new_loop_list, block);
3445 loop_list = new_loop_list;
3448 /* Build block list. */
3450 CloogBlockList *new_block_list = cloog_block_list_malloc ();
3452 cloog_block_list_set_next (new_block_list, block_list);
3453 cloog_block_list_set_block (new_block_list, block);
3454 block_list = new_block_list;
3457 /* Build scattering list. */
3459 /* XXX: Replace with cloog_domain_list_alloc(), when available. */
3460 CloogDomainList *new_scattering
3461 = (CloogDomainList *) xmalloc (sizeof (CloogDomainList));
3462 CloogMatrix *scat_mat = schedule_to_scattering (gbb, nbs);
3464 cloog_set_next_domain (new_scattering, scattering);
3465 cloog_set_domain (new_scattering,
3466 cloog_domain_matrix2domain (scat_mat));
3467 scattering = new_scattering;
3468 cloog_matrix_free (scat_mat);
3472 cloog_program_set_loop (prog, loop_list);
3473 cloog_program_set_blocklist (prog, block_list);
3475 for (i = 0; i < nbs; i++)
3476 scaldims[i] = 0 ;
3478 cloog_program_set_scaldims (prog, scaldims);
3480 /* Extract scalar dimensions to simplify the code generation problem. */
3481 cloog_program_extract_scalars (prog, scattering);
3483 /* Apply scattering. */
3484 cloog_program_scatter (prog, scattering);
3486 /* Iterators corresponding to scalar dimensions have to be extracted. */
3487 cloog_names_scalarize (cloog_program_names (prog), nbs,
3488 cloog_program_scaldims (prog));
3490 /* Free blocklist. */
3492 CloogBlockList *next = cloog_program_blocklist (prog);
3494 while (next)
3496 CloogBlockList *toDelete = next;
3497 next = cloog_block_list_next (next);
3498 cloog_block_list_set_next (toDelete, NULL);
3499 cloog_block_list_set_block (toDelete, NULL);
3500 cloog_block_list_free (toDelete);
3502 cloog_program_set_blocklist (prog, NULL);
3506 /* Return the options that will be used in GLOOG. */
3508 static CloogOptions *
3509 set_cloog_options (void)
3511 CloogOptions *options = cloog_options_malloc ();
3513 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
3514 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
3515 we pass an incomplete program to cloog. */
3516 options->language = LANGUAGE_C;
3518 /* Enable complex equality spreading: removes dummy statements
3519 (assignments) in the generated code which repeats the
3520 substitution equations for statements. This is useless for
3521 GLooG. */
3522 options->esp = 1;
3524 /* Enable C pretty-printing mode: normalizes the substitution
3525 equations for statements. */
3526 options->cpp = 1;
3528 /* Allow cloog to build strides with a stride width different to one.
3529 This example has stride = 4:
3531 for (i = 0; i < 20; i += 4)
3532 A */
3533 options->strides = 1;
3535 /* Disable optimizations and make cloog generate source code closer to the
3536 input. This is useful for debugging, but later we want the optimized
3537 code.
3539 XXX: We can not disable optimizations, as loop blocking is not working
3540 without them. */
3541 if (0)
3543 options->f = -1;
3544 options->l = INT_MAX;
3547 return options;
3550 /* Prints STMT to STDERR. */
3552 void
3553 debug_clast_stmt (struct clast_stmt *stmt)
3555 CloogOptions *options = set_cloog_options ();
3557 pprint (stderr, stmt, 0, options);
3560 /* Find the right transform for the SCOP, and return a Cloog AST
3561 representing the new form of the program. */
3563 static struct clast_stmt *
3564 find_transform (scop_p scop)
3566 CloogProgram *prog;
3567 struct clast_stmt *stmt;
3568 CloogOptions *options = set_cloog_options ();
3570 /* Connect new cloog prog generation to graphite. */
3571 build_cloog_prog (scop);
3573 if (dump_file && (dump_flags & TDF_DETAILS))
3575 fprintf (dump_file, "Cloog Input [\n");
3576 cloog_program_print (dump_file, SCOP_PROG(scop));
3577 fprintf (dump_file, "]\n");
3580 prog = cloog_program_generate (SCOP_PROG (scop), options);
3581 stmt = cloog_clast_create (prog, options);
3583 if (dump_file && (dump_flags & TDF_DETAILS))
3585 fprintf (dump_file, "Cloog Output[\n");
3586 pprint (dump_file, stmt, 0, options);
3587 cloog_program_dump_cloog (dump_file, prog);
3588 fprintf (dump_file, "]\n");
3591 cloog_options_free (options);
3592 return stmt;
3595 /* Return a vector of all the virtual phi nodes in the current
3596 function. */
3598 static VEC (gimple, heap) *
3599 collect_virtual_phis (void)
3601 gimple_stmt_iterator si;
3602 gimple_vec phis = VEC_alloc (gimple, heap, 3);
3603 basic_block bb;
3605 FOR_EACH_BB (bb)
3606 for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
3607 /* The phis we moved will have 0 arguments because the
3608 original edges were removed. */
3609 if (gimple_phi_num_args (gsi_stmt (si)) == 0)
3610 VEC_safe_push (gimple, heap, phis, gsi_stmt (si));
3612 /* Deallocate if we did not find any. */
3613 if (VEC_length (gimple, phis) == 0)
3615 VEC_free (gimple, heap, phis);
3616 phis = NULL;
3619 return phis;
3622 /* Find a virtual definition for variable VAR in BB. */
3624 static tree
3625 find_vdef_for_var_in_bb (basic_block bb, tree var)
3627 gimple_stmt_iterator gsi;
3628 gimple phi;
3629 def_operand_p def_var;
3630 vuse_vec_p vv;
3631 ssa_op_iter op_iter;
3633 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
3634 FOR_EACH_SSA_VDEF_OPERAND (def_var, vv, gsi_stmt (gsi), op_iter)
3635 if (SSA_NAME_VAR (*def_var) == var)
3636 return *def_var;
3638 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
3639 FOR_EACH_SSA_DEF_OPERAND (def_var, gsi_stmt (gsi), op_iter, SSA_OP_DEF)
3640 if (SSA_NAME_VAR (*def_var) == var)
3641 return *def_var;
3643 for (gsi = gsi_start_phis (bb); !gsi_end_p(gsi); gsi_next (&gsi))
3645 phi = gsi_stmt (gsi);
3646 if (SSA_NAME_VAR (PHI_RESULT (phi)) == var)
3647 return PHI_RESULT (phi);
3650 return NULL;
3653 /* Recursive helper. */
3655 static tree
3656 find_vdef_for_var_1 (basic_block bb, struct pointer_set_t *visited, tree var)
3658 tree result = NULL;
3659 edge_iterator ei;
3660 edge pred_edge;
3662 if (pointer_set_contains (visited, bb))
3663 return NULL;
3665 pointer_set_insert (visited, bb);
3666 result = find_vdef_for_var_in_bb (bb, var);
3668 if (!result)
3669 FOR_EACH_EDGE (pred_edge, ei, bb->preds)
3670 if (!result)
3671 result = find_vdef_for_var_1 (pred_edge->src, visited, var);
3673 return result;
3676 /* Finds a virtual definition for variable VAR. */
3678 static tree
3679 find_vdef_for_var (basic_block bb, tree var)
3681 struct pointer_set_t *visited = pointer_set_create ();
3682 tree def = find_vdef_for_var_1 (bb, visited, var);
3684 pointer_set_destroy (visited);
3685 return def;
3688 /* Update the virtual phis after loop bodies are moved to new
3689 loops. */
3691 static void
3692 patch_phis_for_virtual_defs (void)
3694 int i;
3695 gimple phi;
3696 VEC (gimple, heap) *virtual_phis = collect_virtual_phis ();
3698 for (i = 0; VEC_iterate (gimple, virtual_phis, i, phi); i++)
3700 basic_block bb = gimple_bb (phi);
3701 edge_iterator ei;
3702 edge pred_edge;
3703 gimple_stmt_iterator gsi;
3704 gimple new_phi;
3705 tree phi_result = PHI_RESULT (phi);
3706 tree var = SSA_NAME_VAR (phi_result);
3708 new_phi = create_phi_node (phi_result, bb);
3709 SSA_NAME_DEF_STMT (phi_result) = new_phi;
3711 FOR_EACH_EDGE (pred_edge, ei, bb->preds)
3713 tree def = find_vdef_for_var (pred_edge->src, var);
3715 if (def)
3716 add_phi_arg (new_phi, def, pred_edge);
3717 else
3718 add_phi_arg (new_phi, gimple_default_def (cfun, var), pred_edge);
3721 gsi = gsi_for_stmt (phi);
3722 remove_phi_node (&gsi, false);
3726 /* Mark the original loops of SCOP for removal, replacing their header
3727 field with NULL. */
3729 static void
3730 mark_old_loops (scop_p scop)
3732 int i;
3733 struct loop *loop;
3735 for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop); i++)
3737 loop->header = NULL;
3738 loop->latch = NULL;
3742 /* Scan the loops and remove the ones that have been marked for
3743 removal. */
3745 static void
3746 remove_dead_loops (void)
3748 struct loop *loop, *ploop;
3749 loop_iterator li;
3751 FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
3753 /* Remove only those loops that we marked to be removed with
3754 mark_old_loops. */
3755 if (loop->header)
3756 continue;
3758 while (loop->inner)
3760 ploop = loop->inner;
3761 flow_loop_tree_node_remove (ploop);
3762 flow_loop_tree_node_add (loop_outer (loop), ploop);
3765 /* Remove the loop and free its data. */
3766 delete_loop (loop);
3770 /* Returns true when it is possible to generate code for this STMT.
3771 For the moment we cannot generate code when Cloog decides to
3772 duplicate a statement, as we do not do a copy, but a move.
3773 USED_BASIC_BLOCKS records the blocks that have already been seen.
3774 We return false if we have to generate code twice for the same
3775 block. */
3777 static bool
3778 can_generate_code_stmt (struct clast_stmt *stmt,
3779 struct pointer_set_t *used_basic_blocks)
3781 if (!stmt)
3782 return true;
3784 if (CLAST_STMT_IS_A (stmt, stmt_root))
3785 return can_generate_code_stmt (stmt->next, used_basic_blocks);
3787 if (CLAST_STMT_IS_A (stmt, stmt_user))
3789 CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
3790 graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
3792 if (pointer_set_contains (used_basic_blocks, gbb))
3793 return false;
3794 pointer_set_insert (used_basic_blocks, gbb);
3795 return can_generate_code_stmt (stmt->next, used_basic_blocks);
3798 if (CLAST_STMT_IS_A (stmt, stmt_for))
3799 return can_generate_code_stmt (((struct clast_for *) stmt)->body,
3800 used_basic_blocks)
3801 && can_generate_code_stmt (stmt->next, used_basic_blocks);
3803 if (CLAST_STMT_IS_A (stmt, stmt_guard))
3804 return can_generate_code_stmt (((struct clast_guard *) stmt)->then,
3805 used_basic_blocks);
3807 if (CLAST_STMT_IS_A (stmt, stmt_block))
3808 return can_generate_code_stmt (((struct clast_block *) stmt)->body,
3809 used_basic_blocks)
3810 && can_generate_code_stmt (stmt->next, used_basic_blocks);
3812 return false;
3815 /* Returns true when it is possible to generate code for this STMT. */
3817 static bool
3818 can_generate_code (struct clast_stmt *stmt)
3820 bool result;
3821 struct pointer_set_t *used_basic_blocks = pointer_set_create ();
3823 result = can_generate_code_stmt (stmt, used_basic_blocks);
3824 pointer_set_destroy (used_basic_blocks);
3825 return result;
3828 /* Skip any definition that is a phi node with a single phi def. */
3830 static tree
3831 skip_phi_defs (tree ssa_name)
3833 tree result = ssa_name;
3834 gimple def_stmt = SSA_NAME_DEF_STMT (ssa_name);
3836 if (gimple_code (def_stmt) == GIMPLE_PHI
3837 && gimple_phi_num_args (def_stmt) == 1)
3838 result = skip_phi_defs (gimple_phi_arg(def_stmt,0)->def);
3840 return result;
3843 /* Returns a VEC containing the phi-arg defs coming from SCOP_EXIT in
3844 the destination block of SCOP_EXIT. */
3846 static VEC (tree, heap) *
3847 collect_scop_exit_phi_args (edge scop_exit)
3849 VEC (tree, heap) *phi_args = VEC_alloc (tree, heap, 1);
3850 gimple_stmt_iterator gsi;
3852 for (gsi = gsi_start_phis (scop_exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
3854 gimple phi = gsi_stmt (gsi);
3855 tree phi_arg = skip_phi_defs(PHI_ARG_DEF_FROM_EDGE (phi, scop_exit));
3857 VEC_safe_push (tree, heap, phi_args, phi_arg);
3860 return phi_args;
3863 /* Patches (adds) PHI_ARGS to the phi nodes in SCOP_EXIT destination. */
3865 static void
3866 patch_scop_exit_phi_args (edge scop_exit,
3867 VEC (tree, heap) *phi_args)
3869 int i = 0;
3870 gimple_stmt_iterator gsi;
3872 for (gsi = gsi_start_phis (scop_exit->dest); !gsi_end_p (gsi);
3873 gsi_next (&gsi), i++)
3875 tree def = VEC_index (tree, phi_args, i);
3876 gimple phi = gsi_stmt (gsi);
3878 gcc_assert (PHI_ARG_DEF_FROM_EDGE (phi, scop_exit) == NULL);
3880 add_phi_arg (phi, def, scop_exit);
3884 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
3885 the given SCOP. */
3887 static void
3888 gloog (scop_p scop, struct clast_stmt *stmt)
3890 edge new_scop_exit_edge = NULL;
3891 basic_block scop_exit = SCOP_EXIT (scop);
3892 VEC (tree, heap)* phi_args =
3893 collect_scop_exit_phi_args (SESE_EXIT (SCOP_REGION (scop)));
3894 VEC (name_tree, heap) *ivstack = VEC_alloc (name_tree, heap, 10);
3895 edge construction_edge = SESE_ENTRY (SCOP_REGION (scop));
3896 basic_block old_scop_exit_idom = get_immediate_dominator (CDI_DOMINATORS,
3897 scop_exit);
3899 if (!can_generate_code (stmt))
3901 cloog_clast_free (stmt);
3902 return;
3905 new_scop_exit_edge = translate_clast (scop,
3906 construction_edge->src->loop_father,
3907 stmt, construction_edge, &ivstack);
3908 redirect_edge_succ (new_scop_exit_edge, scop_exit);
3909 if (!old_scop_exit_idom
3910 || !dominated_by_p (CDI_DOMINATORS, SCOP_ENTRY (scop),
3911 old_scop_exit_idom)
3912 || SCOP_ENTRY (scop) == old_scop_exit_idom)
3913 set_immediate_dominator (CDI_DOMINATORS,
3914 new_scop_exit_edge->dest,
3915 new_scop_exit_edge->src);
3917 cloog_clast_free (stmt);
3919 if (new_scop_exit_edge->dest == EXIT_BLOCK_PTR)
3920 new_scop_exit_edge->flags = 0;
3922 find_unreachable_blocks ();
3923 delete_unreachable_blocks ();
3924 patch_phis_for_virtual_defs ();
3925 patch_scop_exit_phi_args (new_scop_exit_edge, phi_args);
3926 mark_old_loops (scop);
3927 remove_dead_loops ();
3928 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
3930 #ifdef ENABLE_CHECKING
3931 verify_loop_structure ();
3932 verify_dominators (CDI_DOMINATORS);
3933 verify_ssa (false);
3934 #endif
3937 /* Returns the number of data references in SCOP. */
3939 static int
3940 nb_data_refs_in_scop (scop_p scop)
3942 int i;
3943 graphite_bb_p gbb;
3944 int res = 0;
3946 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++)
3947 res += VEC_length (data_reference_p, GBB_DATA_REFS (gbb));
3949 return res;
3952 /* Check if a graphite bb can be ignored in graphite. We ignore all
3953 bbs, that only contain code, that will be eliminated later.
3955 TODO: - Move PHI nodes and scalar variables out of these bbs, that only
3956 remain conditions and induction variables. */
3958 static bool
3959 gbb_can_be_ignored (graphite_bb_p gb)
3961 gimple_stmt_iterator gsi;
3962 scop_p scop = GBB_SCOP (gb);
3963 loop_p loop = GBB_BB (gb)->loop_father;
3965 if (VEC_length (data_reference_p, GBB_DATA_REFS(gb)))
3966 return false;
3968 /* Check statements. */
3969 for (gsi = gsi_start_bb (GBB_BB (gb)); !gsi_end_p (gsi); gsi_next (&gsi))
3971 gimple stmt = gsi_stmt (gsi);
3972 switch (gimple_code (stmt))
3974 /* Control flow expressions can be ignored, as they are
3975 represented in the iteration domains and will be
3976 regenerated by graphite. */
3977 case GIMPLE_COND:
3978 case GIMPLE_GOTO:
3979 case GIMPLE_SWITCH:
3980 break;
3982 /* Scalar variables can be ignored, if we can regenerate
3983 them later using their scalar evolution function.
3984 XXX: Just a heuristic, that needs further investigation. */
3985 case GIMPLE_ASSIGN:
3987 tree var = gimple_assign_lhs (stmt);
3988 var = analyze_scalar_evolution (loop, var);
3989 var = instantiate_scev (block_before_scop (scop), loop, var);
3991 if (TREE_CODE (var) == SCEV_NOT_KNOWN)
3992 return false;
3994 break;
3996 /* Otherwise not ignoreable. */
3997 default:
3998 return false;
4002 return true;
4005 /* Remove all ignoreable gbbs from SCOP. */
4007 static void
4008 scop_remove_ignoreable_gbbs (scop_p scop)
4010 graphite_bb_p gb;
4011 int i;
4013 int max_schedule = scop_max_loop_depth (scop) + 1;
4014 lambda_vector last_schedule = lambda_vector_new (max_schedule);
4015 lambda_vector_clear (last_schedule, max_schedule);
4017 /* Update schedules. */
4018 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
4020 int nb_loops = gbb_nb_loops (gb);
4022 if (GBB_STATIC_SCHEDULE (gb) [nb_loops] == 0)
4023 last_schedule [nb_loops] = 0;
4025 if (gbb_can_be_ignored (gb))
4027 /* Mark gbb for remove. */
4028 bitmap_clear_bit (SCOP_BBS_B (scop), gb->bb->index);
4029 GBB_SCOP (gb) = NULL;
4030 last_schedule [nb_loops]--;
4032 else
4033 lambda_vector_add (GBB_STATIC_SCHEDULE (gb), last_schedule,
4034 GBB_STATIC_SCHEDULE (gb), nb_loops + 1);
4037 /* Remove gbbs. */
4038 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
4039 if (GBB_SCOP (gb) == NULL)
4041 VEC_unordered_remove (graphite_bb_p, SCOP_BBS (scop), i);
4042 free_graphite_bb (gb);
4043 /* XXX: Hackish? But working. */
4044 i--;
4047 graphite_sort_gbbs (scop);
4050 /* Move the loop at index LOOP and insert it before index NEW_LOOP_POS.
4051 This transformartion is only valid, if the loop nest between i and k is
4052 perfectly nested. Therefore we do not need to change the static schedule.
4054 Example:
4056 for (i = 0; i < 50; i++)
4057 for (j ...)
4058 for (k = 5; k < 100; k++)
4061 To move k before i use:
4063 graphite_trans_bb_move_loop (A, 2, 0)
4065 for (k = 5; k < 100; k++)
4066 for (i = 0; i < 50; i++)
4067 for (j ...)
4070 And to move k back:
4072 graphite_trans_bb_move_loop (A, 0, 2)
4074 This function does not check the validity of interchanging loops.
4075 This should be checked before calling this function. */
4077 static void
4078 graphite_trans_bb_move_loop (graphite_bb_p gb, int loop,
4079 int new_loop_pos)
4081 CloogMatrix *domain = GBB_DOMAIN (gb);
4082 int row, j;
4083 loop_p tmp_loop_p;
4085 gcc_assert (loop < gbb_nb_loops (gb)
4086 && new_loop_pos < gbb_nb_loops (gb));
4088 /* Update LOOPS vector. */
4089 tmp_loop_p = VEC_index (loop_p, GBB_LOOPS (gb), loop);
4090 VEC_ordered_remove (loop_p, GBB_LOOPS (gb), loop);
4091 VEC_safe_insert (loop_p, heap, GBB_LOOPS (gb), new_loop_pos, tmp_loop_p);
4093 /* Move the domain columns. */
4094 if (loop < new_loop_pos)
4095 for (row = 0; row < domain->NbRows; row++)
4097 Value tmp;
4098 value_init (tmp);
4099 value_assign (tmp, domain->p[row][loop + 1]);
4101 for (j = loop ; j < new_loop_pos - 1; j++)
4102 value_assign (domain->p[row][j + 1], domain->p[row][j + 2]);
4104 value_assign (domain->p[row][new_loop_pos], tmp);
4105 value_clear (tmp);
4107 else
4108 for (row = 0; row < domain->NbRows; row++)
4110 Value tmp;
4111 value_init (tmp);
4112 value_assign (tmp, domain->p[row][loop + 1]);
4114 for (j = loop ; j > new_loop_pos; j--)
4115 value_assign (domain->p[row][j + 1], domain->p[row][j]);
4117 value_assign (domain->p[row][new_loop_pos + 1], tmp);
4118 value_clear (tmp);
4122 /* Get the index of the column representing constants in the DOMAIN
4123 matrix. */
4125 static int
4126 const_column_index (CloogMatrix *domain)
4128 return domain->NbColumns - 1;
4132 /* Get the first index that is positive or negative, determined
4133 following the value of POSITIVE, in matrix DOMAIN in COLUMN. */
4135 static int
4136 get_first_matching_sign_row_index (CloogMatrix *domain, int column,
4137 bool positive)
4139 int row;
4141 for (row = 0; row < domain->NbRows; row++)
4143 int val = value_get_si (domain->p[row][column]);
4145 if (val > 0 && positive)
4146 return row;
4148 else if (val < 0 && !positive)
4149 return row;
4152 gcc_unreachable ();
4155 /* Get the lower bound of COLUMN in matrix DOMAIN. */
4157 static int
4158 get_lower_bound_row (CloogMatrix *domain, int column)
4160 return get_first_matching_sign_row_index (domain, column, true);
4163 /* Get the upper bound of COLUMN in matrix DOMAIN. */
4165 static int
4166 get_upper_bound_row (CloogMatrix *domain, int column)
4168 return get_first_matching_sign_row_index (domain, column, false);
4171 /* Get the lower bound of LOOP. */
4173 static void
4174 get_lower_bound (CloogMatrix *domain, int loop, Value lower_bound_result)
4176 int lower_bound_row = get_lower_bound_row (domain, loop);
4177 value_init (lower_bound_result);
4178 value_assign (lower_bound_result,
4179 domain->p[lower_bound_row][const_column_index(domain)]);
4182 /* Get the upper bound of LOOP. */
4184 static void
4185 get_upper_bound (CloogMatrix *domain, int loop, Value upper_bound_result)
4187 int upper_bound_row = get_upper_bound_row (domain, loop);
4188 value_init (upper_bound_result);
4189 value_assign (upper_bound_result,
4190 domain->p[upper_bound_row][const_column_index(domain)]);
4193 /* Strip mines the loop of BB at the position LOOP_DEPTH with STRIDE.
4194 Always valid, but not always a performance improvement. */
4196 static void
4197 graphite_trans_bb_strip_mine (graphite_bb_p gb, int loop_depth, int stride)
4199 int row, col;
4201 CloogMatrix *domain = GBB_DOMAIN (gb);
4202 CloogMatrix *new_domain = cloog_matrix_alloc (domain->NbRows + 3,
4203 domain->NbColumns + 1);
4205 int col_loop_old = loop_depth + 2;
4206 int col_loop_strip = col_loop_old - 1;
4208 Value old_lower_bound;
4209 Value old_upper_bound;
4212 gcc_assert (loop_depth <= gbb_nb_loops (gb) - 1);
4214 VEC_safe_insert (loop_p, heap, GBB_LOOPS (gb), loop_depth, NULL);
4216 GBB_DOMAIN (gb) = new_domain;
4219 nrows = 4, ncols = 4
4220 eq i j c
4221 1 1 0 0
4222 1 -1 0 99
4223 1 0 1 0
4224 1 0 -1 99
4227 /* Move domain. */
4228 for (row = 0; row < domain->NbRows; row++)
4229 for (col = 0; col < domain->NbColumns; col++)
4230 if (col <= loop_depth)
4232 value_assign (new_domain->p[row][col], domain->p[row][col]);
4234 else
4236 value_assign (new_domain->p[row][col + 1], domain->p[row][col]);
4241 nrows = 6, ncols = 5
4242 outer inner
4243 eq i jj j c
4244 1 1 0 0 0
4245 1 -1 0 0 99
4246 1 0 0 1 0
4247 1 0 0 -1 99
4248 0 0 0 0 0
4249 0 0 0 0 0
4250 0 0 0 0 0
4253 row = domain->NbRows;
4255 /* Add outer loop. */
4257 get_lower_bound (new_domain, col_loop_old, old_lower_bound);
4258 get_upper_bound (new_domain, col_loop_old, old_upper_bound);
4260 /* Set Lower Bound */
4261 value_set_si (new_domain->p[row][0], 1);
4262 value_set_si (new_domain->p[row][col_loop_strip], 1);
4263 value_assign (new_domain->p[row][const_column_index (new_domain)],
4264 old_lower_bound);
4265 row++;
4270 eq i jj j c
4271 1 1 0 0 0
4272 1 -1 0 0 99
4273 1 0 0 1 0 -
4274 1 0 0 -1 99 | copy old lower bound
4275 1 0 1 0 0 <-
4276 0 0 0 0 0
4277 0 0 0 0 0
4281 Value new_upper_bound;
4282 Value strip_size_value;
4284 value_init (new_upper_bound);
4286 value_init (strip_size_value);
4287 value_set_si (strip_size_value, (int) stride);
4290 value_pdivision(new_upper_bound,old_upper_bound,strip_size_value);
4291 value_add_int (new_upper_bound, new_upper_bound, 1);
4293 /* Set Upper Bound */
4294 value_set_si (new_domain->p[row][0], 1);
4295 value_set_si (new_domain->p[row][col_loop_strip], -1);
4296 value_assign (new_domain->p[row][const_column_index (new_domain)],
4297 new_upper_bound);
4298 row++;
4302 eq i jj j c
4303 1 1 0 0 0
4304 1 -1 0 0 99
4305 1 0 0 1 0
4306 1 0 0 -1 99
4307 1 0 1 0 0
4308 1 0 -1 0 25 (divide old upper bound with stride)
4309 0 0 0 0 0
4313 row = get_lower_bound_row (new_domain, col_loop_old);
4314 /* Add local variable to keep linear representation. */
4315 value_set_si (new_domain->p[row][0], 1);
4316 value_set_si (new_domain->p[row][const_column_index (new_domain)],0);
4317 value_set_si (new_domain->p[row][col_loop_old], 1);
4318 value_set_si (new_domain->p[row][col_loop_strip], -1*((int)stride));
4323 eq i jj j c
4324 1 1 0 0 0
4325 1 -1 0 0 99
4326 1 0 -1 1 0
4327 1 0 0 -1 99
4328 1 0 1 0 0
4329 1 0 -1 0 25 (divide old upper bound with stride)
4330 0 0 0 0 0
4334 row = new_domain->NbRows-1;
4336 value_set_si (new_domain->p[row][0], 1);
4337 value_set_si (new_domain->p[row][col_loop_old], -1);
4338 value_set_si (new_domain->p[row][col_loop_strip], stride);
4339 value_set_si (new_domain->p[row][const_column_index (new_domain)],
4340 stride-1);
4345 eq i jj j c
4346 1 1 0 0 0 i >= 0
4347 1 -1 0 0 99 99 >= i
4348 1 0 -4 1 0 j >= 4*jj
4349 1 0 0 -1 99 99 >= j
4350 1 0 1 0 0 jj >= 0
4351 1 0 -1 0 25 25 >= jj
4352 0 0 4 -1 3 jj+3 >= j
4355 cloog_matrix_free (domain);
4357 /* Update static schedule. */
4359 int i;
4360 int nb_loops = gbb_nb_loops (gb);
4361 lambda_vector new_schedule = lambda_vector_new (nb_loops + 1);
4363 for (i = 0; i <= loop_depth; i++)
4364 new_schedule[i] = GBB_STATIC_SCHEDULE (gb)[i];
4366 for (i = loop_depth + 1; i <= nb_loops - 2; i++)
4367 new_schedule[i + 2] = GBB_STATIC_SCHEDULE (gb)[i];
4369 GBB_STATIC_SCHEDULE (gb) = new_schedule;
4373 /* Returns true when the strip mining of LOOP_INDEX by STRIDE is
4374 profitable or undecidable. GB is the statement around which the
4375 loops will be strip mined. */
4377 static bool
4378 strip_mine_profitable_p (graphite_bb_p gb, int stride,
4379 int loop_index)
4381 bool res = true;
4382 edge exit = NULL;
4383 tree niter;
4384 loop_p loop;
4385 long niter_val;
4387 loop = VEC_index (loop_p, GBB_LOOPS (gb), loop_index);
4388 exit = single_exit (loop);
4390 niter = find_loop_niter (loop, &exit);
4391 if (niter == chrec_dont_know
4392 || TREE_CODE (niter) != INTEGER_CST)
4393 return true;
4395 niter_val = int_cst_value (niter);
4397 if (niter_val < stride)
4399 res = false;
4400 if (dump_file && (dump_flags & TDF_DETAILS))
4402 fprintf (dump_file, "\nStrip Mining is not profitable for loop %d:",
4403 loop_index);
4404 fprintf (dump_file, "number of iterations is too low.\n");
4408 return res;
4411 /* Determines when the interchange of LOOP_A and LOOP_B belonging to
4412 SCOP is legal. */
4414 static bool
4415 is_interchange_valid (scop_p scop, int loop_a, int loop_b)
4417 bool res;
4418 VEC (ddr_p, heap) *dependence_relations;
4419 VEC (data_reference_p, heap) *datarefs;
4421 struct loop *nest = VEC_index (loop_p, SCOP_LOOP_NEST (scop), loop_a);
4422 int depth = perfect_loop_nest_depth (nest);
4423 lambda_trans_matrix trans;
4425 gcc_assert (loop_a < loop_b);
4427 dependence_relations = VEC_alloc (ddr_p, heap, 10 * 10);
4428 datarefs = VEC_alloc (data_reference_p, heap, 10);
4430 if (!compute_data_dependences_for_loop (nest, true, &datarefs,
4431 &dependence_relations))
4432 return false;
4434 if (dump_file && (dump_flags & TDF_DETAILS))
4435 dump_ddrs (dump_file, dependence_relations);
4437 trans = lambda_trans_matrix_new (depth, depth);
4438 lambda_matrix_id (LTM_MATRIX (trans), depth);
4440 lambda_matrix_row_exchange (LTM_MATRIX (trans), 0, loop_b - loop_a);
4442 if (!lambda_transform_legal_p (trans, depth, dependence_relations))
4444 lambda_matrix_row_exchange (LTM_MATRIX (trans), 0, loop_b - loop_a);
4445 res = false;
4447 else
4448 res = true;
4450 free_dependence_relations (dependence_relations);
4451 free_data_refs (datarefs);
4452 return res;
4455 /* Loop block the LOOPS innermost loops of GB with stride size STRIDE.
4457 Example
4459 for (i = 0; i <= 50; i++=4)
4460 for (k = 0; k <= 100; k++=4)
4461 for (l = 0; l <= 200; l++=4)
4464 To strip mine the two inner most loops with stride = 4 call:
4466 graphite_trans_bb_block (A, 4, 2)
4468 for (i = 0; i <= 50; i++)
4469 for (kk = 0; kk <= 100; kk+=4)
4470 for (ll = 0; ll <= 200; ll+=4)
4471 for (k = kk; k <= min (100, kk + 3); k++)
4472 for (l = ll; l <= min (200, ll + 3); l++)
4476 static bool
4477 graphite_trans_bb_block (graphite_bb_p gb, int stride, int loops)
4479 int i, j;
4480 int nb_loops = gbb_nb_loops (gb);
4481 int start = nb_loops - loops;
4482 scop_p scop = GBB_SCOP (gb);
4484 gcc_assert (scop_contains_loop (scop, gbb_loop (gb)));
4486 for (i = start ; i < nb_loops; i++)
4487 for (j = i + 1; j < nb_loops; j++)
4488 if (!is_interchange_valid (scop, i, j))
4490 if (dump_file && (dump_flags & TDF_DETAILS))
4491 fprintf (dump_file,
4492 "\nInterchange not valid for loops %d and %d:\n", i, j);
4493 return false;
4495 else if (dump_file && (dump_flags & TDF_DETAILS))
4496 fprintf (dump_file,
4497 "\nInterchange valid for loops %d and %d:\n", i, j);
4499 /* Check if strip mining is profitable for every loop. */
4500 for (i = 0; i < nb_loops - start; i++)
4501 if (!strip_mine_profitable_p (gb, stride, start + i))
4502 return false;
4504 /* Strip mine loops. */
4505 for (i = 0; i < nb_loops - start; i++)
4506 graphite_trans_bb_strip_mine (gb, start + 2 * i, stride);
4508 /* Interchange loops. */
4509 for (i = 1; i < nb_loops - start; i++)
4510 graphite_trans_bb_move_loop (gb, start + 2 * i, start + i);
4512 return true;
4515 /* Loop block LOOPS innermost loops of a loop nest. BBS represent the
4516 basic blocks that belong to the loop nest to be blocked. */
4518 static bool
4519 graphite_trans_loop_block (VEC (graphite_bb_p, heap) *bbs, int loops)
4521 graphite_bb_p gb;
4522 int i;
4523 bool transform_done = false;
4525 /* TODO: - Calculate the stride size automatically. */
4526 int stride_size = 64;
4528 for (i = 0; VEC_iterate (graphite_bb_p, bbs, i, gb); i++)
4529 transform_done |= graphite_trans_bb_block (gb, stride_size, loops);
4531 return transform_done;
4534 /* Loop block all basic blocks of SCOP. */
4536 static bool
4537 graphite_trans_scop_block (scop_p scop)
4539 graphite_bb_p gb;
4540 int i, j;
4541 int last_nb_loops;
4542 int nb_loops;
4543 bool perfect = true;
4544 bool transform_done = false;
4546 VEC (graphite_bb_p, heap) *bbs = VEC_alloc (graphite_bb_p, heap, 3);
4547 int max_schedule = scop_max_loop_depth (scop) + 1;
4548 lambda_vector last_schedule = lambda_vector_new (max_schedule);
4550 if (VEC_length (graphite_bb_p, SCOP_BBS (scop)) == 0)
4551 return transform_done;
4553 /* Get the data of the first bb. */
4554 gb = VEC_index (graphite_bb_p, SCOP_BBS (scop), 0);
4555 last_nb_loops = gbb_nb_loops (gb);
4556 lambda_vector_copy (GBB_STATIC_SCHEDULE (gb), last_schedule,
4557 last_nb_loops + 1);
4558 VEC_safe_push (graphite_bb_p, heap, bbs, gb);
4560 for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
4562 /* We did the first bb before. */
4563 if (i == 0)
4564 continue;
4566 nb_loops = gbb_nb_loops (gb);
4568 /* If the number of loops is unchanged and only the last element of the
4569 schedule changes, we stay in the loop nest. */
4570 if (nb_loops == last_nb_loops
4571 && (last_schedule [nb_loops + 1]
4572 != GBB_STATIC_SCHEDULE (gb)[nb_loops + 1]))
4574 VEC_safe_push (graphite_bb_p, heap, bbs, gb);
4575 continue;
4578 /* Otherwise, we left the innermost loop. So check, if the last bb was in
4579 a perfect loop nest and how many loops are contained in this perfect
4580 loop nest.
4582 Count the number of zeros from the end of the schedule. They are the
4583 number of surrounding loops.
4585 Example:
4586 last_bb 2 3 2 0 0 0 0 3
4587 bb 2 4 0
4588 <------ j = 4
4590 last_bb 2 3 2 0 0 0 0 3
4591 bb 2 3 2 0 1
4592 <-- j = 2
4594 If there is no zero, there were other bbs in outer loops and the loop
4595 nest is not perfect. */
4596 for (j = last_nb_loops - 1; j >= 0; j--)
4598 if (last_schedule [j] != 0
4599 || (j <= nb_loops && GBB_STATIC_SCHEDULE (gb)[j] == 1))
4601 j--;
4602 break;
4606 j++;
4608 /* Found perfect loop nest. */
4609 if (perfect && last_nb_loops - j > 0)
4610 transform_done |= graphite_trans_loop_block (bbs, last_nb_loops - j);
4612 /* Check if we start with a new loop.
4614 Example:
4616 last_bb 2 3 2 0 0 0 0 3
4617 bb 2 3 2 0 0 1 0
4619 Here we start with the loop "2 3 2 0 0 1"
4621 last_bb 2 3 2 0 0 0 0 3
4622 bb 2 3 2 0 0 1
4624 But here not, so the loop nest can never be perfect. */
4626 perfect = (GBB_STATIC_SCHEDULE (gb)[nb_loops] == 0);
4628 /* Update the last_bb infos. We do not do that for the bbs in the same
4629 loop, as the data we use is not changed. */
4630 last_nb_loops = nb_loops;
4631 lambda_vector_copy (GBB_STATIC_SCHEDULE (gb), last_schedule,
4632 nb_loops + 1);
4633 VEC_truncate (graphite_bb_p, bbs, 0);
4634 VEC_safe_push (graphite_bb_p, heap, bbs, gb);
4637 /* Check if the last loop nest was perfect. It is the same check as above,
4638 but the comparison with the next bb is missing. */
4639 for (j = last_nb_loops - 1; j >= 0; j--)
4640 if (last_schedule [j] != 0)
4642 j--;
4643 break;
4646 j++;
4648 /* Found perfect loop nest. */
4649 if (last_nb_loops - j > 0)
4650 transform_done |= graphite_trans_loop_block (bbs, last_nb_loops - j);
4651 VEC_free (graphite_bb_p, heap, bbs);
4653 if (dump_file && (dump_flags & TDF_DETAILS))
4654 fprintf (dump_file, "\nLoop blocked.\n");
4656 return transform_done;
4659 /* Apply graphite transformations to all the basic blocks of SCOP. */
4661 static bool
4662 graphite_apply_transformations (scop_p scop)
4664 bool transform_done = false;
4666 /* Sort the list of bbs. Keep them always sorted. */
4667 graphite_sort_gbbs (scop);
4668 scop_remove_ignoreable_gbbs (scop);
4670 if (flag_loop_block)
4671 transform_done = graphite_trans_scop_block (scop);
4673 #if 0 && ENABLE_CHECKING
4674 /* When the compiler is configured with ENABLE_CHECKING, always
4675 generate code, even if we did not apply any transformation. This
4676 provides better code coverage of the backend code generator.
4678 This also allows to check the performance for an identity
4679 transform: GIMPLE -> GRAPHITE -> GIMPLE; and the output of CLooG
4680 is never an identity: if CLooG optimizations are not disabled,
4681 the CLooG output is always optimized in control flow. */
4682 transform_done = true;
4683 #endif
4685 return transform_done;
4688 /* We limit all SCoPs to SCoPs, that are completely surrounded by a loop.
4690 Example:
4692 for (i |
4694 for (j | SCoP 1
4695 for (k |
4698 * SCoP frontier, as this line is not surrounded by any loop. *
4700 for (l | SCoP 2
4702 This is necessary as scalar evolution and parameter detection need a
4703 outermost loop to initialize parameters correctly.
4705 TODO: FIX scalar evolution and parameter detection to allow mor flexible
4706 SCoP frontiers. */
4708 static void
4709 limit_scops (void)
4711 VEC (scop_p, heap) *new_scops = VEC_alloc (scop_p, heap, 3);
4712 int i;
4713 scop_p scop;
4715 for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
4717 int j;
4718 loop_p loop;
4719 build_scop_bbs (scop);
4720 build_scop_loop_nests (scop);
4722 for (j = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), j, loop); j++)
4723 if (!loop_in_scop_p (loop_outer (loop), scop))
4725 scop_p n_scop = new_scop (loop_preheader_edge (loop));
4726 end_scop (n_scop, single_exit (loop), false);
4727 VEC_safe_push (scop_p, heap, new_scops, n_scop);
4731 free_scops (current_scops);
4732 current_scops = new_scops;
4735 /* Perform a set of linear transforms on the loops of the current
4736 function. */
4738 void
4739 graphite_transform_loops (void)
4741 int i;
4742 scop_p scop;
4744 if (number_of_loops () <= 1)
4745 return;
4747 current_scops = VEC_alloc (scop_p, heap, 3);
4749 calculate_dominance_info (CDI_DOMINATORS);
4750 calculate_dominance_info (CDI_POST_DOMINATORS);
4752 if (dump_file && (dump_flags & TDF_DETAILS))
4753 fprintf (dump_file, "Graphite loop transformations \n");
4755 cloog_initialize ();
4756 build_scops ();
4757 limit_scops ();
4759 if (dump_file && (dump_flags & TDF_DETAILS))
4760 fprintf (dump_file, "\nnumber of SCoPs: %d\n",
4761 VEC_length (scop_p, current_scops));
4763 for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
4765 build_scop_bbs (scop);
4766 build_scop_loop_nests (scop);
4767 build_scop_canonical_schedules (scop);
4768 build_bb_loops (scop);
4769 find_scop_parameters (scop);
4770 build_scop_context (scop);
4772 if (dump_file && (dump_flags & TDF_DETAILS))
4774 fprintf (dump_file, "\n(In SCoP %d:\n", i);
4775 fprintf (dump_file, "\nnumber of bbs: %d\n",
4776 VEC_length (graphite_bb_p, SCOP_BBS (scop)));
4777 fprintf (dump_file, "\nnumber of loops: %d)\n",
4778 VEC_length (loop_p, SCOP_LOOP_NEST (scop)));
4781 if (!build_scop_iteration_domain (scop))
4782 continue;
4784 build_scop_conditions (scop);
4785 build_scop_data_accesses (scop);
4787 if (dump_file && (dump_flags & TDF_DETAILS))
4789 int nbrefs = nb_data_refs_in_scop (scop);
4790 fprintf (dump_file, "\nnumber of data refs: %d\n", nbrefs);
4793 if (graphite_apply_transformations (scop))
4794 gloog (scop, find_transform (scop));
4797 /* Cleanup. */
4798 free_scops (current_scops);
4799 cloog_finalize ();
4802 #else /* If Cloog is not available: #ifndef HAVE_cloog. */
4804 void
4805 graphite_transform_loops (void)
4807 sorry ("Graphite loop optimizations cannot be used");
4810 #endif