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