@@ -2004,6 +2004,7 @@ void SchedBoundary::reset() {
2004
2004
IsResourceLimited = false ;
2005
2005
ReservedCycles.clear ();
2006
2006
ReservedCyclesIndex.clear ();
2007
+ ResourceGroupSubUnitMasks.clear ();
2007
2008
#ifndef NDEBUG
2008
2009
// Track the maximum number of stall cycles that could arise either from the
2009
2010
// latency of a DAG edge or the number of cycles that a processor resource is
@@ -2045,11 +2046,18 @@ init(ScheduleDAGMI *dag, const TargetSchedModel *smodel, SchedRemainder *rem) {
2045
2046
unsigned ResourceCount = SchedModel->getNumProcResourceKinds ();
2046
2047
ReservedCyclesIndex.resize (ResourceCount);
2047
2048
ExecutedResCounts.resize (ResourceCount);
2049
+ ResourceGroupSubUnitMasks.resize (ResourceCount, APInt (ResourceCount, 0 ));
2048
2050
unsigned NumUnits = 0 ;
2049
2051
2050
2052
for (unsigned i = 0 ; i < ResourceCount; ++i) {
2051
2053
ReservedCyclesIndex[i] = NumUnits;
2052
2054
NumUnits += SchedModel->getProcResource (i)->NumUnits ;
2055
+ if (isUnbufferedGroup (i)) {
2056
+ auto SubUnits = SchedModel->getProcResource (i)->SubUnitsIdxBegin ;
2057
+ for (unsigned U = 0 , UE = SchedModel->getProcResource (i)->NumUnits ;
2058
+ U != UE; ++U)
2059
+ ResourceGroupSubUnitMasks[i].setBit (SubUnits[U]);
2060
+ }
2053
2061
}
2054
2062
2055
2063
ReservedCycles.resize (NumUnits, InvalidCycle);
@@ -2091,14 +2099,45 @@ unsigned SchedBoundary::getNextResourceCycleByInstance(unsigned InstanceIdx,
2091
2099
// / scheduled. Returns the next cycle and the index of the processor resource
2092
2100
// / instance in the reserved cycles vector.
2093
2101
std::pair<unsigned , unsigned >
2094
- SchedBoundary::getNextResourceCycle (unsigned PIdx, unsigned Cycles) {
2102
+ SchedBoundary::getNextResourceCycle (const MCSchedClassDesc *SC, unsigned PIdx,
2103
+ unsigned Cycles) {
2104
+
2095
2105
unsigned MinNextUnreserved = InvalidCycle;
2096
2106
unsigned InstanceIdx = 0 ;
2097
2107
unsigned StartIndex = ReservedCyclesIndex[PIdx];
2098
2108
unsigned NumberOfInstances = SchedModel->getProcResource (PIdx)->NumUnits ;
2099
2109
assert (NumberOfInstances > 0 &&
2100
2110
" Cannot have zero instances of a ProcResource" );
2101
2111
2112
+ if (isUnbufferedGroup (PIdx)) {
2113
+ // If any subunits are used by the instruction, report that the resource
2114
+ // group is available at 0, effectively removing the group record from
2115
+ // hazarding and basing the hazarding decisions on the subunit records.
2116
+ // Otherwise, choose the first available instance from among the subunits.
2117
+ // Specifications which assign cycles to both the subunits and the group or
2118
+ // which use an unbuffered group with buffered subunits will appear to
2119
+ // schedule strangely. In the first case, the additional cycles for the
2120
+ // group will be ignored. In the second, the group will be ignored
2121
+ // entirely.
2122
+ for (const MCWriteProcResEntry &PE :
2123
+ make_range (SchedModel->getWriteProcResBegin (SC),
2124
+ SchedModel->getWriteProcResEnd (SC)))
2125
+ if (ResourceGroupSubUnitMasks[PIdx][PE.ProcResourceIdx ])
2126
+ return std::make_pair (0u , StartIndex);
2127
+
2128
+ auto SubUnits = SchedModel->getProcResource (PIdx)->SubUnitsIdxBegin ;
2129
+ for (unsigned I = 0 , End = NumberOfInstances; I < End; ++I) {
2130
+ unsigned NextUnreserved, NextInstanceIdx;
2131
+ std::tie (NextUnreserved, NextInstanceIdx) =
2132
+ getNextResourceCycle (SC, SubUnits[I], Cycles);
2133
+ if (MinNextUnreserved > NextUnreserved) {
2134
+ InstanceIdx = NextInstanceIdx;
2135
+ MinNextUnreserved = NextUnreserved;
2136
+ }
2137
+ }
2138
+ return std::make_pair (MinNextUnreserved, InstanceIdx);
2139
+ }
2140
+
2102
2141
for (unsigned I = StartIndex, End = StartIndex + NumberOfInstances; I < End;
2103
2142
++I) {
2104
2143
unsigned NextUnreserved = getNextResourceCycleByInstance (I, Cycles);
@@ -2152,7 +2191,7 @@ bool SchedBoundary::checkHazard(SUnit *SU) {
2152
2191
unsigned ResIdx = PE.ProcResourceIdx ;
2153
2192
unsigned Cycles = PE.Cycles ;
2154
2193
unsigned NRCycle, InstanceIdx;
2155
- std::tie (NRCycle, InstanceIdx) = getNextResourceCycle (ResIdx, Cycles);
2194
+ std::tie (NRCycle, InstanceIdx) = getNextResourceCycle (SC, ResIdx, Cycles);
2156
2195
if (NRCycle > CurrCycle) {
2157
2196
#ifndef NDEBUG
2158
2197
MaxObservedStall = std::max (Cycles, MaxObservedStall);
@@ -2302,8 +2341,8 @@ void SchedBoundary::incExecutedResources(unsigned PIdx, unsigned Count) {
2302
2341
// /
2303
2342
// / \return the next cycle at which the instruction may execute without
2304
2343
// / oversubscribing resources.
2305
- unsigned SchedBoundary::
2306
- countResource ( unsigned PIdx, unsigned Cycles, unsigned NextCycle) {
2344
+ unsigned SchedBoundary::countResource ( const MCSchedClassDesc *SC, unsigned PIdx,
2345
+ unsigned Cycles, unsigned NextCycle) {
2307
2346
unsigned Factor = SchedModel->getResourceFactor (PIdx);
2308
2347
unsigned Count = Factor * Cycles;
2309
2348
LLVM_DEBUG (dbgs () << " " << SchedModel->getResourceName (PIdx) << " +"
@@ -2325,7 +2364,7 @@ countResource(unsigned PIdx, unsigned Cycles, unsigned NextCycle) {
2325
2364
}
2326
2365
// For reserved resources, record the highest cycle using the resource.
2327
2366
unsigned NextAvailable, InstanceIdx;
2328
- std::tie (NextAvailable, InstanceIdx) = getNextResourceCycle (PIdx, Cycles);
2367
+ std::tie (NextAvailable, InstanceIdx) = getNextResourceCycle (SC, PIdx, Cycles);
2329
2368
if (NextAvailable > CurrCycle) {
2330
2369
LLVM_DEBUG (dbgs () << " Resource conflict: "
2331
2370
<< SchedModel->getResourceName (PIdx)
@@ -2405,7 +2444,7 @@ void SchedBoundary::bumpNode(SUnit *SU) {
2405
2444
PI = SchedModel->getWriteProcResBegin (SC),
2406
2445
PE = SchedModel->getWriteProcResEnd (SC); PI != PE; ++PI) {
2407
2446
unsigned RCycle =
2408
- countResource (PI->ProcResourceIdx , PI->Cycles , NextCycle);
2447
+ countResource (SC, PI->ProcResourceIdx , PI->Cycles , NextCycle);
2409
2448
if (RCycle > NextCycle)
2410
2449
NextCycle = RCycle;
2411
2450
}
@@ -2420,7 +2459,8 @@ void SchedBoundary::bumpNode(SUnit *SU) {
2420
2459
unsigned PIdx = PI->ProcResourceIdx ;
2421
2460
if (SchedModel->getProcResource (PIdx)->BufferSize == 0 ) {
2422
2461
unsigned ReservedUntil, InstanceIdx;
2423
- std::tie (ReservedUntil, InstanceIdx) = getNextResourceCycle (PIdx, 0 );
2462
+ std::tie (ReservedUntil, InstanceIdx) =
2463
+ getNextResourceCycle (SC, PIdx, 0 );
2424
2464
if (isTop ()) {
2425
2465
ReservedCycles[InstanceIdx] =
2426
2466
std::max (ReservedUntil, NextCycle + PI->Cycles );
0 commit comments