24 #define DEBUG_TYPE "llvm-mca" 34 uint64_t &NextInSequenceMask) {
37 NextInSequenceMask &= (CandidateMask | (CandidateMask - 1));
43 uint64_t CandidateMask = ReadyMask & NextInSequenceMask;
45 return selectImpl(CandidateMask, NextInSequenceMask);
47 NextInSequenceMask = ResourceUnitMask ^ RemovedFromNextInSequence;
48 RemovedFromNextInSequence = 0;
49 CandidateMask = ReadyMask & NextInSequenceMask;
51 return selectImpl(CandidateMask, NextInSequenceMask);
53 NextInSequenceMask = ResourceUnitMask;
54 CandidateMask = ReadyMask & NextInSequenceMask;
55 return selectImpl(CandidateMask, NextInSequenceMask);
59 if (Mask > NextInSequenceMask) {
60 RemovedFromNextInSequence |=
Mask;
64 NextInSequenceMask &= (~Mask);
65 if (NextInSequenceMask)
68 NextInSequenceMask = ResourceUnitMask ^ RemovedFromNextInSequence;
69 RemovedFromNextInSequence = 0;
74 : ProcResourceDescIndex(Index), ResourceMask(Mask),
75 BufferSize(Desc.BufferSize), IsAGroup(
countPopulation(ResourceMask) > 1) {
80 ResourceSizeMask = (1ULL << Desc.
NumUnits) - 1;
82 ReadyMask = ResourceSizeMask;
83 AvailableSlots = BufferSize == -1 ? 0U :
static_cast<unsigned>(BufferSize);
103 <<
", SZMASK=" <<
format_hex(ResourceSizeMask, 16)
105 <<
", BufferSize=" << BufferSize
106 <<
", AvailableSlots=" << AvailableSlots
107 <<
", Reserved=" << Unavailable <<
'\n';
111 static std::unique_ptr<ResourceStrategy>
114 return llvm::make_unique<DefaultResourceStrategy>(RS.
getReadyMask());
115 return std::unique_ptr<ResourceStrategy>(
nullptr);
119 : Resources(SM.getNumProcResourceKinds()),
120 Strategies(SM.getNumProcResourceKinds()),
121 Resource2Groups(SM.getNumProcResourceKinds(), 0),
122 ProcResID2Mask(SM.getNumProcResourceKinds()) {
126 uint64_t
Mask = ProcResID2Mask[
I];
134 uint64_t
Mask = ProcResID2Mask[
I];
140 uint64_t GroupMaskIdx = 1ULL << (Index - 1);
141 Mask -= GroupMaskIdx;
146 Resource2Groups[IndexUnit] |= GroupMaskIdx;
152 void ResourceManager::setCustomStrategyImpl(std::unique_ptr<ResourceStrategy> S,
153 uint64_t ResourceMask) {
155 assert(Index < Resources.size() &&
"Invalid processor resource index!");
156 assert(S &&
"Unexpected null strategy in input!");
157 Strategies[
Index] = std::move(S);
164 unsigned ResourceManager::getNumUnits(uint64_t ResourceID)
const {
171 ResourceRef ResourceManager::selectPipe(uint64_t ResourceID) {
173 assert(Index < Resources.size() &&
"Invalid resource use!");
175 assert(RS.isReady() &&
"No available units to select!");
179 if (!RS.isAResourceGroup() && RS.getNumUnits() == 1)
180 return std::make_pair(ResourceID, RS.getReadyMask());
182 uint64_t SubResourceID = Strategies[
Index]->select(RS.getReadyMask());
183 if (RS.isAResourceGroup())
184 return selectPipe(SubResourceID);
185 return std::make_pair(ResourceID, SubResourceID);
196 Strategies[RSID]->used(RR.second);
204 uint64_t
Users = Resource2Groups[RSID];
210 Strategies[GroupIndex]->used(RR.first);
216 void ResourceManager::release(
const ResourceRef &RR) {
218 bool WasFullyUsed = !RS.
isReady();
223 for (std::unique_ptr<ResourceState> &Res : Resources) {
236 for (uint64_t Buffer : Buffers) {
246 for (
const uint64_t Buffer : Buffers) {
259 for (
const uint64_t R : Buffers)
265 Desc.
Resources, [&](
const std::pair<uint64_t, const ResourceUsage> &
E) {
266 unsigned NumUnits = E.second.isReserved() ? 0U : E.second.NumUnits;
267 unsigned Index = getResourceStateIndex(E.first);
268 return Resources[Index]->isReady(NumUnits);
275 for (
const std::pair<uint64_t, ResourceUsage> &R : Desc.
Resources) {
282 assert(CS.
begin() == 0 &&
"Invalid {Start, End} cycles!");
283 if (!R.second.isReserved()) {
286 BusyResources[Pipe] += CS.
size();
287 Pipes.emplace_back(std::pair<ResourceRef, ResourceCycles>(
292 assert(R.second.isReserved());
300 for (std::pair<ResourceRef, unsigned> &
BR : BusyResources) {
316 BusyResources.erase(RF);
bool isAResourceGroup() const
ResourceManager(const MCSchedModel &SM)
This class represents lattice values for constants.
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
void push_back(const T &Elt)
static uint64_t selectImpl(uint64_t CandidateMask, uint64_t &NextInSequenceMask)
void markSubResourceAsUsed(uint64_t ID)
const MCProcResourceDesc * getProcResource(unsigned ProcResourceIdx) const
bool containsResource(uint64_t ID) const
virtual ~ResourceStrategy()
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
iv Induction Variable Users
std::size_t countLeadingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the most significant bit to the least stopping at the first 1...
static std::unique_ptr< ResourceStrategy > getStrategyFor(const ResourceState &RS)
void reserveResource(uint64_t ResourceID)
uint64_t getResourceMask() const
void issueInstruction(const InstrDesc &Desc, SmallVectorImpl< std::pair< ResourceRef, ResourceCycles >> &Pipes)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void releaseBuffers(ArrayRef< uint64_t > Buffers)
unsigned getNumUnits() const
bool isReady(unsigned NumUnits=1) const
Returs true if this resource is not reserved, and if there are at least NumUnits available units...
void computeProcResourceMasks(const MCSchedModel &SM, MutableArrayRef< uint64_t > Masks)
Populates vector Masks with processor resource masks.
ResourceStateEvent isBufferAvailable() const
Checks if there is an available slot in the resource buffer.
void releaseResource(uint64_t ResourceID)
uint64_t getReadyMask() const
Control flow instructions. These all have token chains.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::pair< uint64_t, uint64_t > ResourceRef
A resource unit identifier.
bool isADispatchHazard() const
Returns true if this is an in-order dispatch/issue resource.
void reserveBuffer()
Reserve a slot in the buffer.
Helper functions used by various pipeline components.
SmallVector< std::pair< uint64_t, ResourceUsage >, 4 > Resources
ResourceStateEvent
Used to notify the internal state of a processor resource.
bool canBeIssued(const InstrDesc &Desc) const
unsigned countPopulation(T Value)
Count the number of set bits in a value.
void used(uint64_t Mask) override
Called by the ResourceManager when a processor resource group, or a processor resource with multiple ...
Define a kind of processor resource that will be modeled by the scheduler.
static unsigned getResourceStateIndex(uint64_t Mask)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
The classes here represent processor resource units and their management strategy.
This class represents the number of cycles per resource (fractions of cycles).
An instruction descriptor.
uint64_t select(uint64_t ReadyMask) override
Selects a processor resource unit from a ReadyMask.
A processor resource descriptor.
void cycleEvent(SmallVectorImpl< ResourceRef > &ResourcesFreed)
void releaseSubResource(uint64_t ID)
ResourceStateEvent canBeDispatched(ArrayRef< uint64_t > Buffers) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned resolveResourceMask(uint64_t Mask) const
Machine model for scheduling, bundling, and heuristics.
void reserveBuffers(ArrayRef< uint64_t > Buffers)
ResourceState(const MCProcResourceDesc &Desc, unsigned Index, uint64_t Mask)
unsigned getNumProcResourceKinds() const