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; } \
91 /* Pretty print to FILE all the SCoPs in DOT format and mark them with
92 different colors. If there are not enough colors, paint the
93 remaining SCoPs in gray.
96 - "*" after the node number denotes the entry of a SCoP,
97 - "#" after the node number denotes the exit of a SCoP,
98 - "()" around the node number denotes the entry or the
99 exit nodes of the SCOP. These are not part of SCoP. */
102 dot_all_scops_1 (FILE *file
, vec
<scop_p
> scops
)
111 /* Disable debugging while printing graph. */
112 int tmp_dump_flags
= dump_flags
;
115 fprintf (file
, "digraph all {\n");
117 FOR_ALL_BB_FN (bb
, cfun
)
119 int part_of_scop
= false;
121 /* Use HTML for every bb label. So we are able to print bbs
122 which are part of two different SCoPs, with two different
123 background colors. */
124 fprintf (file
, "%d [label=<\n <TABLE BORDER=\"0\" CELLBORDER=\"1\" ",
126 fprintf (file
, "CELLSPACING=\"0\">\n");
128 /* Select color for SCoP. */
129 FOR_EACH_VEC_ELT (scops
, i
, scop
)
131 sese_l region
= scop
->scop_info
->region
;
132 if (bb_in_sese_p (bb
, region
) || (region
.exit
->dest
== bb
)
133 || (region
.entry
->dest
== bb
))
192 fprintf (file
, " <TR><TD WIDTH=\"50\" BGCOLOR=\"%s\">",
195 if (!bb_in_sese_p (bb
, region
))
196 fprintf (file
, " (");
198 if (bb
== region
.entry
->dest
&& bb
== region
.exit
->dest
)
199 fprintf (file
, " %d*# ", bb
->index
);
200 else if (bb
== region
.entry
->dest
)
201 fprintf (file
, " %d* ", bb
->index
);
202 else if (bb
== region
.exit
->dest
)
203 fprintf (file
, " %d# ", bb
->index
);
205 fprintf (file
, " %d ", bb
->index
);
207 fprintf (file
, "{lp_%d}", bb
->loop_father
->num
);
209 if (!bb_in_sese_p (bb
, region
))
212 fprintf (file
, "</TD></TR>\n");
219 fprintf (file
, " <TR><TD WIDTH=\"50\" BGCOLOR=\"#ffffff\">");
220 fprintf (file
, " %d {lp_%d} </TD></TR>\n", bb
->index
,
221 bb
->loop_father
->num
);
223 fprintf (file
, " </TABLE>>, shape=box, style=\"setlinewidth(0)\"]\n");
226 FOR_ALL_BB_FN (bb
, cfun
)
228 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
229 fprintf (file
, "%d -> %d;\n", bb
->index
, e
->dest
->index
);
232 fputs ("}\n\n", file
);
234 /* Enable debugging again. */
235 dump_flags
= tmp_dump_flags
;
238 /* Display all SCoPs using dotty. */
241 dot_all_scops (vec
<scop_p
> scops
)
243 /* When debugging, enable the following code. This cannot be used
244 in production compilers because it calls "system". */
247 FILE *stream
= fopen ("/tmp/allscops.dot", "w");
250 dot_all_scops_1 (stream
, scops
);
253 x
= system ("dotty /tmp/allscops.dot &");
255 dot_all_scops_1 (stderr
, scops
);
259 /* Display all SCoPs using dotty. */
262 dot_scop (scop_p scop
)
264 auto_vec
<scop_p
, 1> scops
;
267 scops
.safe_push (scop
);
269 /* When debugging, enable the following code. This cannot be used
270 in production compilers because it calls "system". */
274 FILE *stream
= fopen ("/tmp/allscops.dot", "w");
277 dot_all_scops_1 (stream
, scops
);
279 x
= system ("dotty /tmp/allscops.dot &");
282 dot_all_scops_1 (stderr
, scops
);
286 /* Return true if BB is empty, contains only DEBUG_INSNs. */
289 trivially_empty_bb_p (basic_block bb
)
291 gimple_stmt_iterator gsi
;
293 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
294 if (gimple_code (gsi_stmt (gsi
)) != GIMPLE_DEBUG
)
300 /* Returns true when P1 and P2 are close phis with the same
304 same_close_phi_node (gphi
*p1
, gphi
*p2
)
306 return operand_equal_p (gimple_phi_arg_def (p1
, 0),
307 gimple_phi_arg_def (p2
, 0), 0);
310 static void make_close_phi_nodes_unique (basic_block bb
);
312 /* Remove the close phi node at GSI and replace its rhs with the rhs
316 remove_duplicate_close_phi (gphi
*phi
, gphi_iterator
*gsi
)
320 imm_use_iterator imm_iter
;
321 tree res
= gimple_phi_result (phi
);
322 tree def
= gimple_phi_result (gsi
->phi ());
324 gcc_assert (same_close_phi_node (phi
, gsi
->phi ()));
326 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
328 FOR_EACH_IMM_USE_ON_STMT (use_p
, imm_iter
)
329 SET_USE (use_p
, res
);
331 update_stmt (use_stmt
);
333 /* It is possible that we just created a duplicate close-phi
334 for an already-processed containing loop. Check for this
335 case and clean it up. */
336 if (gimple_code (use_stmt
) == GIMPLE_PHI
337 && gimple_phi_num_args (use_stmt
) == 1)
338 make_close_phi_nodes_unique (gimple_bb (use_stmt
));
341 remove_phi_node (gsi
, true);
344 /* Removes all the close phi duplicates from BB. */
347 make_close_phi_nodes_unique (basic_block bb
)
351 for (psi
= gsi_start_phis (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
353 gphi_iterator gsi
= psi
;
354 gphi
*phi
= psi
.phi ();
356 /* At this point, PHI should be a close phi in normal form. */
357 gcc_assert (gimple_phi_num_args (phi
) == 1);
359 /* Iterate over the next phis and remove duplicates. */
361 while (!gsi_end_p (gsi
))
362 if (same_close_phi_node (phi
, gsi
.phi ()))
363 remove_duplicate_close_phi (phi
, &gsi
);
369 /* Transforms LOOP to the canonical loop closed SSA form. */
372 canonicalize_loop_closed_ssa (loop_p loop
)
374 edge e
= single_exit (loop
);
377 if (!e
|| e
->flags
& EDGE_ABNORMAL
)
382 if (single_pred_p (bb
))
384 e
= split_block_after_labels (bb
);
385 DEBUG_PRINT (dp
<< "\nSplitting bb_" << bb
->index
);
386 make_close_phi_nodes_unique (e
->src
);
391 basic_block close
= split_edge (e
);
393 e
= single_succ_edge (close
);
394 DEBUG_PRINT (dp
<< "\nSplitting edge (" << e
->src
->index
<< ","
395 << e
->dest
->index
<< ")\n");
397 for (psi
= gsi_start_phis (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
399 gphi
*phi
= psi
.phi ();
402 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
403 if (gimple_phi_arg_edge (phi
, i
) == e
)
405 tree res
, arg
= gimple_phi_arg_def (phi
, i
);
409 if (TREE_CODE (arg
) != SSA_NAME
)
412 close_phi
= create_phi_node (NULL_TREE
, close
);
413 res
= create_new_def_for (arg
, close_phi
,
414 gimple_phi_result_ptr (close_phi
));
415 add_phi_arg (close_phi
, arg
,
416 gimple_phi_arg_edge (close_phi
, 0),
418 use_p
= gimple_phi_arg_imm_use_ptr (phi
, i
);
419 replace_exp (use_p
, res
);
424 make_close_phi_nodes_unique (close
);
427 /* The code above does not properly handle changes in the post dominance
428 information (yet). */
429 recompute_all_dominators ();
432 /* Converts the current loop closed SSA form to a canonical form
433 expected by the Graphite code generation.
435 The loop closed SSA form has the following invariant: a variable
436 defined in a loop that is used outside the loop appears only in the
437 phi nodes in the destination of the loop exit. These phi nodes are
438 called close phi nodes.
440 The canonical loop closed SSA form contains the extra invariants:
442 - when the loop contains only one exit, the close phi nodes contain
443 only one argument. That implies that the basic block that contains
444 the close phi nodes has only one predecessor, that is a basic block
447 - the basic block containing the close phi nodes does not contain
450 - there exist only one phi node per definition in the loop.
454 canonicalize_loop_closed_ssa_form (void)
456 checking_verify_loop_closed_ssa (true);
459 FOR_EACH_LOOP (loop
, 0)
460 canonicalize_loop_closed_ssa (loop
);
462 rewrite_into_loop_closed_ssa (NULL
, TODO_update_ssa
);
463 update_ssa (TODO_update_ssa
);
465 checking_verify_loop_closed_ssa (true);
468 /* Can all ivs be represented by a signed integer?
469 As ISL might generate negative values in its expressions, signed loop ivs
470 are required in the backend. */
473 loop_ivs_can_be_represented (loop_p loop
)
475 unsigned type_long_long
= TYPE_PRECISION (long_long_integer_type_node
);
476 for (gphi_iterator psi
= gsi_start_phis (loop
->header
); !gsi_end_p (psi
);
479 gphi
*phi
= psi
.phi ();
480 tree res
= PHI_RESULT (phi
);
481 tree type
= TREE_TYPE (res
);
483 if (TYPE_UNSIGNED (type
) && TYPE_PRECISION (type
) >= type_long_long
)
490 /* Returns a COND_EXPR statement when BB has a single predecessor, the
491 edge between BB and its predecessor is not a loop exit edge, and
492 the last statement of the single predecessor is a COND_EXPR. */
495 single_pred_cond_non_loop_exit (basic_block bb
)
497 if (single_pred_p (bb
))
499 edge e
= single_pred_edge (bb
);
500 basic_block pred
= e
->src
;
503 if (loop_depth (pred
->loop_father
) > loop_depth (bb
->loop_father
))
506 stmt
= last_stmt (pred
);
508 if (stmt
&& gimple_code (stmt
) == GIMPLE_COND
)
509 return as_a
<gcond
*> (stmt
);
518 /* Build the maximal scop containing LOOPs and add it to SCOPS. */
523 scop_detection () : scops (vNULL
) {}
525 /* A marker for invalid sese_l. */
526 static sese_l invalid_sese
;
528 /* Return the SCOPS in this SCOP_DETECTION. */
536 /* Return an sese_l around the LOOP. */
538 sese_l
get_sese (loop_p loop
);
540 /* Return the closest dominator with a single entry edge. In case of a
541 back-loop the back-edge is not counted. */
543 static edge
get_nearest_dom_with_single_entry (basic_block dom
);
545 /* Return the closest post-dominator with a single exit edge. In case of a
546 back-loop the back-edge is not counted. */
548 static edge
get_nearest_pdom_with_single_exit (basic_block dom
);
550 /* Print S to FILE. */
552 static void print_sese (FILE *file
, sese_l s
);
554 /* Merge scops at same loop depth and returns the new sese.
555 Returns a new SESE when merge was successful, INVALID_SESE otherwise. */
557 sese_l
merge_sese (sese_l first
, sese_l second
) const;
559 /* Build scop outer->inner if possible. */
561 sese_l
build_scop_depth (sese_l s
, loop_p loop
);
563 /* If loop and loop->next are valid scops, try to merge them. */
565 sese_l
build_scop_breadth (sese_l s1
, loop_p loop
);
567 /* Return true when LOOP is a valid scop, that is a Static Control Part, a
568 region of code that can be represented in the polyhedral model. SCOP
569 defines the region we analyse. */
571 bool loop_is_valid_scop (loop_p loop
, sese_l scop
) const;
573 /* Return true when BEGIN is the preheader edge of a loop with a single exit
576 static bool region_has_one_loop (sese_l s
);
578 /* Add to SCOPS a scop starting at SCOP_BEGIN and ending at SCOP_END. */
580 void add_scop (sese_l s
);
582 /* Returns true if S1 subsumes/surrounds S2. */
583 static bool subsumes (sese_l s1
, sese_l s2
);
585 /* Remove a SCoP which is subsumed by S1. */
586 void remove_subscops (sese_l s1
);
588 /* Returns true if S1 intersects with S2. Since we already know that S1 does
589 not subsume S2 or vice-versa, we only check for entry bbs. */
591 static bool intersects (sese_l s1
, sese_l s2
);
593 /* Remove one of the scops when it intersects with any other. */
595 void remove_intersecting_scops (sese_l s1
);
597 /* Return true when the body of LOOP has statements that can be represented
600 bool loop_body_is_valid_scop (loop_p loop
, sese_l scop
) const;
602 /* Return true when BB contains a harmful operation for a scop: that
603 can be a function call with side effects, the induction variables
604 are not linear with respect to SCOP, etc. The current open
605 scop should end before this statement. */
607 bool harmful_stmt_in_bb (sese_l scop
, basic_block bb
) const;
609 /* Return true when a statement in SCOP cannot be represented by Graphite.
610 The assumptions are that L1 dominates L2, and SCOP->entry dominates L1.
611 Limit the number of bbs between adjacent loops to
612 PARAM_SCOP_MAX_NUM_BBS_BETWEEN_LOOPS. */
614 bool harmful_stmt_in_region (sese_l scop
) const;
616 /* Return true only when STMT is simple enough for being handled by Graphite.
617 This depends on SCOP, as the parameters are initialized relatively to
618 this basic block, the linear functions are initialized based on the
619 outermost loop containing STMT inside the SCOP. BB is the place where we
620 try to evaluate the STMT. */
622 bool stmt_simple_for_scop_p (sese_l scop
, gimple
*stmt
,
623 basic_block bb
) const;
625 /* Something like "n * m" is not allowed. */
627 static bool graphite_can_represent_init (tree e
);
629 /* Return true when SCEV can be represented in the polyhedral model.
631 An expression can be represented, if it can be expressed as an
632 affine expression. For loops (i, j) and parameters (m, n) all
633 affine expressions are of the form:
635 x1 * i + x2 * j + x3 * m + x4 * n + x5 * 1 where x1..x5 element of Z
637 1 i + 20 j + (-2) m + 25
639 Something like "i * n" or "n * m" is not allowed. */
641 static bool graphite_can_represent_scev (tree scev
);
643 /* Return true when EXPR can be represented in the polyhedral model.
645 This means an expression can be represented, if it is linear with respect
646 to the loops and the strides are non parametric. LOOP is the place where
647 the expr will be evaluated. SCOP defines the region we analyse. */
649 static bool graphite_can_represent_expr (sese_l scop
, loop_p loop
,
652 /* Return true if the data references of STMT can be represented by Graphite.
653 We try to analyze the data references in a loop contained in the SCOP. */
655 static bool stmt_has_simple_data_refs_p (sese_l scop
, gimple
*stmt
);
657 /* Remove the close phi node at GSI and replace its rhs with the rhs
660 static void remove_duplicate_close_phi (gphi
*phi
, gphi_iterator
*gsi
);
662 /* Returns true when Graphite can represent LOOP in SCOP.
663 FIXME: For the moment, graphite cannot be used on loops that iterate using
664 induction variables that wrap. */
666 static bool can_represent_loop_1 (loop_p loop
, sese_l scop
);
668 /* Return true when all the loops within LOOP can be represented by
671 static bool can_represent_loop (loop_p loop
, sese_l scop
);
673 /* Returns the number of pbbs that are in loops contained in SCOP. */
675 static int nb_pbbs_in_loops (scop_p scop
);
677 static bool graphite_can_represent_stmt (sese_l
, gimple
*, basic_block
);
683 sese_l
scop_detection::invalid_sese (NULL
, NULL
);
685 /* Return an sese_l around the LOOP. */
688 scop_detection::get_sese (loop_p loop
)
693 if (!loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS
))
695 edge scop_end
= single_exit (loop
);
698 edge scop_begin
= loop_preheader_edge (loop
);
699 sese_l
s (scop_begin
, scop_end
);
703 /* Return the closest dominator with a single entry edge. */
706 scop_detection::get_nearest_dom_with_single_entry (basic_block dom
)
710 /* If e1->src dominates e2->src then e1->src will also dominate dom. */
711 if (dom
->preds
->length () == 2)
713 edge e1
= (*dom
->preds
)[0];
714 edge e2
= (*dom
->preds
)[1];
715 if (dominated_by_p (CDI_DOMINATORS
, e2
->src
, e1
->src
))
717 if (dominated_by_p (CDI_DOMINATORS
, e1
->src
, e2
->src
))
721 while (dom
->preds
->length () != 1)
723 if (dom
->preds
->length () < 1)
725 dom
= get_immediate_dominator (CDI_DOMINATORS
, dom
);
729 return (*dom
->preds
)[0];
732 /* Return the closest post-dominator with a single exit edge. In case of a
733 back-loop the back-edge is not counted. */
736 scop_detection::get_nearest_pdom_with_single_exit (basic_block dom
)
740 if (dom
->succs
->length () == 2)
742 edge e1
= (*dom
->succs
)[0];
743 edge e2
= (*dom
->succs
)[1];
744 if (dominated_by_p (CDI_POST_DOMINATORS
, e2
->dest
, e1
->dest
))
746 if (dominated_by_p (CDI_POST_DOMINATORS
, e1
->dest
, e2
->dest
))
750 while (dom
->succs
->length () != 1)
752 if (dom
->succs
->length () < 1)
754 dom
= get_immediate_dominator (CDI_POST_DOMINATORS
, dom
);
758 return (*dom
->succs
)[0];
761 /* Print S to FILE. */
764 scop_detection::print_sese (FILE *file
, sese_l s
)
766 fprintf (file
, "(entry_edge (bb_%d, bb_%d), exit_edge (bb_%d, bb_%d))\n",
767 s
.entry
->src
->index
, s
.entry
->dest
->index
,
768 s
.exit
->src
->index
, s
.exit
->dest
->index
);
771 /* Merge scops at same loop depth and returns the new sese.
772 Returns a new SESE when merge was successful, INVALID_SESE otherwise. */
775 scop_detection::merge_sese (sese_l first
, sese_l second
) const
777 /* In the trivial case first/second may be NULL. */
783 DEBUG_PRINT (dp
<< "[try-merging-sese] s1: "; print_sese (dump_file
, first
);
784 dp
<< "[try-merging-sese] s2: ";
785 print_sese (dump_file
, second
));
787 /* Assumption: Both the sese's should be at the same loop depth or one scop
788 should subsume the other like in case of nested loops. */
790 /* Find the common dominators for entry,
791 and common post-dominators for the exit. */
792 basic_block dom
= nearest_common_dominator (CDI_DOMINATORS
,
793 get_entry_bb (first
),
794 get_entry_bb (second
));
796 edge entry
= get_nearest_dom_with_single_entry (dom
);
800 basic_block pdom
= nearest_common_dominator (CDI_POST_DOMINATORS
,
802 get_exit_bb (second
));
803 pdom
= nearest_common_dominator (CDI_POST_DOMINATORS
, dom
, pdom
);
805 edge exit
= get_nearest_pdom_with_single_exit (pdom
);
809 sese_l
combined (entry
, exit
);
811 /* FIXME: We could iterate to find the dom which dominates pdom, and pdom
812 which post-dominates dom, until it stabilizes. Also, ENTRY->SRC and
813 EXIT->DEST should be in the same loop nest. */
814 if (!dominated_by_p (CDI_DOMINATORS
, pdom
, dom
)
815 || loop_depth (entry
->src
->loop_father
)
816 != loop_depth (exit
->dest
->loop_father
))
819 /* For now we just want to bail out when exit does not post-dominate entry.
820 TODO: We might just add a basic_block at the exit to make exit
821 post-dominate entry (the entire region). */
822 if (!dominated_by_p (CDI_POST_DOMINATORS
, get_entry_bb (combined
),
823 get_exit_bb (combined
))
824 || !dominated_by_p (CDI_DOMINATORS
, get_exit_bb (combined
),
825 get_entry_bb (combined
)))
827 DEBUG_PRINT (dp
<< "[scop-detection-fail] cannot merge seses.\n");
831 /* FIXME: We should remove this piece of code once
832 canonicalize_loop_closed_ssa has been removed, because that function
833 adds a BB with single exit. */
834 if (!trivially_empty_bb_p (get_exit_bb (combined
)))
836 /* Find the first empty succ (with single exit) of combined.exit. */
837 basic_block imm_succ
= combined
.exit
->dest
;
838 if (single_succ_p (imm_succ
) && trivially_empty_bb_p (imm_succ
))
839 combined
.exit
= single_succ_edge (imm_succ
);
842 DEBUG_PRINT (dp
<< "\n[scop-detection-fail] Discarding SCoP because "
843 << "no single exit (empty succ) for sese exit";
844 print_sese (dump_file
, combined
));
849 /* Analyze all the BBs in new sese. */
850 if (harmful_stmt_in_region (combined
))
853 DEBUG_PRINT (dp
<< "[merged-sese] s1: "; print_sese (dump_file
, combined
));
858 /* Build scop outer->inner if possible. */
861 scop_detection::build_scop_depth (sese_l s
, loop_p loop
)
866 DEBUG_PRINT (dp
<< "\n[Depth loop_" << loop
->num
<< "]");
867 s
= build_scop_depth (s
, loop
->inner
);
869 sese_l s2
= merge_sese (s
, get_sese (loop
));
872 /* s might be a valid scop, so return it and start analyzing from the
874 build_scop_depth (invalid_sese
, loop
->next
);
878 if (!loop_is_valid_scop (loop
, s2
))
879 return build_scop_depth (invalid_sese
, loop
->next
);
881 return build_scop_breadth (s2
, loop
);
884 /* If loop and loop->next are valid scops, try to merge them. */
887 scop_detection::build_scop_breadth (sese_l s1
, loop_p loop
)
891 DEBUG_PRINT (dp
<< "\n[Breadth loop_" << loop
->num
<< "]");
895 sese_l s2
= build_scop_depth (invalid_sese
, l
->next
);
903 sese_l combined
= merge_sese (s1
, s2
);
915 /* Returns true when Graphite can represent LOOP in SCOP.
916 FIXME: For the moment, graphite cannot be used on loops that iterate using
917 induction variables that wrap. */
920 scop_detection::can_represent_loop_1 (loop_p loop
, sese_l scop
)
923 struct tree_niter_desc niter_desc
;
925 return single_exit (loop
)
926 && number_of_iterations_exit (loop
, single_exit (loop
), &niter_desc
, false)
927 && niter_desc
.control
.no_overflow
928 && (niter
= number_of_latch_executions (loop
))
929 && !chrec_contains_undetermined (niter
)
930 && graphite_can_represent_expr (scop
, loop
, niter
);
933 /* Return true when all the loops within LOOP can be represented by
937 scop_detection::can_represent_loop (loop_p loop
, sese_l scop
)
939 if (!can_represent_loop_1 (loop
, scop
))
941 if (loop
->inner
&& !can_represent_loop (loop
->inner
, scop
))
943 if (loop
->next
&& !can_represent_loop (loop
->next
, scop
))
949 /* Return true when LOOP is a valid scop, that is a Static Control Part, a
950 region of code that can be represented in the polyhedral model. SCOP
951 defines the region we analyse. */
954 scop_detection::loop_is_valid_scop (loop_p loop
, sese_l scop
) const
959 if (!can_represent_loop (loop
, scop
))
961 DEBUG_PRINT (dp
<< "[scop-detection-fail] cannot represent loop_"
962 << loop
->num
<< "\n");
966 if (loop_body_is_valid_scop (loop
, scop
))
968 DEBUG_PRINT (dp
<< "[valid-scop] loop_" << loop
->num
969 << "is a valid scop.\n");
975 /* Return true when BEGIN is the preheader edge of a loop with a single exit
979 scop_detection::region_has_one_loop (sese_l s
)
981 edge begin
= s
.entry
;
983 /* Check for a single perfectly nested loop. */
984 if (begin
->dest
->loop_father
->inner
)
987 /* Otherwise, check whether we have adjacent loops. */
988 return begin
->dest
->loop_father
== end
->src
->loop_father
;
991 /* Add to SCOPS a scop starting at SCOP_BEGIN and ending at SCOP_END. */
994 scop_detection::add_scop (sese_l s
)
998 /* Do not add scops with only one loop. */
999 if (region_has_one_loop (s
))
1001 DEBUG_PRINT (dp
<< "\n[scop-detection-fail] Discarding one loop SCoP";
1002 print_sese (dump_file
, s
));
1006 if (get_exit_bb (s
) == EXIT_BLOCK_PTR_FOR_FN (cfun
))
1008 DEBUG_PRINT (dp
<< "\n[scop-detection-fail] "
1009 << "Discarding SCoP exiting to return";
1010 print_sese (dump_file
, s
));
1014 /* Remove all the scops which are subsumed by s. */
1015 remove_subscops (s
);
1017 /* Replace this with split-intersecting scops. */
1018 remove_intersecting_scops (s
);
1020 scops
.safe_push (s
);
1021 DEBUG_PRINT (dp
<< "\nAdding SCoP "; print_sese (dump_file
, s
));
1024 /* Return true when a statement in SCOP cannot be represented by Graphite.
1025 The assumptions are that L1 dominates L2, and SCOP->entry dominates L1.
1026 Limit the number of bbs between adjacent loops to
1027 PARAM_SCOP_MAX_NUM_BBS_BETWEEN_LOOPS. */
1030 scop_detection::harmful_stmt_in_region (sese_l scop
) const
1032 basic_block exit_bb
= get_exit_bb (scop
);
1033 basic_block entry_bb
= get_entry_bb (scop
);
1035 DEBUG_PRINT (dp
<< "\n[checking-harmful-bbs] ";
1036 print_sese (dump_file
, scop
));
1037 gcc_assert (dominated_by_p (CDI_DOMINATORS
, exit_bb
, entry_bb
));
1039 int depth
= bb_dom_dfs_in (CDI_DOMINATORS
, exit_bb
)
1040 - bb_dom_dfs_in (CDI_DOMINATORS
, entry_bb
);
1042 gcc_assert (depth
> 0);
1044 vec
<basic_block
> dom
1045 = get_dominated_to_depth (CDI_DOMINATORS
, entry_bb
, depth
);
1048 FOR_EACH_VEC_ELT (dom
, i
, bb
)
1050 DEBUG_PRINT (dp
<< "\nVisiting bb_" << bb
->index
);
1052 /* We don't want to analyze any bb outside sese. */
1053 if (!dominated_by_p (CDI_POST_DOMINATORS
, bb
, exit_bb
))
1056 if (harmful_stmt_in_bb (scop
, bb
))
1063 /* Returns true if S1 subsumes/surrounds S2. */
1065 scop_detection::subsumes (sese_l s1
, sese_l s2
)
1067 if (dominated_by_p (CDI_DOMINATORS
, get_entry_bb (s2
),
1069 && dominated_by_p (CDI_POST_DOMINATORS
, s2
.exit
->dest
,
1075 /* Remove a SCoP which is subsumed by S1. */
1077 scop_detection::remove_subscops (sese_l s1
)
1081 FOR_EACH_VEC_ELT_REVERSE (scops
, j
, s2
)
1083 if (subsumes (s1
, *s2
))
1085 DEBUG_PRINT (dp
<< "\nRemoving sub-SCoP";
1086 print_sese (dump_file
, *s2
));
1087 scops
.unordered_remove (j
);
1092 /* Returns true if S1 intersects with S2. Since we already know that S1 does
1093 not subsume S2 or vice-versa, we only check for entry bbs. */
1096 scop_detection::intersects (sese_l s1
, sese_l s2
)
1098 if (dominated_by_p (CDI_DOMINATORS
, get_entry_bb (s2
),
1100 && !dominated_by_p (CDI_DOMINATORS
, get_entry_bb (s2
),
1103 if ((s1
.exit
== s2
.entry
) || (s2
.exit
== s1
.entry
))
1109 /* Remove one of the scops when it intersects with any other. */
1112 scop_detection::remove_intersecting_scops (sese_l s1
)
1116 FOR_EACH_VEC_ELT_REVERSE (scops
, j
, s2
)
1118 if (intersects (s1
, *s2
))
1120 DEBUG_PRINT (dp
<< "\nRemoving intersecting SCoP";
1121 print_sese (dump_file
, *s2
); dp
<< "Intersects with:";
1122 print_sese (dump_file
, s1
));
1123 scops
.unordered_remove (j
);
1128 /* Something like "n * m" is not allowed. */
1131 scop_detection::graphite_can_represent_init (tree e
)
1133 switch (TREE_CODE (e
))
1135 case POLYNOMIAL_CHREC
:
1136 return graphite_can_represent_init (CHREC_LEFT (e
))
1137 && graphite_can_represent_init (CHREC_RIGHT (e
));
1140 if (chrec_contains_symbols (TREE_OPERAND (e
, 0)))
1141 return graphite_can_represent_init (TREE_OPERAND (e
, 0))
1142 && tree_fits_shwi_p (TREE_OPERAND (e
, 1));
1144 return graphite_can_represent_init (TREE_OPERAND (e
, 1))
1145 && tree_fits_shwi_p (TREE_OPERAND (e
, 0));
1148 case POINTER_PLUS_EXPR
:
1150 return graphite_can_represent_init (TREE_OPERAND (e
, 0))
1151 && graphite_can_represent_init (TREE_OPERAND (e
, 1));
1156 case NON_LVALUE_EXPR
:
1157 return graphite_can_represent_init (TREE_OPERAND (e
, 0));
1166 /* Return true when SCEV can be represented in the polyhedral model.
1168 An expression can be represented, if it can be expressed as an
1169 affine expression. For loops (i, j) and parameters (m, n) all
1170 affine expressions are of the form:
1172 x1 * i + x2 * j + x3 * m + x4 * n + x5 * 1 where x1..x5 element of Z
1174 1 i + 20 j + (-2) m + 25
1176 Something like "i * n" or "n * m" is not allowed. */
1179 scop_detection::graphite_can_represent_scev (tree scev
)
1181 if (chrec_contains_undetermined (scev
))
1184 /* We disable the handling of pointer types, because it’s currently not
1185 supported by Graphite with the ISL AST generator. SSA_NAME nodes are
1186 the only nodes, which are disabled in case they are pointers to object
1187 types, but this can be changed. */
1189 if (POINTER_TYPE_P (TREE_TYPE (scev
)) && TREE_CODE (scev
) == SSA_NAME
)
1192 switch (TREE_CODE (scev
))
1197 case NON_LVALUE_EXPR
:
1198 return graphite_can_represent_scev (TREE_OPERAND (scev
, 0));
1201 case POINTER_PLUS_EXPR
:
1203 return graphite_can_represent_scev (TREE_OPERAND (scev
, 0))
1204 && graphite_can_represent_scev (TREE_OPERAND (scev
, 1));
1207 return !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev
, 0)))
1208 && !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev
, 1)))
1209 && !(chrec_contains_symbols (TREE_OPERAND (scev
, 0))
1210 && chrec_contains_symbols (TREE_OPERAND (scev
, 1)))
1211 && graphite_can_represent_init (scev
)
1212 && graphite_can_represent_scev (TREE_OPERAND (scev
, 0))
1213 && graphite_can_represent_scev (TREE_OPERAND (scev
, 1));
1215 case POLYNOMIAL_CHREC
:
1216 /* Check for constant strides. With a non constant stride of
1217 'n' we would have a value of 'iv * n'. Also check that the
1218 initial value can represented: for example 'n * m' cannot be
1220 if (!evolution_function_right_is_integer_cst (scev
)
1221 || !graphite_can_represent_init (scev
))
1223 return graphite_can_represent_scev (CHREC_LEFT (scev
));
1229 /* Only affine functions can be represented. */
1230 if (tree_contains_chrecs (scev
, NULL
) || !scev_is_linear_expression (scev
))
1236 /* Return true when EXPR can be represented in the polyhedral model.
1238 This means an expression can be represented, if it is linear with respect to
1239 the loops and the strides are non parametric. LOOP is the place where the
1240 expr will be evaluated. SCOP defines the region we analyse. */
1243 scop_detection::graphite_can_represent_expr (sese_l scop
, loop_p loop
,
1246 tree scev
= scalar_evolution_in_region (scop
, loop
, expr
);
1247 return graphite_can_represent_scev (scev
);
1250 /* Return true if the data references of STMT can be represented by Graphite.
1251 We try to analyze the data references in a loop contained in the SCOP. */
1254 scop_detection::stmt_has_simple_data_refs_p (sese_l scop
, gimple
*stmt
)
1256 loop_p nest
= outermost_loop_in_sese (scop
, gimple_bb (stmt
));
1257 loop_p loop
= loop_containing_stmt (stmt
);
1258 vec
<data_reference_p
> drs
= vNULL
;
1260 graphite_find_data_references_in_stmt (nest
, loop
, stmt
, &drs
);
1263 data_reference_p dr
;
1264 FOR_EACH_VEC_ELT (drs
, j
, dr
)
1266 int nb_subscripts
= DR_NUM_DIMENSIONS (dr
);
1268 if (nb_subscripts
< 1)
1270 free_data_refs (drs
);
1274 tree ref
= DR_REF (dr
);
1276 for (int i
= nb_subscripts
- 1; i
>= 0; i
--)
1278 if (!graphite_can_represent_scev (DR_ACCESS_FN (dr
, i
))
1279 || (TREE_CODE (ref
) != ARRAY_REF
&& TREE_CODE (ref
) != MEM_REF
1280 && TREE_CODE (ref
) != COMPONENT_REF
))
1282 free_data_refs (drs
);
1286 ref
= TREE_OPERAND (ref
, 0);
1290 free_data_refs (drs
);
1294 /* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects.
1295 Calls have side-effects, except those to const or pure
1299 stmt_has_side_effects (gimple
*stmt
)
1301 if (gimple_has_volatile_ops (stmt
)
1302 || (gimple_code (stmt
) == GIMPLE_CALL
1303 && !(gimple_call_flags (stmt
) & (ECF_CONST
| ECF_PURE
)))
1304 || (gimple_code (stmt
) == GIMPLE_ASM
))
1306 DEBUG_PRINT (dp
<< "[scop-detection-fail] "
1307 << "Statement has side-effects:\n";
1308 print_gimple_stmt (dump_file
, stmt
, 0, TDF_VOPS
| TDF_MEMSYMS
));
1314 /* Returns true if STMT can be represented in polyhedral model. LABEL,
1315 simple COND stmts, pure calls, and assignments can be repesented. */
1318 scop_detection::graphite_can_represent_stmt (sese_l scop
, gimple
*stmt
,
1321 loop_p loop
= bb
->loop_father
;
1322 switch (gimple_code (stmt
))
1329 /* We can handle all binary comparisons. Inequalities are
1330 also supported as they can be represented with union of
1332 enum tree_code code
= gimple_cond_code (stmt
);
1333 if (!(code
== LT_EXPR
1338 || code
== NE_EXPR
))
1340 DEBUG_PRINT (dp
<< "[scop-detection-fail] "
1341 << "Graphite cannot handle cond stmt:\n";
1342 print_gimple_stmt (dump_file
, stmt
, 0,
1343 TDF_VOPS
| TDF_MEMSYMS
));
1347 for (unsigned i
= 0; i
< 2; ++i
)
1349 tree op
= gimple_op (stmt
, i
);
1350 if (!graphite_can_represent_expr (scop
, loop
, op
)
1351 /* We can only constrain on integer type. */
1352 || (TREE_CODE (TREE_TYPE (op
)) != INTEGER_TYPE
))
1354 DEBUG_PRINT (dp
<< "[scop-detection-fail] "
1355 << "Graphite cannot represent stmt:\n";
1356 print_gimple_stmt (dump_file
, stmt
, 0,
1357 TDF_VOPS
| TDF_MEMSYMS
));
1370 /* These nodes cut a new scope. */
1372 dp
<< "[scop-detection-fail] "
1373 << "Gimple stmt not handled in Graphite:\n";
1374 print_gimple_stmt (dump_file
, stmt
, 0, TDF_VOPS
| TDF_MEMSYMS
));
1379 /* Return true only when STMT is simple enough for being handled by Graphite.
1380 This depends on SCOP, as the parameters are initialized relatively to
1381 this basic block, the linear functions are initialized based on the outermost
1382 loop containing STMT inside the SCOP. BB is the place where we try to
1383 evaluate the STMT. */
1386 scop_detection::stmt_simple_for_scop_p (sese_l scop
, gimple
*stmt
,
1387 basic_block bb
) const
1391 if (is_gimple_debug (stmt
))
1394 if (stmt_has_side_effects (stmt
))
1397 if (!stmt_has_simple_data_refs_p (scop
, stmt
))
1399 DEBUG_PRINT (dp
<< "[scop-detection-fail] "
1400 << "Graphite cannot handle data-refs in stmt:\n";
1401 print_gimple_stmt (dump_file
, stmt
, 0, TDF_VOPS
|TDF_MEMSYMS
););
1405 return graphite_can_represent_stmt (scop
, stmt
, bb
);
1408 /* Return true when BB contains a harmful operation for a scop: that
1409 can be a function call with side effects, the induction variables
1410 are not linear with respect to SCOP, etc. The current open
1411 scop should end before this statement. */
1414 scop_detection::harmful_stmt_in_bb (sese_l scop
, basic_block bb
) const
1416 gimple_stmt_iterator gsi
;
1418 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1419 if (!stmt_simple_for_scop_p (scop
, gsi_stmt (gsi
), bb
))
1425 /* Return true when the body of LOOP has statements that can be represented as a
1429 scop_detection::loop_body_is_valid_scop (loop_p loop
, sese_l scop
) const
1431 if (!loop_ivs_can_be_represented (loop
))
1433 DEBUG_PRINT (dp
<< "[scop-detection-fail] loop_" << loop
->num
1434 << "IV cannot be represented.\n");
1438 if (!loop_nest_has_data_refs (loop
))
1440 DEBUG_PRINT (dp
<< "[scop-detection-fail] loop_" << loop
->num
1441 << "does not have any data reference.\n");
1445 basic_block
*bbs
= get_loop_body (loop
);
1446 for (unsigned i
= 0; i
< loop
->num_nodes
; i
++)
1448 basic_block bb
= bbs
[i
];
1450 if (harmful_stmt_in_bb (scop
, bb
))
1460 if (!loop_body_is_valid_scop (loop
, scop
))
1469 /* Returns the number of pbbs that are in loops contained in SCOP. */
1472 scop_detection::nb_pbbs_in_loops (scop_p scop
)
1478 FOR_EACH_VEC_ELT (scop
->pbbs
, i
, pbb
)
1479 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb
)), scop
->scop_info
->region
))
1485 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
1486 Otherwise returns -1. */
1489 parameter_index_in_region_1 (tree name
, sese_info_p region
)
1494 gcc_assert (TREE_CODE (name
) == SSA_NAME
);
1496 FOR_EACH_VEC_ELT (SESE_PARAMS (region
), i
, p
)
1503 /* When the parameter NAME is in REGION, returns its index in
1504 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
1505 and returns the index of NAME. */
1508 parameter_index_in_region (tree name
, sese_info_p region
)
1512 gcc_assert (TREE_CODE (name
) == SSA_NAME
);
1514 /* Cannot constrain on anything else than INTEGER_TYPE parameters. */
1515 if (TREE_CODE (TREE_TYPE (name
)) != INTEGER_TYPE
)
1518 if (!invariant_in_sese_p_rec (name
, region
->region
, NULL
))
1521 i
= parameter_index_in_region_1 (name
, region
);
1525 i
= SESE_PARAMS (region
).length ();
1526 SESE_PARAMS (region
).safe_push (name
);
1530 /* In the context of sese S, scan the expression E and translate it to
1531 a linear expression C. When parsing a symbolic multiplication, K
1532 represents the constant multiplier of an expression containing
1536 scan_tree_for_params (sese_info_p s
, tree e
)
1538 if (e
== chrec_dont_know
)
1541 switch (TREE_CODE (e
))
1543 case POLYNOMIAL_CHREC
:
1544 scan_tree_for_params (s
, CHREC_LEFT (e
));
1548 if (chrec_contains_symbols (TREE_OPERAND (e
, 0)))
1549 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
1551 scan_tree_for_params (s
, TREE_OPERAND (e
, 1));
1555 case POINTER_PLUS_EXPR
:
1557 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
1558 scan_tree_for_params (s
, TREE_OPERAND (e
, 1));
1564 case NON_LVALUE_EXPR
:
1565 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
1569 parameter_index_in_region (e
, s
);
1585 /* Find parameters with respect to REGION in BB. We are looking in memory
1586 access functions, conditions and loop bounds. */
1589 find_params_in_bb (sese_info_p region
, gimple_poly_bb_p gbb
)
1591 /* Find parameters in the access functions of data references. */
1593 data_reference_p dr
;
1594 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb
), i
, dr
)
1595 for (unsigned j
= 0; j
< DR_NUM_DIMENSIONS (dr
); j
++)
1596 scan_tree_for_params (region
, DR_ACCESS_FN (dr
, j
));
1598 /* Find parameters in conditional statements. */
1600 loop_p loop
= GBB_BB (gbb
)->loop_father
;
1601 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb
), i
, stmt
)
1603 tree lhs
= scalar_evolution_in_region (region
->region
, loop
,
1604 gimple_cond_lhs (stmt
));
1605 tree rhs
= scalar_evolution_in_region (region
->region
, loop
,
1606 gimple_cond_rhs (stmt
));
1608 scan_tree_for_params (region
, lhs
);
1609 scan_tree_for_params (region
, rhs
);
1613 /* Record the parameters used in the SCOP. A variable is a parameter
1614 in a scop if it does not vary during the execution of that scop. */
1617 find_scop_parameters (scop_p scop
)
1620 sese_info_p region
= scop
->scop_info
;
1623 /* Find the parameters used in the loop bounds. */
1624 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region
), i
, loop
)
1626 tree nb_iters
= number_of_latch_executions (loop
);
1628 if (!chrec_contains_symbols (nb_iters
))
1631 nb_iters
= scalar_evolution_in_region (region
->region
, loop
, nb_iters
);
1632 scan_tree_for_params (region
, nb_iters
);
1635 /* Find the parameters used in data accesses. */
1637 FOR_EACH_VEC_ELT (scop
->pbbs
, i
, pbb
)
1638 find_params_in_bb (region
, PBB_BLACK_BOX (pbb
));
1640 int nbp
= sese_nb_params (region
);
1641 scop_set_nb_params (scop
, nbp
);
1644 /* Generates a polyhedral black box only if the bb contains interesting
1647 static gimple_poly_bb_p
1648 try_generate_gimple_bb (scop_p scop
, basic_block bb
)
1650 vec
<data_reference_p
> drs
;
1652 sese_l region
= scop
->scop_info
->region
;
1653 loop_p nest
= outermost_loop_in_sese (region
, bb
);
1655 loop_p loop
= bb
->loop_father
;
1656 if (!loop_in_sese_p (loop
, region
))
1659 gimple_stmt_iterator gsi
;
1660 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1662 gimple
*stmt
= gsi_stmt (gsi
);
1663 if (is_gimple_debug (stmt
))
1666 graphite_find_data_references_in_stmt (nest
, loop
, stmt
, &drs
);
1669 return new_gimple_poly_bb (bb
, drs
);
1672 /* Gather BBs and conditions for a SCOP. */
1673 class gather_bbs
: public dom_walker
1676 gather_bbs (cdi_direction
, scop_p
);
1678 virtual void before_dom_children (basic_block
);
1679 virtual void after_dom_children (basic_block
);
1682 auto_vec
<gimple
*, 3> conditions
, cases
;
1686 gather_bbs::gather_bbs (cdi_direction direction
, scop_p scop
)
1687 : dom_walker (direction
), scop (scop
)
1691 /* Call-back for dom_walk executed before visiting the dominated
1695 gather_bbs::before_dom_children (basic_block bb
)
1697 if (!bb_in_sese_p (bb
, scop
->scop_info
->region
))
1700 gcond
*stmt
= single_pred_cond_non_loop_exit (bb
);
1704 edge e
= single_pred_edge (bb
);
1706 conditions
.safe_push (stmt
);
1708 if (e
->flags
& EDGE_TRUE_VALUE
)
1709 cases
.safe_push (stmt
);
1711 cases
.safe_push (NULL
);
1714 scop
->scop_info
->bbs
.safe_push (bb
);
1716 gimple_poly_bb_p gbb
= try_generate_gimple_bb (scop
, bb
);
1717 GBB_CONDITIONS (gbb
) = conditions
.copy ();
1718 GBB_CONDITION_CASES (gbb
) = cases
.copy ();
1720 poly_bb_p pbb
= new_poly_bb (scop
, gbb
);
1721 scop
->pbbs
.safe_push (pbb
);
1724 /* Call-back for dom_walk executed after visiting the dominated
1728 gather_bbs::after_dom_children (basic_block bb
)
1730 if (!bb_in_sese_p (bb
, scop
->scop_info
->region
))
1733 if (single_pred_cond_non_loop_exit (bb
))
1740 /* Find Static Control Parts (SCoP) in the current function and pushes
1744 build_scops (vec
<scop_p
> *scops
)
1747 dp
.set_dump_file (dump_file
);
1749 canonicalize_loop_closed_ssa_form ();
1752 sb
.build_scop_depth (scop_detection::invalid_sese
, current_loops
->tree_root
);
1754 /* Now create scops from the lightweight SESEs. */
1755 vec
<sese_l
> scops_l
= sb
.get_scops ();
1758 FOR_EACH_VEC_ELT (scops_l
, i
, s
)
1760 scop_p scop
= new_scop (s
->entry
, s
->exit
);
1762 /* Record all basic blocks and their conditions in REGION. */
1763 gather_bbs (CDI_DOMINATORS
, scop
).walk (cfun
->cfg
->x_entry_block_ptr
);
1765 /* Do not optimize a scop containing only PBBs that do not belong
1767 if (sb
.nb_pbbs_in_loops (scop
) == 0)
1769 DEBUG_PRINT (dp
<< "[scop-detection-fail] no data references.\n");
1774 unsigned max_arrays
= PARAM_VALUE (PARAM_GRAPHITE_MAX_ARRAYS_PER_SCOP
);
1775 if (scop
->drs
.length () >= max_arrays
)
1777 DEBUG_PRINT (dp
<< "[scop-detection-fail] too many data references: "
1778 << scop
->drs
.length ()
1779 << " is larger than --param graphite-max-arrays-per-scop="
1780 << max_arrays
<< ".\n");
1785 build_sese_loop_nests (scop
->scop_info
);
1787 find_scop_parameters (scop
);
1788 graphite_dim_t max_dim
= PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS
);
1790 if (scop_nb_params (scop
) > max_dim
)
1792 DEBUG_PRINT (dp
<< "[scop-detection-fail] too many parameters: "
1793 << scop_nb_params (scop
)
1794 << " larger than --param graphite-max-nb-scop-params="
1795 << max_dim
<< ".\n");
1801 scops
->safe_push (scop
);
1804 DEBUG_PRINT (dp
<< "number of SCoPs: " << (scops
? scops
->length () : 0););
1807 #endif /* HAVE_isl */