Skip to content

Commit 91bdf24

Browse files
committed
[llvm-mca] Account for buffered resources when analyzing "Super" resources.
This was noticed when working on PR3946. By construction, a group cannot be used as a "Super" resource. That constraint is enforced by method `SubtargetEmitter::ExpandProcResource()`. A Super resource S can be part of a group G. However, method `SubtargetEmitter::ExpandProcResource()` would not update the number of consumed resource cycles in G based on S. In practice, this is perfectly fine because the resource usage is correctly computed for processor resource units. However, llvm-mca should still check if G is a buffered resource. Before this patch, llvm-mca didn't correctly check if S was part of a group that defines a buffer. So, the instruction descriptor was not correctly set. For now, the semantic change introduced by this patch doesn't affect any of the upstream scheduling models. However, it will allow to make some progress on PR3946. llvm-svn: 346545
1 parent dfc08ba commit 91bdf24

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

llvm/tools/llvm-mca/lib/InstrBuilder.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,15 @@ static void initializeUsedResources(InstrDesc &ID,
5555
// part of a "Super" resource. The key value is the "Super" resource mask ID.
5656
DenseMap<uint64_t, unsigned> SuperResources;
5757

58+
unsigned NumProcResources = SM.getNumProcResourceKinds();
59+
APInt Buffers(NumProcResources, 0);
60+
5861
for (unsigned I = 0, E = SCDesc.NumWriteProcResEntries; I < E; ++I) {
5962
const MCWriteProcResEntry *PRE = STI.getWriteProcResBegin(&SCDesc) + I;
6063
const MCProcResourceDesc &PR = *SM.getProcResource(PRE->ProcResourceIdx);
6164
uint64_t Mask = ProcResourceMasks[PRE->ProcResourceIdx];
6265
if (PR.BufferSize != -1)
63-
ID.Buffers.push_back(Mask);
66+
Buffers.setBit(PRE->ProcResourceIdx);
6467
CycleSegment RCy(0, PRE->Cycles, false);
6568
Worklist.emplace_back(ResourcePlusCycles(Mask, ResourceUsage(RCy)));
6669
if (PR.SuperIdx) {
@@ -138,6 +141,30 @@ static void initializeUsedResources(InstrDesc &ID,
138141
}
139142
}
140143

144+
// Identify extra buffers that are consumed through super resources.
145+
for (const std::pair<uint64_t, unsigned> &SR : SuperResources) {
146+
for (unsigned I = 1, E = NumProcResources; I < E; ++I) {
147+
const MCProcResourceDesc &PR = *SM.getProcResource(I);
148+
if (PR.BufferSize == -1)
149+
continue;
150+
151+
uint64_t Mask = ProcResourceMasks[I];
152+
if (Mask != SR.first && ((Mask & SR.first) == SR.first))
153+
Buffers.setBit(I);
154+
}
155+
}
156+
157+
// Now set the buffers.
158+
if (unsigned NumBuffers = Buffers.countPopulation()) {
159+
ID.Buffers.resize(NumBuffers);
160+
for (unsigned I = 0, E = NumProcResources; I < E && NumBuffers; ++I) {
161+
if (Buffers[I]) {
162+
--NumBuffers;
163+
ID.Buffers[NumBuffers] = ProcResourceMasks[I];
164+
}
165+
}
166+
}
167+
141168
LLVM_DEBUG({
142169
for (const std::pair<uint64_t, ResourceUsage> &R : ID.Resources)
143170
dbgs() << "\t\tMask=" << R.first << ", cy=" << R.second.size() << '\n';

0 commit comments

Comments
 (0)