Skip to content

Commit

Permalink
[TableGen] Rename ResourceCycles and StartAtCycle to clarify semantics
Browse files Browse the repository at this point in the history
D150312 added a TODO:

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.

This patch implements that TODO. This naming clarifies how to use these
fields in the scheduler. In addition it was confusing that `StartAtCycle` was
singular but `Cycles` was plural. This renaming fixes this inconsistency.

Differential Revision: https://reviews.llvm.org/D158568
  • Loading branch information
michaelmaitland committed Aug 24, 2023
1 parent be556ee commit 030d334
Show file tree
Hide file tree
Showing 80 changed files with 2,611 additions and 2,594 deletions.
73 changes: 37 additions & 36 deletions llvm/include/llvm/CodeGen/MachineScheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -656,15 +656,15 @@ class ResourceSegments {
///
/// 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 |
/// +--------+------------+------+
/// X0 X1 X1 X2 +--------+-------------+--------------+
/// |Resource|AcquireAtCycle|ReleaseAtCycle|
/// +--------+-------------+--------------+
/// | 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:
Expand All @@ -685,7 +685,7 @@ class ResourceSegments {
/// of an instruction that can be scheduled at cycle C in top-down
/// scheduling is:
///
/// [C+StartAtCycle, C+Cycles)
/// [C+AcquireAtCycle, C+ReleaseAtCycle)
///
///
/// # BOTTOM UP SCHEDULING
Expand All @@ -709,28 +709,28 @@ class ResourceSegments {
/// of an instruction that can be scheduled at cycle C in bottom-up
/// scheduling is:
///
/// [C-Cycle+1, C-StartAtCycle+1)
/// [C-ReleaseAtCycle+1, C-AcquireAtCycle+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);
/// resources is the value (ReleaseAtCycle - AcquireAtCycle).
static IntervalTy getResourceIntervalBottom(unsigned C, unsigned AcquireAtCycle,
unsigned ReleaseAtCycle) {
return std::make_pair<long, long>((long)C - (long)ReleaseAtCycle + 1L,
(long)C - (long)AcquireAtCycle + 1L);
}
static IntervalTy getResourceIntervalTop(unsigned C, unsigned StartAtCycle,
unsigned Cycle) {
return std::make_pair<long, long>((long)C + (long)StartAtCycle,
(long)C + (long)Cycle);
static IntervalTy getResourceIntervalTop(unsigned C, unsigned AcquireAtCycle,
unsigned ReleaseAtCycle) {
return std::make_pair<long, long>((long)C + (long)AcquireAtCycle,
(long)C + (long)ReleaseAtCycle);
}

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.
/// CurrCycle, \param AcquireAtCycle and \param ReleaseAtCycle.
///
/// The function then loops through the intervals in the ResourceSegments
/// and shifts the interval [a, b[ and the ReturnCycle to the
Expand All @@ -744,7 +744,7 @@ class ResourceSegments {
/// c 1 2 3 4 5 6 7 8 9 10 ... ---> (time
/// flow)
/// ResourceSegments... [---) [-------) [-----------)
/// c [1 3[ -> StartAtCycle=1, Cycles=3
/// c [1 3[ -> AcquireAtCycle=1, ReleaseAtCycle=3
/// ++c [1 3)
/// ++c [1 3)
/// ++c [1 3)
Expand Down Expand Up @@ -772,24 +772,25 @@ class ResourceSegments {
/// [*] 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;
unsigned getFirstAvailableAt(
unsigned CurrCycle, unsigned AcquireAtCycle, unsigned ReleaseAtCycle,
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,
unsigned AcquireAtCycle,
unsigned ReleaseAtCycle) const {
return getFirstAvailableAt(CurrCycle, AcquireAtCycle, ReleaseAtCycle,
getResourceIntervalBottom);
}
unsigned getFirstAvailableAtFromTop(unsigned CurrCycle, unsigned StartAtCycle,
unsigned Cycle) const {
return getFirstAvailableAt(CurrCycle, StartAtCycle, Cycle,
unsigned getFirstAvailableAtFromTop(unsigned CurrCycle,
unsigned AcquireAtCycle,
unsigned ReleaseAtCycle) const {
return getFirstAvailableAt(CurrCycle, AcquireAtCycle, ReleaseAtCycle,
getResourceIntervalTop);
}

Expand Down Expand Up @@ -1006,13 +1007,13 @@ class SchedBoundary {
unsigned getLatencyStallCycles(SUnit *SU);

unsigned getNextResourceCycleByInstance(unsigned InstanceIndex,
unsigned Cycles,
unsigned StartAtCycle);
unsigned ReleaseAtCycle,
unsigned AcquireAtCycle);

std::pair<unsigned, unsigned> getNextResourceCycle(const MCSchedClassDesc *SC,
unsigned PIdx,
unsigned Cycles,
unsigned StartAtCycle);
unsigned ReleaseAtCycle,
unsigned AcquireAtCycle);

bool isUnbufferedGroup(unsigned PIdx) const {
return SchedModel->getProcResource(PIdx)->SubUnitsIdxBegin &&
Expand Down
6 changes: 3 additions & 3 deletions llvm/include/llvm/CodeGen/MachineTraceMetrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class MachineTraceMetrics : public MachineFunctionPass {
/// The getResources() function above must have been called first.
///
/// These numbers have already been scaled by SchedModel.getResourceFactor().
ArrayRef<unsigned> getProcResourceCycles(unsigned MBBNum) const;
ArrayRef<unsigned> getProcReleaseAtCycles(unsigned MBBNum) const;

/// A virtual register or regunit required by a basic block or its trace
/// successors.
Expand Down Expand Up @@ -404,9 +404,9 @@ class MachineTraceMetrics : public MachineFunctionPass {
// Cycles consumed on each processor resource per block.
// The number of processor resource kinds is constant for a given subtarget,
// but it is not known at compile time. The number of cycles consumed by
// block B on processor resource R is at ProcResourceCycles[B*Kinds + R]
// block B on processor resource R is at ProcReleaseAtCycles[B*Kinds + R]
// where Kinds = SchedModel.getNumProcResourceKinds().
SmallVector<unsigned, 0> ProcResourceCycles;
SmallVector<unsigned, 0> ProcReleaseAtCycles;

// One ensemble per strategy.
Ensemble
Expand Down
19 changes: 8 additions & 11 deletions llvm/include/llvm/MC/MCSchedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,21 @@ 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.
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,
uint16_t ReleaseAtCycle;
/// Cycle at which the resource will be aquired by an instruction,
/// relatively to the cycle in which the instruction is issued
/// (assuming no stalls inbetween).
uint16_t StartAtCycle;
uint16_t AcquireAtCycle;

bool operator==(const MCWriteProcResEntry &Other) const {
return ProcResourceIdx == Other.ProcResourceIdx && Cycles == Other.Cycles &&
StartAtCycle == Other.StartAtCycle;
return ProcResourceIdx == Other.ProcResourceIdx &&
ReleaseAtCycle == Other.ReleaseAtCycle &&
AcquireAtCycle == Other.AcquireAtCycle;
}
};

Expand Down Expand Up @@ -226,12 +223,12 @@ struct MCExtraProcessorInfo {
/// consistent. Inaccuracies arise when instructions have different execution
/// delays relative to each other, in addition to their intrinsic latency. Those
/// special cases can be handled by TableGen constructs such as, ReadAdvance,
/// which reduces latency when reading data, and ResourceCycles, which consumes
/// which reduces latency when reading data, and ReleaseAtCycles, which consumes
/// a processor resource when writing data for a number of abstract
/// cycles.
///
/// TODO: One tool currently missing is the ability to add a delay to
/// ResourceCycles. That would be easy to add and would likely cover all cases
/// ReleaseAtCycles. That would be easy to add and would likely cover all cases
/// currently handled by the legacy itinerary tables.
///
/// A note on out-of-order execution and, more generally, instruction
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/MCA/HWEventListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class HWInstructionEvent {
// ResourceRef::second is a bitmask of the referenced sub-unit of the resource.
using ResourceRef = std::pair<uint64_t, uint64_t>;

using ResourceUse = std::pair<ResourceRef, ResourceCycles>;
using ResourceUse = std::pair<ResourceRef, ReleaseAtCycles>;

class HWInstructionIssuedEvent : public HWInstructionEvent {
public:
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/MCA/HardwareUnits/ResourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ class ResourceManager {

void issueInstruction(
const InstrDesc &Desc,
SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &Pipes);
SmallVectorImpl<std::pair<ResourceRef, ReleaseAtCycles>> &Pipes);

void cycleEvent(SmallVectorImpl<ResourceRef> &ResourcesFreed);

Expand Down
4 changes: 2 additions & 2 deletions llvm/include/llvm/MCA/HardwareUnits/Scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class Scheduler : public HardwareUnit {
/// Issue an instruction without updating the ready queue.
void issueInstructionImpl(
InstRef &IR,
SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &Pipes);
SmallVectorImpl<std::pair<ResourceRef, ReleaseAtCycles>> &Pipes);

// Identify instructions that have finished executing, and remove them from
// the IssuedSet. References to executed instructions are added to input
Expand Down Expand Up @@ -202,7 +202,7 @@ class Scheduler : public HardwareUnit {
/// result of this event.
void issueInstruction(
InstRef &IR,
SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &Used,
SmallVectorImpl<std::pair<ResourceRef, ReleaseAtCycles>> &Used,
SmallVectorImpl<InstRef> &Pending,
SmallVectorImpl<InstRef> &Ready);

Expand Down
10 changes: 5 additions & 5 deletions llvm/include/llvm/MCA/Support.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ template <typename T> char InstructionError<T>::ID;
/// number of resources, are kept separate. This is used by the
/// ResourcePressureView to calculate the average resource cycles
/// per instruction/iteration.
class ResourceCycles {
class ReleaseAtCycles {
unsigned Numerator, Denominator;

public:
ResourceCycles() : Numerator(0), Denominator(1) {}
ResourceCycles(unsigned Cycles, unsigned ResourceUnits = 1)
ReleaseAtCycles() : Numerator(0), Denominator(1) {}
ReleaseAtCycles(unsigned Cycles, unsigned ResourceUnits = 1)
: Numerator(Cycles), Denominator(ResourceUnits) {}

operator double() const {
Expand All @@ -67,7 +67,7 @@ class ResourceCycles {
// Add the components of RHS to this instance. Instead of calculating
// the final value here, we keep track of the numerator and denominator
// separately, to reduce floating point error.
ResourceCycles &operator+=(const ResourceCycles &RHS);
ReleaseAtCycles &operator+=(const ReleaseAtCycles &RHS);
};

/// Populates vector Masks with processor resource masks.
Expand Down Expand Up @@ -105,7 +105,7 @@ inline unsigned getResourceStateIndex(uint64_t Mask) {
/// Compute the reciprocal block throughput from a set of processor resource
/// cycles. The reciprocal block throughput is computed as the MAX between:
/// - NumMicroOps / DispatchWidth
/// - ProcResourceCycles / #ProcResourceUnits (for every consumed resource).
/// - ProcReleaseAtCycles / #ProcResourceUnits (for every consumed resource).
double computeBlockRThroughput(const MCSchedModel &SM, unsigned DispatchWidth,
unsigned NumMicroOps,
ArrayRef<unsigned> ProcResourceUsage);
Expand Down
20 changes: 13 additions & 7 deletions llvm/include/llvm/Target/TargetSchedule.td
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class ProcResourceKind;
// changes this to an in-order issue/dispatch resource. In this case,
// the scheduler counts down from the cycle that the instruction
// issues in-order, forcing a stall whenever a subsequent instruction
// requires the same resource until the number of ResourceCycles
// requires the same resource until the number of ReleaseAtCycles
// specified in WriteRes expire. Setting BufferSize=1 changes this to
// an in-order latency resource. In this case, the scheduler models
// producer/consumer stalls between instructions that use the
Expand Down Expand Up @@ -254,8 +254,14 @@ class WriteSequence<list<SchedWrite> writes, int rep = 1> : SchedWrite {
// SchedModel ties these resources to a processor.
class ProcWriteResources<list<ProcResourceKind> resources> {
list<ProcResourceKind> ProcResources = resources;
list<int> ResourceCycles = [];
list<int> StartAtCycles = [];
/// 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).
list<int> ReleaseAtCycles = [];
/// Cycle at which the resource will be aquired by an instruction,
/// relatively to the cycle in which the instruction is issued
/// (assuming no stalls inbetween).
list<int> AcquireAtCycles = [];
int Latency = 1;
int NumMicroOps = 1;
bit BeginGroup = false;
Expand Down Expand Up @@ -285,12 +291,12 @@ class ProcWriteResources<list<ProcResourceKind> resources> {
// itinerary classes to the subtarget's SchedWrites.
//
// ProcResources indicates the set of resources consumed by the write.
// Optionally, ResourceCycles indicates the number of cycles the
// resource is consumed. Each ResourceCycles item is paired with the
// ProcResource item at the same position in its list. ResourceCycles
// Optionally, ReleaseAtCycles indicates the number of cycles the
// resource is consumed. Each ReleaseAtCycles item is paired with the
// ProcResource item at the same position in its list. ReleaseAtCycles
// can be `[]`: in that case, all resources are consumed for a single
// cycle, regardless of latency, which models a fully pipelined processing
// unit. A value of 0 for ResourceCycles means that the resource must
// unit. A value of 0 for ReleaseAtCycles means that the resource must
// be available but is not consumed, which is only relevant for
// unbuffered resources.
//
Expand Down
12 changes: 6 additions & 6 deletions llvm/lib/CodeGen/MachinePipeliner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,7 @@ struct FuncUnitSorter {
for (const MCWriteProcResEntry &PRE :
make_range(STI->getWriteProcResBegin(SCDesc),
STI->getWriteProcResEnd(SCDesc))) {
if (!PRE.Cycles)
if (!PRE.ReleaseAtCycle)
continue;
const MCProcResourceDesc *ProcResource =
STI->getSchedModel().getProcResource(PRE.ProcResourceIdx);
Expand Down Expand Up @@ -1082,7 +1082,7 @@ struct FuncUnitSorter {
for (const MCWriteProcResEntry &PRE :
make_range(STI->getWriteProcResBegin(SCDesc),
STI->getWriteProcResEnd(SCDesc))) {
if (!PRE.Cycles)
if (!PRE.ReleaseAtCycle)
continue;
Resources[PRE.ProcResourceIdx]++;
}
Expand Down Expand Up @@ -3092,7 +3092,7 @@ void ResourceManager::reserveResources(const MCSchedClassDesc *SCDesc,
assert(!UseDFA);
for (const MCWriteProcResEntry &PRE : make_range(
STI->getWriteProcResBegin(SCDesc), STI->getWriteProcResEnd(SCDesc)))
for (int C = Cycle; C < Cycle + PRE.Cycles; ++C)
for (int C = Cycle; C < Cycle + PRE.ReleaseAtCycle; ++C)
++MRT[positiveModulo(C, InitiationInterval)][PRE.ProcResourceIdx];

for (int C = Cycle; C < Cycle + SCDesc->NumMicroOps; ++C)
Expand All @@ -3104,7 +3104,7 @@ void ResourceManager::unreserveResources(const MCSchedClassDesc *SCDesc,
assert(!UseDFA);
for (const MCWriteProcResEntry &PRE : make_range(
STI->getWriteProcResBegin(SCDesc), STI->getWriteProcResEnd(SCDesc)))
for (int C = Cycle; C < Cycle + PRE.Cycles; ++C)
for (int C = Cycle; C < Cycle + PRE.ReleaseAtCycle; ++C)
--MRT[positiveModulo(C, InitiationInterval)][PRE.ProcResourceIdx];

for (int C = Cycle; C < Cycle + SCDesc->NumMicroOps; ++C)
Expand Down Expand Up @@ -3220,10 +3220,10 @@ int ResourceManager::calculateResMII() const {
if (SwpDebugResource) {
const MCProcResourceDesc *Desc =
SM.getProcResource(PRE.ProcResourceIdx);
dbgs() << Desc->Name << ": " << PRE.Cycles << ", ";
dbgs() << Desc->Name << ": " << PRE.ReleaseAtCycle << ", ";
}
});
ResourceCount[PRE.ProcResourceIdx] += PRE.Cycles;
ResourceCount[PRE.ProcResourceIdx] += PRE.ReleaseAtCycle;
}
LLVM_DEBUG(if (SwpDebugResource) dbgs() << "\n");
}
Expand Down

0 comments on commit 030d334

Please sign in to comment.