@@ -1863,6 +1863,7 @@ void SchedBoundary::reset() {
1863
1863
ZoneCritResIdx = 0 ;
1864
1864
IsResourceLimited = false ;
1865
1865
ReservedCycles.clear ();
1866
+ ReservedCyclesIndex.clear ();
1866
1867
#ifndef NDEBUG
1867
1868
// Track the maximum number of stall cycles that could arise either from the
1868
1869
// latency of a DAG edge or the number of cycles that a processor resource is
@@ -1901,8 +1902,17 @@ init(ScheduleDAGMI *dag, const TargetSchedModel *smodel, SchedRemainder *rem) {
1901
1902
SchedModel = smodel;
1902
1903
Rem = rem;
1903
1904
if (SchedModel->hasInstrSchedModel ()) {
1904
- ExecutedResCounts.resize (SchedModel->getNumProcResourceKinds ());
1905
- ReservedCycles.resize (SchedModel->getNumProcResourceKinds (), InvalidCycle);
1905
+ unsigned ResourceCount = SchedModel->getNumProcResourceKinds ();
1906
+ ReservedCyclesIndex.resize (ResourceCount);
1907
+ ExecutedResCounts.resize (ResourceCount);
1908
+ unsigned NumUnits = 0 ;
1909
+
1910
+ for (unsigned i = 0 ; i < ResourceCount; ++i) {
1911
+ ReservedCyclesIndex[i] = NumUnits;
1912
+ NumUnits += SchedModel->getProcResource (i)->NumUnits ;
1913
+ }
1914
+
1915
+ ReservedCycles.resize (NumUnits, InvalidCycle);
1906
1916
}
1907
1917
}
1908
1918
@@ -1923,11 +1933,11 @@ unsigned SchedBoundary::getLatencyStallCycles(SUnit *SU) {
1923
1933
return 0 ;
1924
1934
}
1925
1935
1926
- // / Compute the next cycle at which the given processor resource can be
1927
- // / scheduled.
1928
- unsigned SchedBoundary::
1929
- getNextResourceCycle ( unsigned PIdx, unsigned Cycles) {
1930
- unsigned NextUnreserved = ReservedCycles[PIdx ];
1936
+ // / Compute the next cycle at which the given processor resource unit
1937
+ // / can be scheduled.
1938
+ unsigned SchedBoundary::getNextResourceCycleByInstance ( unsigned InstanceIdx,
1939
+ unsigned Cycles) {
1940
+ unsigned NextUnreserved = ReservedCycles[InstanceIdx ];
1931
1941
// If this resource has never been used, always return cycle zero.
1932
1942
if (NextUnreserved == InvalidCycle)
1933
1943
return 0 ;
@@ -1937,6 +1947,29 @@ getNextResourceCycle(unsigned PIdx, unsigned Cycles) {
1937
1947
return NextUnreserved;
1938
1948
}
1939
1949
1950
+ // / Compute the next cycle at which the given processor resource can be
1951
+ // / scheduled. Returns the next cycle and the index of the processor resource
1952
+ // / instance in the reserved cycles vector.
1953
+ std::pair<unsigned , unsigned >
1954
+ SchedBoundary::getNextResourceCycle (unsigned PIdx, unsigned Cycles) {
1955
+ unsigned MinNextUnreserved = InvalidCycle;
1956
+ unsigned InstanceIdx = 0 ;
1957
+ unsigned StartIndex = ReservedCyclesIndex[PIdx];
1958
+ unsigned NumberOfInstances = SchedModel->getProcResource (PIdx)->NumUnits ;
1959
+ assert (NumberOfInstances > 0 &&
1960
+ " Cannot have zero instances of a ProcResource" );
1961
+
1962
+ for (unsigned I = StartIndex, End = StartIndex + NumberOfInstances; I < End;
1963
+ ++I) {
1964
+ unsigned NextUnreserved = getNextResourceCycleByInstance (I, Cycles);
1965
+ if (MinNextUnreserved > NextUnreserved) {
1966
+ InstanceIdx = I;
1967
+ MinNextUnreserved = NextUnreserved;
1968
+ }
1969
+ }
1970
+ return std::make_pair (MinNextUnreserved, InstanceIdx);
1971
+ }
1972
+
1940
1973
// / Does this SU have a hazard within the current instruction group.
1941
1974
// /
1942
1975
// / The scheduler supports two modes of hazard recognition. The first is the
@@ -1978,14 +2011,16 @@ bool SchedBoundary::checkHazard(SUnit *SU) {
1978
2011
SchedModel->getWriteProcResEnd (SC))) {
1979
2012
unsigned ResIdx = PE.ProcResourceIdx ;
1980
2013
unsigned Cycles = PE.Cycles ;
1981
- unsigned NRCycle = getNextResourceCycle (ResIdx, Cycles);
2014
+ unsigned NRCycle, InstanceIdx;
2015
+ std::tie (NRCycle, InstanceIdx) = getNextResourceCycle (ResIdx, Cycles);
1982
2016
if (NRCycle > CurrCycle) {
1983
2017
#ifndef NDEBUG
1984
2018
MaxObservedStall = std::max (Cycles, MaxObservedStall);
1985
2019
#endif
1986
2020
LLVM_DEBUG (dbgs () << " SU(" << SU->NodeNum << " ) "
1987
- << SchedModel->getResourceName (ResIdx) << " ="
1988
- << NRCycle << " c\n " );
2021
+ << SchedModel->getResourceName (ResIdx)
2022
+ << ' [' << InstanceIdx - ReservedCyclesIndex[ResIdx] << ' ]'
2023
+ << " =" << NRCycle << " c\n " );
1989
2024
return true ;
1990
2025
}
1991
2026
}
@@ -2140,10 +2175,12 @@ countResource(unsigned PIdx, unsigned Cycles, unsigned NextCycle) {
2140
2175
<< " c\n " );
2141
2176
}
2142
2177
// For reserved resources, record the highest cycle using the resource.
2143
- unsigned NextAvailable = getNextResourceCycle (PIdx, Cycles);
2178
+ unsigned NextAvailable, InstanceIdx;
2179
+ std::tie (NextAvailable, InstanceIdx) = getNextResourceCycle (PIdx, Cycles);
2144
2180
if (NextAvailable > CurrCycle) {
2145
2181
LLVM_DEBUG (dbgs () << " Resource conflict: "
2146
- << SchedModel->getProcResource (PIdx)->Name
2182
+ << SchedModel->getResourceName (PIdx)
2183
+ << ' [' << InstanceIdx - ReservedCyclesIndex[PIdx] << ' ]'
2147
2184
<< " reserved until @" << NextAvailable << " \n " );
2148
2185
}
2149
2186
return NextAvailable;
@@ -2233,12 +2270,13 @@ void SchedBoundary::bumpNode(SUnit *SU) {
2233
2270
PE = SchedModel->getWriteProcResEnd (SC); PI != PE; ++PI) {
2234
2271
unsigned PIdx = PI->ProcResourceIdx ;
2235
2272
if (SchedModel->getProcResource (PIdx)->BufferSize == 0 ) {
2273
+ unsigned ReservedUntil, InstanceIdx;
2274
+ std::tie (ReservedUntil, InstanceIdx) = getNextResourceCycle (PIdx, 0 );
2236
2275
if (isTop ()) {
2237
- ReservedCycles[PIdx] =
2238
- std::max (getNextResourceCycle (PIdx, 0 ), NextCycle + PI->Cycles );
2239
- }
2240
- else
2241
- ReservedCycles[PIdx] = NextCycle;
2276
+ ReservedCycles[InstanceIdx] =
2277
+ std::max (ReservedUntil, NextCycle + PI->Cycles );
2278
+ } else
2279
+ ReservedCycles[InstanceIdx] = NextCycle;
2242
2280
}
2243
2281
}
2244
2282
}
0 commit comments