diff options
Diffstat (limited to 'llvm/tools/llvm-mca/InstrBuilder.cpp')
-rw-r--r-- | llvm/tools/llvm-mca/InstrBuilder.cpp | 40 |
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> |