summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2018-11-09 19:30:20 +0000
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2018-11-09 19:30:20 +0000
commit91bdf24cfdcba93fda1872c8c68186cf4118a442 (patch)
treea2b9a8741145d5560b78abfd43bbf9ee780544c8
parentdfc08baceb5af96bf931c1471d5234da846dc7ab (diff)
downloadbcm5719-llvm-91bdf24cfdcba93fda1872c8c68186cf4118a442.tar.gz
bcm5719-llvm-91bdf24cfdcba93fda1872c8c68186cf4118a442.zip
[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
-rw-r--r--llvm/tools/llvm-mca/lib/InstrBuilder.cpp29
1 files changed, 28 insertions, 1 deletions
diff --git a/llvm/tools/llvm-mca/lib/InstrBuilder.cpp b/llvm/tools/llvm-mca/lib/InstrBuilder.cpp
index 535ad4d57fe..c7345e7b976 100644
--- a/llvm/tools/llvm-mca/lib/InstrBuilder.cpp
+++ b/llvm/tools/llvm-mca/lib/InstrBuilder.cpp
@@ -55,12 +55,15 @@ static void initializeUsedResources(InstrDesc &ID,
// part of a "Super" resource. The key value is the "Super" resource mask ID.
DenseMap<uint64_t, unsigned> SuperResources;
+ unsigned NumProcResources = SM.getNumProcResourceKinds();
+ APInt Buffers(NumProcResources, 0);
+
for (unsigned I = 0, E = SCDesc.NumWriteProcResEntries; I < E; ++I) {
const MCWriteProcResEntry *PRE = STI.getWriteProcResBegin(&SCDesc) + I;
const MCProcResourceDesc &PR = *SM.getProcResource(PRE->ProcResourceIdx);
uint64_t Mask = ProcResourceMasks[PRE->ProcResourceIdx];
if (PR.BufferSize != -1)
- ID.Buffers.push_back(Mask);
+ Buffers.setBit(PRE->ProcResourceIdx);
CycleSegment RCy(0, PRE->Cycles, false);
Worklist.emplace_back(ResourcePlusCycles(Mask, ResourceUsage(RCy)));
if (PR.SuperIdx) {
@@ -138,6 +141,30 @@ static void initializeUsedResources(InstrDesc &ID,
}
}
+ // Identify extra buffers that are consumed through super resources.
+ for (const std::pair<uint64_t, unsigned> &SR : SuperResources) {
+ for (unsigned I = 1, E = NumProcResources; I < E; ++I) {
+ const MCProcResourceDesc &PR = *SM.getProcResource(I);
+ if (PR.BufferSize == -1)
+ continue;
+
+ uint64_t Mask = ProcResourceMasks[I];
+ if (Mask != SR.first && ((Mask & SR.first) == SR.first))
+ Buffers.setBit(I);
+ }
+ }
+
+ // Now set the buffers.
+ if (unsigned NumBuffers = Buffers.countPopulation()) {
+ ID.Buffers.resize(NumBuffers);
+ for (unsigned I = 0, E = NumProcResources; I < E && NumBuffers; ++I) {
+ if (Buffers[I]) {
+ --NumBuffers;
+ ID.Buffers[NumBuffers] = ProcResourceMasks[I];
+ }
+ }
+ }
+
LLVM_DEBUG({
for (const std::pair<uint64_t, ResourceUsage> &R : ID.Resources)
dbgs() << "\t\tMask=" << R.first << ", cy=" << R.second.size() << '\n';
OpenPOWER on IntegriCloud