[llvm] [CodeGen][MISched] Handle empty sized resource usage. (PR #75951)

Michael Maitland via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 15 08:57:21 PST 2024


https://github.com/michaelmaitland updated https://github.com/llvm/llvm-project/pull/75951

>From 6b1a87b825e88212b7719e6e7c8acfd3933507a7 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Tue, 19 Dec 2023 08:48:29 -0800
Subject: [PATCH 1/3] [CodeGen][MISched] Handle empty sized resource usage.

TargetSchedule.td explicitly allows the usage of a ProcResource for zero
cycles, in order to represent that the ProcResource must be available
but is not consumed by the instruction. On the other hand,
ResourceSegments explicitly does not allow for a zero sized interval. In
order to remedy this, this patch handles the special case of when there
is a zero sized usage of a resource without creating a ResourceSegment
for it.
---
 llvm/lib/CodeGen/MachineScheduler.cpp | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp
index 886137d86f87de..757a53192f0c55 100644
--- a/llvm/lib/CodeGen/MachineScheduler.cpp
+++ b/llvm/lib/CodeGen/MachineScheduler.cpp
@@ -4266,6 +4266,12 @@ unsigned ResourceSegments::getFirstAvailableAt(
   assert(std::is_sorted(std::begin(_Intervals), std::end(_Intervals),
                         sortIntervals) &&
          "Cannot execute on an un-sorted set of intervals.");
+
+  // Zero resource usage is allowed by TargetSchedule.td but we do not construct
+  // a ResourceSegment interval for that situation.
+  if (AcquireAtCycle == Cycle)
+    return Cycle;
+
   unsigned RetCycle = CurrCycle;
   ResourceSegments::IntervalTy NewInterval =
       IntervalBuilder(RetCycle, AcquireAtCycle, Cycle);
@@ -4285,8 +4291,16 @@ unsigned ResourceSegments::getFirstAvailableAt(
 
 void ResourceSegments::add(ResourceSegments::IntervalTy A,
                            const unsigned CutOff) {
-  assert(A.first < A.second && "Cannot add empty resource usage");
-  assert(CutOff > 0 && "0-size interval history has no use.");
+  assert(A.first <= A.second && "Cannot add negative resource usage");
+
+  // Zero resource usage is allowed by TargetSchedule.td, in the case that the
+  // instruction needed the resource to be available but does not use it.
+  // However, ResourceSegment represents an interval that is closed on the left
+  // and open on the right. It is impossible to represent an empty interval when
+  // the left is closed. Do not add it to Intervals.
+  if (A.first == A.second || CutOff == 0)
+    return;
+
   assert(all_of(_Intervals,
                 [&A](const ResourceSegments::IntervalTy &Interval) -> bool {
                   return !intersects(A, Interval);

>From 4be88e7605feb45cfa598890b9dfbe29ab6280af Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Thu, 21 Dec 2023 07:55:38 -0800
Subject: [PATCH 2/3] !fixup fix failing unit tests

---
 llvm/unittests/CodeGen/SchedBoundary.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/llvm/unittests/CodeGen/SchedBoundary.cpp b/llvm/unittests/CodeGen/SchedBoundary.cpp
index 5ca6543f8e814b..624c0b616b2f46 100644
--- a/llvm/unittests/CodeGen/SchedBoundary.cpp
+++ b/llvm/unittests/CodeGen/SchedBoundary.cpp
@@ -20,9 +20,10 @@ TEST(ResourceSegmentsDeath, FullOverwrite) {
   EXPECT_DEATH(X.add({15, 18}), "A resource is being overwritten");
 }
 
-TEST(ResourceSegmentsDeath, ZeroSizeIntervalsNotAllowed) {
+TEST(ResourceSegmentsDeath, ZeroSizeCuttoffAllowed) {
   auto X = ResourceSegments({{10, 20}});
-  EXPECT_DEATH(X.add({20, 30}, 0), "0-size interval history has no use.");
+  X.add({20, 30}, 0);
+  EXPECT_EQ(X, ResourceSegments({{10, 20}}));
 }
 #endif // NDEBUG
 
@@ -85,7 +86,8 @@ TEST(ResourceSegments, add_02) {
 #ifndef NDEBUG
 TEST(ResourceSegmentsDeath, add_empty) {
   auto X = ResourceSegments({{10, 20}, {30, 40}});
-  EXPECT_DEATH(X.add({22, 22}), "Cannot add empty resource usage");
+  X.add({22, 22});
+  EXPECT_EQ(X, ResourceSegments({{10, 20}, {30, 40}}));
 }
 #endif
 

>From 999863660bb1f57832c19adf2096ceb2272438cb Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Mon, 15 Jan 2024 08:56:08 -0800
Subject: [PATCH 3/3] !fixup do not allow CutOff == 0

---
 llvm/lib/CodeGen/MachineScheduler.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp
index 757a53192f0c55..9c228b8555e99f 100644
--- a/llvm/lib/CodeGen/MachineScheduler.cpp
+++ b/llvm/lib/CodeGen/MachineScheduler.cpp
@@ -4292,13 +4292,13 @@ unsigned ResourceSegments::getFirstAvailableAt(
 void ResourceSegments::add(ResourceSegments::IntervalTy A,
                            const unsigned CutOff) {
   assert(A.first <= A.second && "Cannot add negative resource usage");
-
+  assert(CutOff > 0 && "0-size interval history has no use.");
   // Zero resource usage is allowed by TargetSchedule.td, in the case that the
   // instruction needed the resource to be available but does not use it.
   // However, ResourceSegment represents an interval that is closed on the left
   // and open on the right. It is impossible to represent an empty interval when
   // the left is closed. Do not add it to Intervals.
-  if (A.first == A.second || CutOff == 0)
+  if (A.first == A.second)
     return;
 
   assert(all_of(_Intervals,



More information about the llvm-commits mailing list