summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-mca/InstrBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-mca/InstrBuilder.cpp')
-rw-r--r--llvm/tools/llvm-mca/InstrBuilder.cpp40
1 files changed, 27 insertions, 13 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>
OpenPOWER on IntegriCloud