[llvm] f1d1ca3 - Revert "[MISched] Introduce and use ResourceSegments."
Francesco Petrogalli via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 9 04:23:49 PDT 2023
Author: Francesco Petrogalli
Date: 2023-06-09T13:23:37+02:00
New Revision: f1d1ca3d7434d2f50ff64cefc6155741a6e0bcd0
URL: https://github.com/llvm/llvm-project/commit/f1d1ca3d7434d2f50ff64cefc6155741a6e0bcd0
DIFF: https://github.com/llvm/llvm-project/commit/f1d1ca3d7434d2f50ff64cefc6155741a6e0bcd0.diff
LOG: Revert "[MISched] Introduce and use ResourceSegments."
Reverted because it produces the following builbot failure at https://lab.llvm.org/buildbot#builders/9/builds/27319:
/b/ml-opt-rel-x86-64-b1/llvm-project/llvm/unittests/CodeGen/SchedBoundary.cpp: In member function ‘virtual void ResourceSegments_getFirstAvailableAtFromBottom_empty_Test::TestBody()’:
/b/ml-opt-rel-x86-64-b1/llvm-project/llvm/unittests/CodeGen/SchedBoundary.cpp:395:31: error: call of overloaded ‘ResourceSegments(<brace-enclosed initializer list>)’ is ambiguous
395 | auto X = ResourceSegments({});
| ^
This reverts commit dc312f0331309692e8d6e06e93b3492b6a40989f.
Added:
Modified:
llvm/include/llvm/CodeGen/MachineScheduler.h
llvm/include/llvm/CodeGen/TargetSchedule.h
llvm/include/llvm/MC/MCSchedule.h
llvm/include/llvm/Target/TargetSchedule.td
llvm/lib/CodeGen/MachineScheduler.cpp
llvm/lib/MC/MCSchedule.cpp
llvm/unittests/CodeGen/CMakeLists.txt
llvm/utils/TableGen/SubtargetEmitter.cpp
Removed:
llvm/unittests/CodeGen/SchedBoundary.cpp
################################################################################
diff --git a/llvm/include/llvm/CodeGen/MachineScheduler.h b/llvm/include/llvm/CodeGen/MachineScheduler.h
index bd3885d0463ef..af7c57c950008 100644
--- a/llvm/include/llvm/CodeGen/MachineScheduler.h
+++ b/llvm/include/llvm/CodeGen/MachineScheduler.h
@@ -92,7 +92,6 @@
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <cassert>
-#include <llvm/Support/raw_ostream.h>
#include <memory>
#include <string>
#include <vector>
@@ -611,222 +610,6 @@ struct SchedRemainder {
void init(ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel);
};
-/// ResourceSegments are a collection of intervals closed on the
-/// left and opened on the right:
-///
-/// list{ [a1, b1), [a2, b2), ..., [a_N, b_N) }
-///
-/// The collection has the following properties:
-///
-/// 1. The list is ordered: a_i < b_i and b_i < a_(i+1)
-///
-/// 2. The intervals in the collection do not intersect each other.
-///
-/// A \ref ResourceSegments instance represents the cycle
-/// reservation history of the instance of and individual resource.
-class ResourceSegments {
-public:
- /// Represents an interval of discrete integer values closed on
- /// the left and open on the right: [a, b).
- typedef std::pair<int64_t, int64_t> IntervalTy;
-
- /// Adds an interval [a, b) to the collection of the instance.
- ///
- /// When adding [a, b[ to the collection, the operation merges the
- /// adjacent intervals. For example
- ///
- /// 0 1 2 3 4 5 6 7 8 9 10
- /// [-----) [--) [--)
- /// + [--)
- /// = [-----------) [--)
- ///
- /// To be able to debug duplicate resource usage, the function has
- /// assertion that checks that no interval should be added if it
- /// overlaps any of the intervals in the collection. We can
- /// require this because by definition a \ref ResourceSegments is
- /// attached only to an individual resource instance.
- void add(IntervalTy A, const unsigned CutOff = 10);
-
-public:
- /// Checks whether intervals intersect.
- static bool intersects(IntervalTy A, IntervalTy B);
-
- /// These function return the interval used by a resource in bottom and top
- /// scheduling.
- ///
- /// Consider an instruction that uses resources X0, X1 and X2 as follows:
- ///
- /// X0 X1 X1 X2 +--------+------------+------+
- /// |Resource|StartAtCycle|Cycles|
- /// +--------+------------+------+
- /// | X0 | 0 | 1 |
- /// +--------+------------+------+
- /// | X1 | 1 | 3 |
- /// +--------+------------+------+
- /// | X2 | 3 | 4 |
- /// +--------+------------+------+
- ///
- /// If we can schedule the instruction at cycle C, we need to
- /// compute the interval of the resource as follows:
- ///
- /// # TOP DOWN SCHEDULING
- ///
- /// Cycles scheduling flows to the _right_, in the same direction
- /// of time.
- ///
- /// C 1 2 3 4 5 ...
- /// ------|------|------|------|------|------|----->
- /// X0 X1 X1 X2 ---> direction of time
- /// X0 [C, C+1)
- /// X1 [C+1, C+3)
- /// X2 [C+3, C+4)
- ///
- /// Therefore, the formula to compute the interval for a resource
- /// of an instruction that can be scheduled at cycle C in top-down
- /// scheduling is:
- ///
- /// [C+StartAtCycle, C+Cycles)
- ///
- ///
- /// # BOTTOM UP SCHEDULING
- ///
- /// Cycles scheduling flows to the _left_, in opposite direction
- /// of time.
- ///
- /// In bottom up scheduling, the scheduling happens in opposite
- /// direction to the execution of the cycles of the
- /// instruction. When the instruction is scheduled at cycle `C`,
- /// the resources are allocated in the past relative to `C`:
- ///
- /// 2 1 C -1 -2 -3 -4 -5 ...
- /// <-----|------|------|------|------|------|------|------|---
- /// X0 X1 X1 X2 ---> direction of time
- /// X0 (C+1, C]
- /// X1 (C, C-2]
- /// X2 (C-2, C-3]
- ///
- /// Therefore, the formula to compute the interval for a resource
- /// of an instruction that can be scheduled at cycle C in bottom-up
- /// scheduling is:
- ///
- /// [C-Cycle+1, C-StartAtCycle+1)
- ///
- ///
- /// NOTE: In both cases, the number of cycles booked by a
- /// resources is the value (Cycle - StartAtCycles).
- static IntervalTy getResourceIntervalBottom(unsigned C, unsigned StartAtCycle,
- unsigned Cycle) {
- return std::make_pair<long, long>((long)C - (long)Cycle + 1L,
- (long)C - (long)StartAtCycle + 1L);
- }
- static IntervalTy getResourceIntervalTop(unsigned C, unsigned StartAtCycle,
- unsigned Cycle) {
- return std::make_pair<long, long>((long)C + (long)StartAtCycle,
- (long)C + (long)Cycle);
- }
-
-private:
- /// Finds the first cycle in which a resource can be allocated.
- ///
- /// The function uses the \param IntervalBuider [*] to build a
- /// resource interval [a, b[ out of the input parameters \param
- /// CurrCycle, \param StartAtCycle and \param Cycle.
- ///
- /// The function then loops through the intervals in the ResourceSegments
- /// and shifts the interval [a, b[ and the ReturnCycle to the
- /// right until there is no intersection between the intervals of
- /// the \ref ResourceSegments instance and the new shifted [a, b[. When
- /// this condition is met, the ReturnCycle (which
- /// correspond to the cycle in which the resource can be
- /// allocated) is returned.
- ///
- /// c = CurrCycle in input
- /// c 1 2 3 4 5 6 7 8 9 10 ... ---> (time
- /// flow)
- /// ResourceSegments... [---) [-------) [-----------)
- /// c [1 3[ -> StartAtCycle=1, Cycles=3
- /// ++c [1 3)
- /// ++c [1 3)
- /// ++c [1 3)
- /// ++c [1 3)
- /// ++c [1 3) ---> returns c
- /// incremented by 5 (c+5)
- ///
- ///
- /// Notice that for bottom-up scheduling the diagram is slightly
- ///
diff erent because the current cycle c is always on the right
- /// of the interval [a, b) (see \ref
- /// `getResourceIntervalBottom`). This is because the cycle
- /// increments for bottom-up scheduling moved in the direction
- /// opposite to the direction of time:
- ///
- /// --------> direction of time.
- /// XXYZZZ (resource usage)
- /// --------> direction of top-down execution cycles.
- /// <-------- direction of bottom-up execution cycles.
- ///
- /// Even though bottom-up scheduling moves against the flow of
- /// time, the algorithm used to find the first free slot in between
- /// intervals is the same as for top-down scheduling.
- ///
- /// [*] See \ref `getResourceIntervalTop` and
- /// \ref `getResourceIntervalBottom` to see how such resource intervals
- /// are built.
- unsigned
- getFirstAvailableAt(unsigned CurrCycle, unsigned StartAtCycle, unsigned Cycle,
- std::function<IntervalTy(unsigned, unsigned, unsigned)>
- IntervalBuilder) const;
-
-public:
- /// getFirstAvailableAtFromBottom and getFirstAvailableAtFromTop
- /// should be merged in a single function in which a function that
- /// creates the `NewInterval` is passed as a parameter.
- unsigned getFirstAvailableAtFromBottom(unsigned CurrCycle,
- unsigned StartAtCycle,
- unsigned Cycle) const {
- return getFirstAvailableAt(CurrCycle, StartAtCycle, Cycle,
- getResourceIntervalBottom);
- }
- unsigned getFirstAvailableAtFromTop(unsigned CurrCycle, unsigned StartAtCycle,
- unsigned Cycle) const {
- return getFirstAvailableAt(CurrCycle, StartAtCycle, Cycle,
- getResourceIntervalTop);
- }
-
-private:
- std::list<IntervalTy> _Intervals;
- /// Merge all adjacent intervals in the collection. For all pairs
- /// of adjacient intervals, it performs [a, b) + [b, c) -> [a, c).
- ///
- /// Before performing the merge operation, the intervals are
- /// sorted with \ref sort_predicate.
- void sortAndMerge();
-
-public:
- // constructor for empty set
- explicit ResourceSegments(){};
- bool empty() const { return _Intervals.empty(); }
- explicit ResourceSegments(std::list<IntervalTy> Intervals)
- : _Intervals(Intervals) {
- sortAndMerge();
- }
-
- friend bool operator==(const ResourceSegments &c1,
- const ResourceSegments &c2) {
- return c1._Intervals == c2._Intervals;
- }
-#ifndef NDEBUG
- friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
- const ResourceSegments &Segments) {
- os << "{ ";
- for (auto p : Segments._Intervals)
- os << "[" << p.first << ", " << p.second << "), ";
- os << "}\n";
- return os;
- }
-#endif
-};
-
/// Each Scheduling boundary is associated with ready queues. It tracks the
/// current cycle in the direction of movement, and maintains the state
/// of "hazards" and other interlocks at the current cycle.
@@ -892,14 +675,12 @@ class SchedBoundary {
// Is the scheduled region resource limited vs. latency limited.
bool IsResourceLimited;
-public:
-private:
- /// Record how resources have been allocated across the cycles of
- /// the execution.
- std::map<unsigned, ResourceSegments> ReservedResourceSegments;
- std::vector<unsigned> ReservedCycles;
- /// For each PIdx, stores first index into ReservedResourceSegments that
- /// corresponds to it.
+ // Record the highest cycle at which each resource has been reserved by a
+ // scheduled instruction.
+ SmallVector<unsigned, 16> ReservedCycles;
+
+ /// For each PIdx, stores first index into ReservedCycles that corresponds to
+ /// it.
///
/// For example, consider the following 3 resources (ResourceCount =
/// 3):
@@ -915,14 +696,12 @@ class SchedBoundary {
/// +------------+--------+
///
/// In this case, the total number of resource instances is 6. The
- /// vector \ref ReservedResourceSegments will have a slot for each instance.
- /// The vector \ref ReservedCyclesIndex will track at what index the first
+ /// vector \ref ReservedCycles will have a slot for each instance. The
+ /// vector \ref ReservedCyclesIndex will track at what index the first
/// instance of the resource is found in the vector of \ref
- /// ReservedResourceSegments:
- ///
- /// Indexes of instances in
- /// ReservedResourceSegments
+ /// ReservedCycles:
///
+ /// Indexes of instances in ReservedCycles
/// 0 1 2 3 4 5
/// ReservedCyclesIndex[0] = 0; [X0, X1,
/// ReservedCyclesIndex[1] = 2; Y0, Y1, Y2
@@ -1008,13 +787,11 @@ class SchedBoundary {
unsigned getLatencyStallCycles(SUnit *SU);
unsigned getNextResourceCycleByInstance(unsigned InstanceIndex,
- unsigned Cycles,
- unsigned StartAtCycle);
+ unsigned Cycles);
std::pair<unsigned, unsigned> getNextResourceCycle(const MCSchedClassDesc *SC,
unsigned PIdx,
- unsigned Cycles,
- unsigned StartAtCycle);
+ unsigned Cycles);
bool isUnbufferedGroup(unsigned PIdx) const {
return SchedModel->getProcResource(PIdx)->SubUnitsIdxBegin &&
@@ -1043,8 +820,7 @@ class SchedBoundary {
void incExecutedResources(unsigned PIdx, unsigned Count);
unsigned countResource(const MCSchedClassDesc *SC, unsigned PIdx,
- unsigned Cycles, unsigned ReadyCycle,
- unsigned StartAtCycle);
+ unsigned Cycles, unsigned ReadyCycle);
void bumpNode(SUnit *SU);
diff --git a/llvm/include/llvm/CodeGen/TargetSchedule.h b/llvm/include/llvm/CodeGen/TargetSchedule.h
index bfab9cb92a385..049ede89ab461 100644
--- a/llvm/include/llvm/CodeGen/TargetSchedule.h
+++ b/llvm/include/llvm/CodeGen/TargetSchedule.h
@@ -90,7 +90,7 @@ class TargetSchedModel {
bool hasInstrSchedModelOrItineraries() const {
return hasInstrSchedModel() || hasInstrItineraries();
}
- bool enableIntervals() const { return SchedModel.EnableIntervals; }
+
/// Identify the processor corresponding to the current subtarget.
unsigned getProcessorID() const { return SchedModel.getProcessorID(); }
diff --git a/llvm/include/llvm/MC/MCSchedule.h b/llvm/include/llvm/MC/MCSchedule.h
index e6cf27ce2d651..98254fc23b225 100644
--- a/llvm/include/llvm/MC/MCSchedule.h
+++ b/llvm/include/llvm/MC/MCSchedule.h
@@ -58,17 +58,10 @@ struct MCProcResourceDesc {
}
};
-/// Identify one of the processor resource kinds consumed by a
-/// particular scheduling class for the specified number of cycles.
-/// TODO: consider renaming the field `StartAtCycle` and `Cycles` to
-/// `AcquireAtCycle` and `ReleaseAtCycle` respectively, to stress the
-/// fact that resource allocation is now represented as an interval,
-/// relatively to the issue cycle of the instruction.
+/// Identify one of the processor resource kinds consumed by a particular
+/// scheduling class for the specified number of cycles.
struct MCWriteProcResEntry {
uint16_t ProcResourceIdx;
- /// Cycle at which the resource will be released by an instruction,
- /// relatively to the cycle in which the instruction is issued
- /// (assuming no stalls inbetween).
uint16_t Cycles;
/// Cycle at which the resource will be grabbed by an instruction,
/// relatively to the cycle in which the instruction is issued
@@ -313,11 +306,6 @@ struct MCSchedModel {
bool CompleteModel;
- // Tells the MachineScheduler whether or not to track resource usage
- // using intervals via ResourceSegments (see
- // llvm/include/llvm/CodeGen/MachineScheduler.h).
- bool EnableIntervals;
-
unsigned ProcID;
const MCProcResourceDesc *ProcResourceTable;
const MCSchedClassDesc *SchedClassTable;
diff --git a/llvm/include/llvm/Target/TargetSchedule.td b/llvm/include/llvm/Target/TargetSchedule.td
index f5aa105ec0cbb..d0742c2adb781 100644
--- a/llvm/include/llvm/Target/TargetSchedule.td
+++ b/llvm/include/llvm/Target/TargetSchedule.td
@@ -117,11 +117,6 @@ class SchedMachineModel {
list<Predicate> UnsupportedFeatures = [];
bit NoModel = false; // Special tag to indicate missing machine model.
-
- // Tells the MachineScheduler whether or not to track resource usage
- // using intervals via ResourceSegments (see
- // llvm/include/llvm/CodeGen/MachineScheduler.h).
- bit EnableIntervals = false;
}
def NoSchedModel : SchedMachineModel {
diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp
index 59248bdea1914..b5b91802ef238 100644
--- a/llvm/lib/CodeGen/MachineScheduler.cpp
+++ b/llvm/lib/CodeGen/MachineScheduler.cpp
@@ -162,10 +162,6 @@ static cl::opt<unsigned>
cl::init(5));
#endif
-static cl::opt<unsigned>
- MIResourceCutOff("misched-resource-cutoff", cl::Hidden,
- cl::desc("Number of intervals to track"), cl::init(10));
-
// DAG subtrees must have at least this many nodes.
static const unsigned MinSubtreeSize = 8;
@@ -2172,7 +2168,6 @@ void SchedBoundary::reset() {
ZoneCritResIdx = 0;
IsResourceLimited = false;
ReservedCycles.clear();
- ReservedResourceSegments.clear();
ReservedCyclesIndex.clear();
ResourceGroupSubUnitMasks.clear();
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
@@ -2201,8 +2196,7 @@ init(ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel) {
PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) {
unsigned PIdx = PI->ProcResourceIdx;
unsigned Factor = SchedModel->getResourceFactor(PIdx);
- assert(PI->Cycles >= PI->StartAtCycle);
- RemainingCounts[PIdx] += (Factor * (PI->Cycles - PI->StartAtCycle));
+ RemainingCounts[PIdx] += (Factor * PI->Cycles);
}
}
}
@@ -2255,17 +2249,7 @@ unsigned SchedBoundary::getLatencyStallCycles(SUnit *SU) {
/// Compute the next cycle at which the given processor resource unit
/// can be scheduled.
unsigned SchedBoundary::getNextResourceCycleByInstance(unsigned InstanceIdx,
- unsigned Cycles,
- unsigned StartAtCycle) {
- if (SchedModel && SchedModel->enableIntervals()) {
- if (isTop())
- return ReservedResourceSegments[InstanceIdx].getFirstAvailableAtFromTop(
- CurrCycle, StartAtCycle, Cycles);
-
- return ReservedResourceSegments[InstanceIdx].getFirstAvailableAtFromBottom(
- CurrCycle, StartAtCycle, Cycles);
- }
-
+ unsigned Cycles) {
unsigned NextUnreserved = ReservedCycles[InstanceIdx];
// If this resource has never been used, always return cycle zero.
if (NextUnreserved == InvalidCycle)
@@ -2281,7 +2265,7 @@ unsigned SchedBoundary::getNextResourceCycleByInstance(unsigned InstanceIdx,
/// instance in the reserved cycles vector.
std::pair<unsigned, unsigned>
SchedBoundary::getNextResourceCycle(const MCSchedClassDesc *SC, unsigned PIdx,
- unsigned Cycles, unsigned StartAtCycle) {
+ unsigned Cycles) {
unsigned MinNextUnreserved = InvalidCycle;
unsigned InstanceIdx = 0;
@@ -2310,7 +2294,7 @@ SchedBoundary::getNextResourceCycle(const MCSchedClassDesc *SC, unsigned PIdx,
for (unsigned I = 0, End = NumberOfInstances; I < End; ++I) {
unsigned NextUnreserved, NextInstanceIdx;
std::tie(NextUnreserved, NextInstanceIdx) =
- getNextResourceCycle(SC, SubUnits[I], Cycles, StartAtCycle);
+ getNextResourceCycle(SC, SubUnits[I], Cycles);
if (MinNextUnreserved > NextUnreserved) {
InstanceIdx = NextInstanceIdx;
MinNextUnreserved = NextUnreserved;
@@ -2321,8 +2305,7 @@ SchedBoundary::getNextResourceCycle(const MCSchedClassDesc *SC, unsigned PIdx,
for (unsigned I = StartIndex, End = StartIndex + NumberOfInstances; I < End;
++I) {
- unsigned NextUnreserved =
- getNextResourceCycleByInstance(I, Cycles, StartAtCycle);
+ unsigned NextUnreserved = getNextResourceCycleByInstance(I, Cycles);
if (MinNextUnreserved > NextUnreserved) {
InstanceIdx = I;
MinNextUnreserved = NextUnreserved;
@@ -2372,10 +2355,8 @@ bool SchedBoundary::checkHazard(SUnit *SU) {
SchedModel->getWriteProcResEnd(SC))) {
unsigned ResIdx = PE.ProcResourceIdx;
unsigned Cycles = PE.Cycles;
- unsigned StartAtCycle = PE.StartAtCycle;
unsigned NRCycle, InstanceIdx;
- std::tie(NRCycle, InstanceIdx) =
- getNextResourceCycle(SC, ResIdx, Cycles, StartAtCycle);
+ std::tie(NRCycle, InstanceIdx) = getNextResourceCycle(SC, ResIdx, Cycles);
if (NRCycle > CurrCycle) {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
MaxObservedStall = std::max(Cycles, MaxObservedStall);
@@ -2526,10 +2507,9 @@ void SchedBoundary::incExecutedResources(unsigned PIdx, unsigned Count) {
/// \return the next cycle at which the instruction may execute without
/// oversubscribing resources.
unsigned SchedBoundary::countResource(const MCSchedClassDesc *SC, unsigned PIdx,
- unsigned Cycles, unsigned NextCycle,
- unsigned StartAtCycle) {
+ unsigned Cycles, unsigned NextCycle) {
unsigned Factor = SchedModel->getResourceFactor(PIdx);
- unsigned Count = Factor * (Cycles - StartAtCycle);
+ unsigned Count = Factor * Cycles;
LLVM_DEBUG(dbgs() << " " << SchedModel->getResourceName(PIdx) << " +"
<< Cycles << "x" << Factor << "u\n");
@@ -2549,8 +2529,7 @@ unsigned SchedBoundary::countResource(const MCSchedClassDesc *SC, unsigned PIdx,
}
// For reserved resources, record the highest cycle using the resource.
unsigned NextAvailable, InstanceIdx;
- std::tie(NextAvailable, InstanceIdx) =
- getNextResourceCycle(SC, PIdx, Cycles, StartAtCycle);
+ std::tie(NextAvailable, InstanceIdx) = getNextResourceCycle(SC, PIdx, Cycles);
if (NextAvailable > CurrCycle) {
LLVM_DEBUG(dbgs() << " Resource conflict: "
<< SchedModel->getResourceName(PIdx)
@@ -2629,8 +2608,8 @@ void SchedBoundary::bumpNode(SUnit *SU) {
for (TargetSchedModel::ProcResIter
PI = SchedModel->getWriteProcResBegin(SC),
PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) {
- unsigned RCycle = countResource(SC, PI->ProcResourceIdx, PI->Cycles,
- NextCycle, PI->StartAtCycle);
+ unsigned RCycle =
+ countResource(SC, PI->ProcResourceIdx, PI->Cycles, NextCycle);
if (RCycle > NextCycle)
NextCycle = RCycle;
}
@@ -2644,33 +2623,14 @@ void SchedBoundary::bumpNode(SUnit *SU) {
PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) {
unsigned PIdx = PI->ProcResourceIdx;
if (SchedModel->getProcResource(PIdx)->BufferSize == 0) {
-
- if (SchedModel && SchedModel->enableIntervals()) {
- unsigned ReservedUntil, InstanceIdx;
- std::tie(ReservedUntil, InstanceIdx) =
- getNextResourceCycle(SC, PIdx, PI->Cycles, PI->StartAtCycle);
- if (isTop()) {
- ReservedResourceSegments[InstanceIdx].add(
- ResourceSegments::getResourceIntervalTop(
- NextCycle, PI->StartAtCycle, PI->Cycles),
- MIResourceCutOff);
- } else {
- ReservedResourceSegments[InstanceIdx].add(
- ResourceSegments::getResourceIntervalBottom(
- NextCycle, PI->StartAtCycle, PI->Cycles),
- MIResourceCutOff);
- }
- } else {
-
- unsigned ReservedUntil, InstanceIdx;
- std::tie(ReservedUntil, InstanceIdx) =
- getNextResourceCycle(SC, PIdx, 0, PI->StartAtCycle);
- if (isTop()) {
- ReservedCycles[InstanceIdx] =
- std::max(ReservedUntil, NextCycle + PI->Cycles);
- } else
- ReservedCycles[InstanceIdx] = NextCycle;
- }
+ unsigned ReservedUntil, InstanceIdx;
+ std::tie(ReservedUntil, InstanceIdx) =
+ getNextResourceCycle(SC, PIdx, 0);
+ if (isTop()) {
+ ReservedCycles[InstanceIdx] =
+ std::max(ReservedUntil, NextCycle + PI->Cycles);
+ } else
+ ReservedCycles[InstanceIdx] = NextCycle;
}
}
}
@@ -2810,14 +2770,8 @@ LLVM_DUMP_METHOD void SchedBoundary::dumpReservedCycles() const {
const unsigned NumUnits = SchedModel->getProcResource(ResIdx)->NumUnits;
std::string ResName = SchedModel->getResourceName(ResIdx);
for (unsigned UnitIdx = 0; UnitIdx < NumUnits; ++UnitIdx) {
- dbgs() << ResName << "(" << UnitIdx << ") = ";
- if (SchedModel && SchedModel->enableIntervals()) {
- if (ReservedResourceSegments.count(StartIdx + UnitIdx))
- dbgs() << ReservedResourceSegments.at(StartIdx + UnitIdx);
- else
- dbgs() << "{ }\n";
- } else
- dbgs() << ReservedCycles[StartIdx + UnitIdx] << "\n";
+ dbgs() << ResName << "(" << UnitIdx
+ << ") = " << ReservedCycles[StartIdx + UnitIdx] << "\n";
}
StartIdx += NumUnits;
}
@@ -4184,102 +4138,3 @@ void ScheduleDAGMI::viewGraph(const Twine &Name, const Twine &Title) {
void ScheduleDAGMI::viewGraph() {
viewGraph(getDAGName(), "Scheduling-Units Graph for " + getDAGName());
}
-
-/// Sort predicate for the intervals stored in an instance of
-/// ResourceSegments. Intervals are always disjoint (no intersection
-/// for any pairs of intervals), therefore we can sort the totality of
-/// the intervals by looking only at the left boundary.
-static bool sortIntervals(const ResourceSegments::IntervalTy &A,
- const ResourceSegments::IntervalTy &B) {
- return A.first < B.first;
-}
-
-unsigned ResourceSegments::getFirstAvailableAt(
- unsigned CurrCycle, unsigned StartAtCycle, unsigned Cycle,
- std::function<ResourceSegments::IntervalTy(unsigned, unsigned, unsigned)>
- IntervalBuilder) const {
- assert(std::is_sorted(std::begin(_Intervals), std::end(_Intervals),
- sortIntervals) &&
- "Cannot execute on an un-sorted set of intervals.");
- unsigned RetCycle = CurrCycle;
- ResourceSegments::IntervalTy NewInterval =
- IntervalBuilder(RetCycle, StartAtCycle, Cycle);
- for (auto &Interval : _Intervals) {
- if (!intersects(NewInterval, Interval))
- continue;
-
- // Move the interval right next to the top of the one it
- // intersects.
- assert(Interval.second > NewInterval.first &&
- "Invalid intervals configuration.");
- RetCycle += (unsigned)Interval.second - (unsigned)NewInterval.first;
- NewInterval = IntervalBuilder(RetCycle, StartAtCycle, Cycle);
- }
- return RetCycle;
-}
-
-void ResourceSegments::add(ResourceSegments::IntervalTy A,
- const unsigned CutOff) {
- using IntervalTy = ResourceSegments::IntervalTy;
- assert(A.first < A.second && "Cannot add empty resource usage");
- assert(CutOff > 0 && "0-size interval history has no use.");
- assert(all_of(_Intervals,
- [&A](const IntervalTy &Interval) -> bool {
- return !intersects(A, Interval);
- }) &&
- "A resource is being overwritten");
- _Intervals.push_back(A);
-
- sortAndMerge();
-
- // Do not keep the full history of the intervals, just the
- // latest #CutOff.
- while (_Intervals.size() > CutOff)
- _Intervals.pop_front();
-}
-
-bool ResourceSegments::intersects(ResourceSegments::IntervalTy A,
- ResourceSegments::IntervalTy B) {
- assert(A.first <= A.second && "Invalid interval");
- assert(B.first <= B.second && "Invalid interval");
-
- // Share one boundary.
- if ((A.first == B.first) || (A.second == B.second))
- return true;
-
- // full intersersect: [ *** ) B
- // [***) A
- if ((A.first > B.first) && (A.second < B.second))
- return true;
-
- // right intersect: [ ***) B
- // [*** ) A
- if ((A.first > B.first) && (A.first < B.second) && (A.second > B.second))
- return true;
-
- // left intersect: [*** ) B
- // [ ***) A
- if ((A.first < B.first) && (B.first < A.second) && (B.second > B.first))
- return true;
-
- return false;
-}
-
-void ResourceSegments::sortAndMerge() {
- if (_Intervals.size() <= 1)
- return;
-
- // First sort the collection.
- _Intervals.sort(sortIntervals);
-
- // can use next because I have at least 2 elements in the list
- auto next = std::next(std::begin(_Intervals));
- auto E = std::end(_Intervals);
- for (; next != E; ++next) {
- if (std::prev(next)->second >= next->first) {
- next->first = std::prev(next)->first;
- _Intervals.erase(std::prev(next));
- continue;
- }
- }
-}
diff --git a/llvm/lib/MC/MCSchedule.cpp b/llvm/lib/MC/MCSchedule.cpp
index 5a893b803fd07..9f00064f501bb 100644
--- a/llvm/lib/MC/MCSchedule.cpp
+++ b/llvm/lib/MC/MCSchedule.cpp
@@ -30,7 +30,6 @@ const MCSchedModel MCSchedModel::Default = {DefaultIssueWidth,
DefaultMispredictPenalty,
false,
true,
- false /*EnableIntervals*/,
0,
nullptr,
nullptr,
diff --git a/llvm/unittests/CodeGen/CMakeLists.txt b/llvm/unittests/CodeGen/CMakeLists.txt
index dc47174b9513e..f3a5b0f8e75db 100644
--- a/llvm/unittests/CodeGen/CMakeLists.txt
+++ b/llvm/unittests/CodeGen/CMakeLists.txt
@@ -35,7 +35,6 @@ add_llvm_unittest(CodeGenTests
RegAllocScoreTest.cpp
PassManagerTest.cpp
ScalableVectorMVTsTest.cpp
- SchedBoundary.cpp
SelectionDAGAddressAnalysisTest.cpp
TypeTraitsTest.cpp
TargetOptionsTest.cpp
diff --git a/llvm/unittests/CodeGen/SchedBoundary.cpp b/llvm/unittests/CodeGen/SchedBoundary.cpp
deleted file mode 100644
index 0eaa1b216f2cc..0000000000000
--- a/llvm/unittests/CodeGen/SchedBoundary.cpp
+++ /dev/null
@@ -1,398 +0,0 @@
-#include "llvm/CodeGen/MachineScheduler.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-#ifndef NDEBUG
-TEST(ResourceSegmentsDeath, OverwriteOnRight) {
- auto X = ResourceSegments({{10, 20}});
- EXPECT_DEATH(X.add({15, 30}), "A resource is being overwritten");
-}
-
-TEST(ResourceSegmentsDeath, OverwriteOnLeft) {
- auto X = ResourceSegments({{10, 20}});
- EXPECT_DEATH(X.add({5, 11}), "A resource is being overwritten");
- ;
-}
-
-TEST(ResourceSegmentsDeath, FullOverwrite) {
- auto X = ResourceSegments({{10, 20}});
- EXPECT_DEATH(X.add({15, 18}), "A resource is being overwritten");
-}
-
-TEST(ResourceSegmentsDeath, ZeroSizeIntervalsNotAllowed) {
- auto X = ResourceSegments({{10, 20}});
- EXPECT_DEATH(X.add({20, 30}, 0), "0-size interval history has no use.");
-}
-#endif // NDEBUG
-
-TEST(ResourceSegments, ConsecutiveLeftNoOverlap) {
- auto X = ResourceSegments({{10, 20}});
- X.add({7, 9});
- EXPECT_EQ(X, ResourceSegments({{7, 9}, {10, 20}}));
-}
-
-TEST(ResourceSegments, ConsecutiveLeftWithOverlap) {
- auto X = ResourceSegments({{10, 20}});
- X.add({7, 10});
- EXPECT_EQ(X, ResourceSegments({{7, 20}}));
-}
-
-TEST(ResourceSegments, ConsecutiveRightNoOverlap) {
- auto X = ResourceSegments({{10, 20}});
- X.add({21, 22});
- EXPECT_EQ(X, ResourceSegments({{10, 20}, {21, 22}}));
-}
-
-TEST(ResourceSegments, ConsecutiveRightWithOverlap) {
- auto X = ResourceSegments({{10, 20}});
- X.add({20, 22});
- EXPECT_EQ(X, ResourceSegments({{10, 22}}));
-}
-
-TEST(ResourceSegments, Disjoint) {
- auto X = ResourceSegments({{10, 20}});
- X.add({22, 23});
- EXPECT_EQ(X, ResourceSegments({{10, 20}, {22, 23}}));
-}
-
-TEST(ResourceSegments, SortAfterAdd) {
- auto X = ResourceSegments({{10, 20}, {3, 4}});
- X.add({6, 8});
- EXPECT_EQ(X, ResourceSegments({{3, 4}, {6, 8}, {10, 20}}));
-}
-
-TEST(ResourceSegments, AddWithCutOff) {
- auto X = ResourceSegments({{1, 2}, {3, 4}});
- X.add({6, 8}, 2);
- EXPECT_EQ(X, ResourceSegments({{3, 4}, {6, 8}}));
-}
-
-TEST(ResourceSegments, add_01) {
- auto X = ResourceSegments({{10, 20}, {30, 40}});
- X.add({21, 29});
- EXPECT_EQ(X, ResourceSegments({{10, 20}, {21, 29}, {30, 40}}));
-}
-
-TEST(ResourceSegments, add_02) {
- auto X = ResourceSegments({{10, 20}, {30, 40}});
- X.add({22, 29});
- EXPECT_EQ(X, ResourceSegments({{10, 20}, {22, 29}, {30, 40}}));
- X.add({29, 30});
- EXPECT_EQ(X, ResourceSegments({{10, 20}, {22, 40}}));
-}
-
-#ifndef NDEBUG
-TEST(ResourceSegmentsDeath, add_empty) {
- auto X = ResourceSegments({{10, 20}, {30, 40}});
- EXPECT_DEATH(X.add({22, 22}), "Cannot add empty resource usage");
-}
-#endif
-
-TEST(ResourceSegments, sort_two) {
- EXPECT_EQ(ResourceSegments({{30, 40}, {10, 28}}),
- ResourceSegments({{10, 28}, {30, 40}}));
-}
-
-TEST(ResourceSegments, sort_three) {
- EXPECT_EQ(ResourceSegments({{30, 40}, {71, 200}, {10, 29}}),
- ResourceSegments({{10, 29}, {30, 40}, {71, 200}}));
-}
-
-TEST(ResourceSegments, merge_two) {
- EXPECT_EQ(ResourceSegments({{10, 33}, {30, 40}}),
- ResourceSegments({{10, 40}}));
- EXPECT_EQ(ResourceSegments({{10, 30}, {30, 40}}),
- ResourceSegments({{10, 40}}));
- // Cycle 29 is resource free, so the interval is disjoint.
- EXPECT_EQ(ResourceSegments({{10, 29}, {30, 40}}),
- ResourceSegments({{10, 29}, {30, 40}}));
-}
-
-TEST(ResourceSegments, merge_three) {
- EXPECT_EQ(ResourceSegments({{10, 29}, {30, 40}, {71, 200}}),
- ResourceSegments({{10, 29}, {30, 40}, {71, 200}}));
- EXPECT_EQ(ResourceSegments({{10, 29}, {30, 40}, {41, 200}}),
- ResourceSegments({{10, 29}, {30, 40}, {41, 200}}));
- EXPECT_EQ(ResourceSegments({{10, 30}, {30, 40}, {40, 200}}),
- ResourceSegments({{10, 200}}));
- EXPECT_EQ(ResourceSegments({{10, 28}, {30, 71}, {71, 200}}),
- ResourceSegments({{10, 28}, {30, 200}}));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Intersection
-TEST(ResourceSegments, intersects) {
- // no intersect
- EXPECT_FALSE(ResourceSegments::intersects({0, 1}, {3, 4}));
- EXPECT_FALSE(ResourceSegments::intersects({3, 4}, {0, 1}));
- EXPECT_FALSE(ResourceSegments::intersects({0, 3}, {3, 4}));
- EXPECT_FALSE(ResourceSegments::intersects({3, 4}, {0, 3}));
-
- // Share one boundary
- EXPECT_TRUE(ResourceSegments::intersects({5, 6}, {5, 10}));
- EXPECT_TRUE(ResourceSegments::intersects({5, 10}, {5, 6}));
-
- // full intersect
- EXPECT_TRUE(ResourceSegments::intersects({1, 2}, {0, 3}));
- EXPECT_TRUE(ResourceSegments::intersects({1, 2}, {0, 2}));
- EXPECT_TRUE(ResourceSegments::intersects({0, 3}, {1, 2}));
- EXPECT_TRUE(ResourceSegments::intersects({0, 2}, {1, 2}));
-
- // right intersect
- EXPECT_TRUE(ResourceSegments::intersects({2, 4}, {0, 3}));
- EXPECT_TRUE(ResourceSegments::intersects({0, 3}, {2, 4}));
-
- // left intersect
- EXPECT_TRUE(ResourceSegments::intersects({2, 4}, {3, 5}));
- EXPECT_TRUE(ResourceSegments::intersects({3, 5}, {2, 4}));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// TOP-DOWN getFirstAvailableAt
-TEST(ResourceSegments, getFirstAvailableAtFromTop_oneCycle) {
- auto X = ResourceSegments({{2, 5}});
- // 0 1 2 3 4 5 6 7
- // Res X X X
- // ...X...
- EXPECT_EQ(X.getFirstAvailableAtFromTop(0, 0, 1), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromTop(1, 0, 1), 1U);
- // Skip to five when hitting cycle 2
- EXPECT_EQ(X.getFirstAvailableAtFromTop(2, 0, 1), 5U);
-}
-
-TEST(ResourceSegments, getFirstAvailableAtFromTop_twoCycles) {
- auto X = ResourceSegments({{4, 5}});
- // 0 1 2 3 4 5 6 7
- // Res X
- // ...X X....
- EXPECT_EQ(X.getFirstAvailableAtFromTop(0, 0, 2), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromTop(1, 0, 2), 1U);
- EXPECT_EQ(X.getFirstAvailableAtFromTop(2, 0, 2), 2U);
- // Skip to cycle 5
- EXPECT_EQ(X.getFirstAvailableAtFromTop(3, 0, 2), 5U);
-}
-
-TEST(ResourceSegments, getFirstAvailableAtFromTop_twoCycles_Shifted) {
- auto X = ResourceSegments({{4, 5}});
- // 0 1 2 3 4 5 6 7
- // Res X
- // ...c X X...
- EXPECT_EQ(X.getFirstAvailableAtFromTop(0, 1, 3), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromTop(1, 1, 3), 1U);
- // Skip to cycle 4
- EXPECT_EQ(X.getFirstAvailableAtFromTop(2, 1, 3), 4U);
- // Stay con cycle 4
- // 0 1 2 3 4 5 6 7
- // Res X
- // ...c X X...
- EXPECT_EQ(X.getFirstAvailableAtFromTop(3, 1, 3), 4U);
- //
- EXPECT_EQ(X.getFirstAvailableAtFromTop(4, 1, 3), 4U);
- EXPECT_EQ(X.getFirstAvailableAtFromTop(5, 1, 3), 5U);
-}
-
-TEST(ResourceSegments, getFirstAvailableAtFromTop_twoCycles_Shifted_withGap) {
- auto X = ResourceSegments({{4, 5}, {7, 9}});
- // 0 1 2 3 4 5 6 7 8 9
- // Res X X X
- // c X X
- EXPECT_EQ(X.getFirstAvailableAtFromTop(1, 1, 3), 1U);
- // 0 1 2 3 4 5 6 7 8 9
- // Res X X X
- // c X X --> moves to 4
- EXPECT_EQ(X.getFirstAvailableAtFromTop(2, 1, 3), 4U);
- // 0 1 2 3 4 5 6 7 8 9
- // Res X X X
- // c X X --> moves to 4
- EXPECT_EQ(X.getFirstAvailableAtFromTop(3, 1, 3), 4U);
- // 0 1 2 3 4 5 6 7 8 9
- // Res X X X
- // c X X --> stays on 4
- EXPECT_EQ(X.getFirstAvailableAtFromTop(4, 1, 3), 4U);
- // 0 1 2 3 4 5 6 7 8 9
- // Res X X X
- // c X X --> skips to 8
- EXPECT_EQ(X.getFirstAvailableAtFromTop(5, 1, 3), 8U);
-}
-
-TEST(ResourceSegments, getFirstAvailableAtFromTop_basic) {
- auto X = ResourceSegments({{5, 10}, {30, 40}});
-
- EXPECT_EQ(X.getFirstAvailableAtFromTop(0, 3, 4), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromTop(1, 3, 4), 1U);
- EXPECT_EQ(X.getFirstAvailableAtFromTop(2, 3, 4), 7U);
- EXPECT_EQ(X.getFirstAvailableAtFromTop(3, 3, 4), 7U);
- EXPECT_EQ(X.getFirstAvailableAtFromTop(4, 3, 4), 7U);
- EXPECT_EQ(X.getFirstAvailableAtFromTop(5, 3, 4), 7U);
- EXPECT_EQ(X.getFirstAvailableAtFromTop(6, 3, 4), 7U);
- EXPECT_EQ(X.getFirstAvailableAtFromTop(7, 3, 4), 7U);
- // Check the empty range between the two intervals of X.
- EXPECT_EQ(X.getFirstAvailableAtFromTop(15, 3, 4), 15U);
- // Overlap the second interval.
- EXPECT_EQ(X.getFirstAvailableAtFromTop(28, 3, 4), 37U);
-}
-
-TEST(ResourceSegments, getFirstAvailableAtFromTop_advanced) {
- auto X = ResourceSegments({{3, 6}, {7, 9}, {11, 14}, {30, 33}});
-
- EXPECT_EQ(X.getFirstAvailableAtFromTop(2, 4, 5), 2U);
-
- EXPECT_EQ(X.getFirstAvailableAtFromTop(2, 3, 4), 3U);
- // Can schedule at 7U because the interval [14, 19[ does not
- // overlap any of the intervals in X.
- EXPECT_EQ(X.getFirstAvailableAtFromTop(1, 7, 12), 7U);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// BOTTOM-UP getFirstAvailableAt
-TEST(ResourceSegments, getFirstAvailableAtFromBottom) {
- // Scheduling cycles move to the left...
- //
- // 41 40 39 ... 31 30 29 ... 21 20 19 ... 11 10 9 8 7 6 ... 1 0
- // Res X X X X X X X X
- // X X X X X X
- // Time (relative to instruction execution) 0 1 2 3 4 5
- auto X = ResourceSegments({{10, 20}, {30, 40}});
- // .. but time (instruction cycle) moves to the right. Therefore, it
- // is always possible to llocate a resource to the right of 0 if 0
- // is not taken, because the right side of the scheduling cycles is
- // empty.
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 0, 1), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 0, 9), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 0, 10), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 0, 20), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 0, 21), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 0, 22), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 0, 29), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 0, 30), 0U);
-}
-
-TEST(ResourceSegments, getFirstAvailableAtFromBottom_01) {
- auto X = ResourceSegments({{3, 7}});
- // 10 9 8 7 6 5 4 3 2 1 0
- // X X X X
- // ...X... <- one cycle resource placement
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 0, 1), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(1, 0, 1), 1U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(2, 0, 1), 2U);
- // Skip to 7
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(3, 0, 1), 7U);
-}
-
-TEST(ResourceSegments, getFirstAvailableAtFromBottom_02) {
- auto X = ResourceSegments({{3, 7}});
- // 10 9 8 7 6 5 4 3 2 1 0
- // X X X X
- // ...X X... <- two cycles resource placement
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 0, 2), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(1, 0, 2), 1U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(2, 0, 2), 2U);
- // skip to 8
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(3, 0, 2), 8U);
-}
-
-TEST(ResourceSegments, getFirstAvailableAtFromBottom_02_shifted) {
- auto X = ResourceSegments({{3, 7}});
- // 10 9 8 7 6 5 4 3 2 1 0
- // X X X X
- // c X X <- two cycles resource placement but shifted by 1
- // 0 1 2 <- cycles relative to the execution of the
- // instruction
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 1, 3), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(1, 1, 3), 1U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(2, 1, 3), 2U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(3, 1, 3), 3U);
- // 10 9 8 7 6 5 4 3 2 1 0
- // X X X X
- // c X X -> skip to 9
- // 0 1 2
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(4, 1, 3), 9U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(5, 1, 3), 9U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(6, 1, 3), 9U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(7, 1, 3), 9U);
- // 10 9 8 7 6 5 4 3 2 1 0
- // X X X X
- // c X X <- skip to 9
- // 0 1 2
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(8, 1, 3), 9U);
- // 10 9 8 7 6 5 4 3 2 1 0
- // X X X X
- // c X X
- // 0 1 2
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(9, 1, 3), 9U);
- // 10 9 8 7 6 5 4 3 2 1 0
- // X X X X
- // c X X
- // 0 1 2
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(10, 1, 3), 10U);
-}
-
-TEST(ResourceSegments, getFirstAvailableAtFromBottom_03) {
- auto X = ResourceSegments({{1, 2}, {3, 7}});
- // 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- // X X X X X
- // X
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 0, 1), 0U);
- // 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- // X X X X X
- // X
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(1, 0, 1), 2U);
- // 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- // X X X X X
- // X
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(2, 0, 1), 2U);
- // 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- // X X X X X
- // X X X X X
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(2, 0, 5), 11U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(3, 0, 5), 11U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(5, 0, 5), 11U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(11, 0, 5), 11U);
- // 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- // X X X X X
- // X X X X X
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(12, 0, 5), 12U);
-}
-
-TEST(ResourceSegments, getFirstAvailableAtFromBottom_03_shifted) {
- // 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3
- // X X X X X X X X
- auto X = ResourceSegments({{-3, -1}, {1, 2}, {3, 7}, {9, 10}});
-
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 1, 2), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 0, 2), 0U);
-
- // 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3
- // X X X X X X X X
- // X X X -> skip to cycle 12
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 0, 3), 12U);
- // 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3
- // X X X X X X X X
- // X X
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 1, 3), 1U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 1, 4), 13U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(12, 1, 4), 13U);
- // 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3
- // X X X X X X X X
- // c X X X
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(13, 1, 4), 13U);
- // 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3
- // X X X X X X X X
- // X X
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(1, 1, 3), 1U);
- // 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3
- // X X X X X X X X
- // C X X 0 -> skip to cycle 9
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(2, 1, 3), 9U);
- // 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3
- // X X X X X X X X
- // C C X X X X X -> skip to cycle 16
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(3, 2, 7), 16U);
-}
-TEST(ResourceSegments, getFirstAvailableAtFromBottom_empty) {
- // Empty resource usage can accept schediling at any cycle
- auto X = ResourceSegments({});
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(0, 0, 1), 0U);
- EXPECT_EQ(X.getFirstAvailableAtFromBottom(17, 1, 22), 17U);
-}
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index bd96ea74829d9..69884a050852e 100644
--- a/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -1453,12 +1453,6 @@ void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) {
OS << " " << (CompleteModel ? "true" : "false") << ", // "
<< "CompleteModel\n";
- bool EnableIntervals =
- (PM.ModelDef ? PM.ModelDef->getValueAsBit("EnableIntervals") : false);
-
- OS << " " << (EnableIntervals ? "true" : "false") << ", // "
- << "EnableIntervals\n";
-
OS << " " << PM.Index << ", // Processor ID\n";
if (PM.hasInstrSchedModel())
OS << " " << PM.ModelName << "ProcResources" << ",\n"
More information about the llvm-commits
mailing list