1 /* Detection of Static Control Parts (SCoP) for Graphite.
2 Copyright (C) 2009-2015 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <sebastian.pop@amd.com> and
4 Tobias Grosser <grosser@fim.uni-passau.de>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
25 /* Workaround for GMP 5.1.3 bug, see PR56019. */
28 #include <isl/constraint.h>
31 #include <isl/union_map.h>
34 #include "coretypes.h"
42 #include "fold-const.h"
43 #include "gimple-iterator.h"
45 #include "tree-ssa-loop-manip.h"
46 #include "tree-ssa-loop-niter.h"
47 #include "tree-ssa-loop.h"
48 #include "tree-into-ssa.h"
51 #include "tree-data-ref.h"
52 #include "tree-scalar-evolution.h"
53 #include "tree-pass.h"
54 #include "graphite-poly.h"
55 #include "tree-ssa-propagate.h"
56 #include "graphite-scop-detection.h"
57 #include "gimple-pretty-print.h"
66 set_dump_file (FILE *f
)
72 friend debug_printer
&
73 operator<< (debug_printer
&output
, int i
)
75 fprintf (output
.dump_file
, "%d", i
);
78 friend debug_printer
&
79 operator<< (debug_printer
&output
, const char *s
)
81 fprintf (output
.dump_file
, "%s", s
);
86 #define DEBUG_PRINT(args) do \
88 if (dump_file && (dump_flags & TDF_DETAILS)) { args; } \
92 /* Return true if BB is empty, contains only DEBUG_INSNs. */
95 trivially_empty_bb_p (basic_block bb
)
97 gimple_stmt_iterator gsi
;
99 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
100 if (gimple_code (gsi_stmt (gsi
)) != GIMPLE_DEBUG
)
106 /* Returns true when P1 and P2 are close phis with the same
110 same_close_phi_node (gphi
*p1
, gphi
*p2
)
112 return operand_equal_p (gimple_phi_arg_def (p1
, 0),
113 gimple_phi_arg_def (p2
, 0), 0);
116 static void make_close_phi_nodes_unique (basic_block bb
);
118 /* Remove the close phi node at GSI and replace its rhs with the rhs
122 remove_duplicate_close_phi (gphi
*phi
, gphi_iterator
*gsi
)
126 imm_use_iterator imm_iter
;
127 tree res
= gimple_phi_result (phi
);
128 tree def
= gimple_phi_result (gsi
->phi ());
130 gcc_assert (same_close_phi_node (phi
, gsi
->phi ()));
132 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
134 FOR_EACH_IMM_USE_ON_STMT (use_p
, imm_iter
)
135 SET_USE (use_p
, res
);
137 update_stmt (use_stmt
);
139 /* It is possible that we just created a duplicate close-phi
140 for an already-processed containing loop. Check for this
141 case and clean it up. */
142 if (gimple_code (use_stmt
) == GIMPLE_PHI
143 && gimple_phi_num_args (use_stmt
) == 1)
144 make_close_phi_nodes_unique (gimple_bb (use_stmt
));
147 remove_phi_node (gsi
, true);
150 /* Removes all the close phi duplicates from BB. */
153 make_close_phi_nodes_unique (basic_block bb
)
157 for (psi
= gsi_start_phis (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
159 gphi_iterator gsi
= psi
;
160 gphi
*phi
= psi
.phi ();
162 /* At this point, PHI should be a close phi in normal form. */
163 gcc_assert (gimple_phi_num_args (phi
) == 1);
165 /* Iterate over the next phis and remove duplicates. */
167 while (!gsi_end_p (gsi
))
168 if (same_close_phi_node (phi
, gsi
.phi ()))
169 remove_duplicate_close_phi (phi
, &gsi
);
175 /* Transforms LOOP to the canonical loop closed SSA form. */
178 canonicalize_loop_closed_ssa (loop_p loop
)
180 edge e
= single_exit (loop
);
183 if (!e
|| e
->flags
& EDGE_ABNORMAL
)
188 if (single_pred_p (bb
))
190 e
= split_block_after_labels (bb
);
191 DEBUG_PRINT (dp
<< "\nSplitting bb_" << bb
->index
);
192 make_close_phi_nodes_unique (e
->src
);
197 basic_block close
= split_edge (e
);
199 e
= single_succ_edge (close
);
200 DEBUG_PRINT (dp
<< "\nSplitting edge (" << e
->src
->index
<< ","
201 << e
->dest
->index
<< ")\n");
203 for (psi
= gsi_start_phis (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
205 gphi
*phi
= psi
.phi ();
208 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
209 if (gimple_phi_arg_edge (phi
, i
) == e
)
211 tree res
, arg
= gimple_phi_arg_def (phi
, i
);
215 if (TREE_CODE (arg
) != SSA_NAME
)
218 close_phi
= create_phi_node (NULL_TREE
, close
);
219 res
= create_new_def_for (arg
, close_phi
,
220 gimple_phi_result_ptr (close_phi
));
221 add_phi_arg (close_phi
, arg
,
222 gimple_phi_arg_edge (close_phi
, 0),
224 use_p
= gimple_phi_arg_imm_use_ptr (phi
, i
);
225 replace_exp (use_p
, res
);
230 make_close_phi_nodes_unique (close
);
233 /* The code above does not properly handle changes in the post dominance
234 information (yet). */
235 recompute_all_dominators ();
238 /* Converts the current loop closed SSA form to a canonical form
239 expected by the Graphite code generation.
241 The loop closed SSA form has the following invariant: a variable
242 defined in a loop that is used outside the loop appears only in the
243 phi nodes in the destination of the loop exit. These phi nodes are
244 called close phi nodes.
246 The canonical loop closed SSA form contains the extra invariants:
248 - when the loop contains only one exit, the close phi nodes contain
249 only one argument. That implies that the basic block that contains
250 the close phi nodes has only one predecessor, that is a basic block
253 - the basic block containing the close phi nodes does not contain
256 - there exist only one phi node per definition in the loop.
260 canonicalize_loop_closed_ssa_form (void)
262 checking_verify_loop_closed_ssa (true);
265 FOR_EACH_LOOP (loop
, 0)
266 canonicalize_loop_closed_ssa (loop
);
268 rewrite_into_loop_closed_ssa (NULL
, TODO_update_ssa
);
269 update_ssa (TODO_update_ssa
);
271 checking_verify_loop_closed_ssa (true);
274 /* Can all ivs be represented by a signed integer?
275 As ISL might generate negative values in its expressions, signed loop ivs
276 are required in the backend. */
279 loop_ivs_can_be_represented (loop_p loop
)
281 unsigned type_long_long
= TYPE_PRECISION (long_long_integer_type_node
);
282 for (gphi_iterator psi
= gsi_start_phis (loop
->header
); !gsi_end_p (psi
);
285 gphi
*phi
= psi
.phi ();
286 tree res
= PHI_RESULT (phi
);
287 tree type
= TREE_TYPE (res
);
289 if (TYPE_UNSIGNED (type
) && TYPE_PRECISION (type
) >= type_long_long
)
296 /* Returns a COND_EXPR statement when BB has a single predecessor, the
297 edge between BB and its predecessor is not a loop exit edge, and
298 the last statement of the single predecessor is a COND_EXPR. */
301 single_pred_cond_non_loop_exit (basic_block bb
)
303 if (single_pred_p (bb
))
305 edge e
= single_pred_edge (bb
);
306 basic_block pred
= e
->src
;
309 if (loop_depth (pred
->loop_father
) > loop_depth (bb
->loop_father
))
312 stmt
= last_stmt (pred
);
314 if (stmt
&& gimple_code (stmt
) == GIMPLE_COND
)
315 return as_a
<gcond
*> (stmt
);
324 /* Build the maximal scop containing LOOPs and add it to SCOPS. */
329 scop_detection () : scops (vNULL
) {}
331 /* A marker for invalid sese_l. */
332 static sese_l invalid_sese
;
334 /* Return the SCOPS in this SCOP_DETECTION. */
342 /* Return an sese_l around the LOOP. */
344 sese_l
get_sese (loop_p loop
);
346 /* Return the closest dominator with a single entry edge. In case of a
347 back-loop the back-edge is not counted. */
349 static edge
get_nearest_dom_with_single_entry (basic_block dom
);
351 /* Return the closest post-dominator with a single exit edge. In case of a
352 back-loop the back-edge is not counted. */
354 static edge
get_nearest_pdom_with_single_exit (basic_block dom
);
356 /* Print S to FILE. */
358 static void print_sese (FILE *file
, sese_l s
);
360 /* Merge scops at same loop depth and returns the new sese.
361 Returns a new SESE when merge was successful, INVALID_SESE otherwise. */
363 sese_l
merge_sese (sese_l first
, sese_l second
) const;
365 /* Build scop outer->inner if possible. */
367 sese_l
build_scop_depth (sese_l s
, loop_p loop
);
369 /* If loop and loop->next are valid scops, try to merge them. */
371 sese_l
build_scop_breadth (sese_l s1
, loop_p loop
);
373 /* Return true when LOOP is a valid scop, that is a Static Control Part, a
374 region of code that can be represented in the polyhedral model. SCOP
375 defines the region we analyse. */
377 bool loop_is_valid_scop (loop_p loop
, sese_l scop
) const;
379 /* Return true when BEGIN is the preheader edge of a loop with a single exit
382 static bool region_has_one_loop (sese_l s
);
384 /* Add to SCOPS a scop starting at SCOP_BEGIN and ending at SCOP_END. */
386 void add_scop (sese_l s
);
388 /* Returns true if S1 subsumes/surrounds S2. */
389 static bool subsumes (sese_l s1
, sese_l s2
);
391 /* Remove a SCoP which is subsumed by S1. */
392 void remove_subscops (sese_l s1
);
394 /* Returns true if S1 intersects with S2. Since we already know that S1 does
395 not subsume S2 or vice-versa, we only check for entry bbs. */
397 static bool intersects (sese_l s1
, sese_l s2
);
399 /* Remove one of the scops when it intersects with any other. */
401 void remove_intersecting_scops (sese_l s1
);
403 /* Return true when the body of LOOP has statements that can be represented
406 bool loop_body_is_valid_scop (loop_p loop
, sese_l scop
) const;
408 /* Return true when BB contains a harmful operation for a scop: that
409 can be a function call with side effects, the induction variables
410 are not linear with respect to SCOP, etc. The current open
411 scop should end before this statement. */
413 bool harmful_stmt_in_bb (sese_l scop
, basic_block bb
) const;
415 /* Return true when a statement in SCOP cannot be represented by Graphite.
416 The assumptions are that L1 dominates L2, and SCOP->entry dominates L1.
417 Limit the number of bbs between adjacent loops to
418 PARAM_SCOP_MAX_NUM_BBS_BETWEEN_LOOPS. */
420 bool harmful_stmt_in_region (sese_l scop
) const;
422 /* Return true only when STMT is simple enough for being handled by Graphite.
423 This depends on SCOP, as the parameters are initialized relatively to
424 this basic block, the linear functions are initialized based on the
425 outermost loop containing STMT inside the SCOP. BB is the place where we
426 try to evaluate the STMT. */
428 bool stmt_simple_for_scop_p (sese_l scop
, gimple
*stmt
,
429 basic_block bb
) const;
431 /* Something like "n * m" is not allowed. */
433 static bool graphite_can_represent_init (tree e
);
435 /* Return true when SCEV can be represented in the polyhedral model.
437 An expression can be represented, if it can be expressed as an
438 affine expression. For loops (i, j) and parameters (m, n) all
439 affine expressions are of the form:
441 x1 * i + x2 * j + x3 * m + x4 * n + x5 * 1 where x1..x5 element of Z
443 1 i + 20 j + (-2) m + 25
445 Something like "i * n" or "n * m" is not allowed. */
447 static bool graphite_can_represent_scev (tree scev
);
449 /* Return true when EXPR can be represented in the polyhedral model.
451 This means an expression can be represented, if it is linear with respect
452 to the loops and the strides are non parametric. LOOP is the place where
453 the expr will be evaluated. SCOP defines the region we analyse. */
455 static bool graphite_can_represent_expr (sese_l scop
, loop_p loop
,
458 /* Return true if the data references of STMT can be represented by Graphite.
459 We try to analyze the data references in a loop contained in the SCOP. */
461 static bool stmt_has_simple_data_refs_p (sese_l scop
, gimple
*stmt
);
463 /* Remove the close phi node at GSI and replace its rhs with the rhs
466 static void remove_duplicate_close_phi (gphi
*phi
, gphi_iterator
*gsi
);
468 /* Returns true when Graphite can represent LOOP in SCOP.
469 FIXME: For the moment, graphite cannot be used on loops that iterate using
470 induction variables that wrap. */
472 static bool can_represent_loop_1 (loop_p loop
, sese_l scop
);
474 /* Return true when all the loops within LOOP can be represented by
477 static bool can_represent_loop (loop_p loop
, sese_l scop
);
479 /* Returns the number of pbbs that are in loops contained in SCOP. */
481 static int nb_pbbs_in_loops (scop_p scop
);
483 static bool graphite_can_represent_stmt (sese_l
, gimple
*, basic_block
);
489 sese_l
scop_detection::invalid_sese (NULL
, NULL
);
491 /* Return an sese_l around the LOOP. */
494 scop_detection::get_sese (loop_p loop
)
499 if (!loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS
))
501 edge scop_end
= single_exit (loop
);
504 edge scop_begin
= loop_preheader_edge (loop
);
505 sese_l
s (scop_begin
, scop_end
);
509 /* Return the closest dominator with a single entry edge. */
512 scop_detection::get_nearest_dom_with_single_entry (basic_block dom
)
516 /* If e1->src dominates e2->src then e1->src will also dominate dom. */
517 if (dom
->preds
->length () == 2)
519 edge e1
= (*dom
->preds
)[0];
520 edge e2
= (*dom
->preds
)[1];
521 if (dominated_by_p (CDI_DOMINATORS
, e2
->src
, e1
->src
))
523 if (dominated_by_p (CDI_DOMINATORS
, e1
->src
, e2
->src
))
527 while (dom
->preds
->length () != 1)
529 if (dom
->preds
->length () < 1)
531 dom
= get_immediate_dominator (CDI_DOMINATORS
, dom
);
535 return (*dom
->preds
)[0];
538 /* Return the closest post-dominator with a single exit edge. In case of a
539 back-loop the back-edge is not counted. */
542 scop_detection::get_nearest_pdom_with_single_exit (basic_block dom
)
546 if (dom
->succs
->length () == 2)
548 edge e1
= (*dom
->succs
)[0];
549 edge e2
= (*dom
->succs
)[1];
550 if (dominated_by_p (CDI_POST_DOMINATORS
, e2
->dest
, e1
->dest
))
552 if (dominated_by_p (CDI_POST_DOMINATORS
, e1
->dest
, e2
->dest
))
556 while (dom
->succs
->length () != 1)
558 if (dom
->succs
->length () < 1)
560 dom
= get_immediate_dominator (CDI_POST_DOMINATORS
, dom
);
564 return (*dom
->succs
)[0];
567 /* Print S to FILE. */
570 scop_detection::print_sese (FILE *file
, sese_l s
)
572 fprintf (file
, "(entry_edge (bb_%d, bb_%d), exit_edge (bb_%d, bb_%d))\n",
573 s
.entry
->src
->index
, s
.entry
->dest
->index
,
574 s
.exit
->src
->index
, s
.exit
->dest
->index
);
577 /* Merge scops at same loop depth and returns the new sese.
578 Returns a new SESE when merge was successful, INVALID_SESE otherwise. */
581 scop_detection::merge_sese (sese_l first
, sese_l second
) const
583 /* In the trivial case first/second may be NULL. */
589 DEBUG_PRINT (dp
<< "[try-merging-sese] s1: "; print_sese (dump_file
, first
);
590 dp
<< "[try-merging-sese] s2: ";
591 print_sese (dump_file
, second
));
593 /* Assumption: Both the sese's should be at the same loop depth or one scop
594 should subsume the other like in case of nested loops. */
596 /* Find the common dominators for entry,
597 and common post-dominators for the exit. */
598 basic_block dom
= nearest_common_dominator (CDI_DOMINATORS
,
599 get_entry_bb (first
),
600 get_entry_bb (second
));
602 edge entry
= get_nearest_dom_with_single_entry (dom
);
606 basic_block pdom
= nearest_common_dominator (CDI_POST_DOMINATORS
,
608 get_exit_bb (second
));
609 pdom
= nearest_common_dominator (CDI_POST_DOMINATORS
, dom
, pdom
);
611 edge exit
= get_nearest_pdom_with_single_exit (pdom
);
615 sese_l
combined (entry
, exit
);
617 /* FIXME: We could iterate to find the dom which dominates pdom, and pdom
618 which post-dominates dom, until it stabilizes. Also, ENTRY->SRC and
619 EXIT->DEST should be in the same loop nest. */
620 if (!dominated_by_p (CDI_DOMINATORS
, pdom
, dom
)
621 || loop_depth (entry
->src
->loop_father
)
622 != loop_depth (exit
->dest
->loop_father
))
625 /* For now we just want to bail out when exit does not post-dominate entry.
626 TODO: We might just add a basic_block at the exit to make exit
627 post-dominate entry (the entire region). */
628 if (!dominated_by_p (CDI_POST_DOMINATORS
, get_entry_bb (combined
),
629 get_exit_bb (combined
))
630 || !dominated_by_p (CDI_DOMINATORS
, get_exit_bb (combined
),
631 get_entry_bb (combined
)))
633 DEBUG_PRINT (dp
<< "[scop-detection-fail] cannot merge seses.\n");
637 /* FIXME: We should remove this piece of code once
638 canonicalize_loop_closed_ssa has been removed, because that function
639 adds a BB with single exit. */
640 if (!trivially_empty_bb_p (get_exit_bb (combined
)))
642 /* Find the first empty succ (with single exit) of combined.exit. */
643 basic_block imm_succ
= combined
.exit
->dest
;
644 if (single_succ_p (imm_succ
) && trivially_empty_bb_p (imm_succ
))
645 combined
.exit
= single_succ_edge (imm_succ
);
648 DEBUG_PRINT (dp
<< "\n[scop-detection-fail] Discarding SCoP because "
649 << "no single exit (empty succ) for sese exit";
650 print_sese (dump_file
, combined
));
655 /* Analyze all the BBs in new sese. */
656 if (harmful_stmt_in_region (combined
))
659 DEBUG_PRINT (dp
<< "[merged-sese] s1: "; print_sese (dump_file
, combined
));
664 /* Build scop outer->inner if possible. */
667 scop_detection::build_scop_depth (sese_l s
, loop_p loop
)
672 DEBUG_PRINT (dp
<< "\n[Depth loop_" << loop
->num
<< "]");
673 s
= build_scop_depth (s
, loop
->inner
);
675 sese_l s2
= merge_sese (s
, get_sese (loop
));
678 /* s might be a valid scop, so return it and start analyzing from the
680 build_scop_depth (invalid_sese
, loop
->next
);
684 if (!loop_is_valid_scop (loop
, s2
))
685 return build_scop_depth (invalid_sese
, loop
->next
);
687 return build_scop_breadth (s2
, loop
);
690 /* If loop and loop->next are valid scops, try to merge them. */
693 scop_detection::build_scop_breadth (sese_l s1
, loop_p loop
)
697 DEBUG_PRINT (dp
<< "\n[Breadth loop_" << loop
->num
<< "]");
701 sese_l s2
= build_scop_depth (invalid_sese
, l
->next
);
709 sese_l combined
= merge_sese (s1
, s2
);
721 /* Returns true when Graphite can represent LOOP in SCOP.
722 FIXME: For the moment, graphite cannot be used on loops that iterate using
723 induction variables that wrap. */
726 scop_detection::can_represent_loop_1 (loop_p loop
, sese_l scop
)
729 struct tree_niter_desc niter_desc
;
731 return single_exit (loop
)
732 && number_of_iterations_exit (loop
, single_exit (loop
), &niter_desc
, false)
733 && niter_desc
.control
.no_overflow
734 && (niter
= number_of_latch_executions (loop
))
735 && !chrec_contains_undetermined (niter
)
736 && graphite_can_represent_expr (scop
, loop
, niter
);
739 /* Return true when all the loops within LOOP can be represented by
743 scop_detection::can_represent_loop (loop_p loop
, sese_l scop
)
745 if (!can_represent_loop_1 (loop
, scop
))
747 if (loop
->inner
&& !can_represent_loop (loop
->inner
, scop
))
749 if (loop
->next
&& !can_represent_loop (loop
->next
, scop
))
755 /* Return true when LOOP is a valid scop, that is a Static Control Part, a
756 region of code that can be represented in the polyhedral model. SCOP
757 defines the region we analyse. */
760 scop_detection::loop_is_valid_scop (loop_p loop
, sese_l scop
) const
765 if (!can_represent_loop (loop
, scop
))
767 DEBUG_PRINT (dp
<< "[scop-detection-fail] cannot represent loop_"
768 << loop
->num
<< "\n");
772 if (loop_body_is_valid_scop (loop
, scop
))
774 DEBUG_PRINT (dp
<< "[valid-scop] loop_" << loop
->num
775 << "is a valid scop.\n");
781 /* Return true when BEGIN is the preheader edge of a loop with a single exit
785 scop_detection::region_has_one_loop (sese_l s
)
787 edge begin
= s
.entry
;
789 /* Check for a single perfectly nested loop. */
790 if (begin
->dest
->loop_father
->inner
)
793 /* Otherwise, check whether we have adjacent loops. */
794 return begin
->dest
->loop_father
== end
->src
->loop_father
;
797 /* Add to SCOPS a scop starting at SCOP_BEGIN and ending at SCOP_END. */
800 scop_detection::add_scop (sese_l s
)
804 /* Do not add scops with only one loop. */
805 if (region_has_one_loop (s
))
807 DEBUG_PRINT (dp
<< "\n[scop-detection-fail] Discarding one loop SCoP";
808 print_sese (dump_file
, s
));
812 if (get_exit_bb (s
) == EXIT_BLOCK_PTR_FOR_FN (cfun
))
814 DEBUG_PRINT (dp
<< "\n[scop-detection-fail] "
815 << "Discarding SCoP exiting to return";
816 print_sese (dump_file
, s
));
820 /* Remove all the scops which are subsumed by s. */
823 /* Replace this with split-intersecting scops. */
824 remove_intersecting_scops (s
);
827 DEBUG_PRINT (dp
<< "\nAdding SCoP "; print_sese (dump_file
, s
));
830 /* Return true when a statement in SCOP cannot be represented by Graphite.
831 The assumptions are that L1 dominates L2, and SCOP->entry dominates L1.
832 Limit the number of bbs between adjacent loops to
833 PARAM_SCOP_MAX_NUM_BBS_BETWEEN_LOOPS. */
836 scop_detection::harmful_stmt_in_region (sese_l scop
) const
838 basic_block exit_bb
= get_exit_bb (scop
);
839 basic_block entry_bb
= get_entry_bb (scop
);
841 DEBUG_PRINT (dp
<< "\n[checking-harmful-bbs] ";
842 print_sese (dump_file
, scop
));
843 gcc_assert (dominated_by_p (CDI_DOMINATORS
, exit_bb
, entry_bb
));
845 int depth
= bb_dom_dfs_in (CDI_DOMINATORS
, exit_bb
)
846 - bb_dom_dfs_in (CDI_DOMINATORS
, entry_bb
);
848 gcc_assert (depth
> 0);
851 = get_dominated_to_depth (CDI_DOMINATORS
, entry_bb
, depth
);
854 FOR_EACH_VEC_ELT (dom
, i
, bb
)
856 DEBUG_PRINT (dp
<< "\nVisiting bb_" << bb
->index
);
858 /* We don't want to analyze any bb outside sese. */
859 if (!dominated_by_p (CDI_POST_DOMINATORS
, bb
, exit_bb
))
862 if (harmful_stmt_in_bb (scop
, bb
))
869 /* Returns true if S1 subsumes/surrounds S2. */
871 scop_detection::subsumes (sese_l s1
, sese_l s2
)
873 if (dominated_by_p (CDI_DOMINATORS
, get_entry_bb (s2
),
875 && dominated_by_p (CDI_POST_DOMINATORS
, s2
.exit
->dest
,
881 /* Remove a SCoP which is subsumed by S1. */
883 scop_detection::remove_subscops (sese_l s1
)
887 FOR_EACH_VEC_ELT_REVERSE (scops
, j
, s2
)
889 if (subsumes (s1
, *s2
))
891 DEBUG_PRINT (dp
<< "\nRemoving sub-SCoP";
892 print_sese (dump_file
, *s2
));
893 scops
.unordered_remove (j
);
898 /* Returns true if S1 intersects with S2. Since we already know that S1 does
899 not subsume S2 or vice-versa, we only check for entry bbs. */
902 scop_detection::intersects (sese_l s1
, sese_l s2
)
904 if (dominated_by_p (CDI_DOMINATORS
, get_entry_bb (s2
),
906 && !dominated_by_p (CDI_DOMINATORS
, get_entry_bb (s2
),
909 if ((s1
.exit
== s2
.entry
) || (s2
.exit
== s1
.entry
))
915 /* Remove one of the scops when it intersects with any other. */
918 scop_detection::remove_intersecting_scops (sese_l s1
)
922 FOR_EACH_VEC_ELT_REVERSE (scops
, j
, s2
)
924 if (intersects (s1
, *s2
))
926 DEBUG_PRINT (dp
<< "\nRemoving intersecting SCoP";
927 print_sese (dump_file
, *s2
); dp
<< "Intersects with:";
928 print_sese (dump_file
, s1
));
929 scops
.unordered_remove (j
);
934 /* Something like "n * m" is not allowed. */
937 scop_detection::graphite_can_represent_init (tree e
)
939 switch (TREE_CODE (e
))
941 case POLYNOMIAL_CHREC
:
942 return graphite_can_represent_init (CHREC_LEFT (e
))
943 && graphite_can_represent_init (CHREC_RIGHT (e
));
946 if (chrec_contains_symbols (TREE_OPERAND (e
, 0)))
947 return graphite_can_represent_init (TREE_OPERAND (e
, 0))
948 && tree_fits_shwi_p (TREE_OPERAND (e
, 1));
950 return graphite_can_represent_init (TREE_OPERAND (e
, 1))
951 && tree_fits_shwi_p (TREE_OPERAND (e
, 0));
954 case POINTER_PLUS_EXPR
:
956 return graphite_can_represent_init (TREE_OPERAND (e
, 0))
957 && graphite_can_represent_init (TREE_OPERAND (e
, 1));
962 case NON_LVALUE_EXPR
:
963 return graphite_can_represent_init (TREE_OPERAND (e
, 0));
972 /* Return true when SCEV can be represented in the polyhedral model.
974 An expression can be represented, if it can be expressed as an
975 affine expression. For loops (i, j) and parameters (m, n) all
976 affine expressions are of the form:
978 x1 * i + x2 * j + x3 * m + x4 * n + x5 * 1 where x1..x5 element of Z
980 1 i + 20 j + (-2) m + 25
982 Something like "i * n" or "n * m" is not allowed. */
985 scop_detection::graphite_can_represent_scev (tree scev
)
987 if (chrec_contains_undetermined (scev
))
990 /* We disable the handling of pointer types, because it’s currently not
991 supported by Graphite with the ISL AST generator. SSA_NAME nodes are
992 the only nodes, which are disabled in case they are pointers to object
993 types, but this can be changed. */
995 if (POINTER_TYPE_P (TREE_TYPE (scev
)) && TREE_CODE (scev
) == SSA_NAME
)
998 switch (TREE_CODE (scev
))
1003 case NON_LVALUE_EXPR
:
1004 return graphite_can_represent_scev (TREE_OPERAND (scev
, 0));
1007 case POINTER_PLUS_EXPR
:
1009 return graphite_can_represent_scev (TREE_OPERAND (scev
, 0))
1010 && graphite_can_represent_scev (TREE_OPERAND (scev
, 1));
1013 return !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev
, 0)))
1014 && !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev
, 1)))
1015 && !(chrec_contains_symbols (TREE_OPERAND (scev
, 0))
1016 && chrec_contains_symbols (TREE_OPERAND (scev
, 1)))
1017 && graphite_can_represent_init (scev
)
1018 && graphite_can_represent_scev (TREE_OPERAND (scev
, 0))
1019 && graphite_can_represent_scev (TREE_OPERAND (scev
, 1));
1021 case POLYNOMIAL_CHREC
:
1022 /* Check for constant strides. With a non constant stride of
1023 'n' we would have a value of 'iv * n'. Also check that the
1024 initial value can represented: for example 'n * m' cannot be
1026 if (!evolution_function_right_is_integer_cst (scev
)
1027 || !graphite_can_represent_init (scev
))
1029 return graphite_can_represent_scev (CHREC_LEFT (scev
));
1035 /* Only affine functions can be represented. */
1036 if (tree_contains_chrecs (scev
, NULL
) || !scev_is_linear_expression (scev
))
1042 /* Return true when EXPR can be represented in the polyhedral model.
1044 This means an expression can be represented, if it is linear with respect to
1045 the loops and the strides are non parametric. LOOP is the place where the
1046 expr will be evaluated. SCOP defines the region we analyse. */
1049 scop_detection::graphite_can_represent_expr (sese_l scop
, loop_p loop
,
1052 tree scev
= scalar_evolution_in_region (scop
, loop
, expr
);
1053 return graphite_can_represent_scev (scev
);
1056 /* Return true if the data references of STMT can be represented by Graphite.
1057 We try to analyze the data references in a loop contained in the SCOP. */
1060 scop_detection::stmt_has_simple_data_refs_p (sese_l scop
, gimple
*stmt
)
1062 loop_p nest
= outermost_loop_in_sese (scop
, gimple_bb (stmt
));
1063 loop_p loop
= loop_containing_stmt (stmt
);
1064 vec
<data_reference_p
> drs
= vNULL
;
1066 graphite_find_data_references_in_stmt (nest
, loop
, stmt
, &drs
);
1069 data_reference_p dr
;
1070 FOR_EACH_VEC_ELT (drs
, j
, dr
)
1072 int nb_subscripts
= DR_NUM_DIMENSIONS (dr
);
1074 if (nb_subscripts
< 1)
1076 free_data_refs (drs
);
1080 tree ref
= DR_REF (dr
);
1082 for (int i
= nb_subscripts
- 1; i
>= 0; i
--)
1084 if (!graphite_can_represent_scev (DR_ACCESS_FN (dr
, i
))
1085 || (TREE_CODE (ref
) != ARRAY_REF
&& TREE_CODE (ref
) != MEM_REF
1086 && TREE_CODE (ref
) != COMPONENT_REF
))
1088 free_data_refs (drs
);
1092 ref
= TREE_OPERAND (ref
, 0);
1096 free_data_refs (drs
);
1100 /* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects.
1101 Calls have side-effects, except those to const or pure
1105 stmt_has_side_effects (gimple
*stmt
)
1107 if (gimple_has_volatile_ops (stmt
)
1108 || (gimple_code (stmt
) == GIMPLE_CALL
1109 && !(gimple_call_flags (stmt
) & (ECF_CONST
| ECF_PURE
)))
1110 || (gimple_code (stmt
) == GIMPLE_ASM
))
1112 DEBUG_PRINT (dp
<< "[scop-detection-fail] "
1113 << "Statement has side-effects:\n";
1114 print_gimple_stmt (dump_file
, stmt
, 0, TDF_VOPS
| TDF_MEMSYMS
));
1120 /* Returns true if STMT can be represented in polyhedral model. LABEL,
1121 simple COND stmts, pure calls, and assignments can be repesented. */
1124 scop_detection::graphite_can_represent_stmt (sese_l scop
, gimple
*stmt
,
1127 loop_p loop
= bb
->loop_father
;
1128 switch (gimple_code (stmt
))
1135 /* We can handle all binary comparisons. Inequalities are
1136 also supported as they can be represented with union of
1138 enum tree_code code
= gimple_cond_code (stmt
);
1139 if (!(code
== LT_EXPR
1144 || code
== NE_EXPR
))
1146 DEBUG_PRINT (dp
<< "[scop-detection-fail] "
1147 << "Graphite cannot handle cond stmt:\n";
1148 print_gimple_stmt (dump_file
, stmt
, 0,
1149 TDF_VOPS
| TDF_MEMSYMS
));
1153 for (unsigned i
= 0; i
< 2; ++i
)
1155 tree op
= gimple_op (stmt
, i
);
1156 if (!graphite_can_represent_expr (scop
, loop
, op
)
1157 /* We can only constrain on integer type. */
1158 || (TREE_CODE (TREE_TYPE (op
)) != INTEGER_TYPE
))
1160 DEBUG_PRINT (dp
<< "[scop-detection-fail] "
1161 << "Graphite cannot represent stmt:\n";
1162 print_gimple_stmt (dump_file
, stmt
, 0,
1163 TDF_VOPS
| TDF_MEMSYMS
));
1176 /* These nodes cut a new scope. */
1178 dp
<< "[scop-detection-fail] "
1179 << "Gimple stmt not handled in Graphite:\n";
1180 print_gimple_stmt (dump_file
, stmt
, 0, TDF_VOPS
| TDF_MEMSYMS
));
1185 /* Return true only when STMT is simple enough for being handled by Graphite.
1186 This depends on SCOP, as the parameters are initialized relatively to
1187 this basic block, the linear functions are initialized based on the outermost
1188 loop containing STMT inside the SCOP. BB is the place where we try to
1189 evaluate the STMT. */
1192 scop_detection::stmt_simple_for_scop_p (sese_l scop
, gimple
*stmt
,
1193 basic_block bb
) const
1197 if (is_gimple_debug (stmt
))
1200 if (stmt_has_side_effects (stmt
))
1203 if (!stmt_has_simple_data_refs_p (scop
, stmt
))
1205 DEBUG_PRINT (dp
<< "[scop-detection-fail] "
1206 << "Graphite cannot handle data-refs in stmt:\n";
1207 print_gimple_stmt (dump_file
, stmt
, 0, TDF_VOPS
|TDF_MEMSYMS
););
1211 return graphite_can_represent_stmt (scop
, stmt
, bb
);
1214 /* Return true when BB contains a harmful operation for a scop: that
1215 can be a function call with side effects, the induction variables
1216 are not linear with respect to SCOP, etc. The current open
1217 scop should end before this statement. */
1220 scop_detection::harmful_stmt_in_bb (sese_l scop
, basic_block bb
) const
1222 gimple_stmt_iterator gsi
;
1224 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1225 if (!stmt_simple_for_scop_p (scop
, gsi_stmt (gsi
), bb
))
1231 /* Pretty print to FILE all the SCoPs in DOT format and mark them with
1232 different colors. If there are not enough colors, paint the
1233 remaining SCoPs in gray.
1236 - "*" after the node number denotes the entry of a SCoP,
1237 - "#" after the node number denotes the exit of a SCoP,
1238 - "()" around the node number denotes the entry or the
1239 exit nodes of the SCOP. These are not part of SCoP. */
1242 dot_all_scops_1 (FILE *file
, vec
<scop_p
> scops
)
1251 /* Disable debugging while printing graph. */
1252 int tmp_dump_flags
= dump_flags
;
1255 fprintf (file
, "digraph all {\n");
1257 FOR_ALL_BB_FN (bb
, cfun
)
1259 int part_of_scop
= false;
1261 /* Use HTML for every bb label. So we are able to print bbs
1262 which are part of two different SCoPs, with two different
1263 background colors. */
1264 fprintf (file
, "%d [label=<\n <TABLE BORDER=\"0\" CELLBORDER=\"1\" ",
1266 fprintf (file
, "CELLSPACING=\"0\">\n");
1268 /* Select color for SCoP. */
1269 FOR_EACH_VEC_ELT (scops
, i
, scop
)
1271 sese_l region
= scop
->scop_info
->region
;
1272 if (bb_in_sese_p (bb
, region
) || (region
.exit
->dest
== bb
)
1273 || (region
.entry
->dest
== bb
))
1286 case 3: /* purple */
1289 case 4: /* orange */
1292 case 5: /* yellow */
1332 fprintf (file
, " <TR><TD WIDTH=\"50\" BGCOLOR=\"%s\">",
1335 if (!bb_in_sese_p (bb
, region
))
1336 fprintf (file
, " (");
1338 if (bb
== region
.entry
->dest
&& bb
== region
.exit
->dest
)
1339 fprintf (file
, " %d*# ", bb
->index
);
1340 else if (bb
== region
.entry
->dest
)
1341 fprintf (file
, " %d* ", bb
->index
);
1342 else if (bb
== region
.exit
->dest
)
1343 fprintf (file
, " %d# ", bb
->index
);
1345 fprintf (file
, " %d ", bb
->index
);
1347 fprintf (file
, "{lp_%d}", bb
->loop_father
->num
);
1349 if (!bb_in_sese_p (bb
, region
))
1350 fprintf (file
, ")");
1352 fprintf (file
, "</TD></TR>\n");
1353 part_of_scop
= true;
1359 fprintf (file
, " <TR><TD WIDTH=\"50\" BGCOLOR=\"#ffffff\">");
1360 fprintf (file
, " %d {lp_%d} </TD></TR>\n", bb
->index
,
1361 bb
->loop_father
->num
);
1363 fprintf (file
, " </TABLE>>, shape=box, style=\"setlinewidth(0)\"]\n");
1366 FOR_ALL_BB_FN (bb
, cfun
)
1368 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1369 fprintf (file
, "%d -> %d;\n", bb
->index
, e
->dest
->index
);
1372 fputs ("}\n\n", file
);
1374 /* Enable debugging again. */
1375 dump_flags
= tmp_dump_flags
;
1378 /* Display all SCoPs using dotty. */
1381 dot_all_scops (vec
<scop_p
> scops
)
1383 /* When debugging, enable the following code. This cannot be used
1384 in production compilers because it calls "system". */
1387 FILE *stream
= fopen ("/tmp/allscops.dot", "w");
1388 gcc_assert (stream
);
1390 dot_all_scops_1 (stream
, scops
);
1393 x
= system ("dotty /tmp/allscops.dot &");
1395 dot_all_scops_1 (stderr
, scops
);
1399 /* Display all SCoPs using dotty. */
1402 dot_scop (scop_p scop
)
1404 auto_vec
<scop_p
, 1> scops
;
1407 scops
.safe_push (scop
);
1409 /* When debugging, enable the following code. This cannot be used
1410 in production compilers because it calls "system". */
1414 FILE *stream
= fopen ("/tmp/allscops.dot", "w");
1415 gcc_assert (stream
);
1417 dot_all_scops_1 (stream
, scops
);
1419 x
= system ("dotty /tmp/allscops.dot &");
1422 dot_all_scops_1 (stderr
, scops
);
1426 /* Return true when the body of LOOP has statements that can be represented as a
1430 scop_detection::loop_body_is_valid_scop (loop_p loop
, sese_l scop
) const
1432 if (!loop_ivs_can_be_represented (loop
))
1434 DEBUG_PRINT (dp
<< "[scop-detection-fail] loop_" << loop
->num
1435 << "IV cannot be represented.\n");
1439 if (!loop_nest_has_data_refs (loop
))
1441 DEBUG_PRINT (dp
<< "[scop-detection-fail] loop_" << loop
->num
1442 << "does not have any data reference.\n");
1446 basic_block
*bbs
= get_loop_body (loop
);
1447 for (unsigned i
= 0; i
< loop
->num_nodes
; i
++)
1449 basic_block bb
= bbs
[i
];
1451 if (harmful_stmt_in_bb (scop
, bb
))
1461 if (!loop_body_is_valid_scop (loop
, scop
))
1470 /* Returns the number of pbbs that are in loops contained in SCOP. */
1473 scop_detection::nb_pbbs_in_loops (scop_p scop
)
1479 FOR_EACH_VEC_ELT (scop
->pbbs
, i
, pbb
)
1480 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb
)), scop
->scop_info
->region
))
1486 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
1487 Otherwise returns -1. */
1490 parameter_index_in_region_1 (tree name
, sese_info_p region
)
1495 gcc_assert (TREE_CODE (name
) == SSA_NAME
);
1497 FOR_EACH_VEC_ELT (SESE_PARAMS (region
), i
, p
)
1504 /* When the parameter NAME is in REGION, returns its index in
1505 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
1506 and returns the index of NAME. */
1509 parameter_index_in_region (tree name
, sese_info_p region
)
1513 gcc_assert (TREE_CODE (name
) == SSA_NAME
);
1515 /* Cannot constrain on anything else than INTEGER_TYPE parameters. */
1516 if (TREE_CODE (TREE_TYPE (name
)) != INTEGER_TYPE
)
1519 if (!invariant_in_sese_p_rec (name
, region
->region
, NULL
))
1522 i
= parameter_index_in_region_1 (name
, region
);
1526 i
= SESE_PARAMS (region
).length ();
1527 SESE_PARAMS (region
).safe_push (name
);
1531 /* In the context of sese S, scan the expression E and translate it to
1532 a linear expression C. When parsing a symbolic multiplication, K
1533 represents the constant multiplier of an expression containing
1537 scan_tree_for_params (sese_info_p s
, tree e
)
1539 if (e
== chrec_dont_know
)
1542 switch (TREE_CODE (e
))
1544 case POLYNOMIAL_CHREC
:
1545 scan_tree_for_params (s
, CHREC_LEFT (e
));
1549 if (chrec_contains_symbols (TREE_OPERAND (e
, 0)))
1550 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
1552 scan_tree_for_params (s
, TREE_OPERAND (e
, 1));
1556 case POINTER_PLUS_EXPR
:
1558 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
1559 scan_tree_for_params (s
, TREE_OPERAND (e
, 1));
1565 case NON_LVALUE_EXPR
:
1566 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
1570 parameter_index_in_region (e
, s
);
1586 /* Find parameters with respect to REGION in BB. We are looking in memory
1587 access functions, conditions and loop bounds. */
1590 find_params_in_bb (sese_info_p region
, gimple_poly_bb_p gbb
)
1592 /* Find parameters in the access functions of data references. */
1594 data_reference_p dr
;
1595 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb
), i
, dr
)
1596 for (unsigned j
= 0; j
< DR_NUM_DIMENSIONS (dr
); j
++)
1597 scan_tree_for_params (region
, DR_ACCESS_FN (dr
, j
));
1599 /* Find parameters in conditional statements. */
1601 loop_p loop
= GBB_BB (gbb
)->loop_father
;
1602 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb
), i
, stmt
)
1604 tree lhs
= scalar_evolution_in_region (region
->region
, loop
,
1605 gimple_cond_lhs (stmt
));
1606 tree rhs
= scalar_evolution_in_region (region
->region
, loop
,
1607 gimple_cond_rhs (stmt
));
1609 scan_tree_for_params (region
, lhs
);
1610 scan_tree_for_params (region
, rhs
);
1614 /* Record the parameters used in the SCOP. A variable is a parameter
1615 in a scop if it does not vary during the execution of that scop. */
1618 find_scop_parameters (scop_p scop
)
1621 sese_info_p region
= scop
->scop_info
;
1624 /* Find the parameters used in the loop bounds. */
1625 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region
), i
, loop
)
1627 tree nb_iters
= number_of_latch_executions (loop
);
1629 if (!chrec_contains_symbols (nb_iters
))
1632 nb_iters
= scalar_evolution_in_region (region
->region
, loop
, nb_iters
);
1633 scan_tree_for_params (region
, nb_iters
);
1636 /* Find the parameters used in data accesses. */
1638 FOR_EACH_VEC_ELT (scop
->pbbs
, i
, pbb
)
1639 find_params_in_bb (region
, PBB_BLACK_BOX (pbb
));
1641 int nbp
= sese_nb_params (region
);
1642 scop_set_nb_params (scop
, nbp
);
1645 /* Generates a polyhedral black box only if the bb contains interesting
1648 static gimple_poly_bb_p
1649 try_generate_gimple_bb (scop_p scop
, basic_block bb
)
1651 vec
<data_reference_p
> drs
;
1653 sese_l region
= scop
->scop_info
->region
;
1654 loop_p nest
= outermost_loop_in_sese (region
, bb
);
1656 loop_p loop
= bb
->loop_father
;
1657 if (!loop_in_sese_p (loop
, region
))
1660 gimple_stmt_iterator gsi
;
1661 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1663 gimple
*stmt
= gsi_stmt (gsi
);
1664 if (is_gimple_debug (stmt
))
1667 graphite_find_data_references_in_stmt (nest
, loop
, stmt
, &drs
);
1670 return new_gimple_poly_bb (bb
, drs
);
1673 /* Gather BBs and conditions for a SCOP. */
1674 class gather_bbs
: public dom_walker
1677 gather_bbs (cdi_direction
, scop_p
);
1679 virtual void before_dom_children (basic_block
);
1680 virtual void after_dom_children (basic_block
);
1683 auto_vec
<gimple
*, 3> conditions
, cases
;
1687 gather_bbs::gather_bbs (cdi_direction direction
, scop_p scop
)
1688 : dom_walker (direction
), scop (scop
)
1692 /* Call-back for dom_walk executed before visiting the dominated
1696 gather_bbs::before_dom_children (basic_block bb
)
1698 if (!bb_in_sese_p (bb
, scop
->scop_info
->region
))
1701 gcond
*stmt
= single_pred_cond_non_loop_exit (bb
);
1705 edge e
= single_pred_edge (bb
);
1707 conditions
.safe_push (stmt
);
1709 if (e
->flags
& EDGE_TRUE_VALUE
)
1710 cases
.safe_push (stmt
);
1712 cases
.safe_push (NULL
);
1715 scop
->scop_info
->bbs
.safe_push (bb
);
1717 gimple_poly_bb_p gbb
= try_generate_gimple_bb (scop
, bb
);
1718 GBB_CONDITIONS (gbb
) = conditions
.copy ();
1719 GBB_CONDITION_CASES (gbb
) = cases
.copy ();
1721 poly_bb_p pbb
= new_poly_bb (scop
, gbb
);
1722 scop
->pbbs
.safe_push (pbb
);
1725 /* Call-back for dom_walk executed after visiting the dominated
1729 gather_bbs::after_dom_children (basic_block bb
)
1731 if (!bb_in_sese_p (bb
, scop
->scop_info
->region
))
1734 if (single_pred_cond_non_loop_exit (bb
))
1741 /* Find Static Control Parts (SCoP) in the current function and pushes
1745 build_scops (vec
<scop_p
> *scops
)
1748 dp
.set_dump_file (dump_file
);
1750 canonicalize_loop_closed_ssa_form ();
1753 sb
.build_scop_depth (scop_detection::invalid_sese
, current_loops
->tree_root
);
1755 /* Now create scops from the lightweight SESEs. */
1756 vec
<sese_l
> scops_l
= sb
.get_scops ();
1759 FOR_EACH_VEC_ELT (scops_l
, i
, s
)
1761 scop_p scop
= new_scop (s
->entry
, s
->exit
);
1763 /* Record all basic blocks and their conditions in REGION. */
1764 gather_bbs (CDI_DOMINATORS
, scop
).walk (cfun
->cfg
->x_entry_block_ptr
);
1766 /* Do not optimize a scop containing only PBBs that do not belong
1768 if (sb
.nb_pbbs_in_loops (scop
) == 0)
1770 DEBUG_PRINT (dp
<< "[scop-detection-fail] no data references.\n");
1775 unsigned max_arrays
= PARAM_VALUE (PARAM_GRAPHITE_MAX_ARRAYS_PER_SCOP
);
1776 if (scop
->drs
.length () >= max_arrays
)
1778 DEBUG_PRINT (dp
<< "[scop-detection-fail] too many data references: "
1779 << scop
->drs
.length ()
1780 << " is larger than --param graphite-max-arrays-per-scop="
1781 << max_arrays
<< ".\n");
1786 build_sese_loop_nests (scop
->scop_info
);
1788 find_scop_parameters (scop
);
1789 graphite_dim_t max_dim
= PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS
);
1791 if (scop_nb_params (scop
) > max_dim
)
1793 DEBUG_PRINT (dp
<< "[scop-detection-fail] too many parameters: "
1794 << scop_nb_params (scop
)
1795 << " larger than --param graphite-max-nb-scop-params="
1796 << max_dim
<< ".\n");
1802 scops
->safe_push (scop
);
1805 DEBUG_PRINT (dp
<< "number of SCoPs: " << (scops
? scops
->length () : 0););
1808 #endif /* HAVE_isl */