Index: tools/llvm-mca/InstrBuilder.h =================================================================== --- tools/llvm-mca/InstrBuilder.h +++ tools/llvm-mca/InstrBuilder.h @@ -39,10 +39,10 @@ const llvm::MCInstrInfo &MCII; llvm::SmallVector ProcResourceMasks; - llvm::DenseMap> Descriptors; + llvm::DenseMap> + Descriptors; const InstrDesc &createInstrDescImpl(const llvm::MCInst &MCI); - InstrBuilder(const InstrBuilder &) = delete; InstrBuilder &operator=(const InstrBuilder &) = delete; Index: tools/llvm-mca/InstrBuilder.cpp =================================================================== --- tools/llvm-mca/InstrBuilder.cpp +++ tools/llvm-mca/InstrBuilder.cpp @@ -378,18 +378,23 @@ // Then obtain the scheduling class information from the instruction. unsigned SchedClassID = MCDesc.getSchedClass(); - const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID); + + // Try to solve variant scheduling classes. + while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant()) + SchedClassID = + STI.resolveVariantSchedClass(SchedClassID, &MCI, SM.getProcessorID()); + + const MCSchedClassDesc &SCDesc = + SchedClassID ? *SM.getSchedClassDesc(SchedClassID) + : *SM.getSchedClassDesc(MCDesc.getSchedClass()); // Create a new empty descriptor. std::unique_ptr ID = llvm::make_unique(); + if (SCDesc.isVariant()) + llvm::report_fatal_error( + "don't know how to resolve this variant scheduling class.\n"); - 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; - } + ID->NumMicroOps = SCDesc.NumMicroOps; if (MCDesc.isCall()) { // We don't correctly model calls. @@ -417,14 +422,15 @@ DEBUG(dbgs() << "\t\tNumMicroOps=" << ID->NumMicroOps << '\n'); // Now add the new descriptor. - Descriptors[Opcode] = std::move(ID); - return *Descriptors[Opcode]; + SchedClassID = MCDesc.getSchedClass(); + Descriptors[&MCI] = std::move(ID); + return *Descriptors[&MCI]; } const InstrDesc &InstrBuilder::getOrCreateInstrDesc(const MCInst &MCI) { - if (Descriptors.find_as(MCI.getOpcode()) == Descriptors.end()) + if (Descriptors.find(&MCI) == Descriptors.end()) return createInstrDescImpl(MCI); - return *Descriptors[MCI.getOpcode()]; + return *Descriptors[&MCI]; } std::unique_ptr Index: tools/llvm-mca/InstructionInfoView.cpp =================================================================== --- tools/llvm-mca/InstructionInfoView.cpp +++ tools/llvm-mca/InstructionInfoView.cpp @@ -33,8 +33,18 @@ for (unsigned I = 0, E = Instructions; I < E; ++I) { const MCInst &Inst = Source.getMCInstFromIndex(I); const MCInstrDesc &MCDesc = MCII.get(Inst.getOpcode()); + + // Obtain the scheduling class information from the instruction. + unsigned SchedClassID = MCDesc.getSchedClass(); + + // Try to solve variant scheduling classes. + while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant()) + SchedClassID = STI.resolveVariantSchedClass(SchedClassID, &Inst, + SM.getProcessorID()); + const MCSchedClassDesc &SCDesc = - *SM.getSchedClassDesc(MCDesc.getSchedClass()); + SchedClassID ? *SM.getSchedClassDesc(SchedClassID) + : *SM.getSchedClassDesc(MCDesc.getSchedClass()); unsigned NumMicroOpcodes = SCDesc.NumMicroOps; unsigned Latency = MCSchedModel::computeInstrLatency(STI, SCDesc);