[ScheduleOptimizer] Allow tiling after fusion
In ScheduleOptimizer::isTileableBand(), allow the case in which
the band node's child is an isl_schedule_sequence_node and its
grandchildren isl_schedule_leaf_nodes. This case can arise when
two or more statements are fused by the isl scheduler.
The tile_after_fusion.ll test has two statements in separate
loop nests and checks whether they are tiled after being fused
when polly-opt-fusion equals "max".
Reviewers: grosser
Subscribers: gareevroman, pollydev
Tags: #polly
Contributed-by: Theodoros Theodoridis <theodort@student.ethz.ch>
Differential Revision: https://reviews.llvm.org/D30815
llvm-svn: 297587
diff --git a/polly/lib/Transform/ScheduleOptimizer.cpp b/polly/lib/Transform/ScheduleOptimizer.cpp
index 546ad40..edb01a4 100644
--- a/polly/lib/Transform/ScheduleOptimizer.cpp
+++ b/polly/lib/Transform/ScheduleOptimizer.cpp
@@ -433,6 +433,34 @@
return Node;
}
+namespace {
+bool isSimpleInnermostBand(const isl::schedule_node &Node) {
+ assert(isl_schedule_node_get_type(Node.keep()) == isl_schedule_node_band);
+ assert(isl_schedule_node_n_children(Node.keep()) == 1);
+
+ auto ChildType = isl_schedule_node_get_type(Node.child(0).keep());
+
+ if (ChildType == isl_schedule_node_leaf)
+ return true;
+
+ if (ChildType != isl_schedule_node_sequence)
+ return false;
+
+ auto Sequence = Node.child(0);
+
+ for (int c = 0, nc = isl_schedule_node_n_children(Sequence.keep()); c < nc;
+ ++c) {
+ auto Child = Sequence.child(c);
+ if (isl_schedule_node_get_type(Child.keep()) != isl_schedule_node_filter)
+ return false;
+ if (isl_schedule_node_get_type(Child.child(0).keep()) !=
+ isl_schedule_node_leaf)
+ return false;
+ }
+ return true;
+}
+} // namespace
+
bool ScheduleTreeOptimizer::isTileableBandNode(
__isl_keep isl_schedule_node *Node) {
if (isl_schedule_node_get_type(Node) != isl_schedule_node_band)
@@ -451,14 +479,8 @@
if (Dims <= 1)
return false;
- auto Child = isl_schedule_node_get_child(Node, 0);
- auto Type = isl_schedule_node_get_type(Child);
- isl_schedule_node_free(Child);
-
- if (Type != isl_schedule_node_leaf)
- return false;
-
- return true;
+ auto ManagedNode = isl::manage(isl_schedule_node_copy(Node));
+ return isSimpleInnermostBand(ManagedNode);
}
__isl_give isl_schedule_node *