Skip to content

Commit 97ed076

Browse files
committed
[MCA] Fix wrong definition of ResourceUnitMask in DefaultResourceStrategy.
Field ResourceUnitMask was incorrectly defined as a 'const unsigned' mask. It should have been a 64 bit quantity instead. That means, ResourceUnitMask was always implicitly truncated to a 32 bit quantity. This issue has been found by inspection. Surprisingly, that bug was latent, and it never negatively affected any existing upstream targets. This patch fixes the wrong definition of ResourceUnitMask, and adds a bunch of extra debug prints to help debugging potential issues related to invalid processor resource masks. llvm-svn: 350820
1 parent 73af3d4 commit 97ed076

File tree

11 files changed

+52
-32
lines changed

11 files changed

+52
-32
lines changed

llvm/include/llvm/MCA/HardwareUnits/ResourceManager.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class DefaultResourceStrategy final : public ResourceStrategy {
7272
///
7373
/// There is one bit set for every available resource unit.
7474
/// It defaults to the value of field ResourceSizeMask in ResourceState.
75-
const unsigned ResourceUnitMask;
75+
const uint64_t ResourceUnitMask;
7676

7777
/// A simple round-robin selector for processor resource units.
7878
/// Each bit of this mask identifies a sub resource within a group.
@@ -335,13 +335,13 @@ class ResourceManager {
335335
// Used to quickly identify groups that own a particular resource unit.
336336
std::vector<uint64_t> Resource2Groups;
337337

338+
// A table to map processor resource IDs to processor resource masks.
339+
SmallVector<uint64_t, 8> ProcResID2Mask;
340+
338341
// Keeps track of which resources are busy, and how many cycles are left
339342
// before those become usable again.
340343
SmallDenseMap<ResourceRef, unsigned> BusyResources;
341344

342-
// A table to map processor resource IDs to processor resource masks.
343-
SmallVector<uint64_t, 8> ProcResID2Mask;
344-
345345
// Returns the actual resource unit that will be used.
346346
ResourceRef selectPipe(uint64_t ResourceID);
347347

llvm/include/llvm/MCA/Instruction.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ class WriteState {
138138
public:
139139
WriteState(const WriteDescriptor &Desc, unsigned RegID,
140140
bool clearsSuperRegs = false, bool writesZero = false)
141-
: WD(&Desc), CyclesLeft(UNKNOWN_CYCLES), RegisterID(RegID),
142-
PRFID(0), ClearsSuperRegs(clearsSuperRegs), WritesZero(writesZero),
141+
: WD(&Desc), CyclesLeft(UNKNOWN_CYCLES), RegisterID(RegID), PRFID(0),
142+
ClearsSuperRegs(clearsSuperRegs), WritesZero(writesZero),
143143
IsEliminated(false), DependentWrite(nullptr), PartialWrite(nullptr),
144144
DependentWriteCyclesLeft(0) {}
145145

@@ -155,7 +155,9 @@ class WriteState {
155155
void addUser(ReadState *Use, int ReadAdvance);
156156
void addUser(WriteState *Use);
157157

158-
unsigned getDependentWriteCyclesLeft() const { return DependentWriteCyclesLeft; }
158+
unsigned getDependentWriteCyclesLeft() const {
159+
return DependentWriteCyclesLeft;
160+
}
159161

160162
unsigned getNumUsers() const {
161163
unsigned NumUsers = Users.size();
@@ -348,11 +350,6 @@ struct InstrDesc {
348350
InstrDesc() = default;
349351
InstrDesc(const InstrDesc &Other) = delete;
350352
InstrDesc &operator=(const InstrDesc &Other) = delete;
351-
352-
#ifndef NDEBUG
353-
// Original instruction name for debugging purposes.
354-
StringRef Name;
355-
#endif
356353
};
357354

358355
/// Base class for instructions consumed by the simulation pipeline.
@@ -551,4 +548,4 @@ class WriteRef {
551548
} // namespace mca
552549
} // namespace llvm
553550

554-
#endif // LLVM_MCA_INSTRUCTION_H
551+
#endif // LLVM_MCA_INSTRUCTION_H

llvm/include/llvm/MCA/Stages/ExecuteStage.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class ExecuteStage final : public Stage {
6565

6666
void notifyInstructionIssued(
6767
const InstRef &IR,
68-
ArrayRef<std::pair<ResourceRef, ResourceCycles>> Used) const;
68+
MutableArrayRef<std::pair<ResourceRef, ResourceCycles>> Used) const;
6969
void notifyInstructionExecuted(const InstRef &IR) const;
7070
void notifyInstructionReady(const InstRef &IR) const;
7171
void notifyResourceAvailable(const ResourceRef &RR) const;

llvm/include/llvm/MCA/Stages/InstructionTables.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ class InstructionTables final : public Stage {
3232
SmallVector<uint64_t, 8> Masks;
3333

3434
public:
35-
InstructionTables(const MCSchedModel &Model) : Stage(), SM(Model) {
35+
InstructionTables(const MCSchedModel &Model)
36+
: Stage(), SM(Model), Masks(Model.getNumProcResourceKinds()) {
3637
computeProcResourceMasks(Model, Masks);
3738
}
3839

llvm/include/llvm/MCA/Support.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class ResourceCycles {
104104
/// Resource masks are used by the ResourceManager to solve set membership
105105
/// problems with simple bit manipulation operations.
106106
void computeProcResourceMasks(const MCSchedModel &SM,
107-
SmallVectorImpl<uint64_t> &Masks);
107+
MutableArrayRef<uint64_t> Masks);
108108

109109
/// Compute the reciprocal block throughput from a set of processor resource
110110
/// cycles. The reciprocal block throughput is computed as the MAX between:

llvm/lib/MCA/HardwareUnits/ResourceManager.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ getStrategyFor(const ResourceState &RS) {
118118
ResourceManager::ResourceManager(const MCSchedModel &SM)
119119
: Resources(SM.getNumProcResourceKinds()),
120120
Strategies(SM.getNumProcResourceKinds()),
121-
Resource2Groups(SM.getNumProcResourceKinds(), 0) {
121+
Resource2Groups(SM.getNumProcResourceKinds(), 0),
122+
ProcResID2Mask(SM.getNumProcResourceKinds()) {
122123
computeProcResourceMasks(SM, ProcResID2Mask);
123124

124125
for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
@@ -283,9 +284,6 @@ void ResourceManager::issueInstruction(
283284
ResourceRef Pipe = selectPipe(R.first);
284285
use(Pipe);
285286
BusyResources[Pipe] += CS.size();
286-
// Replace the resource mask with a valid processor resource index.
287-
const ResourceState &RS = *Resources[getResourceStateIndex(Pipe.first)];
288-
Pipe.first = RS.getProcResourceID();
289287
Pipes.emplace_back(std::pair<ResourceRef, ResourceCycles>(
290288
Pipe, ResourceCycles(CS.size())));
291289
} else {

llvm/lib/MCA/InstrBuilder.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ InstrBuilder::InstrBuilder(const llvm::MCSubtargetInfo &sti,
3131
const llvm::MCInstrAnalysis *mcia)
3232
: STI(sti), MCII(mcii), MRI(mri), MCIA(mcia), FirstCallInst(true),
3333
FirstReturnInst(true) {
34+
const MCSchedModel &SM = STI.getSchedModel();
35+
ProcResourceMasks.resize(SM.getNumProcResourceKinds());
3436
computeProcResourceMasks(STI.getSchedModel(), ProcResourceMasks);
3537
}
3638

@@ -178,8 +180,8 @@ static void initializeUsedResources(InstrDesc &ID,
178180

179181
LLVM_DEBUG({
180182
for (const std::pair<uint64_t, ResourceUsage> &R : ID.Resources)
181-
dbgs() << "\t\tMask=" << format_hex(R.first, 16) << ", " <<
182-
"cy=" << R.second.size() << '\n';
183+
dbgs() << "\t\tMask=" << format_hex(R.first, 16) << ", "
184+
<< "cy=" << R.second.size() << '\n';
183185
for (const uint64_t R : ID.Buffers)
184186
dbgs() << "\t\tBuffer Mask=" << format_hex(R, 16) << '\n';
185187
});
@@ -525,6 +527,9 @@ InstrBuilder::createInstrDescImpl(const MCInst &MCI) {
525527
MCI);
526528
}
527529

530+
LLVM_DEBUG(dbgs() << "\n\t\tOpcode Name= " << MCII.getName(Opcode) << '\n');
531+
LLVM_DEBUG(dbgs() << "\t\tSchedClassID=" << SchedClassID << '\n');
532+
528533
// Create a new empty descriptor.
529534
std::unique_ptr<InstrDesc> ID = llvm::make_unique<InstrDesc>();
530535
ID->NumMicroOps = SCDesc.NumMicroOps;
@@ -559,9 +564,6 @@ InstrBuilder::createInstrDescImpl(const MCInst &MCI) {
559564
populateWrites(*ID, MCI, SchedClassID);
560565
populateReads(*ID, MCI, SchedClassID);
561566

562-
#ifndef NDEBUG
563-
ID->Name = MCII.getName(Opcode);
564-
#endif
565567
LLVM_DEBUG(dbgs() << "\t\tMaxLatency=" << ID->MaxLatency << '\n');
566568
LLVM_DEBUG(dbgs() << "\t\tNumMicroOps=" << ID->NumMicroOps << '\n');
567569

llvm/lib/MCA/Pipeline.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,13 @@ void Pipeline::appendStage(std::unique_ptr<Stage> S) {
8383
}
8484

8585
void Pipeline::notifyCycleBegin() {
86-
LLVM_DEBUG(dbgs() << "[E] Cycle begin: " << Cycles << '\n');
86+
LLVM_DEBUG(dbgs() << "\n[E] Cycle begin: " << Cycles << '\n');
8787
for (HWEventListener *Listener : Listeners)
8888
Listener->onCycleBegin();
8989
}
9090

9191
void Pipeline::notifyCycleEnd() {
92-
LLVM_DEBUG(dbgs() << "[E] Cycle end: " << Cycles << "\n\n");
92+
LLVM_DEBUG(dbgs() << "[E] Cycle end: " << Cycles << "\n");
9393
for (HWEventListener *Listener : Listeners)
9494
Listener->onCycleEnd();
9595
}

llvm/lib/MCA/Stages/ExecuteStage.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Error ExecuteStage::issueInstruction(InstRef &IR) {
5757
HWS.issueInstruction(IR, Used, Ready);
5858

5959
notifyReservedOrReleasedBuffers(IR, /* Reserved */ false);
60+
6061
notifyInstructionIssued(IR, Used);
6162
if (IR.getInstruction()->isExecuted()) {
6263
notifyInstructionExecuted(IR);
@@ -184,7 +185,7 @@ void ExecuteStage::notifyResourceAvailable(const ResourceRef &RR) const {
184185

185186
void ExecuteStage::notifyInstructionIssued(
186187
const InstRef &IR,
187-
ArrayRef<std::pair<ResourceRef, ResourceCycles>> Used) const {
188+
MutableArrayRef<std::pair<ResourceRef, ResourceCycles>> Used) const {
188189
LLVM_DEBUG({
189190
dbgs() << "[E] Instruction Issued: #" << IR << '\n';
190191
for (const std::pair<ResourceRef, ResourceCycles> &Resource : Used) {
@@ -193,6 +194,11 @@ void ExecuteStage::notifyInstructionIssued(
193194
dbgs() << "cycles: " << Resource.second << '\n';
194195
}
195196
});
197+
198+
// Replace resource masks with valid resource processor IDs.
199+
for (std::pair<ResourceRef, ResourceCycles> &Use : Used)
200+
Use.first.first = HWS.getResourceID(Use.first.first);
201+
196202
notifyEvent<HWInstructionEvent>(HWInstructionIssuedEvent(IR, Used));
197203
}
198204

llvm/lib/MCA/Support.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,18 @@
1919
namespace llvm {
2020
namespace mca {
2121

22+
#define DEBUG_TYPE "llvm-mca"
23+
2224
void computeProcResourceMasks(const MCSchedModel &SM,
23-
SmallVectorImpl<uint64_t> &Masks) {
25+
MutableArrayRef<uint64_t> Masks) {
2426
unsigned ProcResourceID = 0;
2527

28+
assert(Masks.size() == SM.getNumProcResourceKinds() &&
29+
"Invalid number of elements");
30+
// Resource at index 0 is the 'InvalidUnit'. Set an invalid mask for it.
31+
Masks[0] = 0;
32+
2633
// Create a unique bitmask for every processor resource unit.
27-
// Skip resource at index 0, since it always references 'InvalidUnit'.
28-
Masks.resize(SM.getNumProcResourceKinds());
2934
for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
3035
const MCProcResourceDesc &Desc = *SM.getProcResource(I);
3136
if (Desc.SubUnitsIdxBegin)
@@ -46,6 +51,16 @@ void computeProcResourceMasks(const MCSchedModel &SM,
4651
}
4752
ProcResourceID++;
4853
}
54+
55+
#ifndef NDEBUG
56+
LLVM_DEBUG(dbgs() << "\nProcessor resource masks:"
57+
<< "\n");
58+
for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
59+
const MCProcResourceDesc &Desc = *SM.getProcResource(I);
60+
LLVM_DEBUG(dbgs() << '[' << I << "] " << Desc.Name << " - " << Masks[I]
61+
<< '\n');
62+
}
63+
#endif
4964
}
5065

5166
double computeBlockRThroughput(const MCSchedModel &SM, unsigned DispatchWidth,

llvm/tools/llvm-mca/Views/SummaryView.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ SummaryView::SummaryView(const MCSchedModel &Model, ArrayRef<MCInst> S,
2727
unsigned Width)
2828
: SM(Model), Source(S), DispatchWidth(Width), LastInstructionIdx(0),
2929
TotalCycles(0), NumMicroOps(0),
30-
ProcResourceUsage(Model.getNumProcResourceKinds(), 0) {
30+
ProcResourceUsage(Model.getNumProcResourceKinds(), 0),
31+
ProcResourceMasks(Model.getNumProcResourceKinds()) {
3132
computeProcResourceMasks(SM, ProcResourceMasks);
3233
}
3334

0 commit comments

Comments
 (0)