summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-mca
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-mca')
-rw-r--r--llvm/tools/llvm-mca/InstrBuilder.cpp40
-rw-r--r--llvm/tools/llvm-mca/InstrBuilder.h3
-rw-r--r--llvm/tools/llvm-mca/InstructionInfoView.cpp11
3 files changed, 38 insertions, 16 deletions
diff --git a/llvm/tools/llvm-mca/InstrBuilder.cpp b/llvm/tools/llvm-mca/InstrBuilder.cpp
index a745e1a6150..8a66a76605f 100644
--- a/llvm/tools/llvm-mca/InstrBuilder.cpp
+++ b/llvm/tools/llvm-mca/InstrBuilder.cpp
@@ -396,18 +396,22 @@ const InstrDesc &InstrBuilder::createInstrDescImpl(const MCInst &MCI) {
// Then obtain the scheduling class information from the instruction.
unsigned SchedClassID = MCDesc.getSchedClass();
- const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
+ unsigned CPUID = SM.getProcessorID();
+
+ // Try to solve variant scheduling classes.
+ if (SchedClassID) {
+ while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant())
+ SchedClassID = STI.resolveVariantSchedClass(SchedClassID, &MCI, CPUID);
+
+ if (!SchedClassID)
+ llvm::report_fatal_error("unable to resolve this variant class.");
+ }
// Create a new empty descriptor.
std::unique_ptr<InstrDesc> ID = llvm::make_unique<InstrDesc>();
- if (SCDesc.isVariant()) {
- WithColor::warning() << "don't know how to model variant opcodes.\n";
- WithColor::note() << "assume 1 micro opcode.\n";
- ID->NumMicroOps = 1U;
- } else {
- ID->NumMicroOps = SCDesc.NumMicroOps;
- }
+ const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
+ ID->NumMicroOps = SCDesc.NumMicroOps;
if (MCDesc.isCall()) {
// We don't correctly model calls.
@@ -435,14 +439,24 @@ const InstrDesc &InstrBuilder::createInstrDescImpl(const MCInst &MCI) {
LLVM_DEBUG(dbgs() << "\t\tNumMicroOps=" << ID->NumMicroOps << '\n');
// Now add the new descriptor.
- Descriptors[Opcode] = std::move(ID);
- return *Descriptors[Opcode];
+ SchedClassID = MCDesc.getSchedClass();
+ if (!SM.getSchedClassDesc(SchedClassID)->isVariant()) {
+ Descriptors[MCI.getOpcode()] = std::move(ID);
+ return *Descriptors[MCI.getOpcode()];
+ }
+
+ VariantDescriptors[&MCI] = std::move(ID);
+ return *VariantDescriptors[&MCI];
}
const InstrDesc &InstrBuilder::getOrCreateInstrDesc(const MCInst &MCI) {
- if (Descriptors.find_as(MCI.getOpcode()) == Descriptors.end())
- return createInstrDescImpl(MCI);
- return *Descriptors[MCI.getOpcode()];
+ if (Descriptors.find_as(MCI.getOpcode()) != Descriptors.end())
+ return *Descriptors[MCI.getOpcode()];
+
+ if (VariantDescriptors.find(&MCI) != VariantDescriptors.end())
+ return *VariantDescriptors[&MCI];
+
+ return createInstrDescImpl(MCI);
}
std::unique_ptr<Instruction>
diff --git a/llvm/tools/llvm-mca/InstrBuilder.h b/llvm/tools/llvm-mca/InstrBuilder.h
index c22b7dcdbc6..146e917eb62 100644
--- a/llvm/tools/llvm-mca/InstrBuilder.h
+++ b/llvm/tools/llvm-mca/InstrBuilder.h
@@ -40,9 +40,10 @@ class InstrBuilder {
llvm::SmallVector<uint64_t, 8> ProcResourceMasks;
llvm::DenseMap<unsigned short, std::unique_ptr<const InstrDesc>> Descriptors;
+ llvm::DenseMap<const llvm::MCInst *, std::unique_ptr<const InstrDesc>>
+ VariantDescriptors;
const InstrDesc &createInstrDescImpl(const llvm::MCInst &MCI);
-
InstrBuilder(const InstrBuilder &) = delete;
InstrBuilder &operator=(const InstrBuilder &) = delete;
diff --git a/llvm/tools/llvm-mca/InstructionInfoView.cpp b/llvm/tools/llvm-mca/InstructionInfoView.cpp
index 76d63d21cb2..3b1e4dc8188 100644
--- a/llvm/tools/llvm-mca/InstructionInfoView.cpp
+++ b/llvm/tools/llvm-mca/InstructionInfoView.cpp
@@ -36,9 +36,16 @@ void InstructionInfoView::printView(raw_ostream &OS) const {
for (unsigned I = 0, E = Instructions; I < E; ++I) {
const MCInst &Inst = Source.getMCInstFromIndex(I);
const MCInstrDesc &MCDesc = MCII.get(Inst.getOpcode());
- const MCSchedClassDesc &SCDesc =
- *SM.getSchedClassDesc(MCDesc.getSchedClass());
+ // Obtain the scheduling class information from the instruction.
+ unsigned SchedClassID = MCDesc.getSchedClass();
+ unsigned CPUID = SM.getProcessorID();
+
+ // Try to solve variant scheduling classes.
+ while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant())
+ SchedClassID = STI.resolveVariantSchedClass(SchedClassID, &Inst, CPUID);
+
+ const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
unsigned NumMicroOpcodes = SCDesc.NumMicroOps;
unsigned Latency = MCSchedModel::computeInstrLatency(STI, SCDesc);
Optional<double> RThroughput =
OpenPOWER on IntegriCloud