1 /* Gimple Represented as Polyhedra.
2 Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <sebastian.pop@inria.fr>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This pass converts GIMPLE to GRAPHITE, performs some loop
22 transformations and then converts the resulting representation back
25 An early description of this pass can be found in the GCC Summit'06
26 paper "GRAPHITE: Polyhedral Analyses and Optimizations for GCC".
27 The wiki page http://gcc.gnu.org/wiki/Graphite contains pointers to
30 One important document to read is CLooG's internal manual:
31 http://repo.or.cz/w/cloog-ppl.git?a=blob_plain;f=doc/cloog.texi;hb=HEAD
32 that describes the data structure of loops used in this file, and
33 the functions that are used for transforming the code. */
37 #include "coretypes.h"
42 #include "basic-block.h"
43 #include "diagnostic.h"
44 #include "tree-flow.h"
46 #include "tree-dump.h"
49 #include "tree-chrec.h"
50 #include "tree-data-ref.h"
51 #include "tree-scalar-evolution.h"
52 #include "tree-pass.h"
54 #include "value-prof.h"
55 #include "pointer-set.h"
59 #include "cloog/cloog.h"
62 static VEC (scop_p
, heap
) *current_scops
;
64 /* Converts a GMP constant V to a tree and returns it. */
67 gmp_cst_to_tree (tree type
, Value v
)
69 return build_int_cst (type
, value_get_si (v
));
72 /* Debug the list of old induction variables for this SCOP. */
75 debug_oldivs (scop_p scop
)
80 fprintf (stderr
, "Old IVs:");
82 for (i
= 0; VEC_iterate (name_tree
, SCOP_OLDIVS (scop
), i
, oldiv
); i
++)
84 fprintf (stderr
, "(");
85 print_generic_expr (stderr
, oldiv
->t
, 0);
86 fprintf (stderr
, ", %s, %d)\n", oldiv
->name
, oldiv
->loop
->num
);
88 fprintf (stderr
, "\n");
91 /* Debug the loops around basic block GB. */
94 debug_loop_vec (graphite_bb_p gb
)
99 fprintf (stderr
, "Loop Vec:");
101 for (i
= 0; VEC_iterate (loop_p
, GBB_LOOPS (gb
), i
, loop
); i
++)
102 fprintf (stderr
, "%d: %d, ", i
, loop
? loop
->num
: -1);
104 fprintf (stderr
, "\n");
107 /* Returns true if stack ENTRY is a constant. */
110 iv_stack_entry_is_constant (iv_stack_entry
*entry
)
112 return entry
->kind
== iv_stack_entry_const
;
115 /* Returns true if stack ENTRY is an induction variable. */
118 iv_stack_entry_is_iv (iv_stack_entry
*entry
)
120 return entry
->kind
== iv_stack_entry_iv
;
123 /* Push (IV, NAME) on STACK. */
126 loop_iv_stack_push_iv (loop_iv_stack stack
, tree iv
, const char *name
)
128 iv_stack_entry
*entry
= XNEW (iv_stack_entry
);
129 name_tree named_iv
= XNEW (struct name_tree
);
132 named_iv
->name
= name
;
134 entry
->kind
= iv_stack_entry_iv
;
135 entry
->data
.iv
= named_iv
;
137 VEC_safe_push (iv_stack_entry_p
, heap
, *stack
, entry
);
140 /* Inserts a CONSTANT in STACK at INDEX. */
143 loop_iv_stack_insert_constant (loop_iv_stack stack
, int index
,
146 iv_stack_entry
*entry
= XNEW (iv_stack_entry
);
148 entry
->kind
= iv_stack_entry_const
;
149 entry
->data
.constant
= constant
;
151 VEC_safe_insert (iv_stack_entry_p
, heap
, *stack
, index
, entry
);
154 /* Pops and frees an element out of STACK. */
157 loop_iv_stack_pop (loop_iv_stack stack
)
159 iv_stack_entry_p entry
= VEC_pop (iv_stack_entry_p
, *stack
);
161 free (entry
->data
.iv
);
165 /* Get the IV at INDEX in STACK. */
168 loop_iv_stack_get_iv (loop_iv_stack stack
, int index
)
170 iv_stack_entry_p entry
= VEC_index (iv_stack_entry_p
, *stack
, index
);
171 iv_stack_entry_data data
= entry
->data
;
173 return iv_stack_entry_is_iv (entry
) ? data
.iv
->t
: data
.constant
;
176 /* Get the IV from its NAME in STACK. */
179 loop_iv_stack_get_iv_from_name (loop_iv_stack stack
, const char* name
)
182 iv_stack_entry_p entry
;
184 for (i
= 0; VEC_iterate (iv_stack_entry_p
, *stack
, i
, entry
); i
++)
186 name_tree iv
= entry
->data
.iv
;
187 if (!strcmp (name
, iv
->name
))
194 /* Prints on stderr the contents of STACK. */
197 debug_loop_iv_stack (loop_iv_stack stack
)
200 iv_stack_entry_p entry
;
203 fprintf (stderr
, "(");
205 for (i
= 0; VEC_iterate (iv_stack_entry_p
, *stack
, i
, entry
); i
++)
210 fprintf (stderr
, " ");
212 if (iv_stack_entry_is_iv (entry
))
214 name_tree iv
= entry
->data
.iv
;
215 fprintf (stderr
, "%s:", iv
->name
);
216 print_generic_expr (stderr
, iv
->t
, 0);
220 tree constant
= entry
->data
.constant
;
221 print_generic_expr (stderr
, constant
, 0);
222 fprintf (stderr
, ":");
223 print_generic_expr (stderr
, constant
, 0);
227 fprintf (stderr
, ")\n");
233 free_loop_iv_stack (loop_iv_stack stack
)
236 iv_stack_entry_p entry
;
238 for (i
= 0; VEC_iterate (iv_stack_entry_p
, *stack
, i
, entry
); i
++)
240 free (entry
->data
.iv
);
244 VEC_free (iv_stack_entry_p
, heap
, *stack
);
249 /* Structure containing the mapping between the CLooG's induction
250 variable and the type of the old induction variable. */
251 typedef struct ivtype_map_elt
254 const char *cloog_iv
;
257 /* Print to stderr the element ELT. */
260 debug_ivtype_elt (ivtype_map_elt elt
)
262 fprintf (stderr
, "(%s, ", elt
->cloog_iv
);
263 print_generic_expr (stderr
, elt
->type
, 0);
264 fprintf (stderr
, ")\n");
267 /* Helper function for debug_ivtype_map. */
270 debug_ivtype_map_1 (void **slot
, void *s ATTRIBUTE_UNUSED
)
272 struct ivtype_map_elt
*entry
= (struct ivtype_map_elt
*) *slot
;
273 debug_ivtype_elt (entry
);
277 /* Print to stderr all the elements of MAP. */
280 debug_ivtype_map (htab_t map
)
282 htab_traverse (map
, debug_ivtype_map_1
, NULL
);
285 /* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW. */
287 static inline ivtype_map_elt
288 new_ivtype_map_elt (const char *cloog_iv
, tree type
)
292 res
= XNEW (struct ivtype_map_elt
);
293 res
->cloog_iv
= cloog_iv
;
299 /* Computes a hash function for database element ELT. */
302 ivtype_map_elt_info (const void *elt
)
304 return htab_hash_pointer (((const struct ivtype_map_elt
*) elt
)->cloog_iv
);
307 /* Compares database elements E1 and E2. */
310 eq_ivtype_map_elts (const void *e1
, const void *e2
)
312 const struct ivtype_map_elt
*elt1
= (const struct ivtype_map_elt
*) e1
;
313 const struct ivtype_map_elt
*elt2
= (const struct ivtype_map_elt
*) e2
;
315 return (elt1
->cloog_iv
== elt2
->cloog_iv
);
320 /* Given a CLOOG_IV, returns the type that it should have in GCC land.
321 If the information is not available, i.e. in the case one of the
322 transforms created the loop, just return integer_type_node. */
325 gcc_type_for_cloog_iv (const char *cloog_iv
, graphite_bb_p gbb
)
327 struct ivtype_map_elt tmp
;
330 tmp
.cloog_iv
= cloog_iv
;
331 slot
= htab_find_slot (GBB_CLOOG_IV_TYPES (gbb
), &tmp
, NO_INSERT
);
334 return ((ivtype_map_elt
) *slot
)->type
;
336 return integer_type_node
;
339 /* Inserts constants derived from the USER_STMT argument list into the
340 STACK. This is needed to map old ivs to constants when loops have
344 loop_iv_stack_patch_for_consts (loop_iv_stack stack
,
345 struct clast_user_stmt
*user_stmt
)
347 struct clast_stmt
*t
;
349 CloogStatement
*cs
= user_stmt
->statement
;
350 graphite_bb_p gbb
= (graphite_bb_p
) cloog_statement_usr (cs
);
352 for (t
= user_stmt
->substitutions
; t
; t
= t
->next
)
354 struct clast_expr
*expr
= (struct clast_expr
*)
355 ((struct clast_assignment
*)t
)->RHS
;
356 struct clast_term
*term
= (struct clast_term
*) expr
;
358 /* FIXME: What should be done with expr_bin, expr_red? */
359 if (expr
->type
== expr_term
362 loop_p loop
= gbb_loop_at_index (gbb
, index
);
363 tree oldiv
= oldiv_for_loop (GBB_SCOP (gbb
), loop
);
364 tree type
= oldiv
? TREE_TYPE (oldiv
) : integer_type_node
;
365 tree value
= gmp_cst_to_tree (type
, term
->val
);
366 loop_iv_stack_insert_constant (stack
, index
, value
);
372 /* Removes all constants in the iv STACK. */
375 loop_iv_stack_remove_constants (loop_iv_stack stack
)
378 iv_stack_entry
*entry
;
380 for (i
= 0; VEC_iterate (iv_stack_entry_p
, *stack
, i
, entry
);)
382 if (iv_stack_entry_is_constant (entry
))
384 free (VEC_index (iv_stack_entry_p
, *stack
, i
));
385 VEC_ordered_remove (iv_stack_entry_p
, *stack
, i
);
392 /* Returns a new loop_to_cloog_loop_str structure. */
394 static inline struct loop_to_cloog_loop_str
*
395 new_loop_to_cloog_loop_str (int loop_num
,
397 CloogLoop
*cloog_loop
)
399 struct loop_to_cloog_loop_str
*result
;
401 result
= XNEW (struct loop_to_cloog_loop_str
);
402 result
->loop_num
= loop_num
;
403 result
->cloog_loop
= cloog_loop
;
404 result
->loop_position
= loop_position
;
409 /* Hash function for SCOP_LOOP2CLOOG_LOOP hash table. */
412 hash_loop_to_cloog_loop (const void *elt
)
414 return ((const struct loop_to_cloog_loop_str
*) elt
)->loop_num
;
417 /* Equality function for SCOP_LOOP2CLOOG_LOOP hash table. */
420 eq_loop_to_cloog_loop (const void *el1
, const void *el2
)
422 const struct loop_to_cloog_loop_str
*elt1
, *elt2
;
424 elt1
= (const struct loop_to_cloog_loop_str
*) el1
;
425 elt2
= (const struct loop_to_cloog_loop_str
*) el2
;
426 return elt1
->loop_num
== elt2
->loop_num
;
429 /* Compares two graphite bbs and returns an integer less than, equal to, or
430 greater than zero if the first argument is considered to be respectively
431 less than, equal to, or greater than the second.
432 We compare using the lexicographic order of the static schedules. */
435 gbb_compare (const void *p_1
, const void *p_2
)
437 const struct graphite_bb
*const gbb_1
438 = *(const struct graphite_bb
*const*) p_1
;
439 const struct graphite_bb
*const gbb_2
440 = *(const struct graphite_bb
*const*) p_2
;
442 return lambda_vector_compare (GBB_STATIC_SCHEDULE (gbb_1
),
443 gbb_nb_loops (gbb_1
) + 1,
444 GBB_STATIC_SCHEDULE (gbb_2
),
445 gbb_nb_loops (gbb_2
) + 1);
448 /* Sort graphite bbs in SCOP. */
451 graphite_sort_gbbs (scop_p scop
)
453 VEC (graphite_bb_p
, heap
) *bbs
= SCOP_BBS (scop
);
455 qsort (VEC_address (graphite_bb_p
, bbs
),
456 VEC_length (graphite_bb_p
, bbs
),
457 sizeof (graphite_bb_p
), gbb_compare
);
460 /* Dump conditions of a graphite basic block GBB on FILE. */
463 dump_gbb_conditions (FILE *file
, graphite_bb_p gbb
)
467 VEC (gimple
, heap
) *conditions
= GBB_CONDITIONS (gbb
);
469 if (VEC_empty (gimple
, conditions
))
472 fprintf (file
, "\tbb %d\t: cond = {", GBB_BB (gbb
)->index
);
474 for (i
= 0; VEC_iterate (gimple
, conditions
, i
, stmt
); i
++)
475 print_gimple_stmt (file
, stmt
, 0, 0);
477 fprintf (file
, "}\n");
480 /* Converts the graphite scheduling function into a cloog scattering
481 matrix. This scattering matrix is used to limit the possible cloog
482 output to valid programs in respect to the scheduling function.
484 SCATTERING_DIMENSIONS specifies the dimensionality of the scattering
485 matrix. CLooG 0.14.0 and previous versions require, that all scattering
486 functions of one CloogProgram have the same dimensionality, therefore we
487 allow to specify it. (Should be removed in future versions) */
490 schedule_to_scattering (graphite_bb_p gb
, int scattering_dimensions
)
493 scop_p scop
= GBB_SCOP (gb
);
495 int nb_iterators
= gbb_nb_loops (gb
);
497 /* The cloog scattering matrix consists of these colums:
499 scattering_dimensions cols = Scattering dimensions,
500 nb_iterators cols = bb's iterators,
501 scop_nb_params cols = Parameters,
506 scattering_dimensions = 5
516 s1 s2 s3 s4 s5 i p1 p2 1
517 1 0 0 0 0 0 0 0 -4 = 0
518 0 1 0 0 0 -1 0 0 0 = 0
519 0 0 1 0 0 0 0 0 -5 = 0 */
520 int nb_params
= scop_nb_params (scop
);
521 int nb_cols
= 1 + scattering_dimensions
+ nb_iterators
+ nb_params
+ 1;
522 int col_const
= nb_cols
- 1;
523 int col_iter_offset
= 1 + scattering_dimensions
;
525 CloogMatrix
*scat
= cloog_matrix_alloc (scattering_dimensions
, nb_cols
);
527 gcc_assert (scattering_dimensions
>= nb_iterators
* 2 + 1);
529 /* Initialize the identity matrix. */
530 for (i
= 0; i
< scattering_dimensions
; i
++)
531 value_set_si (scat
->p
[i
][i
+ 1], 1);
533 /* Textual order outside the first loop */
534 value_set_si (scat
->p
[0][col_const
], -GBB_STATIC_SCHEDULE (gb
)[0]);
536 /* For all surrounding loops. */
537 for (i
= 0; i
< nb_iterators
; i
++)
539 int schedule
= GBB_STATIC_SCHEDULE (gb
)[i
+ 1];
541 /* Iterations of this loop. */
542 value_set_si (scat
->p
[2 * i
+ 1][col_iter_offset
+ i
], -1);
544 /* Textual order inside this loop. */
545 value_set_si (scat
->p
[2 * i
+ 2][col_const
], -schedule
);
551 /* Print the schedules of GB to FILE with INDENT white spaces before.
552 VERBOSITY determines how verbose the code pretty printers are. */
555 print_graphite_bb (FILE *file
, graphite_bb_p gb
, int indent
, int verbosity
)
557 CloogMatrix
*scattering
;
560 fprintf (file
, "\nGBB (\n");
562 print_loops_bb (file
, GBB_BB (gb
), indent
+2, verbosity
);
566 fprintf (file
, " (domain: \n");
567 cloog_matrix_print (file
, GBB_DOMAIN (gb
));
568 fprintf (file
, " )\n");
571 if (GBB_STATIC_SCHEDULE (gb
))
573 fprintf (file
, " (static schedule: ");
574 print_lambda_vector (file
, GBB_STATIC_SCHEDULE (gb
),
575 gbb_nb_loops (gb
) + 1);
576 fprintf (file
, " )\n");
581 fprintf (file
, " (contained loops: \n");
582 for (i
= 0; VEC_iterate (loop_p
, GBB_LOOPS (gb
), i
, loop
); i
++)
584 fprintf (file
, " iterator %d => NULL \n", i
);
586 fprintf (file
, " iterator %d => loop %d \n", i
,
588 fprintf (file
, " )\n");
591 if (GBB_DATA_REFS (gb
))
592 dump_data_references (file
, GBB_DATA_REFS (gb
));
594 if (GBB_CONDITIONS (gb
))
596 fprintf (file
, " (conditions: \n");
597 dump_gbb_conditions (file
, gb
);
598 fprintf (file
, " )\n");
602 && GBB_STATIC_SCHEDULE (gb
))
604 fprintf (file
, " (scattering: \n");
605 scattering
= schedule_to_scattering (gb
, 2 * gbb_nb_loops (gb
) + 1);
606 cloog_matrix_print (file
, scattering
);
607 cloog_matrix_free (scattering
);
608 fprintf (file
, " )\n");
611 fprintf (file
, ")\n");
614 /* Print to STDERR the schedules of GB with VERBOSITY level. */
617 debug_gbb (graphite_bb_p gb
, int verbosity
)
619 print_graphite_bb (stderr
, gb
, 0, verbosity
);
623 /* Print SCOP to FILE. VERBOSITY determines how verbose the pretty
627 print_scop (FILE *file
, scop_p scop
, int verbosity
)
632 fprintf (file
, "\nSCoP_%d_%d (\n",
633 SCOP_ENTRY (scop
)->index
, SCOP_EXIT (scop
)->index
);
635 fprintf (file
, " (cloog: \n");
636 cloog_program_print (file
, SCOP_PROG (scop
));
637 fprintf (file
, " )\n");
644 for (i
= 0; VEC_iterate (graphite_bb_p
, SCOP_BBS (scop
), i
, gb
); i
++)
645 print_graphite_bb (file
, gb
, 0, verbosity
);
648 fprintf (file
, ")\n");
651 /* Print all the SCOPs to FILE. VERBOSITY determines how verbose the
652 code pretty printers are. */
655 print_scops (FILE *file
, int verbosity
)
660 for (i
= 0; VEC_iterate (scop_p
, current_scops
, i
, scop
); i
++)
661 print_scop (file
, scop
, verbosity
);
664 /* Debug SCOP. VERBOSITY determines how verbose the code pretty
668 debug_scop (scop_p scop
, int verbosity
)
670 print_scop (stderr
, scop
, verbosity
);
673 /* Debug all SCOPs from CURRENT_SCOPS. VERBOSITY determines how
674 verbose the code pretty printers are. */
677 debug_scops (int verbosity
)
679 print_scops (stderr
, verbosity
);
682 /* Pretty print to FILE the SCOP in DOT format. */
685 dot_scop_1 (FILE *file
, scop_p scop
)
690 basic_block entry
= SCOP_ENTRY (scop
);
691 basic_block exit
= SCOP_EXIT (scop
);
693 fprintf (file
, "digraph SCoP_%d_%d {\n", entry
->index
,
699 fprintf (file
, "%d [shape=triangle];\n", bb
->index
);
702 fprintf (file
, "%d [shape=box];\n", bb
->index
);
704 if (bb_in_scop_p (bb
, scop
))
705 fprintf (file
, "%d [color=red];\n", bb
->index
);
707 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
708 fprintf (file
, "%d -> %d;\n", bb
->index
, e
->dest
->index
);
711 fputs ("}\n\n", file
);
714 /* Display SCOP using dotty. */
717 dot_scop (scop_p scop
)
719 dot_scop_1 (stderr
, scop
);
722 /* Pretty print all SCoPs in DOT format and mark them with different colors.
723 If there are not enough colors, paint later SCoPs gray.
725 - "*" after the node number: entry of a SCoP,
726 - "#" after the node number: exit of a SCoP,
727 - "()" entry or exit not part of SCoP. */
730 dot_all_scops_1 (FILE *file
)
739 /* Disable debugging while printing graph. */
740 int tmp_dump_flags
= dump_flags
;
743 fprintf (file
, "digraph all {\n");
747 int part_of_scop
= false;
749 /* Use HTML for every bb label. So we are able to print bbs
750 which are part of two different SCoPs, with two different
751 background colors. */
752 fprintf (file
, "%d [label=<\n <TABLE BORDER=\"0\" CELLBORDER=\"1\" ",
754 fprintf (file
, "CELLSPACING=\"0\">\n");
756 /* Select color for SCoP. */
757 for (i
= 0; VEC_iterate (scop_p
, current_scops
, i
, scop
); i
++)
758 if (bb_in_scop_p (bb
, scop
)
759 || (SCOP_EXIT (scop
) == bb
)
760 || (SCOP_ENTRY (scop
) == bb
))
819 fprintf (file
, " <TR><TD WIDTH=\"50\" BGCOLOR=\"%s\">", color
);
821 if (!bb_in_scop_p (bb
, scop
))
822 fprintf (file
, " (");
824 if (bb
== SCOP_ENTRY (scop
)
825 && bb
== SCOP_EXIT (scop
))
826 fprintf (file
, " %d*# ", bb
->index
);
827 else if (bb
== SCOP_ENTRY (scop
))
828 fprintf (file
, " %d* ", bb
->index
);
829 else if (bb
== SCOP_EXIT (scop
))
830 fprintf (file
, " %d# ", bb
->index
);
832 fprintf (file
, " %d ", bb
->index
);
834 if (!bb_in_scop_p (bb
, scop
))
837 fprintf (file
, "</TD></TR>\n");
843 fprintf (file
, " <TR><TD WIDTH=\"50\" BGCOLOR=\"#ffffff\">");
844 fprintf (file
, " %d </TD></TR>\n", bb
->index
);
847 fprintf (file
, " </TABLE>>, shape=box, style=\"setlinewidth(0)\"]\n");
852 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
853 fprintf (file
, "%d -> %d;\n", bb
->index
, e
->dest
->index
);
856 fputs ("}\n\n", file
);
858 /* Enable debugging again. */
859 dump_flags
= tmp_dump_flags
;
862 /* Display all SCoPs using dotty. */
867 /* When debugging, enable the following code. This cannot be used
868 in production compilers because it calls "system". */
870 FILE *stream
= fopen ("/tmp/allscops.dot", "w");
873 dot_all_scops_1 (stream
);
876 system ("dotty /tmp/allscops.dot");
878 dot_all_scops_1 (stderr
);
882 /* Returns the outermost loop in SCOP that contains BB. */
885 outermost_loop_in_scop (scop_p scop
, basic_block bb
)
889 nest
= bb
->loop_father
;
890 while (loop_outer (nest
) && loop_in_scop_p (loop_outer (nest
), scop
))
891 nest
= loop_outer (nest
);
896 /* Returns the block preceding the entry of SCOP. */
899 block_before_scop (scop_p scop
)
901 return SESE_ENTRY (SCOP_REGION (scop
))->src
;
904 /* Return true when EXPR is an affine function in LOOP with parameters
905 instantiated relative to SCOP_ENTRY. */
908 loop_affine_expr (basic_block scop_entry
, struct loop
*loop
, tree expr
)
911 tree scev
= analyze_scalar_evolution (loop
, expr
);
913 scev
= instantiate_scev (scop_entry
, loop
, scev
);
915 return (evolution_function_is_invariant_p (scev
, n
)
916 || evolution_function_is_affine_multivariate_p (scev
, n
));
919 /* Return false if the tree_code of the operand OP or any of its operands
923 exclude_component_ref (tree op
)
930 if (TREE_CODE (op
) == COMPONENT_REF
)
934 len
= TREE_OPERAND_LENGTH (op
);
935 for (i
= 0; i
< len
; ++i
)
937 if (!exclude_component_ref (TREE_OPERAND (op
, i
)))
946 /* Return true if the operand OP is simple. */
949 is_simple_operand (loop_p loop
, gimple stmt
, tree op
)
951 /* It is not a simple operand when it is a declaration, */
953 /* or a structure, */
954 || AGGREGATE_TYPE_P (TREE_TYPE (op
))
955 /* or a memory access that cannot be analyzed by the data
956 reference analysis. */
957 || ((handled_component_p (op
) || INDIRECT_REF_P (op
))
958 && !stmt_simple_memref_p (loop
, stmt
, op
)))
961 return exclude_component_ref (op
);
964 /* Return true only when STMT is simple enough for being handled by
965 Graphite. This depends on SCOP_ENTRY, as the parametetrs are
966 initialized relatively to this basic block. */
969 stmt_simple_for_scop_p (basic_block scop_entry
, gimple stmt
)
971 basic_block bb
= gimple_bb (stmt
);
972 struct loop
*loop
= bb
->loop_father
;
974 /* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects.
975 Calls have side-effects, except those to const or pure
977 if (gimple_has_volatile_ops (stmt
)
978 || (gimple_code (stmt
) == GIMPLE_CALL
979 && !(gimple_call_flags (stmt
) & (ECF_CONST
| ECF_PURE
)))
980 || (gimple_code (stmt
) == GIMPLE_ASM
))
983 switch (gimple_code (stmt
))
993 enum tree_code code
= gimple_cond_code (stmt
);
995 /* We can only handle this kind of conditional expressions.
996 For inequalities like "if (i != 3 * k)" we need unions of
997 polyhedrons. Expressions like "if (a)" or "if (a == 15)" need
998 them for the else branch. */
999 if (!(code
== LT_EXPR
1002 || code
== GE_EXPR
))
1008 FOR_EACH_SSA_TREE_OPERAND (op
, stmt
, op_iter
, SSA_OP_ALL_USES
)
1009 if (!loop_affine_expr (scop_entry
, loop
, op
))
1017 enum tree_code code
= gimple_assign_rhs_code (stmt
);
1019 switch (get_gimple_rhs_class (code
))
1021 case GIMPLE_UNARY_RHS
:
1022 case GIMPLE_SINGLE_RHS
:
1023 return (is_simple_operand (loop
, stmt
, gimple_assign_lhs (stmt
))
1024 && is_simple_operand (loop
, stmt
, gimple_assign_rhs1 (stmt
)));
1026 case GIMPLE_BINARY_RHS
:
1027 return (is_simple_operand (loop
, stmt
, gimple_assign_lhs (stmt
))
1028 && is_simple_operand (loop
, stmt
, gimple_assign_rhs1 (stmt
))
1029 && is_simple_operand (loop
, stmt
, gimple_assign_rhs2 (stmt
)));
1031 case GIMPLE_INVALID_RHS
:
1040 size_t n
= gimple_call_num_args (stmt
);
1041 tree lhs
= gimple_call_lhs (stmt
);
1043 for (i
= 0; i
< n
; i
++)
1045 tree arg
= gimple_call_arg (stmt
, i
);
1047 if (!(is_simple_operand (loop
, stmt
, lhs
)
1048 && is_simple_operand (loop
, stmt
, arg
)))
1056 /* These nodes cut a new scope. */
1063 /* Returns the statement of BB that contains a harmful operation: that
1064 can be a function call with side effects, the induction variables
1065 are not linear with respect to SCOP_ENTRY, etc. The current open
1066 scop should end before this statement. */
1069 harmful_stmt_in_bb (basic_block scop_entry
, basic_block bb
)
1071 gimple_stmt_iterator gsi
;
1073 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1074 if (!stmt_simple_for_scop_p (scop_entry
, gsi_stmt (gsi
)))
1075 return gsi_stmt (gsi
);
1080 /* Returns true when BB will be represented in graphite. Return false
1081 for the basic blocks that contain code eliminated in the code
1082 generation pass: i.e. induction variables and exit conditions. */
1085 graphite_stmt_p (scop_p scop
, basic_block bb
,
1086 VEC (data_reference_p
, heap
) *drs
)
1088 gimple_stmt_iterator gsi
;
1089 loop_p loop
= bb
->loop_father
;
1091 if (VEC_length (data_reference_p
, drs
) > 0)
1094 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1096 gimple stmt
= gsi_stmt (gsi
);
1098 switch (gimple_code (stmt
))
1100 /* Control flow expressions can be ignored, as they are
1101 represented in the iteration domains and will be
1102 regenerated by graphite. */
1110 tree var
= gimple_assign_lhs (stmt
);
1111 var
= analyze_scalar_evolution (loop
, var
);
1112 var
= instantiate_scev (block_before_scop (scop
), loop
, var
);
1114 if (chrec_contains_undetermined (var
))
1128 /* Store the GRAPHITE representation of BB. */
1131 new_graphite_bb (scop_p scop
, basic_block bb
)
1133 struct graphite_bb
*gbb
;
1134 VEC (data_reference_p
, heap
) *drs
= VEC_alloc (data_reference_p
, heap
, 5);
1135 struct loop
*nest
= outermost_loop_in_scop (scop
, bb
);
1136 gimple_stmt_iterator gsi
;
1138 bitmap_set_bit (SCOP_BBS_B (scop
), bb
->index
);
1140 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1141 find_data_references_in_stmt (nest
, gsi_stmt (gsi
), &drs
);
1143 if (!graphite_stmt_p (scop
, bb
, drs
))
1145 free_data_refs (drs
);
1149 gbb
= XNEW (struct graphite_bb
);
1152 GBB_SCOP (gbb
) = scop
;
1153 GBB_DATA_REFS (gbb
) = drs
;
1154 GBB_DOMAIN (gbb
) = NULL
;
1155 GBB_CONDITIONS (gbb
) = NULL
;
1156 GBB_CONDITION_CASES (gbb
) = NULL
;
1157 GBB_LOOPS (gbb
) = NULL
;
1158 GBB_STATIC_SCHEDULE (gbb
) = NULL
;
1159 GBB_CLOOG_IV_TYPES (gbb
) = NULL
;
1160 VEC_safe_push (graphite_bb_p
, heap
, SCOP_BBS (scop
), gbb
);
1166 free_graphite_bb (struct graphite_bb
*gbb
)
1168 if (GBB_DOMAIN (gbb
))
1169 cloog_matrix_free (GBB_DOMAIN (gbb
));
1171 if (GBB_CLOOG_IV_TYPES (gbb
))
1172 htab_delete (GBB_CLOOG_IV_TYPES (gbb
));
1174 /* FIXME: free_data_refs is disabled for the moment, but should be
1177 free_data_refs (GBB_DATA_REFS (gbb)); */
1179 VEC_free (gimple
, heap
, GBB_CONDITIONS (gbb
));
1180 VEC_free (gimple
, heap
, GBB_CONDITION_CASES (gbb
));
1181 VEC_free (loop_p
, heap
, GBB_LOOPS (gbb
));
1182 GBB_BB (gbb
)->aux
= 0;
1186 /* Register basic blocks belonging to a region in a pointer set. */
1189 register_bb_in_sese (basic_block entry_bb
, basic_block exit_bb
, sese region
)
1193 basic_block bb
= entry_bb
;
1195 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1197 if (!pointer_set_contains (SESE_REGION_BBS (region
), e
->dest
) &&
1198 e
->dest
->index
!= exit_bb
->index
)
1200 pointer_set_insert (SESE_REGION_BBS (region
), e
->dest
);
1201 register_bb_in_sese (e
->dest
, exit_bb
, region
);
1206 /* Creates a new scop starting with ENTRY. */
1209 new_scop (edge entry
, edge exit
)
1211 scop_p scop
= XNEW (struct scop
);
1213 gcc_assert (entry
&& exit
);
1215 SCOP_REGION (scop
) = XNEW (struct sese
);
1216 SESE_ENTRY (SCOP_REGION (scop
)) = entry
;
1217 SESE_EXIT (SCOP_REGION (scop
)) = exit
;
1218 SESE_REGION_BBS (SCOP_REGION (scop
)) = pointer_set_create ();
1219 register_bb_in_sese (SCOP_ENTRY (scop
), SCOP_EXIT (scop
),
1220 SCOP_REGION (scop
));
1221 SCOP_BBS (scop
) = VEC_alloc (graphite_bb_p
, heap
, 3);
1222 SCOP_OLDIVS (scop
) = VEC_alloc (name_tree
, heap
, 3);
1223 SCOP_BBS_B (scop
) = BITMAP_ALLOC (NULL
);
1224 SCOP_LOOPS (scop
) = BITMAP_ALLOC (NULL
);
1225 SCOP_LOOP_NEST (scop
) = VEC_alloc (loop_p
, heap
, 3);
1226 SCOP_ADD_PARAMS (scop
) = true;
1227 SCOP_PARAMS (scop
) = VEC_alloc (name_tree
, heap
, 3);
1228 SCOP_PROG (scop
) = cloog_program_malloc ();
1229 cloog_program_set_names (SCOP_PROG (scop
), cloog_names_malloc ());
1230 SCOP_LOOP2CLOOG_LOOP (scop
) = htab_create (10, hash_loop_to_cloog_loop
,
1231 eq_loop_to_cloog_loop
,
1239 free_scop (scop_p scop
)
1243 struct graphite_bb
*gb
;
1246 for (i
= 0; VEC_iterate (graphite_bb_p
, SCOP_BBS (scop
), i
, gb
); i
++)
1247 free_graphite_bb (gb
);
1249 VEC_free (graphite_bb_p
, heap
, SCOP_BBS (scop
));
1250 BITMAP_FREE (SCOP_BBS_B (scop
));
1251 BITMAP_FREE (SCOP_LOOPS (scop
));
1252 VEC_free (loop_p
, heap
, SCOP_LOOP_NEST (scop
));
1254 for (i
= 0; VEC_iterate (name_tree
, SCOP_OLDIVS (scop
), i
, iv
); i
++)
1256 VEC_free (name_tree
, heap
, SCOP_OLDIVS (scop
));
1258 for (i
= 0; VEC_iterate (name_tree
, SCOP_PARAMS (scop
), i
, p
); i
++)
1261 VEC_free (name_tree
, heap
, SCOP_PARAMS (scop
));
1262 cloog_program_free (SCOP_PROG (scop
));
1263 htab_delete (SCOP_LOOP2CLOOG_LOOP (scop
));
1264 XDELETE (SCOP_REGION (scop
));
1268 /* Deletes all scops in SCOPS. */
1271 free_scops (VEC (scop_p
, heap
) *scops
)
1276 for (i
= 0; VEC_iterate (scop_p
, scops
, i
, scop
); i
++)
1279 VEC_free (scop_p
, heap
, scops
);
1282 typedef enum gbb_type
{
1284 GBB_LOOP_SING_EXIT_HEADER
,
1285 GBB_LOOP_MULT_EXIT_HEADER
,
1292 /* Detect the type of BB. Loop headers are only marked, if they are
1293 new. This means their loop_father is different to LAST_LOOP.
1294 Otherwise they are treated like any other bb and their type can be
1298 get_bb_type (basic_block bb
, struct loop
*last_loop
)
1300 VEC (basic_block
, heap
) *dom
;
1302 struct loop
*loop
= bb
->loop_father
;
1304 /* Check, if we entry into a new loop. */
1305 if (loop
!= last_loop
)
1307 if (single_exit (loop
) != NULL
)
1308 return GBB_LOOP_SING_EXIT_HEADER
;
1309 else if (loop
->num
!= 0)
1310 return GBB_LOOP_MULT_EXIT_HEADER
;
1312 return GBB_COND_HEADER
;
1315 dom
= get_dominated_by (CDI_DOMINATORS
, bb
);
1316 nb_dom
= VEC_length (basic_block
, dom
);
1317 VEC_free (basic_block
, heap
, dom
);
1322 nb_suc
= VEC_length (edge
, bb
->succs
);
1324 if (nb_dom
== 1 && nb_suc
== 1)
1327 return GBB_COND_HEADER
;
1330 /* A SCoP detection region, defined using bbs as borders.
1331 All control flow touching this region, comes in passing basic_block ENTRY and
1332 leaves passing basic_block EXIT. By using bbs instead of edges for the
1333 borders we are able to represent also regions that do not have a single
1335 But as they have a single entry basic_block and a single exit basic_block, we
1336 are able to generate for every sd_region a single entry and exit edge.
1343 / \ This region contains: {3, 4, 5, 6, 7, 8}
1351 typedef struct sd_region_p
1353 /* The entry bb dominates all bbs in the sd_region. It is part of the
1357 /* The exit bb postdominates all bbs in the sd_region, but is not
1358 part of the region. */
1362 DEF_VEC_O(sd_region
);
1363 DEF_VEC_ALLOC_O(sd_region
, heap
);
1366 /* Moves the scops from SOURCE to TARGET and clean up SOURCE. */
1369 move_sd_regions (VEC (sd_region
, heap
) **source
, VEC (sd_region
, heap
) **target
)
1374 for (i
= 0; VEC_iterate (sd_region
, *source
, i
, s
); i
++)
1375 VEC_safe_push (sd_region
, heap
, *target
, s
);
1377 VEC_free (sd_region
, heap
, *source
);
1380 /* Store information needed by scopdet_* functions. */
1384 /* Where the last open scop would stop if the current BB is harmful. */
1387 /* Where the next scop would start if the current BB is harmful. */
1390 /* The bb or one of its children contains open loop exits. That means
1391 loop exit nodes that are not surrounded by a loop dominated by bb. */
1394 /* The bb or one of its children contains only structures we can handle. */
1399 static struct scopdet_info
build_scops_1 (basic_block
, VEC (sd_region
, heap
) **,
1402 /* Calculates BB infos. If bb is difficult we add valid SCoPs dominated by BB
1403 to SCOPS. TYPE is the gbb_type of BB. */
1405 static struct scopdet_info
1406 scopdet_basic_block_info (basic_block bb
, VEC (sd_region
, heap
) **scops
,
1409 struct loop
*loop
= bb
->loop_father
;
1410 struct scopdet_info result
;
1413 /* XXX: ENTRY_BLOCK_PTR could be optimized in later steps. */
1414 stmt
= harmful_stmt_in_bb (ENTRY_BLOCK_PTR
, bb
);
1415 result
.difficult
= (stmt
!= NULL
);
1422 result
.exits
= false;
1427 result
.next
= single_succ (bb
);
1428 result
.exits
= false;
1432 case GBB_LOOP_SING_EXIT_HEADER
:
1434 VEC (sd_region
, heap
) *tmp_scops
= VEC_alloc (sd_region
, heap
,3);
1435 struct scopdet_info sinfo
;
1437 sinfo
= build_scops_1 (bb
, &tmp_scops
, loop
);
1439 result
.last
= single_exit (bb
->loop_father
)->src
;
1440 result
.next
= single_exit (bb
->loop_father
)->dest
;
1442 /* If we do not dominate result.next, remove it. It's either
1443 the EXIT_BLOCK_PTR, or another bb dominates it and will
1444 call the scop detection for this bb. */
1445 if (!dominated_by_p (CDI_DOMINATORS
, result
.next
, bb
))
1448 if (result
.last
->loop_father
!= loop
)
1451 if (TREE_CODE (number_of_latch_executions (loop
))
1453 result
.difficult
= true;
1455 if (sinfo
.difficult
)
1456 move_sd_regions (&tmp_scops
, scops
);
1458 VEC_free (sd_region
, heap
, tmp_scops
);
1460 result
.exits
= false;
1461 result
.difficult
|= sinfo
.difficult
;
1465 case GBB_LOOP_MULT_EXIT_HEADER
:
1467 /* XXX: For now we just do not join loops with multiple exits. If the
1468 exits lead to the same bb it may be possible to join the loop. */
1469 VEC (sd_region
, heap
) *tmp_scops
= VEC_alloc (sd_region
, heap
, 3);
1470 VEC (edge
, heap
) *exits
= get_loop_exit_edges (loop
);
1473 build_scops_1 (bb
, &tmp_scops
, loop
);
1475 /* Scan the code dominated by this loop. This means all bbs, that are
1476 are dominated by a bb in this loop, but are not part of this loop.
1479 - The loop exit destination is dominated by the exit sources.
1481 TODO: We miss here the more complex cases:
1482 - The exit destinations are dominated by another bb inside the
1484 - The loop dominates bbs, that are not exit destinations. */
1485 for (i
= 0; VEC_iterate (edge
, exits
, i
, e
); i
++)
1486 if (e
->src
->loop_father
== loop
1487 && dominated_by_p (CDI_DOMINATORS
, e
->dest
, e
->src
))
1489 /* Pass loop_outer to recognize e->dest as loop header in
1491 if (e
->dest
->loop_father
->header
== e
->dest
)
1492 build_scops_1 (e
->dest
, &tmp_scops
,
1493 loop_outer (e
->dest
->loop_father
));
1495 build_scops_1 (e
->dest
, &tmp_scops
, e
->dest
->loop_father
);
1500 result
.difficult
= true;
1501 result
.exits
= false;
1502 move_sd_regions (&tmp_scops
, scops
);
1503 VEC_free (edge
, heap
, exits
);
1506 case GBB_COND_HEADER
:
1508 VEC (sd_region
, heap
) *tmp_scops
= VEC_alloc (sd_region
, heap
, 3);
1509 struct scopdet_info sinfo
;
1510 VEC (basic_block
, heap
) *dominated
;
1513 basic_block last_bb
= NULL
;
1515 result
.exits
= false;
1517 /* First check the successors of BB, and check if it is possible to join
1518 the different branches. */
1519 for (i
= 0; VEC_iterate (edge
, bb
->succs
, i
, e
); i
++)
1521 /* Ignore loop exits. They will be handled after the loop body. */
1522 if (is_loop_exit (loop
, e
->dest
))
1524 result
.exits
= true;
1528 /* Do not follow edges that lead to the end of the
1529 conditions block. For example, in
1539 the edge from 0 => 6. Only check if all paths lead to
1542 if (!single_pred_p (e
->dest
))
1544 /* Check, if edge leads directly to the end of this
1551 if (e
->dest
!= last_bb
)
1552 result
.difficult
= true;
1557 if (!dominated_by_p (CDI_DOMINATORS
, e
->dest
, bb
))
1559 result
.difficult
= true;
1563 sinfo
= build_scops_1 (e
->dest
, &tmp_scops
, loop
);
1565 result
.exits
|= sinfo
.exits
;
1566 result
.last
= sinfo
.last
;
1567 result
.difficult
|= sinfo
.difficult
;
1569 /* Checks, if all branches end at the same point.
1570 If that is true, the condition stays joinable.
1571 Have a look at the example above. */
1572 if (sinfo
.last
&& single_succ_p (sinfo
.last
))
1574 basic_block next_tmp
= single_succ (sinfo
.last
);
1579 if (next_tmp
!= last_bb
)
1580 result
.difficult
= true;
1583 result
.difficult
= true;
1586 /* If the condition is joinable. */
1587 if (!result
.exits
&& !result
.difficult
)
1589 /* Only return a next pointer if we dominate this pointer.
1590 Otherwise it will be handled by the bb dominating it. */
1591 if (dominated_by_p (CDI_DOMINATORS
, last_bb
, bb
) && last_bb
!= bb
)
1592 result
.next
= last_bb
;
1596 VEC_free (sd_region
, heap
, tmp_scops
);
1600 /* Scan remaining bbs dominated by BB. */
1601 dominated
= get_dominated_by (CDI_DOMINATORS
, bb
);
1603 for (i
= 0; VEC_iterate (basic_block
, dominated
, i
, dom_bb
); i
++)
1605 /* Ignore loop exits: they will be handled after the loop body. */
1606 if (loop_depth (find_common_loop (loop
, dom_bb
->loop_father
))
1607 < loop_depth (loop
))
1609 result
.exits
= true;
1613 /* Ignore the bbs processed above. */
1614 if (single_pred_p (dom_bb
) && single_pred (dom_bb
) == bb
)
1617 if (loop_depth (loop
) > loop_depth (dom_bb
->loop_father
))
1618 sinfo
= build_scops_1 (dom_bb
, &tmp_scops
, loop_outer (loop
));
1620 sinfo
= build_scops_1 (dom_bb
, &tmp_scops
, loop
);
1623 result
.exits
|= sinfo
.exits
;
1624 result
.difficult
= true;
1628 VEC_free (basic_block
, heap
, dominated
);
1631 move_sd_regions (&tmp_scops
, scops
);
1643 /* Creates the SCoPs and writes entry and exit points for every SCoP. */
1645 static struct scopdet_info
1646 build_scops_1 (basic_block current
, VEC (sd_region
, heap
) **scops
, loop_p loop
)
1648 bool in_scop
= false;
1649 sd_region open_scop
;
1650 struct scopdet_info sinfo
;
1652 /* Initialize result. */
1653 struct scopdet_info result
;
1654 result
.exits
= false;
1655 result
.difficult
= false;
1658 open_scop
.entry
= NULL
;
1659 open_scop
.exit
= NULL
;
1662 /* Loop over the dominance tree. If we meet a difficult bb, close
1663 the current SCoP. Loop and condition header start a new layer,
1664 and can only be added if all bbs in deeper layers are simple. */
1665 while (current
!= NULL
)
1667 sinfo
= scopdet_basic_block_info (current
, scops
, get_bb_type (current
,
1670 if (!in_scop
&& !(sinfo
.exits
|| sinfo
.difficult
))
1672 open_scop
.entry
= current
;
1673 open_scop
.exit
= NULL
;
1676 else if (in_scop
&& (sinfo
.exits
|| sinfo
.difficult
))
1678 open_scop
.exit
= current
;
1679 VEC_safe_push (sd_region
, heap
, *scops
, &open_scop
);
1683 result
.difficult
|= sinfo
.difficult
;
1684 result
.exits
|= sinfo
.exits
;
1686 current
= sinfo
.next
;
1689 /* Try to close open_scop, if we are still in an open SCoP. */
1695 for (i
= 0; VEC_iterate (edge
, sinfo
.last
->succs
, i
, e
); i
++)
1696 if (dominated_by_p (CDI_POST_DOMINATORS
, sinfo
.last
, e
->dest
))
1697 open_scop
.exit
= e
->dest
;
1699 if (!open_scop
.exit
&& open_scop
.entry
!= sinfo
.last
)
1700 open_scop
.exit
= sinfo
.last
;
1703 VEC_safe_push (sd_region
, heap
, *scops
, &open_scop
);
1707 result
.last
= sinfo
.last
;
1711 /* Checks if a bb is contained in REGION. */
1714 bb_in_sd_region (basic_block bb
, sd_region
*region
)
1716 return dominated_by_p (CDI_DOMINATORS
, bb
, region
->entry
)
1717 && !(dominated_by_p (CDI_DOMINATORS
, bb
, region
->exit
)
1718 && !dominated_by_p (CDI_DOMINATORS
, region
->entry
,
1722 /* Returns the single entry edge of REGION, if it does not exits NULL. */
1725 find_single_entry_edge (sd_region
*region
)
1731 FOR_EACH_EDGE (e
, ei
, region
->entry
->preds
)
1732 if (!bb_in_sd_region (e
->src
, region
))
1747 /* Returns the single exit edge of REGION, if it does not exits NULL. */
1750 find_single_exit_edge (sd_region
*region
)
1756 FOR_EACH_EDGE (e
, ei
, region
->exit
->preds
)
1757 if (bb_in_sd_region (e
->src
, region
))
1772 /* Create a single entry edge for REGION. */
1775 create_single_entry_edge (sd_region
*region
)
1777 if (find_single_entry_edge (region
))
1780 /* There are multiple predecessors for bb_3
1793 There are two edges (1->3, 2->3), that point from outside into the region,
1794 and another one (5->3), a loop latch, lead to bb_3.
1802 | |\ (3.0 -> 3.1) = single entry edge
1811 If the loop is part of the SCoP, we have to redirect the loop latches.
1817 | | (3.0 -> 3.1) = entry edge
1826 if (region
->entry
->loop_father
->header
!= region
->entry
1827 || dominated_by_p (CDI_DOMINATORS
,
1828 loop_latch_edge (region
->entry
->loop_father
)->src
,
1831 edge forwarder
= split_block_after_labels (region
->entry
);
1832 region
->entry
= forwarder
->dest
;
1835 /* This case is never executed, as the loop headers seem always to have a
1836 single edge pointing from outside into the loop. */
1839 #ifdef ENABLE_CHECKING
1840 gcc_assert (find_single_entry_edge (region
));
1844 /* Check if the sd_region, mentioned in EDGE, has no exit bb. */
1847 sd_region_without_exit (edge e
)
1849 sd_region
*r
= (sd_region
*) e
->aux
;
1852 return r
->exit
== NULL
;
1857 /* Create a single exit edge for REGION. */
1860 create_single_exit_edge (sd_region
*region
)
1864 edge forwarder
= NULL
;
1867 if (find_single_exit_edge (region
))
1870 /* We create a forwarder bb (5) for all edges leaving this region
1871 (3->5, 4->5). All other edges leading to the same bb, are moved
1872 to a new bb (6). If these edges where part of another region (2->5)
1873 we update the region->exit pointer, of this region.
1875 To identify which edge belongs to which region we depend on the e->aux
1876 pointer in every edge. It points to the region of the edge or to NULL,
1877 if the edge is not part of any region.
1879 1 2 3 4 1->5 no region, 2->5 region->exit = 5,
1880 \| |/ 3->5 region->exit = NULL, 4->5 region->exit = NULL
1885 1 2 3 4 1->6 no region, 2->6 region->exit = 6,
1886 | | \/ 3->5 no region, 4->5 no region,
1888 \| / 5->6 region->exit = 6
1891 Now there is only a single exit edge (5->6). */
1892 exit
= region
->exit
;
1893 region
->exit
= NULL
;
1894 forwarder
= make_forwarder_block (exit
, &sd_region_without_exit
, NULL
);
1896 /* Unmark the edges, that are no longer exit edges. */
1897 FOR_EACH_EDGE (e
, ei
, forwarder
->src
->preds
)
1901 /* Mark the new exit edge. */
1902 single_succ_edge (forwarder
->src
)->aux
= region
;
1904 /* Update the exit bb of all regions, where exit edges lead to
1906 FOR_EACH_EDGE (e
, ei
, forwarder
->dest
->preds
)
1908 ((sd_region
*) e
->aux
)->exit
= forwarder
->dest
;
1910 #ifdef ENABLE_CHECKING
1911 gcc_assert (find_single_exit_edge (region
));
1915 /* Unmark the exit edges of all REGIONS.
1916 See comment in "create_single_exit_edge". */
1919 unmark_exit_edges (VEC (sd_region
, heap
) *regions
)
1926 for (i
= 0; VEC_iterate (sd_region
, regions
, i
, s
); i
++)
1927 FOR_EACH_EDGE (e
, ei
, s
->exit
->preds
)
1932 /* Mark the exit edges of all REGIONS.
1933 See comment in "create_single_exit_edge". */
1936 mark_exit_edges (VEC (sd_region
, heap
) *regions
)
1943 for (i
= 0; VEC_iterate (sd_region
, regions
, i
, s
); i
++)
1944 FOR_EACH_EDGE (e
, ei
, s
->exit
->preds
)
1945 if (bb_in_sd_region (e
->src
, s
))
1949 /* Free and compute again all the dominators information. */
1952 recompute_all_dominators (void)
1954 free_dominance_info (CDI_DOMINATORS
);
1955 free_dominance_info (CDI_POST_DOMINATORS
);
1956 calculate_dominance_info (CDI_DOMINATORS
);
1957 calculate_dominance_info (CDI_POST_DOMINATORS
);
1960 /* Verifies properties that GRAPHITE should maintain during translation. */
1963 graphite_verify (void)
1965 #ifdef ENABLE_CHECKING
1966 verify_loop_structure ();
1967 verify_dominators (CDI_DOMINATORS
);
1968 verify_dominators (CDI_POST_DOMINATORS
);
1973 /* Create for all scop regions a single entry and a single exit edge. */
1976 create_sese_edges (VEC (sd_region
, heap
) *regions
)
1981 for (i
= 0; VEC_iterate (sd_region
, regions
, i
, s
); i
++)
1982 create_single_entry_edge (s
);
1984 mark_exit_edges (regions
);
1986 for (i
= 0; VEC_iterate (sd_region
, regions
, i
, s
); i
++)
1987 create_single_exit_edge (s
);
1989 unmark_exit_edges (regions
);
1991 #ifdef ENABLE_CHECKING
1992 verify_loop_structure ();
1993 verify_dominators (CDI_DOMINATORS
);
1998 /* Create graphite SCoPs from an array of scop detection regions. */
2001 build_graphite_scops (VEC (sd_region
, heap
) *scop_regions
)
2006 for (i
= 0; VEC_iterate (sd_region
, scop_regions
, i
, s
); i
++)
2008 edge entry
= find_single_entry_edge (s
);
2009 edge exit
= find_single_exit_edge (s
);
2010 scop_p scop
= new_scop (entry
, exit
);
2011 VEC_safe_push (scop_p
, heap
, current_scops
, scop
);
2013 /* Are there overlapping SCoPs? */
2014 #ifdef ENABLE_CHECKING
2019 for (j
= 0; VEC_iterate (sd_region
, scop_regions
, j
, s2
); j
++)
2021 gcc_assert (!bb_in_sd_region (s
->entry
, s2
));
2027 /* Find static control parts. */
2032 struct loop
*loop
= current_loops
->tree_root
;
2033 VEC (sd_region
, heap
) *tmp_scops
= VEC_alloc (sd_region
, heap
, 3);
2035 build_scops_1 (single_succ (ENTRY_BLOCK_PTR
), &tmp_scops
, loop
);
2036 create_sese_edges (tmp_scops
);
2037 build_graphite_scops (tmp_scops
);
2038 VEC_free (sd_region
, heap
, tmp_scops
);
2041 /* Gather the basic blocks belonging to the SCOP. */
2044 build_scop_bbs (scop_p scop
)
2046 basic_block
*stack
= XNEWVEC (basic_block
, n_basic_blocks
+ 1);
2047 sbitmap visited
= sbitmap_alloc (last_basic_block
);
2050 sbitmap_zero (visited
);
2051 stack
[sp
++] = SCOP_ENTRY (scop
);
2055 basic_block bb
= stack
[--sp
];
2056 int depth
= loop_depth (bb
->loop_father
);
2057 int num
= bb
->loop_father
->num
;
2061 /* Scop's exit is not in the scop. Exclude also bbs, which are
2062 dominated by the SCoP exit. These are e.g. loop latches. */
2063 if (TEST_BIT (visited
, bb
->index
)
2064 || dominated_by_p (CDI_DOMINATORS
, bb
, SCOP_EXIT (scop
))
2065 /* Every block in the scop is dominated by scop's entry. */
2066 || !dominated_by_p (CDI_DOMINATORS
, bb
, SCOP_ENTRY (scop
)))
2069 new_graphite_bb (scop
, bb
);
2070 SET_BIT (visited
, bb
->index
);
2072 /* First push the blocks that have to be processed last. Note
2073 that this means that the order in which the code is organized
2074 below is important: do not reorder the following code. */
2075 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
2076 if (! TEST_BIT (visited
, e
->dest
->index
)
2077 && (int) loop_depth (e
->dest
->loop_father
) < depth
)
2078 stack
[sp
++] = e
->dest
;
2080 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
2081 if (! TEST_BIT (visited
, e
->dest
->index
)
2082 && (int) loop_depth (e
->dest
->loop_father
) == depth
2083 && e
->dest
->loop_father
->num
!= num
)
2084 stack
[sp
++] = e
->dest
;
2086 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
2087 if (! TEST_BIT (visited
, e
->dest
->index
)
2088 && (int) loop_depth (e
->dest
->loop_father
) == depth
2089 && e
->dest
->loop_father
->num
== num
2090 && EDGE_COUNT (e
->dest
->preds
) > 1)
2091 stack
[sp
++] = e
->dest
;
2093 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
2094 if (! TEST_BIT (visited
, e
->dest
->index
)
2095 && (int) loop_depth (e
->dest
->loop_father
) == depth
2096 && e
->dest
->loop_father
->num
== num
2097 && EDGE_COUNT (e
->dest
->preds
) == 1)
2098 stack
[sp
++] = e
->dest
;
2100 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
2101 if (! TEST_BIT (visited
, e
->dest
->index
)
2102 && (int) loop_depth (e
->dest
->loop_father
) > depth
)
2103 stack
[sp
++] = e
->dest
;
2107 sbitmap_free (visited
);
2110 /* Returns the number of reduction phi nodes in LOOP. */
2113 nb_reductions_in_loop (loop_p loop
)
2116 gimple_stmt_iterator gsi
;
2118 for (gsi
= gsi_start_phis (loop
->header
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2120 gimple phi
= gsi_stmt (gsi
);
2124 if (!is_gimple_reg (PHI_RESULT (phi
)))
2127 scev
= analyze_scalar_evolution (loop
, PHI_RESULT (phi
));
2128 scev
= instantiate_parameters (loop
, scev
);
2129 if (!simple_iv (loop
, phi
, PHI_RESULT (phi
), &iv
, true))
2136 /* A LOOP is in normal form when it contains only one scalar phi node
2137 that defines the main induction variable of the loop, only one
2138 increment of the IV, and only one exit condition. */
2141 graphite_loop_normal_form (loop_p loop
)
2143 struct tree_niter_desc niter
;
2146 edge exit
= single_dom_exit (loop
);
2148 if (!number_of_iterations_exit (loop
, exit
, &niter
, false))
2151 nit
= force_gimple_operand (unshare_expr (niter
.niter
), &stmts
, true,
2154 gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop
), stmts
);
2156 /* One IV per loop. */
2157 if (nb_reductions_in_loop (loop
) > 0)
2160 return canonicalize_loop_ivs (loop
, NULL
, nit
);
2163 /* Record LOOP as occuring in SCOP. Returns true when the operation
2167 scop_record_loop (scop_p scop
, loop_p loop
)
2172 if (bitmap_bit_p (SCOP_LOOPS (scop
), loop
->num
))
2175 bitmap_set_bit (SCOP_LOOPS (scop
), loop
->num
);
2176 VEC_safe_push (loop_p
, heap
, SCOP_LOOP_NEST (scop
), loop
);
2178 induction_var
= graphite_loop_normal_form (loop
);
2182 oldiv
= XNEW (struct name_tree
);
2183 oldiv
->t
= induction_var
;
2184 oldiv
->name
= get_name (SSA_NAME_VAR (oldiv
->t
));
2186 VEC_safe_push (name_tree
, heap
, SCOP_OLDIVS (scop
), oldiv
);
2190 /* Build the loop nests contained in SCOP. Returns true when the
2191 operation was successful. */
2194 build_scop_loop_nests (scop_p scop
)
2198 struct loop
*loop0
, *loop1
;
2201 if (bb_in_scop_p (bb
, scop
))
2203 struct loop
*loop
= bb
->loop_father
;
2205 /* Only add loops if they are completely contained in the SCoP. */
2206 if (loop
->header
== bb
2207 && bb_in_scop_p (loop
->latch
, scop
))
2209 if (!scop_record_loop (scop
, loop
))
2214 /* Make sure that the loops in the SCOP_LOOP_NEST are ordered. It
2215 can be the case that an inner loop is inserted before an outer
2216 loop. To avoid this, semi-sort once. */
2217 for (i
= 0; VEC_iterate (loop_p
, SCOP_LOOP_NEST (scop
), i
, loop0
); i
++)
2219 if (VEC_length (loop_p
, SCOP_LOOP_NEST (scop
)) == i
+ 1)
2222 loop1
= VEC_index (loop_p
, SCOP_LOOP_NEST (scop
), i
+ 1);
2223 if (loop0
->num
> loop1
->num
)
2225 VEC_replace (loop_p
, SCOP_LOOP_NEST (scop
), i
, loop1
);
2226 VEC_replace (loop_p
, SCOP_LOOP_NEST (scop
), i
+ 1, loop0
);
2233 /* Build dynamic schedules for all the BBs. */
2236 build_scop_dynamic_schedules (scop_p scop
)
2238 int i
, dim
, loop_num
, row
, col
;
2241 for (i
= 0; VEC_iterate (graphite_bb_p
, SCOP_BBS (scop
), i
, gb
); i
++)
2243 loop_num
= GBB_BB (gb
)->loop_father
->num
;
2247 dim
= nb_loops_around_gb (gb
);
2248 GBB_DYNAMIC_SCHEDULE (gb
) = cloog_matrix_alloc (dim
, dim
);
2250 for (row
= 0; row
< GBB_DYNAMIC_SCHEDULE (gb
)->NbRows
; row
++)
2251 for (col
= 0; col
< GBB_DYNAMIC_SCHEDULE (gb
)->NbColumns
; col
++)
2253 value_set_si (GBB_DYNAMIC_SCHEDULE (gb
)->p
[row
][col
], 1);
2255 value_set_si (GBB_DYNAMIC_SCHEDULE (gb
)->p
[row
][col
], 0);
2258 GBB_DYNAMIC_SCHEDULE (gb
) = NULL
;
2262 /* Build for BB the static schedule.
2264 The STATIC_SCHEDULE is defined like this:
2283 Static schedules for A to F:
2296 build_scop_canonical_schedules (scop_p scop
)
2300 int nb
= scop_nb_loops (scop
) + 1;
2302 SCOP_STATIC_SCHEDULE (scop
) = lambda_vector_new (nb
);
2304 for (i
= 0; VEC_iterate (graphite_bb_p
, SCOP_BBS (scop
), i
, gb
); i
++)
2306 int offset
= nb_loops_around_gb (gb
);
2308 /* After leaving a loop, it is possible that the schedule is not
2309 set at zero. This loop reinitializes components located
2312 for (j
= offset
+ 1; j
< nb
; j
++)
2313 if (SCOP_STATIC_SCHEDULE (scop
)[j
])
2315 memset (&(SCOP_STATIC_SCHEDULE (scop
)[j
]), 0,
2316 sizeof (int) * (nb
- j
));
2317 ++SCOP_STATIC_SCHEDULE (scop
)[offset
];
2321 GBB_STATIC_SCHEDULE (gb
) = lambda_vector_new (offset
+ 1);
2322 lambda_vector_copy (SCOP_STATIC_SCHEDULE (scop
),
2323 GBB_STATIC_SCHEDULE (gb
), offset
+ 1);
2325 ++SCOP_STATIC_SCHEDULE (scop
)[offset
];
2329 /* Build the LOOPS vector for all bbs in SCOP. */
2332 build_bb_loops (scop_p scop
)
2337 for (i
= 0; VEC_iterate (graphite_bb_p
, SCOP_BBS (scop
), i
, gb
); i
++)
2342 depth
= nb_loops_around_gb (gb
) - 1;
2344 GBB_LOOPS (gb
) = VEC_alloc (loop_p
, heap
, 3);
2345 VEC_safe_grow_cleared (loop_p
, heap
, GBB_LOOPS (gb
), depth
+ 1);
2347 loop
= GBB_BB (gb
)->loop_father
;
2349 while (scop_contains_loop (scop
, loop
))
2351 VEC_replace (loop_p
, GBB_LOOPS (gb
), depth
, loop
);
2352 loop
= loop_outer (loop
);
2358 /* Get the index for parameter VAR in SCOP. */
2361 param_index (tree var
, scop_p scop
)
2367 gcc_assert (TREE_CODE (var
) == SSA_NAME
);
2369 for (i
= 0; VEC_iterate (name_tree
, SCOP_PARAMS (scop
), i
, p
); i
++)
2373 gcc_assert (SCOP_ADD_PARAMS (scop
));
2375 nvar
= XNEW (struct name_tree
);
2378 VEC_safe_push (name_tree
, heap
, SCOP_PARAMS (scop
), nvar
);
2379 return VEC_length (name_tree
, SCOP_PARAMS (scop
)) - 1;
2382 /* Scan EXPR and translate it to an inequality vector INEQ that will
2383 be added, or subtracted, in the constraint domain matrix C at row
2384 R. K is the number of columns for loop iterators in C. */
2387 scan_tree_for_params (scop_p s
, tree e
, CloogMatrix
*c
, int r
, Value k
,
2390 int cst_col
, param_col
;
2392 if (e
== chrec_dont_know
)
2395 switch (TREE_CODE (e
))
2397 case POLYNOMIAL_CHREC
:
2399 tree left
= CHREC_LEFT (e
);
2400 tree right
= CHREC_RIGHT (e
);
2401 int var
= CHREC_VARIABLE (e
);
2403 if (TREE_CODE (right
) != INTEGER_CST
)
2408 int loop_col
= scop_gimple_loop_depth (s
, get_loop (var
)) + 1;
2411 value_sub_int (c
->p
[r
][loop_col
], c
->p
[r
][loop_col
],
2412 int_cst_value (right
));
2414 value_add_int (c
->p
[r
][loop_col
], c
->p
[r
][loop_col
],
2415 int_cst_value (right
));
2418 switch (TREE_CODE (left
))
2420 case POLYNOMIAL_CHREC
:
2421 scan_tree_for_params (s
, left
, c
, r
, k
, subtract
);
2425 /* Constant part. */
2428 int v
= int_cst_value (left
);
2429 cst_col
= c
->NbColumns
- 1;
2434 subtract
= subtract
? false : true;
2438 value_sub_int (c
->p
[r
][cst_col
], c
->p
[r
][cst_col
], v
);
2440 value_add_int (c
->p
[r
][cst_col
], c
->p
[r
][cst_col
], v
);
2445 scan_tree_for_params (s
, left
, c
, r
, k
, subtract
);
2452 if (chrec_contains_symbols (TREE_OPERAND (e
, 0)))
2457 gcc_assert (host_integerp (TREE_OPERAND (e
, 1), 0));
2459 value_set_si (val
, int_cst_value (TREE_OPERAND (e
, 1)));
2460 value_multiply (k
, k
, val
);
2463 scan_tree_for_params (s
, TREE_OPERAND (e
, 0), c
, r
, k
, subtract
);
2470 gcc_assert (host_integerp (TREE_OPERAND (e
, 0), 0));
2472 value_set_si (val
, int_cst_value (TREE_OPERAND (e
, 0)));
2473 value_multiply (k
, k
, val
);
2476 scan_tree_for_params (s
, TREE_OPERAND (e
, 1), c
, r
, k
, subtract
);
2481 case POINTER_PLUS_EXPR
:
2482 scan_tree_for_params (s
, TREE_OPERAND (e
, 0), c
, r
, k
, subtract
);
2483 scan_tree_for_params (s
, TREE_OPERAND (e
, 1), c
, r
, k
, subtract
);
2487 scan_tree_for_params (s
, TREE_OPERAND (e
, 0), c
, r
, k
, subtract
);
2488 value_oppose (k
, k
);
2489 scan_tree_for_params (s
, TREE_OPERAND (e
, 1), c
, r
, k
, subtract
);
2493 value_oppose (k
, k
);
2494 scan_tree_for_params (s
, TREE_OPERAND (e
, 0), c
, r
, k
, subtract
);
2498 param_col
= param_index (e
, s
);
2502 param_col
+= c
->NbColumns
- scop_nb_params (s
) - 1;
2505 value_subtract (c
->p
[r
][param_col
], c
->p
[r
][param_col
], k
);
2507 value_addto (c
->p
[r
][param_col
], c
->p
[r
][param_col
], k
);
2514 int v
= int_cst_value (e
);
2515 cst_col
= c
->NbColumns
- 1;
2520 subtract
= subtract
? false : true;
2524 value_sub_int (c
->p
[r
][cst_col
], c
->p
[r
][cst_col
], v
);
2526 value_add_int (c
->p
[r
][cst_col
], c
->p
[r
][cst_col
], v
);
2532 case NON_LVALUE_EXPR
:
2533 scan_tree_for_params (s
, TREE_OPERAND (e
, 0), c
, r
, k
, subtract
);
2542 /* Data structure for idx_record_params. */
2550 /* For a data reference with an ARRAY_REF as its BASE, record the
2551 parameters occurring in IDX. DTA is passed in as complementary
2552 information, and is used by the automatic walker function. This
2553 function is a callback for for_each_index. */
2556 idx_record_params (tree base
, tree
*idx
, void *dta
)
2558 struct irp_data
*data
= (struct irp_data
*) dta
;
2560 if (TREE_CODE (base
) != ARRAY_REF
)
2563 if (TREE_CODE (*idx
) == SSA_NAME
)
2566 scop_p scop
= data
->scop
;
2567 struct loop
*loop
= data
->loop
;
2570 scev
= analyze_scalar_evolution (loop
, *idx
);
2571 scev
= instantiate_scev (block_before_scop (scop
), loop
, scev
);
2574 value_set_si (one
, 1);
2575 scan_tree_for_params (scop
, scev
, NULL
, 0, one
, false);
2582 /* Find parameters with respect to SCOP in BB. We are looking in memory
2583 access functions, conditions and loop bounds. */
2586 find_params_in_bb (scop_p scop
, graphite_bb_p gb
)
2589 data_reference_p dr
;
2591 loop_p father
= GBB_BB (gb
)->loop_father
;
2593 for (i
= 0; VEC_iterate (data_reference_p
, GBB_DATA_REFS (gb
), i
, dr
); i
++)
2595 struct irp_data irp
;
2599 for_each_index (&dr
->ref
, idx_record_params
, &irp
);
2602 /* Find parameters in conditional statements. */
2603 for (i
= 0; VEC_iterate (gimple
, GBB_CONDITIONS (gb
), i
, stmt
); i
++)
2606 loop_p loop
= father
;
2610 lhs
= gimple_cond_lhs (stmt
);
2611 lhs
= analyze_scalar_evolution (loop
, lhs
);
2612 lhs
= instantiate_scev (block_before_scop (scop
), loop
, lhs
);
2614 rhs
= gimple_cond_rhs (stmt
);
2615 rhs
= analyze_scalar_evolution (loop
, rhs
);
2616 rhs
= instantiate_scev (block_before_scop (scop
), loop
, rhs
);
2619 scan_tree_for_params (scop
, lhs
, NULL
, 0, one
, false);
2620 value_set_si (one
, 1);
2621 scan_tree_for_params (scop
, rhs
, NULL
, 0, one
, false);
2626 /* Saves in NV the name of variable P->T. */
2629 save_var_name (char **nv
, int i
, name_tree p
)
2631 const char *name
= get_name (SSA_NAME_VAR (p
->t
));
2635 int len
= strlen (name
) + 16;
2636 nv
[i
] = XNEWVEC (char, len
);
2637 snprintf (nv
[i
], len
, "%s_%d", name
, SSA_NAME_VERSION (p
->t
));
2641 nv
[i
] = XNEWVEC (char, 16);
2642 snprintf (nv
[i
], 2 + 16, "T_%d", SSA_NAME_VERSION (p
->t
));
2648 /* Return the maximal loop depth in SCOP. */
2651 scop_max_loop_depth (scop_p scop
)
2655 int max_nb_loops
= 0;
2657 for (i
= 0; VEC_iterate (graphite_bb_p
, SCOP_BBS (scop
), i
, gbb
); i
++)
2659 int nb_loops
= gbb_nb_loops (gbb
);
2660 if (max_nb_loops
< nb_loops
)
2661 max_nb_loops
= nb_loops
;
2664 return max_nb_loops
;
2667 /* Initialize Cloog's parameter names from the names used in GIMPLE.
2668 Initialize Cloog's iterator names, using 'graphite_iterator_%d'
2669 from 0 to scop_nb_loops (scop). */
2672 initialize_cloog_names (scop_p scop
)
2674 int i
, nb_params
= VEC_length (name_tree
, SCOP_PARAMS (scop
));
2675 char **params
= XNEWVEC (char *, nb_params
);
2676 int nb_iterators
= scop_max_loop_depth (scop
);
2677 int nb_scattering
= cloog_program_nb_scattdims (SCOP_PROG (scop
));
2678 char **iterators
= XNEWVEC (char *, nb_iterators
* 2);
2679 char **scattering
= XNEWVEC (char *, nb_scattering
);
2682 for (i
= 0; VEC_iterate (name_tree
, SCOP_PARAMS (scop
), i
, p
); i
++)
2683 save_var_name (params
, i
, p
);
2685 cloog_names_set_nb_parameters (cloog_program_names (SCOP_PROG (scop
)),
2687 cloog_names_set_parameters (cloog_program_names (SCOP_PROG (scop
)),
2690 for (i
= 0; i
< nb_iterators
; i
++)
2693 iterators
[i
] = XNEWVEC (char, len
);
2694 snprintf (iterators
[i
], len
, "graphite_iterator_%d", i
);
2697 cloog_names_set_nb_iterators (cloog_program_names (SCOP_PROG (scop
)),
2699 cloog_names_set_iterators (cloog_program_names (SCOP_PROG (scop
)),
2702 for (i
= 0; i
< nb_scattering
; i
++)
2705 scattering
[i
] = XNEWVEC (char, len
);
2706 snprintf (scattering
[i
], len
, "s_%d", i
);
2709 cloog_names_set_nb_scattering (cloog_program_names (SCOP_PROG (scop
)),
2711 cloog_names_set_scattering (cloog_program_names (SCOP_PROG (scop
)),
2715 /* Record the parameters used in the SCOP. A variable is a parameter
2716 in a scop if it does not vary during the execution of that scop. */
2719 find_scop_parameters (scop_p scop
)
2727 value_set_si (one
, 1);
2729 /* Find the parameters used in the loop bounds. */
2730 for (i
= 0; VEC_iterate (loop_p
, SCOP_LOOP_NEST (scop
), i
, loop
); i
++)
2732 tree nb_iters
= number_of_latch_executions (loop
);
2734 if (!chrec_contains_symbols (nb_iters
))
2737 nb_iters
= analyze_scalar_evolution (loop
, nb_iters
);
2738 nb_iters
= instantiate_scev (block_before_scop (scop
), loop
, nb_iters
);
2739 scan_tree_for_params (scop
, nb_iters
, NULL
, 0, one
, false);
2744 /* Find the parameters used in data accesses. */
2745 for (i
= 0; VEC_iterate (graphite_bb_p
, SCOP_BBS (scop
), i
, gb
); i
++)
2746 find_params_in_bb (scop
, gb
);
2748 SCOP_ADD_PARAMS (scop
) = false;
2751 /* Build the context constraints for SCOP: constraints and relations
2755 build_scop_context (scop_p scop
)
2757 int nb_params
= scop_nb_params (scop
);
2758 CloogMatrix
*matrix
= cloog_matrix_alloc (1, nb_params
+ 2);
2760 /* Insert '0 >= 0' in the context matrix, as it is not allowed to be
2763 value_set_si (matrix
->p
[0][0], 1);
2765 value_set_si (matrix
->p
[0][nb_params
+ 1], 0);
2767 cloog_program_set_context (SCOP_PROG (scop
),
2768 cloog_domain_matrix2domain (matrix
));
2769 cloog_matrix_free (matrix
);
2772 /* Returns a graphite_bb from BB. */
2774 static inline graphite_bb_p
2775 gbb_from_bb (basic_block bb
)
2777 return (graphite_bb_p
) bb
->aux
;
2780 /* Builds the constraint matrix for LOOP in SCOP. NB_OUTER_LOOPS is the
2781 number of loops surrounding LOOP in SCOP. OUTER_CSTR gives the
2782 constraints matrix for the surrounding loops. */
2785 build_loop_iteration_domains (scop_p scop
, struct loop
*loop
,
2786 CloogMatrix
*outer_cstr
, int nb_outer_loops
)
2792 int nb_rows
= outer_cstr
->NbRows
+ 1;
2793 int nb_cols
= outer_cstr
->NbColumns
+ 1;
2795 /* Last column of CSTR is the column of constants. */
2796 int cst_col
= nb_cols
- 1;
2798 /* The column for the current loop is just after the columns of
2799 other outer loops. */
2800 int loop_col
= nb_outer_loops
+ 1;
2802 tree nb_iters
= number_of_latch_executions (loop
);
2804 /* When the number of iterations is a constant or a parameter, we
2805 add a constraint for the upper bound of the loop. So add a row
2806 to the constraint matrix before allocating it. */
2807 if (TREE_CODE (nb_iters
) == INTEGER_CST
2808 || !chrec_contains_undetermined (nb_iters
))
2811 cstr
= cloog_matrix_alloc (nb_rows
, nb_cols
);
2813 /* Copy the outer constraints. */
2814 for (i
= 0; i
< outer_cstr
->NbRows
; i
++)
2816 /* Copy the eq/ineq and loops columns. */
2817 for (j
= 0; j
< loop_col
; j
++)
2818 value_assign (cstr
->p
[i
][j
], outer_cstr
->p
[i
][j
]);
2820 /* Leave an empty column in CSTR for the current loop, and then
2821 copy the parameter columns. */
2822 for (j
= loop_col
; j
< outer_cstr
->NbColumns
; j
++)
2823 value_assign (cstr
->p
[i
][j
+ 1], outer_cstr
->p
[i
][j
]);
2827 row
= outer_cstr
->NbRows
;
2828 value_set_si (cstr
->p
[row
][0], 1);
2829 value_set_si (cstr
->p
[row
][loop_col
], 1);
2831 /* loop_i <= nb_iters */
2832 if (TREE_CODE (nb_iters
) == INTEGER_CST
)
2835 value_set_si (cstr
->p
[row
][0], 1);
2836 value_set_si (cstr
->p
[row
][loop_col
], -1);
2838 value_set_si (cstr
->p
[row
][cst_col
],
2839 int_cst_value (nb_iters
));
2841 else if (!chrec_contains_undetermined (nb_iters
))
2843 /* Otherwise nb_iters contains parameters: scan the nb_iters
2844 expression and build its matrix representation. */
2848 value_set_si (cstr
->p
[row
][0], 1);
2849 value_set_si (cstr
->p
[row
][loop_col
], -1);
2851 nb_iters
= analyze_scalar_evolution (loop
, nb_iters
);
2852 nb_iters
= instantiate_scev (block_before_scop (scop
), loop
, nb_iters
);
2855 value_set_si (one
, 1);
2856 scan_tree_for_params (scop
, nb_iters
, cstr
, row
, one
, false);
2862 if (loop
->inner
&& loop_in_scop_p (loop
->inner
, scop
))
2863 build_loop_iteration_domains (scop
, loop
->inner
, cstr
, nb_outer_loops
+ 1);
2865 /* Only go to the next loops, if we are not at the outermost layer. These
2866 have to be handled seperately, as we can be sure, that the chain at this
2867 layer will be connected. */
2868 if (nb_outer_loops
!= 0 && loop
->next
&& loop_in_scop_p (loop
->next
, scop
))
2869 build_loop_iteration_domains (scop
, loop
->next
, outer_cstr
, nb_outer_loops
);
2871 for (i
= 0; VEC_iterate (graphite_bb_p
, SCOP_BBS (scop
), i
, gb
); i
++)
2872 if (gbb_loop (gb
) == loop
)
2873 GBB_DOMAIN (gb
) = cloog_matrix_copy (cstr
);
2875 cloog_matrix_free (cstr
);
2878 /* Add conditions to the domain of GB. */
2881 add_conditions_to_domain (graphite_bb_p gb
)
2885 VEC (gimple
, heap
) *conditions
= GBB_CONDITIONS (gb
);
2886 CloogMatrix
*domain
= GBB_DOMAIN (gb
);
2887 scop_p scop
= GBB_SCOP (gb
);
2891 unsigned nb_new_rows
= 0;
2894 if (VEC_empty (gimple
, conditions
))
2899 nb_rows
= domain
->NbRows
;
2900 nb_cols
= domain
->NbColumns
;
2905 nb_cols
= scop_nb_params (scop
) + 2;
2908 /* Count number of necessary new rows to add the conditions to the
2910 for (i
= 0; VEC_iterate (gimple
, conditions
, i
, stmt
); i
++)
2912 switch (gimple_code (stmt
))
2916 enum tree_code code
= gimple_cond_code (stmt
);
2922 /* NE and EQ statements are not supported right know. */
2938 /* Switch statements are not supported right know. */
2949 /* Enlarge the matrix. */
2951 CloogMatrix
*new_domain
;
2952 new_domain
= cloog_matrix_alloc (nb_rows
+ nb_new_rows
, nb_cols
);
2954 for (i
= 0; i
< nb_rows
; i
++)
2955 for (j
= 0; j
< nb_cols
; j
++)
2956 value_assign (new_domain
->p
[i
][j
], domain
->p
[i
][j
]);
2958 cloog_matrix_free (domain
);
2959 domain
= new_domain
;
2960 GBB_DOMAIN (gb
) = new_domain
;
2963 /* Add the conditions to the new enlarged domain matrix. */
2965 for (i
= 0; VEC_iterate (gimple
, conditions
, i
, stmt
); i
++)
2967 switch (gimple_code (stmt
))
2972 enum tree_code code
;
2975 loop_p loop
= GBB_BB (gb
)->loop_father
;
2977 left
= gimple_cond_lhs (stmt
);
2978 right
= gimple_cond_rhs (stmt
);
2980 left
= analyze_scalar_evolution (loop
, left
);
2981 right
= analyze_scalar_evolution (loop
, right
);
2983 left
= instantiate_scev (block_before_scop (scop
), loop
, left
);
2984 right
= instantiate_scev (block_before_scop (scop
), loop
, right
);
2986 code
= gimple_cond_code (stmt
);
2988 /* The conditions for ELSE-branches are inverted. */
2989 if (VEC_index (gimple
, gb
->condition_cases
, i
) == NULL
)
2990 code
= invert_tree_comparison (code
, false);
2995 /* NE statements are not supported right know. */
2999 value_set_si (domain
->p
[row
][0], 1);
3001 value_set_si (one
, 1);
3002 scan_tree_for_params (scop
, left
, domain
, row
, one
, true);
3003 value_set_si (one
, 1);
3004 scan_tree_for_params (scop
, right
, domain
, row
, one
, false);
3006 value_set_si (domain
->p
[row
][0], 1);
3007 value_set_si (one
, 1);
3008 scan_tree_for_params (scop
, left
, domain
, row
, one
, false);
3009 value_set_si (one
, 1);
3010 scan_tree_for_params (scop
, right
, domain
, row
, one
, true);
3015 value_set_si (domain
->p
[row
][0], 1);
3017 value_set_si (one
, 1);
3018 scan_tree_for_params (scop
, left
, domain
, row
, one
, true);
3019 value_set_si (one
, 1);
3020 scan_tree_for_params (scop
, right
, domain
, row
, one
, false);
3021 value_sub_int (domain
->p
[row
][nb_cols
- 1],
3022 domain
->p
[row
][nb_cols
- 1], 1);
3027 value_set_si (domain
->p
[row
][0], 1);
3029 value_set_si (one
, 1);
3030 scan_tree_for_params (scop
, left
, domain
, row
, one
, false);
3031 value_set_si (one
, 1);
3032 scan_tree_for_params (scop
, right
, domain
, row
, one
, true);
3033 value_sub_int (domain
->p
[row
][nb_cols
- 1],
3034 domain
->p
[row
][nb_cols
- 1], 1);
3039 value_set_si (domain
->p
[row
][0], 1);
3041 value_set_si (one
, 1);
3042 scan_tree_for_params (scop
, left
, domain
, row
, one
, true);
3043 value_set_si (one
, 1);
3044 scan_tree_for_params (scop
, right
, domain
, row
, one
, false);
3049 value_set_si (domain
->p
[row
][0], 1);
3051 value_set_si (one
, 1);
3052 scan_tree_for_params (scop
, left
, domain
, row
, one
, false);
3053 value_set_si (one
, 1);
3054 scan_tree_for_params (scop
, right
, domain
, row
, one
, true);
3065 /* Switch statements are not supported right know. */
3076 /* Helper recursive function. */
3079 build_scop_conditions_1 (VEC (gimple
, heap
) **conditions
,
3080 VEC (gimple
, heap
) **cases
, basic_block bb
,
3085 gimple_stmt_iterator gsi
;
3086 basic_block bb_child
, bb_iter
;
3087 VEC (basic_block
, heap
) *dom
;
3089 /* Make sure we are in the SCoP. */
3090 if (!bb_in_scop_p (bb
, scop
))
3093 /* Record conditions in graphite_bb. */
3094 gbb
= gbb_from_bb (bb
);
3097 GBB_CONDITIONS (gbb
) = VEC_copy (gimple
, heap
, *conditions
);
3098 GBB_CONDITION_CASES (gbb
) = VEC_copy (gimple
, heap
, *cases
);
3099 add_conditions_to_domain (gbb
);
3102 dom
= get_dominated_by (CDI_DOMINATORS
, bb
);
3104 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
3106 gimple stmt
= gsi_stmt (gsi
);
3107 VEC (edge
, gc
) *edges
;
3110 switch (gimple_code (stmt
))
3114 for (i
= 0; VEC_iterate (edge
, edges
, i
, e
); i
++)
3115 if ((dominated_by_p (CDI_DOMINATORS
, e
->dest
, bb
))
3116 && VEC_length (edge
, e
->dest
->preds
) == 1)
3118 /* Remove the scanned block from the dominator successors. */
3119 for (j
= 0; VEC_iterate (basic_block
, dom
, j
, bb_iter
); j
++)
3120 if (bb_iter
== e
->dest
)
3122 VEC_unordered_remove (basic_block
, dom
, j
);
3126 /* Recursively scan the then or else part. */
3127 if (e
->flags
& EDGE_TRUE_VALUE
)
3128 VEC_safe_push (gimple
, heap
, *cases
, stmt
);
3129 else if (e
->flags
& EDGE_FALSE_VALUE
)
3130 VEC_safe_push (gimple
, heap
, *cases
, NULL
);
3134 VEC_safe_push (gimple
, heap
, *conditions
, stmt
);
3135 build_scop_conditions_1 (conditions
, cases
, e
->dest
, scop
);
3136 VEC_pop (gimple
, *conditions
);
3137 VEC_pop (gimple
, *cases
);
3144 gimple_stmt_iterator gsi_search_gimple_label
;
3146 for (i
= 0; i
< gimple_switch_num_labels (stmt
); ++i
)
3148 basic_block bb_iter
;
3150 size_t n_cases
= VEC_length (gimple
, *conditions
);
3151 unsigned n
= gimple_switch_num_labels (stmt
);
3153 bb_child
= label_to_block
3154 (CASE_LABEL (gimple_switch_label (stmt
, i
)));
3156 /* Do not handle multiple values for the same block. */
3157 for (k
= 0; k
< n
; k
++)
3160 (CASE_LABEL (gimple_switch_label (stmt
, k
))) == bb_child
)
3166 /* Switch cases with more than one predecessor are not
3168 if (VEC_length (edge
, bb_child
->preds
) != 1)
3171 /* Recursively scan the corresponding 'case' block. */
3173 for (gsi_search_gimple_label
= gsi_start_bb (bb_child
);
3174 !gsi_end_p (gsi_search_gimple_label
);
3175 gsi_next (&gsi_search_gimple_label
))
3177 gimple stmt_gimple_label
3178 = gsi_stmt (gsi_search_gimple_label
);
3180 if (gimple_code (stmt_gimple_label
) == GIMPLE_LABEL
)
3182 tree t
= gimple_label_label (stmt_gimple_label
);
3184 if (t
== gimple_switch_label (stmt
, i
))
3185 VEC_replace (gimple
, *cases
, n_cases
,
3192 build_scop_conditions_1 (conditions
, cases
, bb_child
, scop
);
3194 /* Remove the scanned block from the dominator successors. */
3195 for (j
= 0; VEC_iterate (basic_block
, dom
, j
, bb_iter
); j
++)
3196 if (bb_iter
== bb_child
)
3198 VEC_unordered_remove (basic_block
, dom
, j
);
3203 VEC_pop (gimple
, *conditions
);
3204 VEC_pop (gimple
, *cases
);
3212 /* Scan all immediate dominated successors. */
3213 for (i
= 0; VEC_iterate (basic_block
, dom
, i
, bb_child
); i
++)
3214 build_scop_conditions_1 (conditions
, cases
, bb_child
, scop
);
3216 VEC_free (basic_block
, heap
, dom
);
3219 /* Record all 'if' and 'switch' conditions in each gbb of SCOP. */
3222 build_scop_conditions (scop_p scop
)
3224 VEC (gimple
, heap
) *conditions
= NULL
;
3225 VEC (gimple
, heap
) *cases
= NULL
;
3227 build_scop_conditions_1 (&conditions
, &cases
, SCOP_ENTRY (scop
), scop
);
3229 VEC_free (gimple
, heap
, conditions
);
3230 VEC_free (gimple
, heap
, cases
);
3233 /* Build the current domain matrix: the loops belonging to the current
3234 SCOP, and that vary for the execution of the current basic block.
3235 Returns false if there is no loop in SCOP. */
3238 build_scop_iteration_domain (scop_p scop
)
3241 CloogMatrix
*outer_cstr
;
3244 /* Build cloog loop for all loops, that are in the uppermost loop layer of
3246 for (i
= 0; VEC_iterate (loop_p
, SCOP_LOOP_NEST (scop
), i
, loop
); i
++)
3247 if (!loop_in_scop_p (loop_outer (loop
), scop
))
3249 /* The outermost constraints is a matrix that has:
3250 -first column: eq/ineq boolean
3251 -last column: a constant
3252 -scop_nb_params columns for the parameters used in the scop. */
3253 outer_cstr
= cloog_matrix_alloc (0, scop_nb_params (scop
) + 2);
3254 build_loop_iteration_domains (scop
, loop
, outer_cstr
, 0);
3255 cloog_matrix_free (outer_cstr
);
3261 /* Initializes an equation CY of the access matrix using the
3262 information for a subscript from AF, relatively to the loop
3263 indexes from LOOP_NEST and parameter indexes from PARAMS. NDIM is
3264 the dimension of the array access, i.e. the number of
3265 subscripts. Returns true when the operation succeeds. */
3268 build_access_matrix_with_af (tree af
, lambda_vector cy
,
3269 scop_p scop
, int ndim
)
3273 switch (TREE_CODE (af
))
3275 case POLYNOMIAL_CHREC
:
3277 struct loop
*outer_loop
;
3278 tree left
= CHREC_LEFT (af
);
3279 tree right
= CHREC_RIGHT (af
);
3282 if (TREE_CODE (right
) != INTEGER_CST
)
3285 outer_loop
= get_loop (CHREC_VARIABLE (af
));
3286 var
= nb_loops_around_loop_in_scop (outer_loop
, scop
);
3287 cy
[var
] = int_cst_value (right
);
3289 switch (TREE_CODE (left
))
3291 case POLYNOMIAL_CHREC
:
3292 return build_access_matrix_with_af (left
, cy
, scop
, ndim
);
3295 cy
[ndim
- 1] = int_cst_value (left
);
3299 return build_access_matrix_with_af (left
, cy
, scop
, ndim
);
3304 build_access_matrix_with_af (TREE_OPERAND (af
, 0), cy
, scop
, ndim
);
3305 build_access_matrix_with_af (TREE_OPERAND (af
, 1), cy
, scop
, ndim
);
3309 build_access_matrix_with_af (TREE_OPERAND (af
, 0), cy
, scop
, ndim
);
3310 build_access_matrix_with_af (TREE_OPERAND (af
, 1), cy
, scop
, ndim
);
3314 cy
[ndim
- 1] = int_cst_value (af
);
3318 param_col
= param_index (af
, scop
);
3319 cy
[ndim
- scop_nb_params (scop
) + param_col
- 1] = 1;
3323 /* FIXME: access_fn can have parameters. */
3328 /* Initialize the access matrix in the data reference REF with respect
3329 to the loop nesting LOOP_NEST. Return true when the operation
3333 build_access_matrix (data_reference_p ref
, graphite_bb_p gb
)
3335 int i
, ndim
= DR_NUM_DIMENSIONS (ref
);
3336 struct access_matrix
*am
= GGC_NEW (struct access_matrix
);
3338 AM_MATRIX (am
) = VEC_alloc (lambda_vector
, heap
, ndim
);
3339 DR_SCOP (ref
) = GBB_SCOP (gb
);
3341 for (i
= 0; i
< ndim
; i
++)
3343 lambda_vector v
= lambda_vector_new (ref_nb_loops (ref
));
3344 scop_p scop
= GBB_SCOP (gb
);
3345 tree af
= DR_ACCESS_FN (ref
, i
);
3347 if (!build_access_matrix_with_af (af
, v
, scop
, ref_nb_loops (ref
)))
3350 VEC_safe_push (lambda_vector
, heap
, AM_MATRIX (am
), v
);
3353 DR_ACCESS_MATRIX (ref
) = am
;
3357 /* Build the access matrices for the data references in the SCOP. */
3360 build_scop_data_accesses (scop_p scop
)
3365 /* FIXME: Construction of access matrix is disabled until some
3366 pass, like the data dependence analysis, is using it. */
3369 for (i
= 0; VEC_iterate (graphite_bb_p
, SCOP_BBS (scop
), i
, gb
); i
++)
3372 data_reference_p dr
;
3374 /* Construct the access matrix for each data ref, with respect to
3375 the loop nest of the current BB in the considered SCOP. */
3377 VEC_iterate (data_reference_p
, GBB_DATA_REFS (gb
), j
, dr
);
3380 bool res
= build_access_matrix (dr
, gb
);
3382 /* FIXME: At this point the DRs should always have an affine
3383 form. For the moment this fails as build_access_matrix
3384 does not build matrices with parameters. */
3390 /* Returns the tree variable from the name NAME that was given in
3391 Cloog representation. All the parameters are stored in PARAMS, and
3392 all the loop induction variables are stored in IVSTACK.
3394 FIXME: This is a hack, and Cloog should be fixed to not work with
3395 variable names represented as "char *string", but with void
3396 pointers that could be casted back to a tree. The only problem in
3397 doing that is that Cloog's pretty printer still assumes that
3398 variable names are char *strings. The solution would be to have a
3399 function pointer for pretty-printing that can be redirected to be
3400 print_generic_stmt in our case, or fprintf by default.
3401 ??? Too ugly to live. */
3404 clast_name_to_gcc (const char *name
, VEC (name_tree
, heap
) *params
,
3405 loop_iv_stack ivstack
)
3412 for (i
= 0; VEC_iterate (name_tree
, params
, i
, t
); i
++)
3413 if (!strcmp (name
, t
->name
))
3416 iv
= loop_iv_stack_get_iv_from_name (ivstack
, name
);
3423 /* Returns the maximal precision type for expressions E1 and E2. */
3426 max_precision_type (tree e1
, tree e2
)
3428 tree type1
= TREE_TYPE (e1
);
3429 tree type2
= TREE_TYPE (e2
);
3430 return TYPE_PRECISION (type1
) > TYPE_PRECISION (type2
) ? type1
: type2
;
3433 /* Converts a Cloog AST expression E back to a GCC expression tree
3437 clast_to_gcc_expression (tree type
, struct clast_expr
*e
,
3438 VEC (name_tree
, heap
) *params
,
3439 loop_iv_stack ivstack
)
3445 struct clast_term
*t
= (struct clast_term
*) e
;
3449 if (value_one_p (t
->val
))
3451 tree name
= clast_name_to_gcc (t
->var
, params
, ivstack
);
3452 return fold_convert (type
, name
);
3455 else if (value_mone_p (t
->val
))
3457 tree name
= clast_name_to_gcc (t
->var
, params
, ivstack
);
3458 name
= fold_convert (type
, name
);
3459 return fold_build1 (NEGATE_EXPR
, type
, name
);
3463 tree name
= clast_name_to_gcc (t
->var
, params
, ivstack
);
3464 tree cst
= gmp_cst_to_tree (type
, t
->val
);
3465 name
= fold_convert (type
, name
);
3466 return fold_build2 (MULT_EXPR
, type
, cst
, name
);
3470 return gmp_cst_to_tree (type
, t
->val
);
3475 struct clast_reduction
*r
= (struct clast_reduction
*) e
;
3481 return clast_to_gcc_expression (type
, r
->elts
[0], params
, ivstack
);
3485 tree tl
= clast_to_gcc_expression (type
, r
->elts
[0], params
, ivstack
);
3486 tree tr
= clast_to_gcc_expression (type
, r
->elts
[1], params
, ivstack
);
3488 gcc_assert (r
->n
>= 1
3489 && r
->elts
[0]->type
== expr_term
3490 && r
->elts
[1]->type
== expr_term
);
3492 return fold_build2 (PLUS_EXPR
, type
, tl
, tr
);
3499 return clast_to_gcc_expression (type
, r
->elts
[0], params
, ivstack
);
3503 tree tl
= clast_to_gcc_expression (type
, r
->elts
[0], params
, ivstack
);
3504 tree tr
= clast_to_gcc_expression (type
, r
->elts
[1], params
, ivstack
);
3505 return fold_build2 (MIN_EXPR
, type
, tl
, tr
);
3515 return clast_to_gcc_expression (type
, r
->elts
[0], params
, ivstack
);
3519 tree tl
= clast_to_gcc_expression (type
, r
->elts
[0], params
, ivstack
);
3520 tree tr
= clast_to_gcc_expression (type
, r
->elts
[1], params
, ivstack
);
3521 return fold_build2 (MAX_EXPR
, type
, tl
, tr
);
3537 struct clast_binary
*b
= (struct clast_binary
*) e
;
3538 struct clast_expr
*lhs
= (struct clast_expr
*) b
->LHS
;
3539 tree tl
= clast_to_gcc_expression (type
, lhs
, params
, ivstack
);
3540 tree tr
= gmp_cst_to_tree (type
, b
->RHS
);
3544 case clast_bin_fdiv
:
3545 return fold_build2 (FLOOR_DIV_EXPR
, type
, tl
, tr
);
3547 case clast_bin_cdiv
:
3548 return fold_build2 (CEIL_DIV_EXPR
, type
, tl
, tr
);
3551 return fold_build2 (EXACT_DIV_EXPR
, type
, tl
, tr
);
3554 return fold_build2 (TRUNC_MOD_EXPR
, type
, tl
, tr
);
3568 /* Returns the type for the expression E. */
3571 gcc_type_for_clast_expr (struct clast_expr
*e
,
3572 VEC (name_tree
, heap
) *params
,
3573 loop_iv_stack ivstack
)
3579 struct clast_term
*t
= (struct clast_term
*) e
;
3582 return TREE_TYPE (clast_name_to_gcc (t
->var
, params
, ivstack
));
3589 struct clast_reduction
*r
= (struct clast_reduction
*) e
;
3592 return gcc_type_for_clast_expr (r
->elts
[0], params
, ivstack
);
3596 for (i
= 0; i
< r
->n
; i
++)
3598 tree type
= gcc_type_for_clast_expr (r
->elts
[i
], params
, ivstack
);
3608 struct clast_binary
*b
= (struct clast_binary
*) e
;
3609 struct clast_expr
*lhs
= (struct clast_expr
*) b
->LHS
;
3610 return gcc_type_for_clast_expr (lhs
, params
, ivstack
);
3620 /* Returns the type for the equation CLEQ. */
3623 gcc_type_for_clast_eq (struct clast_equation
*cleq
,
3624 VEC (name_tree
, heap
) *params
,
3625 loop_iv_stack ivstack
)
3627 tree type
= gcc_type_for_clast_expr (cleq
->LHS
, params
, ivstack
);
3631 return gcc_type_for_clast_expr (cleq
->RHS
, params
, ivstack
);
3634 /* Translates a clast equation CLEQ to a tree. */
3637 graphite_translate_clast_equation (scop_p scop
,
3638 struct clast_equation
*cleq
,
3639 loop_iv_stack ivstack
)
3641 enum tree_code comp
;
3642 tree type
= gcc_type_for_clast_eq (cleq
, SCOP_PARAMS (scop
), ivstack
);
3643 tree lhs
= clast_to_gcc_expression (type
, cleq
->LHS
, SCOP_PARAMS (scop
), ivstack
);
3644 tree rhs
= clast_to_gcc_expression (type
, cleq
->RHS
, SCOP_PARAMS (scop
), ivstack
);
3646 if (cleq
->sign
== 0)
3649 else if (cleq
->sign
> 0)
3655 return fold_build2 (comp
, type
, lhs
, rhs
);
3658 /* Creates the test for the condition in STMT. */
3661 graphite_create_guard_cond_expr (scop_p scop
, struct clast_guard
*stmt
,
3662 loop_iv_stack ivstack
)
3667 for (i
= 0; i
< stmt
->n
; i
++)
3669 tree eq
= graphite_translate_clast_equation (scop
, &stmt
->eq
[i
], ivstack
);
3672 cond
= fold_build2 (TRUTH_AND_EXPR
, TREE_TYPE (eq
), cond
, eq
);
3680 /* Creates a new if region corresponding to Cloog's guard. */
3683 graphite_create_new_guard (scop_p scop
, edge entry_edge
,
3684 struct clast_guard
*stmt
,
3685 loop_iv_stack ivstack
)
3687 tree cond_expr
= graphite_create_guard_cond_expr (scop
, stmt
, ivstack
);
3688 edge exit_edge
= create_empty_if_region_on_edge (entry_edge
, cond_expr
);
3692 /* Walks a CLAST and returns the first statement in the body of a
3695 static struct clast_user_stmt
*
3696 clast_get_body_of_loop (struct clast_stmt
*stmt
)
3699 || CLAST_STMT_IS_A (stmt
, stmt_user
))
3700 return (struct clast_user_stmt
*) stmt
;
3702 if (CLAST_STMT_IS_A (stmt
, stmt_for
))
3703 return clast_get_body_of_loop (((struct clast_for
*) stmt
)->body
);
3705 if (CLAST_STMT_IS_A (stmt
, stmt_guard
))
3706 return clast_get_body_of_loop (((struct clast_guard
*) stmt
)->then
);
3708 if (CLAST_STMT_IS_A (stmt
, stmt_block
))
3709 return clast_get_body_of_loop (((struct clast_block
*) stmt
)->body
);
3714 /* Returns the induction variable for the loop that gets translated to
3718 gcc_type_for_iv_of_clast_loop (struct clast_for
*stmt_for
)
3720 struct clast_user_stmt
*stmt
= clast_get_body_of_loop ((struct clast_stmt
*) stmt_for
);
3721 const char *cloog_iv
= stmt_for
->iterator
;
3722 CloogStatement
*cs
= stmt
->statement
;
3723 graphite_bb_p gbb
= (graphite_bb_p
) cloog_statement_usr (cs
);
3725 return gcc_type_for_cloog_iv (cloog_iv
, gbb
);
3728 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an induction
3729 variable for the new LOOP. New LOOP is attached to CFG starting at
3730 ENTRY_EDGE. LOOP is inserted into the loop tree and becomes the child
3731 loop of the OUTER_LOOP. */
3733 static struct loop
*
3734 graphite_create_new_loop (scop_p scop
, edge entry_edge
,
3735 struct clast_for
*stmt
, loop_iv_stack ivstack
,
3738 tree type
= gcc_type_for_iv_of_clast_loop (stmt
);
3739 VEC (name_tree
, heap
) *params
= SCOP_PARAMS (scop
);
3740 tree lb
= clast_to_gcc_expression (type
, stmt
->LB
, params
, ivstack
);
3741 tree ub
= clast_to_gcc_expression (type
, stmt
->UB
, params
, ivstack
);
3742 tree stride
= gmp_cst_to_tree (type
, stmt
->stride
);
3743 tree ivvar
= create_tmp_var (type
, "graphiteIV");
3745 loop_p loop
= create_empty_loop_on_edge
3746 (entry_edge
, lb
, stride
, ub
, ivvar
, &iv_before
,
3747 outer
? outer
: entry_edge
->src
->loop_father
);
3749 add_referenced_var (ivvar
);
3750 loop_iv_stack_push_iv (ivstack
, iv_before
, stmt
->iterator
);
3754 /* Structure containing the mapping between the old names and the new
3755 names used after block copy in the new loop context. */
3756 typedef struct rename_map_elt
3758 tree old_name
, new_name
;
3762 /* Print to stderr the element ELT. */
3765 debug_rename_elt (rename_map_elt elt
)
3767 fprintf (stderr
, "(");
3768 print_generic_expr (stderr
, elt
->old_name
, 0);
3769 fprintf (stderr
, ", ");
3770 print_generic_expr (stderr
, elt
->new_name
, 0);
3771 fprintf (stderr
, ")\n");
3774 /* Helper function for debug_rename_map. */
3777 debug_rename_map_1 (void **slot
, void *s ATTRIBUTE_UNUSED
)
3779 struct rename_map_elt
*entry
= (struct rename_map_elt
*) *slot
;
3780 debug_rename_elt (entry
);
3784 /* Print to stderr all the elements of MAP. */
3787 debug_rename_map (htab_t map
)
3789 htab_traverse (map
, debug_rename_map_1
, NULL
);
3792 /* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW. */
3794 static inline rename_map_elt
3795 new_rename_map_elt (tree old_name
, tree new_name
)
3799 res
= XNEW (struct rename_map_elt
);
3800 res
->old_name
= old_name
;
3801 res
->new_name
= new_name
;
3806 /* Computes a hash function for database element ELT. */
3809 rename_map_elt_info (const void *elt
)
3811 return htab_hash_pointer (((const struct rename_map_elt
*) elt
)->old_name
);
3814 /* Compares database elements E1 and E2. */
3817 eq_rename_map_elts (const void *e1
, const void *e2
)
3819 const struct rename_map_elt
*elt1
= (const struct rename_map_elt
*) e1
;
3820 const struct rename_map_elt
*elt2
= (const struct rename_map_elt
*) e2
;
3822 return (elt1
->old_name
== elt2
->old_name
);
3825 /* Returns the new name associated to OLD_NAME in MAP. */
3828 get_new_name_from_old_name (htab_t map
, tree old_name
)
3830 struct rename_map_elt tmp
;
3833 tmp
.old_name
= old_name
;
3834 slot
= htab_find_slot (map
, &tmp
, NO_INSERT
);
3837 return ((rename_map_elt
) *slot
)->new_name
;
3842 /* Rename the SSA_NAMEs used in STMT and that appear in IVSTACK. */
3845 rename_variables_in_stmt (gimple stmt
, htab_t map
)
3848 use_operand_p use_p
;
3850 FOR_EACH_SSA_USE_OPERAND (use_p
, stmt
, iter
, SSA_OP_USE
)
3852 tree use
= USE_FROM_PTR (use_p
);
3853 tree new_name
= get_new_name_from_old_name (map
, use
);
3855 replace_exp (use_p
, new_name
);
3861 /* Returns true if SSA_NAME is a parameter of SCOP. */
3864 is_parameter (scop_p scop
, tree ssa_name
)
3867 VEC (name_tree
, heap
) *params
= SCOP_PARAMS (scop
);
3870 for (i
= 0; VEC_iterate (name_tree
, params
, i
, param
); i
++)
3871 if (param
->t
== ssa_name
)
3877 /* Returns true if NAME is an induction variable. */
3882 return gimple_code (SSA_NAME_DEF_STMT (name
)) == GIMPLE_PHI
;
3885 static void expand_scalar_variables_stmt (gimple
, basic_block
, scop_p
,
3888 /* Constructs a tree which only contains old_ivs and parameters. Any
3889 other variables that are defined outside BB will be eliminated by
3890 using their definitions in the constructed tree. OLD_LOOP_FATHER
3891 is the original loop that contained BB. */
3894 expand_scalar_variables_expr (tree type
, tree op0
, enum tree_code code
,
3895 tree op1
, basic_block bb
, scop_p scop
,
3896 loop_p old_loop_father
, htab_t map
)
3898 if ((TREE_CODE_CLASS (code
) == tcc_constant
3899 && code
== INTEGER_CST
)
3900 || TREE_CODE_CLASS (code
) == tcc_reference
)
3903 if (TREE_CODE_CLASS (code
) == tcc_unary
)
3905 tree op0_type
= TREE_TYPE (op0
);
3906 enum tree_code op0_code
= TREE_CODE (op0
);
3908 expand_scalar_variables_expr (op0_type
, op0
, op0_code
,
3909 NULL
, bb
, scop
, old_loop_father
, map
);
3911 return fold_build1 (code
, type
, op0_expr
);
3914 if (TREE_CODE_CLASS (code
) == tcc_binary
)
3916 tree op0_type
= TREE_TYPE (op0
);
3917 enum tree_code op0_code
= TREE_CODE (op0
);
3919 expand_scalar_variables_expr (op0_type
, op0
, op0_code
,
3920 NULL
, bb
, scop
, old_loop_father
, map
);
3921 tree op1_type
= TREE_TYPE (op1
);
3922 enum tree_code op1_code
= TREE_CODE (op1
);
3924 expand_scalar_variables_expr (op1_type
, op1
, op1_code
,
3925 NULL
, bb
, scop
, old_loop_father
, map
);
3927 return fold_build2 (code
, type
, op0_expr
, op1_expr
);
3930 if (code
== SSA_NAME
)
3934 enum tree_code subcode
;
3936 if (is_parameter (scop
, op0
)
3938 return get_new_name_from_old_name (map
, op0
);
3940 def_stmt
= SSA_NAME_DEF_STMT (op0
);
3942 if (gimple_bb (def_stmt
) == bb
)
3944 /* If the defining statement is in the basic block already
3945 we do not need to create a new expression for it, we
3946 only need to ensure its operands are expanded. */
3947 expand_scalar_variables_stmt (def_stmt
, bb
, scop
,
3948 old_loop_father
, map
);
3949 return get_new_name_from_old_name (map
, op0
);
3954 if (gimple_code (def_stmt
) != GIMPLE_ASSIGN
3955 || !bb_in_scop_p (gimple_bb (def_stmt
), scop
))
3956 return get_new_name_from_old_name (map
, op0
);
3958 var0
= gimple_assign_rhs1 (def_stmt
);
3959 subcode
= gimple_assign_rhs_code (def_stmt
);
3960 var1
= gimple_assign_rhs2 (def_stmt
);
3962 return expand_scalar_variables_expr (type
, var0
, subcode
, var1
,
3963 bb
, scop
, old_loop_father
, map
);
3971 /* Replicates any uses of non-parameters and non-old-ivs variablesthat
3972 are defind outside BB with code that is inserted in BB.
3973 OLD_LOOP_FATHER is the original loop that contained STMT. */
3976 expand_scalar_variables_stmt (gimple stmt
, basic_block bb
, scop_p scop
,
3977 loop_p old_loop_father
, htab_t map
)
3980 use_operand_p use_p
;
3982 FOR_EACH_SSA_USE_OPERAND (use_p
, stmt
, iter
, SSA_OP_USE
)
3984 tree use
= USE_FROM_PTR (use_p
);
3985 tree type
= TREE_TYPE (use
);
3986 enum tree_code code
= TREE_CODE (use
);
3987 tree use_expr
= expand_scalar_variables_expr (type
, use
, code
, NULL
, bb
,
3988 scop
, old_loop_father
, map
);
3989 if (use_expr
!= use
)
3991 gimple_stmt_iterator gsi
= gsi_after_labels (bb
);
3993 force_gimple_operand_gsi (&gsi
, use_expr
, true, NULL
,
3994 true, GSI_NEW_STMT
);
3995 replace_exp (use_p
, new_use
);
4002 /* Copies the definitions outside of BB of variables that are not
4003 induction variables nor parameters. BB must only contain
4004 "external" references to these types of variables. OLD_LOOP_FATHER
4005 is the original loop that contained BB. */
4008 expand_scalar_variables (basic_block bb
, scop_p scop
,
4009 loop_p old_loop_father
, htab_t map
)
4011 gimple_stmt_iterator gsi
;
4013 for (gsi
= gsi_after_labels (bb
); !gsi_end_p (gsi
);)
4015 gimple stmt
= gsi_stmt (gsi
);
4016 expand_scalar_variables_stmt (stmt
, bb
, scop
, old_loop_father
, map
);
4021 /* Rename all the SSA_NAMEs from block BB according to the MAP. */
4024 rename_variables (basic_block bb
, htab_t map
)
4026 gimple_stmt_iterator gsi
;
4028 for (gsi
= gsi_after_labels (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4029 rename_variables_in_stmt (gsi_stmt (gsi
), map
);
4032 /* Rename following the information from MAP the PHI node argument
4033 corresponding to the edge E. In order to allow several renames of
4034 that argument, we match the original SSA_NAME on the argument
4035 coming from the edge different than E. */
4038 rename_variables_from_edge (edge e
, gimple phi
, htab_t map
)
4040 int n
= e
->dest_idx
== 0 ? 1 : 0;
4041 tree old_name
= gimple_phi_arg_def (phi
, n
);
4042 tree new_name
= get_new_name_from_old_name (map
, old_name
);
4044 gcc_assert (gimple_phi_num_args (phi
) == 2
4045 && gimple_phi_arg_edge (phi
, e
->dest_idx
) == e
);
4047 SET_PHI_ARG_DEF (phi
, n
, new_name
);
4050 /* Rename all the phi arguments for the edges comming from the scop
4051 according to the MAP. */
4054 rename_phis_end_scop (scop_p scop
, htab_t map
)
4056 basic_block after_scop
= SCOP_EXIT (scop
);
4057 edge e
= SESE_EXIT (SCOP_REGION (scop
));
4058 gimple_stmt_iterator gsi
;
4060 for (gsi
= gsi_start_phis (after_scop
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4061 rename_variables_from_edge (e
, gsi_stmt (gsi
), map
);
4064 /* Remove condition from BB. */
4067 remove_condition (basic_block bb
)
4069 gimple last
= last_stmt (bb
);
4071 if (last
&& gimple_code (last
) == GIMPLE_COND
)
4073 gimple_stmt_iterator gsi
= gsi_last_bb (bb
);
4074 gsi_remove (&gsi
, true);
4078 /* Returns the first successor edge of BB with EDGE_TRUE_VALUE flag set. */
4081 get_true_edge_from_guard_bb (basic_block bb
)
4086 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
4087 if (e
->flags
& EDGE_TRUE_VALUE
)
4094 /* Returns the first successor edge of BB with EDGE_TRUE_VALUE flag cleared. */
4097 get_false_edge_from_guard_bb (basic_block bb
)
4102 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
4103 if (!(e
->flags
& EDGE_TRUE_VALUE
))
4110 /* Inserts in MAP a tuple (OLD_NAME, NEW_NAME) for the induction
4111 variables of the loops around GBB in SCOP, i.e. GBB_LOOPS.
4112 NEW_NAME is obtained from IVSTACK. IVSTACK has the same stack
4113 ordering as GBB_LOOPS. */
4116 build_iv_mapping (loop_iv_stack ivstack
, htab_t map
, gbb_p gbb
, scop_p scop
)
4122 for (i
= 0; VEC_iterate (name_tree
, SCOP_OLDIVS (scop
), i
, iv
); i
++)
4124 struct rename_map_elt tmp
;
4126 if (!flow_bb_inside_loop_p (iv
->loop
, GBB_BB (gbb
)))
4129 tmp
.old_name
= iv
->t
;
4130 slot
= htab_find_slot (map
, &tmp
, INSERT
);
4134 tree new_name
= loop_iv_stack_get_iv (ivstack
,
4135 gbb_loop_index (gbb
, iv
->loop
));
4136 *slot
= new_rename_map_elt (iv
->t
, new_name
);
4141 /* Register in MAP the tuple (old_name, new_name). */
4144 register_old_new_names (htab_t map
, tree old_name
, tree new_name
)
4146 struct rename_map_elt tmp
;
4149 tmp
.old_name
= old_name
;
4150 slot
= htab_find_slot (map
, &tmp
, INSERT
);
4153 *slot
= new_rename_map_elt (old_name
, new_name
);
4156 /* Create a duplicate of the basic block BB. NOTE: This does not
4157 preserve SSA form. */
4160 graphite_copy_stmts_from_block (basic_block bb
, basic_block new_bb
, htab_t map
)
4162 gimple_stmt_iterator gsi
, gsi_tgt
;
4164 gsi_tgt
= gsi_start_bb (new_bb
);
4165 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4167 def_operand_p def_p
;
4168 ssa_op_iter op_iter
;
4170 gimple stmt
= gsi_stmt (gsi
);
4173 if (gimple_code (stmt
) == GIMPLE_LABEL
)
4176 /* Create a new copy of STMT and duplicate STMT's virtual
4178 copy
= gimple_copy (stmt
);
4179 gsi_insert_after (&gsi_tgt
, copy
, GSI_NEW_STMT
);
4180 mark_symbols_for_renaming (copy
);
4182 region
= lookup_stmt_eh_region (stmt
);
4184 add_stmt_to_eh_region (copy
, region
);
4185 gimple_duplicate_stmt_histograms (cfun
, copy
, cfun
, stmt
);
4187 /* Create new names for all the definitions created by COPY and
4188 add replacement mappings for each new name. */
4189 FOR_EACH_SSA_DEF_OPERAND (def_p
, copy
, op_iter
, SSA_OP_DEF
)
4191 tree old_name
= DEF_FROM_PTR (def_p
);
4192 tree new_name
= create_new_def_for (old_name
, copy
, def_p
);
4193 register_old_new_names (map
, old_name
, new_name
);
4198 /* Copies BB and includes in the copied BB all the statements that can
4199 be reached following the use-def chains from the memory accesses,
4200 and returns the next edge following this new block. */
4203 copy_bb_and_scalar_dependences (basic_block bb
, scop_p scop
,
4204 loop_p context_loop
,
4205 edge next_e
, htab_t map
)
4207 basic_block new_bb
= split_edge (next_e
);
4209 next_e
= single_succ_edge (new_bb
);
4210 graphite_copy_stmts_from_block (bb
, new_bb
, map
);
4211 remove_condition (new_bb
);
4212 rename_variables (new_bb
, map
);
4213 remove_phi_nodes (new_bb
);
4214 expand_scalar_variables (new_bb
, scop
, context_loop
, map
);
4215 rename_phis_end_scop (scop
, map
);
4220 /* Translates a CLAST statement STMT to GCC representation. NEXT_E is
4221 the edge where new generated code should be attached. BB_EXIT is the last
4222 basic block that defines the scope of code generation. CONTEXT_LOOP is the
4223 loop in which the generated code will be placed (might be NULL). */
4226 translate_clast (scop_p scop
, struct loop
*context_loop
,
4227 struct clast_stmt
*stmt
, edge next_e
, loop_iv_stack ivstack
)
4232 if (CLAST_STMT_IS_A (stmt
, stmt_root
))
4233 return translate_clast (scop
, context_loop
, stmt
->next
, next_e
, ivstack
);
4235 if (CLAST_STMT_IS_A (stmt
, stmt_user
))
4238 CloogStatement
*cs
= ((struct clast_user_stmt
*) stmt
)->statement
;
4239 graphite_bb_p gbb
= (graphite_bb_p
) cloog_statement_usr (cs
);
4241 if (GBB_BB (gbb
) == ENTRY_BLOCK_PTR
)
4244 map
= htab_create (10, rename_map_elt_info
, eq_rename_map_elts
, free
);
4245 loop_iv_stack_patch_for_consts (ivstack
, (struct clast_user_stmt
*) stmt
);
4246 build_iv_mapping (ivstack
, map
, gbb
, scop
);
4247 next_e
= copy_bb_and_scalar_dependences (GBB_BB (gbb
), scop
,
4248 context_loop
, next_e
, map
);
4250 loop_iv_stack_remove_constants (ivstack
);
4251 update_ssa (TODO_update_ssa
);
4252 recompute_all_dominators ();
4254 return translate_clast (scop
, context_loop
, stmt
->next
, next_e
, ivstack
);
4257 if (CLAST_STMT_IS_A (stmt
, stmt_for
))
4260 = graphite_create_new_loop (scop
, next_e
, (struct clast_for
*) stmt
,
4261 ivstack
, context_loop
? context_loop
4263 edge last_e
= single_exit (loop
);
4265 next_e
= translate_clast (scop
, loop
, ((struct clast_for
*) stmt
)->body
,
4266 single_pred_edge (loop
->latch
), ivstack
);
4267 redirect_edge_succ_nodup (next_e
, loop
->latch
);
4269 set_immediate_dominator (CDI_DOMINATORS
, next_e
->dest
, next_e
->src
);
4270 loop_iv_stack_pop (ivstack
);
4271 last_e
= single_succ_edge (split_edge (last_e
));
4272 recompute_all_dominators ();
4274 return translate_clast (scop
, context_loop
, stmt
->next
, last_e
, ivstack
);
4277 if (CLAST_STMT_IS_A (stmt
, stmt_guard
))
4279 edge last_e
= graphite_create_new_guard (scop
, next_e
,
4280 ((struct clast_guard
*) stmt
),
4282 edge true_e
= get_true_edge_from_guard_bb (next_e
->dest
);
4283 next_e
= translate_clast (scop
, context_loop
,
4284 ((struct clast_guard
*) stmt
)->then
,
4287 return translate_clast (scop
, context_loop
, stmt
->next
, last_e
, ivstack
);
4290 if (CLAST_STMT_IS_A (stmt
, stmt_block
))
4292 next_e
= translate_clast (scop
, context_loop
,
4293 ((struct clast_block
*) stmt
)->body
,
4296 return translate_clast (scop
, context_loop
, stmt
->next
, next_e
, ivstack
);
4302 /* Free the SCATTERING domain list. */
4305 free_scattering (CloogDomainList
*scattering
)
4309 CloogDomain
*dom
= cloog_domain (scattering
);
4310 CloogDomainList
*next
= cloog_next_domain (scattering
);
4312 cloog_domain_free (dom
);
4318 /* Build cloog program for SCoP. */
4321 build_cloog_prog (scop_p scop
)
4324 int max_nb_loops
= scop_max_loop_depth (scop
);
4326 CloogLoop
*loop_list
= NULL
;
4327 CloogBlockList
*block_list
= NULL
;
4328 CloogDomainList
*scattering
= NULL
;
4329 CloogProgram
*prog
= SCOP_PROG (scop
);
4330 int nbs
= 2 * max_nb_loops
+ 1;
4331 int *scaldims
= (int *) xmalloc (nbs
* (sizeof (int)));
4333 cloog_program_set_nb_scattdims (prog
, nbs
);
4334 initialize_cloog_names (scop
);
4336 for (i
= 0; VEC_iterate (graphite_bb_p
, SCOP_BBS (scop
), i
, gbb
); i
++)
4338 /* Build new block. */
4339 CloogMatrix
*domain
= GBB_DOMAIN (gbb
);
4340 CloogStatement
*stmt
= cloog_statement_alloc (GBB_BB (gbb
)->index
);
4341 CloogBlock
*block
= cloog_block_alloc (stmt
, 0, NULL
,
4342 nb_loops_around_gb (gbb
));
4343 cloog_statement_set_usr (stmt
, gbb
);
4345 /* Add empty domain to all bbs, which do not yet have a domain, as they
4346 are not part of any loop. */
4349 domain
= cloog_matrix_alloc (0, scop_nb_params (scop
) + 2);
4350 GBB_DOMAIN (gbb
) = domain
;
4353 /* Build loop list. */
4355 CloogLoop
*new_loop_list
= cloog_loop_malloc ();
4356 cloog_loop_set_next (new_loop_list
, loop_list
);
4357 cloog_loop_set_domain (new_loop_list
,
4358 cloog_domain_matrix2domain (domain
));
4359 cloog_loop_set_block (new_loop_list
, block
);
4360 loop_list
= new_loop_list
;
4363 /* Build block list. */
4365 CloogBlockList
*new_block_list
= cloog_block_list_malloc ();
4367 cloog_block_list_set_next (new_block_list
, block_list
);
4368 cloog_block_list_set_block (new_block_list
, block
);
4369 block_list
= new_block_list
;
4372 /* Build scattering list. */
4374 /* XXX: Replace with cloog_domain_list_alloc(), when available. */
4375 CloogDomainList
*new_scattering
4376 = (CloogDomainList
*) xmalloc (sizeof (CloogDomainList
));
4377 CloogMatrix
*scat_mat
= schedule_to_scattering (gbb
, nbs
);
4379 cloog_set_next_domain (new_scattering
, scattering
);
4380 cloog_set_domain (new_scattering
,
4381 cloog_domain_matrix2domain (scat_mat
));
4382 scattering
= new_scattering
;
4383 cloog_matrix_free (scat_mat
);
4387 cloog_program_set_loop (prog
, loop_list
);
4388 cloog_program_set_blocklist (prog
, block_list
);
4390 for (i
= 0; i
< nbs
; i
++)
4393 cloog_program_set_scaldims (prog
, scaldims
);
4395 /* Extract scalar dimensions to simplify the code generation problem. */
4396 cloog_program_extract_scalars (prog
, scattering
);
4398 /* Apply scattering. */
4399 cloog_program_scatter (prog
, scattering
);
4400 free_scattering (scattering
);
4402 /* Iterators corresponding to scalar dimensions have to be extracted. */
4403 cloog_names_scalarize (cloog_program_names (prog
), nbs
,
4404 cloog_program_scaldims (prog
));
4406 /* Free blocklist. */
4408 CloogBlockList
*next
= cloog_program_blocklist (prog
);
4412 CloogBlockList
*toDelete
= next
;
4413 next
= cloog_block_list_next (next
);
4414 cloog_block_list_set_next (toDelete
, NULL
);
4415 cloog_block_list_set_block (toDelete
, NULL
);
4416 cloog_block_list_free (toDelete
);
4418 cloog_program_set_blocklist (prog
, NULL
);
4422 /* Return the options that will be used in GLOOG. */
4424 static CloogOptions
*
4425 set_cloog_options (void)
4427 CloogOptions
*options
= cloog_options_malloc ();
4429 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
4430 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
4431 we pass an incomplete program to cloog. */
4432 options
->language
= LANGUAGE_C
;
4434 /* Enable complex equality spreading: removes dummy statements
4435 (assignments) in the generated code which repeats the
4436 substitution equations for statements. This is useless for
4440 /* Enable C pretty-printing mode: normalizes the substitution
4441 equations for statements. */
4444 /* Allow cloog to build strides with a stride width different to one.
4445 This example has stride = 4:
4447 for (i = 0; i < 20; i += 4)
4449 options
->strides
= 1;
4451 /* Disable optimizations and make cloog generate source code closer to the
4452 input. This is useful for debugging, but later we want the optimized
4455 XXX: We can not disable optimizations, as loop blocking is not working
4460 options
->l
= INT_MAX
;
4466 /* Prints STMT to STDERR. */
4469 debug_clast_stmt (struct clast_stmt
*stmt
)
4471 CloogOptions
*options
= set_cloog_options ();
4473 pprint (stderr
, stmt
, 0, options
);
4476 /* Find the right transform for the SCOP, and return a Cloog AST
4477 representing the new form of the program. */
4479 static struct clast_stmt
*
4480 find_transform (scop_p scop
)
4482 struct clast_stmt
*stmt
;
4483 CloogOptions
*options
= set_cloog_options ();
4485 /* Connect new cloog prog generation to graphite. */
4486 build_cloog_prog (scop
);
4488 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4490 fprintf (dump_file
, "Cloog Input [\n");
4491 cloog_program_print (dump_file
, SCOP_PROG(scop
));
4492 fprintf (dump_file
, "]\n");
4495 SCOP_PROG (scop
) = cloog_program_generate (SCOP_PROG (scop
), options
);
4496 stmt
= cloog_clast_create (SCOP_PROG (scop
), options
);
4498 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4500 fprintf (dump_file
, "Cloog Output[\n");
4501 pprint (dump_file
, stmt
, 0, options
);
4502 cloog_program_dump_cloog (dump_file
, SCOP_PROG (scop
));
4503 fprintf (dump_file
, "]\n");
4506 cloog_options_free (options
);
4510 /* Returns true when it is possible to generate code for this STMT.
4511 For the moment we cannot generate code when Cloog decides to
4512 duplicate a statement, as we do not do a copy, but a move.
4513 USED_BASIC_BLOCKS records the blocks that have already been seen.
4514 We return false if we have to generate code twice for the same
4518 can_generate_code_stmt (struct clast_stmt
*stmt
,
4519 struct pointer_set_t
*used_basic_blocks
)
4524 if (CLAST_STMT_IS_A (stmt
, stmt_root
))
4525 return can_generate_code_stmt (stmt
->next
, used_basic_blocks
);
4527 if (CLAST_STMT_IS_A (stmt
, stmt_user
))
4529 CloogStatement
*cs
= ((struct clast_user_stmt
*) stmt
)->statement
;
4530 graphite_bb_p gbb
= (graphite_bb_p
) cloog_statement_usr (cs
);
4532 if (pointer_set_contains (used_basic_blocks
, gbb
))
4534 pointer_set_insert (used_basic_blocks
, gbb
);
4535 return can_generate_code_stmt (stmt
->next
, used_basic_blocks
);
4538 if (CLAST_STMT_IS_A (stmt
, stmt_for
))
4539 return can_generate_code_stmt (((struct clast_for
*) stmt
)->body
,
4541 && can_generate_code_stmt (stmt
->next
, used_basic_blocks
);
4543 if (CLAST_STMT_IS_A (stmt
, stmt_guard
))
4544 return can_generate_code_stmt (((struct clast_guard
*) stmt
)->then
,
4547 if (CLAST_STMT_IS_A (stmt
, stmt_block
))
4548 return can_generate_code_stmt (((struct clast_block
*) stmt
)->body
,
4550 && can_generate_code_stmt (stmt
->next
, used_basic_blocks
);
4555 /* Returns true when it is possible to generate code for this STMT. */
4558 can_generate_code (struct clast_stmt
*stmt
)
4561 struct pointer_set_t
*used_basic_blocks
= pointer_set_create ();
4563 result
= can_generate_code_stmt (stmt
, used_basic_blocks
);
4564 pointer_set_destroy (used_basic_blocks
);
4568 /* Remove from the CFG the REGION. */
4571 remove_sese_region (sese region
)
4573 VEC (basic_block
, heap
) *bbs
= NULL
;
4574 basic_block entry_bb
= SESE_ENTRY (region
)->dest
;
4575 basic_block exit_bb
= SESE_EXIT (region
)->dest
;
4579 VEC_safe_push (basic_block
, heap
, bbs
, entry_bb
);
4580 gather_blocks_in_sese_region (entry_bb
, exit_bb
, &bbs
);
4582 for (i
= 0; VEC_iterate (basic_block
, bbs
, i
, bb
); i
++)
4583 delete_basic_block (bb
);
4585 VEC_free (basic_block
, heap
, bbs
);
4588 typedef struct ifsese
{
4595 if_region_entry (ifsese if_region
)
4597 return SESE_ENTRY (if_region
->region
);
4601 if_region_exit (ifsese if_region
)
4603 return SESE_EXIT (if_region
->region
);
4606 static inline basic_block
4607 if_region_get_condition_block (ifsese if_region
)
4609 return if_region_entry (if_region
)->dest
;
4613 if_region_set_false_region (ifsese if_region
, sese region
)
4615 basic_block condition
= if_region_get_condition_block (if_region
);
4616 edge false_edge
= get_false_edge_from_guard_bb (condition
);
4617 edge entry_region
= SESE_ENTRY (region
);
4618 edge exit_region
= SESE_EXIT (region
);
4619 basic_block before_region
= entry_region
->src
;
4620 basic_block last_in_region
= exit_region
->src
;
4621 void **slot
= htab_find_slot_with_hash (current_loops
->exits
, exit_region
,
4622 htab_hash_pointer (exit_region
),
4625 entry_region
->flags
= false_edge
->flags
;
4626 false_edge
->flags
= exit_region
->flags
;
4628 redirect_edge_pred (entry_region
, condition
);
4629 redirect_edge_pred (exit_region
, before_region
);
4630 redirect_edge_pred (false_edge
, last_in_region
);
4632 exit_region
->flags
= EDGE_FALLTHRU
;
4633 recompute_all_dominators ();
4635 SESE_EXIT (region
) = single_succ_edge (false_edge
->dest
);
4636 if_region
->false_region
= region
;
4640 struct loop_exit
*loop_exit
= GGC_CNEW (struct loop_exit
);
4642 memcpy (loop_exit
, *((struct loop_exit
**) slot
), sizeof (struct loop_exit
));
4643 htab_clear_slot (current_loops
->exits
, slot
);
4645 slot
= htab_find_slot_with_hash (current_loops
->exits
, false_edge
,
4646 htab_hash_pointer (false_edge
),
4648 loop_exit
->e
= false_edge
;
4650 false_edge
->src
->loop_father
->exits
->next
= loop_exit
;
4655 create_if_region_on_edge (edge entry
, tree condition
)
4659 sese sese_region
= GGC_NEW (struct sese
);
4660 sese true_region
= GGC_NEW (struct sese
);
4661 sese false_region
= GGC_NEW (struct sese
);
4662 ifsese if_region
= GGC_NEW (struct ifsese
);
4663 edge exit
= create_empty_if_region_on_edge (entry
, condition
);
4665 if_region
->region
= sese_region
;
4666 if_region
->region
->entry
= entry
;
4667 if_region
->region
->exit
= exit
;
4669 FOR_EACH_EDGE (e
, ei
, entry
->dest
->succs
)
4671 if (e
->flags
& EDGE_TRUE_VALUE
)
4673 true_region
->entry
= e
;
4674 true_region
->exit
= single_succ_edge (e
->dest
);
4675 if_region
->true_region
= true_region
;
4677 else if (e
->flags
& EDGE_FALSE_VALUE
)
4679 false_region
->entry
= e
;
4680 false_region
->exit
= single_succ_edge (e
->dest
);
4681 if_region
->false_region
= false_region
;
4688 /* Moves REGION in a condition expression:
4696 move_sese_in_condition (sese region
)
4698 basic_block pred_block
= split_edge (SESE_ENTRY (region
));
4699 ifsese if_region
= NULL
;
4701 SESE_ENTRY (region
) = single_succ_edge (pred_block
);
4702 if_region
= create_if_region_on_edge (single_pred_edge (pred_block
), integer_one_node
);
4703 if_region_set_false_region (if_region
, region
);
4708 /* Returns true when BB is in REGION. */
4711 bb_in_sese_p (basic_block bb
, sese region
)
4713 return pointer_set_contains (SESE_REGION_BBS (region
), bb
);
4716 /* For USE in BB, if it is used outside of the REGION it is defined in,
4717 mark it for rewrite. Record basic block BB where it is used
4718 to USE_BLOCKS. Record the ssa name index to NEED_PHIS bitmap. */
4721 sese_find_uses_to_rename_use (sese region
, basic_block bb
, tree use
,
4722 bitmap
*use_blocks
, bitmap need_phis
)
4727 if (TREE_CODE (use
) != SSA_NAME
)
4730 ver
= SSA_NAME_VERSION (use
);
4731 def_bb
= gimple_bb (SSA_NAME_DEF_STMT (use
));
4733 || !bb_in_sese_p (def_bb
, region
)
4734 || bb_in_sese_p (bb
, region
))
4737 if (!use_blocks
[ver
])
4738 use_blocks
[ver
] = BITMAP_ALLOC (NULL
);
4739 bitmap_set_bit (use_blocks
[ver
], bb
->index
);
4741 bitmap_set_bit (need_phis
, ver
);
4744 /* Marks names that are used in BB and outside of the loop they are
4745 defined in for rewrite. Records the set of blocks in that the ssa
4746 names are defined to USE_BLOCKS. Record the SSA names that will
4747 need exit PHIs in NEED_PHIS. */
4750 sese_find_uses_to_rename_bb (sese region
, basic_block bb
,
4751 bitmap
*use_blocks
, bitmap need_phis
)
4753 gimple_stmt_iterator bsi
;
4759 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
4760 for (bsi
= gsi_start_phis (e
->dest
); !gsi_end_p (bsi
); gsi_next (&bsi
))
4761 sese_find_uses_to_rename_use (region
, bb
,
4762 PHI_ARG_DEF_FROM_EDGE (gsi_stmt (bsi
), e
),
4763 use_blocks
, need_phis
);
4765 for (bsi
= gsi_start_bb (bb
); !gsi_end_p (bsi
); gsi_next (&bsi
))
4766 FOR_EACH_SSA_TREE_OPERAND (var
, gsi_stmt (bsi
), iter
, SSA_OP_ALL_USES
)
4767 sese_find_uses_to_rename_use (region
, bb
, var
, use_blocks
, need_phis
);
4770 /* Add exit phis for USE on EXIT. */
4773 sese_add_exit_phis_edge (basic_block exit
, tree use
, edge false_e
, edge true_e
)
4775 gimple phi
= create_phi_node (use
, exit
);
4777 create_new_def_for (gimple_phi_result (phi
), phi
,
4778 gimple_phi_result_ptr (phi
));
4779 add_phi_arg (phi
, use
, false_e
);
4780 add_phi_arg (phi
, use
, true_e
);
4783 /* Add phi nodes for VAR that is used in LIVEIN. Phi nodes are
4784 inserted in block WHERE. */
4787 sese_add_exit_phis_var (basic_block where
, tree var
, bitmap livein
,
4788 edge false_e
, edge true_e
)
4791 basic_block def_bb
= gimple_bb (SSA_NAME_DEF_STMT (var
));
4793 if (is_gimple_reg (var
))
4794 bitmap_clear_bit (livein
, def_bb
->index
);
4796 bitmap_set_bit (livein
, def_bb
->index
);
4798 def
= BITMAP_ALLOC (NULL
);
4799 bitmap_set_bit (def
, def_bb
->index
);
4800 compute_global_livein (livein
, def
);
4803 sese_add_exit_phis_edge (where
, var
, false_e
, true_e
);
4806 /* Insert in the block WHERE phi nodes for variables defined in REGION
4807 and used outside the REGION. */
4810 rewrite_into_sese_closed_ssa (sese region
, basic_block where
,
4811 edge false_e
, edge true_e
)
4816 bitmap names_to_rename
= BITMAP_ALLOC (NULL
);
4817 unsigned old_num_ssa_names
= num_ssa_names
;
4818 bitmap
*use_blocks
= XCNEWVEC (bitmap
, old_num_ssa_names
);
4820 update_ssa (TODO_update_ssa
);
4823 sese_find_uses_to_rename_bb (region
, bb
, use_blocks
, names_to_rename
);
4825 EXECUTE_IF_SET_IN_BITMAP (names_to_rename
, 0, i
, bi
)
4826 sese_add_exit_phis_var (where
, ssa_name (i
), use_blocks
[i
],
4829 update_ssa (TODO_update_ssa
);
4831 for (i
= 0; i
< old_num_ssa_names
; i
++)
4832 BITMAP_FREE (use_blocks
[i
]);
4835 BITMAP_FREE (names_to_rename
);
4838 /* Returns the first cloog name used in EXPR. */
4841 find_cloog_iv_in_expr (struct clast_expr
*expr
)
4843 struct clast_term
*term
= (struct clast_term
*) expr
;
4845 if (expr
->type
== expr_term
4849 if (expr
->type
== expr_term
)
4852 if (expr
->type
== expr_red
)
4855 struct clast_reduction
*red
= (struct clast_reduction
*) expr
;
4857 for (i
= 0; i
< red
->n
; i
++)
4859 const char *res
= find_cloog_iv_in_expr ((red
)->elts
[i
]);
4869 /* Build for a clast_user_stmt USER_STMT a map between the CLAST
4870 induction variables and the corresponding GCC old induction
4871 variables. This information is stored on each GRAPHITE_BB. */
4874 compute_cloog_iv_types_1 (graphite_bb_p gbb
,
4875 struct clast_user_stmt
*user_stmt
)
4877 struct clast_stmt
*t
;
4880 for (t
= user_stmt
->substitutions
; t
; t
= t
->next
, index
++)
4883 struct ivtype_map_elt tmp
;
4884 struct clast_expr
*expr
= (struct clast_expr
*)
4885 ((struct clast_assignment
*)t
)->RHS
;
4887 /* Create an entry (clast_var, type). */
4888 tmp
.cloog_iv
= find_cloog_iv_in_expr (expr
);
4892 slot
= htab_find_slot (GBB_CLOOG_IV_TYPES (gbb
), &tmp
, INSERT
);
4896 loop_p loop
= gbb_loop_at_index (gbb
, index
);
4897 tree oldiv
= oldiv_for_loop (GBB_SCOP (gbb
), loop
);
4898 tree type
= oldiv
? TREE_TYPE (oldiv
) : integer_type_node
;
4899 *slot
= new_ivtype_map_elt (tmp
.cloog_iv
, type
);
4904 /* Walk the CLAST tree starting from STMT and build for each
4905 clast_user_stmt a map between the CLAST induction variables and the
4906 corresponding GCC old induction variables. This information is
4907 stored on each GRAPHITE_BB. */
4910 compute_cloog_iv_types (struct clast_stmt
*stmt
)
4915 if (CLAST_STMT_IS_A (stmt
, stmt_root
))
4918 if (CLAST_STMT_IS_A (stmt
, stmt_user
))
4920 CloogStatement
*cs
= ((struct clast_user_stmt
*) stmt
)->statement
;
4921 graphite_bb_p gbb
= (graphite_bb_p
) cloog_statement_usr (cs
);
4922 GBB_CLOOG_IV_TYPES (gbb
) = htab_create (10, ivtype_map_elt_info
,
4923 eq_ivtype_map_elts
, free
);
4924 compute_cloog_iv_types_1 (gbb
, (struct clast_user_stmt
*) stmt
);
4928 if (CLAST_STMT_IS_A (stmt
, stmt_for
))
4930 struct clast_stmt
*s
= ((struct clast_for
*) stmt
)->body
;
4931 compute_cloog_iv_types (s
);
4935 if (CLAST_STMT_IS_A (stmt
, stmt_guard
))
4937 struct clast_stmt
*s
= ((struct clast_guard
*) stmt
)->then
;
4938 compute_cloog_iv_types (s
);
4942 if (CLAST_STMT_IS_A (stmt
, stmt_block
))
4944 struct clast_stmt
*s
= ((struct clast_block
*) stmt
)->body
;
4945 compute_cloog_iv_types (s
);
4952 compute_cloog_iv_types (stmt
->next
);
4955 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
4959 gloog (scop_p scop
, struct clast_stmt
*stmt
)
4961 edge new_scop_exit_edge
= NULL
;
4962 VEC (iv_stack_entry_p
, heap
) *ivstack
= VEC_alloc (iv_stack_entry_p
, heap
,
4964 loop_p context_loop
;
4965 ifsese if_region
= NULL
;
4967 if (!can_generate_code (stmt
))
4969 cloog_clast_free (stmt
);
4973 if_region
= move_sese_in_condition (SCOP_REGION (scop
));
4974 rewrite_into_sese_closed_ssa (SCOP_REGION (scop
),
4975 if_region
->region
->exit
->src
,
4976 if_region
->false_region
->exit
,
4977 if_region
->true_region
->exit
);
4979 context_loop
= SESE_ENTRY (SCOP_REGION (scop
))->src
->loop_father
;
4980 compute_cloog_iv_types (stmt
);
4981 new_scop_exit_edge
= translate_clast (scop
, context_loop
,
4982 stmt
, if_region
->true_region
->entry
,
4985 cleanup_tree_cfg ();
4986 recompute_all_dominators ();
4988 free_loop_iv_stack (&ivstack
);
4989 cloog_clast_free (stmt
);
4992 /* Returns the number of data references in SCOP. */
4995 nb_data_refs_in_scop (scop_p scop
)
5001 for (i
= 0; VEC_iterate (graphite_bb_p
, SCOP_BBS (scop
), i
, gbb
); i
++)
5002 res
+= VEC_length (data_reference_p
, GBB_DATA_REFS (gbb
));
5007 /* Move the loop at index LOOP and insert it before index NEW_LOOP_POS.
5008 This transformartion is only valid, if the loop nest between i and k is
5009 perfectly nested. Therefore we do not need to change the static schedule.
5013 for (i = 0; i < 50; i++)
5015 for (k = 5; k < 100; k++)
5018 To move k before i use:
5020 graphite_trans_bb_move_loop (A, 2, 0)
5022 for (k = 5; k < 100; k++)
5023 for (i = 0; i < 50; i++)
5029 graphite_trans_bb_move_loop (A, 0, 2)
5031 This function does not check the validity of interchanging loops.
5032 This should be checked before calling this function. */
5035 graphite_trans_bb_move_loop (graphite_bb_p gb
, int loop
,
5038 CloogMatrix
*domain
= GBB_DOMAIN (gb
);
5042 gcc_assert (loop
< gbb_nb_loops (gb
)
5043 && new_loop_pos
< gbb_nb_loops (gb
));
5045 /* Update LOOPS vector. */
5046 tmp_loop_p
= VEC_index (loop_p
, GBB_LOOPS (gb
), loop
);
5047 VEC_ordered_remove (loop_p
, GBB_LOOPS (gb
), loop
);
5048 VEC_safe_insert (loop_p
, heap
, GBB_LOOPS (gb
), new_loop_pos
, tmp_loop_p
);
5050 /* Move the domain columns. */
5051 if (loop
< new_loop_pos
)
5052 for (row
= 0; row
< domain
->NbRows
; row
++)
5056 value_assign (tmp
, domain
->p
[row
][loop
+ 1]);
5058 for (j
= loop
; j
< new_loop_pos
- 1; j
++)
5059 value_assign (domain
->p
[row
][j
+ 1], domain
->p
[row
][j
+ 2]);
5061 value_assign (domain
->p
[row
][new_loop_pos
], tmp
);
5065 for (row
= 0; row
< domain
->NbRows
; row
++)
5069 value_assign (tmp
, domain
->p
[row
][loop
+ 1]);
5071 for (j
= loop
; j
> new_loop_pos
; j
--)
5072 value_assign (domain
->p
[row
][j
+ 1], domain
->p
[row
][j
]);
5074 value_assign (domain
->p
[row
][new_loop_pos
+ 1], tmp
);
5079 /* Get the index of the column representing constants in the DOMAIN
5083 const_column_index (CloogMatrix
*domain
)
5085 return domain
->NbColumns
- 1;
5089 /* Get the first index that is positive or negative, determined
5090 following the value of POSITIVE, in matrix DOMAIN in COLUMN. */
5093 get_first_matching_sign_row_index (CloogMatrix
*domain
, int column
,
5098 for (row
= 0; row
< domain
->NbRows
; row
++)
5100 int val
= value_get_si (domain
->p
[row
][column
]);
5102 if (val
> 0 && positive
)
5105 else if (val
< 0 && !positive
)
5112 /* Get the lower bound of COLUMN in matrix DOMAIN. */
5115 get_lower_bound_row (CloogMatrix
*domain
, int column
)
5117 return get_first_matching_sign_row_index (domain
, column
, true);
5120 /* Get the upper bound of COLUMN in matrix DOMAIN. */
5123 get_upper_bound_row (CloogMatrix
*domain
, int column
)
5125 return get_first_matching_sign_row_index (domain
, column
, false);
5128 /* Get the lower bound of LOOP. */
5131 get_lower_bound (CloogMatrix
*domain
, int loop
, Value lower_bound_result
)
5133 int lower_bound_row
= get_lower_bound_row (domain
, loop
);
5134 value_assign (lower_bound_result
,
5135 domain
->p
[lower_bound_row
][const_column_index(domain
)]);
5138 /* Get the upper bound of LOOP. */
5141 get_upper_bound (CloogMatrix
*domain
, int loop
, Value upper_bound_result
)
5143 int upper_bound_row
= get_upper_bound_row (domain
, loop
);
5144 value_assign (upper_bound_result
,
5145 domain
->p
[upper_bound_row
][const_column_index(domain
)]);
5148 /* Strip mines the loop of BB at the position LOOP_DEPTH with STRIDE.
5149 Always valid, but not always a performance improvement. */
5152 graphite_trans_bb_strip_mine (graphite_bb_p gb
, int loop_depth
, int stride
)
5156 CloogMatrix
*domain
= GBB_DOMAIN (gb
);
5157 CloogMatrix
*new_domain
= cloog_matrix_alloc (domain
->NbRows
+ 3,
5158 domain
->NbColumns
+ 1);
5160 int col_loop_old
= loop_depth
+ 2;
5161 int col_loop_strip
= col_loop_old
- 1;
5163 Value old_lower_bound
;
5164 Value old_upper_bound
;
5166 gcc_assert (loop_depth
<= gbb_nb_loops (gb
) - 1);
5168 VEC_safe_insert (loop_p
, heap
, GBB_LOOPS (gb
), loop_depth
, NULL
);
5170 GBB_DOMAIN (gb
) = new_domain
;
5173 nrows = 4, ncols = 4
5182 for (row
= 0; row
< domain
->NbRows
; row
++)
5183 for (col
= 0; col
< domain
->NbColumns
; col
++)
5184 if (col
<= loop_depth
)
5185 value_assign (new_domain
->p
[row
][col
], domain
->p
[row
][col
]);
5187 value_assign (new_domain
->p
[row
][col
+ 1], domain
->p
[row
][col
]);
5191 nrows = 6, ncols = 5
5203 row
= domain
->NbRows
;
5205 /* Add outer loop. */
5206 value_init (old_lower_bound
);
5207 value_init (old_upper_bound
);
5208 get_lower_bound (new_domain
, col_loop_old
, old_lower_bound
);
5209 get_upper_bound (new_domain
, col_loop_old
, old_upper_bound
);
5211 /* Set Lower Bound */
5212 value_set_si (new_domain
->p
[row
][0], 1);
5213 value_set_si (new_domain
->p
[row
][col_loop_strip
], 1);
5214 value_assign (new_domain
->p
[row
][const_column_index (new_domain
)],
5216 value_clear (old_lower_bound
);
5226 1 0 0 -1 99 | copy old lower bound
5233 Value new_upper_bound
;
5234 Value strip_size_value
;
5236 value_init (new_upper_bound
);
5237 value_init (strip_size_value
);
5238 value_set_si (strip_size_value
, (int) stride
);
5240 value_pdivision (new_upper_bound
, old_upper_bound
, strip_size_value
);
5241 value_add_int (new_upper_bound
, new_upper_bound
, 1);
5243 /* Set Upper Bound */
5244 value_set_si (new_domain
->p
[row
][0], 1);
5245 value_set_si (new_domain
->p
[row
][col_loop_strip
], -1);
5246 value_assign (new_domain
->p
[row
][const_column_index (new_domain
)],
5249 value_clear (strip_size_value
);
5250 value_clear (old_upper_bound
);
5251 value_clear (new_upper_bound
);
5262 1 0 -1 0 25 (divide old upper bound with stride)
5267 row
= get_lower_bound_row (new_domain
, col_loop_old
);
5268 /* Add local variable to keep linear representation. */
5269 value_set_si (new_domain
->p
[row
][0], 1);
5270 value_set_si (new_domain
->p
[row
][const_column_index (new_domain
)],0);
5271 value_set_si (new_domain
->p
[row
][col_loop_old
], 1);
5272 value_set_si (new_domain
->p
[row
][col_loop_strip
], -1*((int)stride
));
5283 1 0 -1 0 25 (divide old upper bound with stride)
5288 row
= new_domain
->NbRows
-1;
5290 value_set_si (new_domain
->p
[row
][0], 1);
5291 value_set_si (new_domain
->p
[row
][col_loop_old
], -1);
5292 value_set_si (new_domain
->p
[row
][col_loop_strip
], stride
);
5293 value_set_si (new_domain
->p
[row
][const_column_index (new_domain
)],
5302 1 0 -4 1 0 j >= 4*jj
5305 1 0 -1 0 25 25 >= jj
5306 0 0 4 -1 3 jj+3 >= j
5309 cloog_matrix_free (domain
);
5311 /* Update static schedule. */
5314 int nb_loops
= gbb_nb_loops (gb
);
5315 lambda_vector new_schedule
= lambda_vector_new (nb_loops
+ 1);
5317 for (i
= 0; i
<= loop_depth
; i
++)
5318 new_schedule
[i
] = GBB_STATIC_SCHEDULE (gb
)[i
];
5320 for (i
= loop_depth
+ 1; i
<= nb_loops
- 2; i
++)
5321 new_schedule
[i
+ 2] = GBB_STATIC_SCHEDULE (gb
)[i
];
5323 GBB_STATIC_SCHEDULE (gb
) = new_schedule
;
5327 /* Returns true when the strip mining of LOOP_INDEX by STRIDE is
5328 profitable or undecidable. GB is the statement around which the
5329 loops will be strip mined. */
5332 strip_mine_profitable_p (graphite_bb_p gb
, int stride
,
5341 loop
= VEC_index (loop_p
, GBB_LOOPS (gb
), loop_index
);
5342 exit
= single_exit (loop
);
5344 niter
= find_loop_niter (loop
, &exit
);
5345 if (niter
== chrec_dont_know
5346 || TREE_CODE (niter
) != INTEGER_CST
)
5349 niter_val
= int_cst_value (niter
);
5351 if (niter_val
< stride
)
5354 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5356 fprintf (dump_file
, "\nStrip Mining is not profitable for loop %d:",
5358 fprintf (dump_file
, "number of iterations is too low.\n");
5365 /* Determines when the interchange of LOOP_A and LOOP_B belonging to
5369 is_interchange_valid (scop_p scop
, int loop_a
, int loop_b
)
5372 VEC (ddr_p
, heap
) *dependence_relations
;
5373 VEC (data_reference_p
, heap
) *datarefs
;
5375 struct loop
*nest
= VEC_index (loop_p
, SCOP_LOOP_NEST (scop
), loop_a
);
5376 int depth
= perfect_loop_nest_depth (nest
);
5377 lambda_trans_matrix trans
;
5379 gcc_assert (loop_a
< loop_b
);
5381 dependence_relations
= VEC_alloc (ddr_p
, heap
, 10 * 10);
5382 datarefs
= VEC_alloc (data_reference_p
, heap
, 10);
5384 if (!compute_data_dependences_for_loop (nest
, true, &datarefs
,
5385 &dependence_relations
))
5388 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5389 dump_ddrs (dump_file
, dependence_relations
);
5391 trans
= lambda_trans_matrix_new (depth
, depth
);
5392 lambda_matrix_id (LTM_MATRIX (trans
), depth
);
5394 lambda_matrix_row_exchange (LTM_MATRIX (trans
), 0, loop_b
- loop_a
);
5396 if (!lambda_transform_legal_p (trans
, depth
, dependence_relations
))
5398 lambda_matrix_row_exchange (LTM_MATRIX (trans
), 0, loop_b
- loop_a
);
5404 free_dependence_relations (dependence_relations
);
5405 free_data_refs (datarefs
);
5409 /* Loop block the LOOPS innermost loops of GB with stride size STRIDE.
5413 for (i = 0; i <= 50; i++=4)
5414 for (k = 0; k <= 100; k++=4)
5415 for (l = 0; l <= 200; l++=4)
5418 To strip mine the two inner most loops with stride = 4 call:
5420 graphite_trans_bb_block (A, 4, 2)
5422 for (i = 0; i <= 50; i++)
5423 for (kk = 0; kk <= 100; kk+=4)
5424 for (ll = 0; ll <= 200; ll+=4)
5425 for (k = kk; k <= min (100, kk + 3); k++)
5426 for (l = ll; l <= min (200, ll + 3); l++)
5431 graphite_trans_bb_block (graphite_bb_p gb
, int stride
, int loops
)
5434 int nb_loops
= gbb_nb_loops (gb
);
5435 int start
= nb_loops
- loops
;
5436 scop_p scop
= GBB_SCOP (gb
);
5438 gcc_assert (scop_contains_loop (scop
, gbb_loop (gb
)));
5440 for (i
= start
; i
< nb_loops
; i
++)
5441 for (j
= i
+ 1; j
< nb_loops
; j
++)
5442 if (!is_interchange_valid (scop
, i
, j
))
5444 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5446 "\nInterchange not valid for loops %d and %d:\n", i
, j
);
5449 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5451 "\nInterchange valid for loops %d and %d:\n", i
, j
);
5453 /* Check if strip mining is profitable for every loop. */
5454 for (i
= 0; i
< nb_loops
- start
; i
++)
5455 if (!strip_mine_profitable_p (gb
, stride
, start
+ i
))
5458 /* Strip mine loops. */
5459 for (i
= 0; i
< nb_loops
- start
; i
++)
5460 graphite_trans_bb_strip_mine (gb
, start
+ 2 * i
, stride
);
5462 /* Interchange loops. */
5463 for (i
= 1; i
< nb_loops
- start
; i
++)
5464 graphite_trans_bb_move_loop (gb
, start
+ 2 * i
, start
+ i
);
5469 /* Loop block LOOPS innermost loops of a loop nest. BBS represent the
5470 basic blocks that belong to the loop nest to be blocked. */
5473 graphite_trans_loop_block (VEC (graphite_bb_p
, heap
) *bbs
, int loops
)
5477 bool transform_done
= false;
5479 /* TODO: - Calculate the stride size automatically. */
5480 int stride_size
= 64;
5482 for (i
= 0; VEC_iterate (graphite_bb_p
, bbs
, i
, gb
); i
++)
5483 transform_done
|= graphite_trans_bb_block (gb
, stride_size
, loops
);
5485 return transform_done
;
5488 /* Loop block all basic blocks of SCOP. Return false when the
5489 transform is not performed. */
5492 graphite_trans_scop_block (scop_p scop
)
5498 bool perfect
= true;
5499 bool transform_done
= false;
5501 VEC (graphite_bb_p
, heap
) *bbs
= VEC_alloc (graphite_bb_p
, heap
, 3);
5502 int max_schedule
= scop_max_loop_depth (scop
) + 1;
5503 lambda_vector last_schedule
= lambda_vector_new (max_schedule
);
5505 if (VEC_length (graphite_bb_p
, SCOP_BBS (scop
)) == 0)
5508 /* Get the data of the first bb. */
5509 gb
= VEC_index (graphite_bb_p
, SCOP_BBS (scop
), 0);
5510 last_nb_loops
= gbb_nb_loops (gb
);
5511 lambda_vector_copy (GBB_STATIC_SCHEDULE (gb
), last_schedule
,
5513 VEC_safe_push (graphite_bb_p
, heap
, bbs
, gb
);
5515 for (i
= 0; VEC_iterate (graphite_bb_p
, SCOP_BBS (scop
), i
, gb
); i
++)
5517 /* We did the first bb before. */
5521 nb_loops
= gbb_nb_loops (gb
);
5523 /* If the number of loops is unchanged and only the last element of the
5524 schedule changes, we stay in the loop nest. */
5525 if (nb_loops
== last_nb_loops
5526 && (last_schedule
[nb_loops
+ 1]
5527 != GBB_STATIC_SCHEDULE (gb
)[nb_loops
+ 1]))
5529 VEC_safe_push (graphite_bb_p
, heap
, bbs
, gb
);
5533 /* Otherwise, we left the innermost loop. So check, if the last bb was in
5534 a perfect loop nest and how many loops are contained in this perfect
5537 Count the number of zeros from the end of the schedule. They are the
5538 number of surrounding loops.
5541 last_bb 2 3 2 0 0 0 0 3
5545 last_bb 2 3 2 0 0 0 0 3
5549 If there is no zero, there were other bbs in outer loops and the loop
5550 nest is not perfect. */
5551 for (j
= last_nb_loops
- 1; j
>= 0; j
--)
5553 if (last_schedule
[j
] != 0
5554 || (j
<= nb_loops
&& GBB_STATIC_SCHEDULE (gb
)[j
] == 1))
5563 /* Found perfect loop nest. */
5564 if (perfect
&& last_nb_loops
- j
>= 2)
5565 transform_done
|= graphite_trans_loop_block (bbs
, last_nb_loops
- j
);
5567 /* Check if we start with a new loop.
5571 last_bb 2 3 2 0 0 0 0 3
5574 Here we start with the loop "2 3 2 0 0 1"
5576 last_bb 2 3 2 0 0 0 0 3
5579 But here not, so the loop nest can never be perfect. */
5581 perfect
= (GBB_STATIC_SCHEDULE (gb
)[nb_loops
] == 0);
5583 /* Update the last_bb infos. We do not do that for the bbs in the same
5584 loop, as the data we use is not changed. */
5585 last_nb_loops
= nb_loops
;
5586 lambda_vector_copy (GBB_STATIC_SCHEDULE (gb
), last_schedule
,
5588 VEC_truncate (graphite_bb_p
, bbs
, 0);
5589 VEC_safe_push (graphite_bb_p
, heap
, bbs
, gb
);
5592 /* Check if the last loop nest was perfect. It is the same check as above,
5593 but the comparison with the next bb is missing. */
5594 for (j
= last_nb_loops
- 1; j
>= 0; j
--)
5595 if (last_schedule
[j
] != 0)
5603 /* Found perfect loop nest. */
5604 if (last_nb_loops
- j
> 0)
5605 transform_done
|= graphite_trans_loop_block (bbs
, last_nb_loops
- j
);
5606 VEC_free (graphite_bb_p
, heap
, bbs
);
5608 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5609 fprintf (dump_file
, "\nLoop blocked.\n");
5611 return transform_done
;
5614 /* Apply graphite transformations to all the basic blocks of SCOP. */
5617 graphite_apply_transformations (scop_p scop
)
5619 bool transform_done
= false;
5621 /* Sort the list of bbs. Keep them always sorted. */
5622 graphite_sort_gbbs (scop
);
5624 if (flag_loop_block
)
5625 transform_done
= graphite_trans_scop_block (scop
);
5627 /* Generate code even if we did not apply any real transformation.
5628 This also allows to check the performance for the identity
5629 transformation: GIMPLE -> GRAPHITE -> GIMPLE
5630 Keep in mind that CLooG optimizes in control, so the loop structure
5631 may change, even if we only use -fgraphite-identity. */
5632 if (flag_graphite_identity
)
5633 transform_done
= true;
5635 return transform_done
;
5638 /* We limit all SCoPs to SCoPs, that are completely surrounded by a loop.
5648 * SCoP frontier, as this line is not surrounded by any loop. *
5652 This is necessary as scalar evolution and parameter detection need a
5653 outermost loop to initialize parameters correctly.
5655 TODO: FIX scalar evolution and parameter detection to allow more flexible
5661 VEC (sd_region
, heap
) *tmp_scops
= VEC_alloc (sd_region
, heap
, 3);
5666 for (i
= 0; VEC_iterate (scop_p
, current_scops
, i
, scop
); i
++)
5670 build_scop_bbs (scop
);
5672 if (!build_scop_loop_nests (scop
))
5675 for (j
= 0; VEC_iterate (loop_p
, SCOP_LOOP_NEST (scop
), j
, loop
); j
++)
5676 if (!loop_in_scop_p (loop_outer (loop
), scop
))
5678 sd_region open_scop
;
5679 open_scop
.entry
= loop
->header
;
5680 open_scop
.exit
= single_exit (loop
)->dest
;
5681 VEC_safe_push (sd_region
, heap
, tmp_scops
, &open_scop
);
5685 free_scops (current_scops
);
5686 current_scops
= VEC_alloc (scop_p
, heap
, 3);
5688 create_sese_edges (tmp_scops
);
5689 build_graphite_scops (tmp_scops
);
5690 VEC_free (sd_region
, heap
, tmp_scops
);
5693 /* Perform a set of linear transforms on the loops of the current
5697 graphite_transform_loops (void)
5702 if (number_of_loops () <= 1)
5705 current_scops
= VEC_alloc (scop_p
, heap
, 3);
5706 recompute_all_dominators ();
5708 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5709 fprintf (dump_file
, "Graphite loop transformations \n");
5711 initialize_original_copy_tables ();
5712 cloog_initialize ();
5716 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5717 fprintf (dump_file
, "\nnumber of SCoPs: %d\n",
5718 VEC_length (scop_p
, current_scops
));
5720 for (i
= 0; VEC_iterate (scop_p
, current_scops
, i
, scop
); i
++)
5722 build_scop_bbs (scop
);
5723 if (!build_scop_loop_nests (scop
))
5726 build_scop_canonical_schedules (scop
);
5727 build_bb_loops (scop
);
5728 build_scop_conditions (scop
);
5729 find_scop_parameters (scop
);
5730 build_scop_context (scop
);
5732 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5734 fprintf (dump_file
, "\n(In SCoP %d:\n", i
);
5735 fprintf (dump_file
, "\nnumber of bbs: %d\n",
5736 VEC_length (graphite_bb_p
, SCOP_BBS (scop
)));
5737 fprintf (dump_file
, "\nnumber of loops: %d)\n",
5738 VEC_length (loop_p
, SCOP_LOOP_NEST (scop
)));
5741 if (!build_scop_iteration_domain (scop
))
5744 build_scop_data_accesses (scop
);
5745 build_scop_dynamic_schedules (scop
);
5747 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5749 int nbrefs
= nb_data_refs_in_scop (scop
);
5750 fprintf (dump_file
, "\nnumber of data refs: %d\n", nbrefs
);
5753 if (graphite_apply_transformations (scop
))
5754 gloog (scop
, find_transform (scop
));
5755 #ifdef ENABLE_CHECKING
5758 struct clast_stmt
*stmt
= find_transform (scop
);
5759 cloog_clast_free (stmt
);
5765 free_scops (current_scops
);
5767 free_original_copy_tables ();
5770 #else /* If Cloog is not available: #ifndef HAVE_cloog. */
5773 graphite_transform_loops (void)
5775 sorry ("Graphite loop optimizations cannot be used");