llvm-project/llvm/lib/MC/MCSchedule.cpp

153 lines
5.7 KiB
C++
Raw Normal View History

//===- MCSchedule.cpp - Scheduling ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the default scheduling model.
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCSchedule.h"
[MCSchedule] Add the ability to compute the latency and throughput information for MCInst. This patch extends the MCSchedModel API with new methods that can be used to obtain the latency and reciprocal througput information for an MCInst. Scheduling models have recently gained the ability to resolve variant scheduling classes associated with MCInst objects. Before, models were only able to resolve a variant scheduling class from a MachineInstr object. This patch is mainly required by D47374 to avoid regressing a pair of x86 specific -print-schedule tests for btver2. Patch D47374 introduces a new variant class to teach the btver scheduling model (x86 target) how to correctly compute the latency profile for some zero-idioms using the new scheduling predicates. The new methods added by this patch would be mainly used by llc when flag -print-schedule is specified. In particular, tests that contain inline assembly require that code is parsed at code emission stage into a sequence of MCInst. That forces the print-schedule functionality to query the latency/rthroughput information for MCInst instructions too. If we don't expose this new API, then we lose "-print-schedule" test coverage as soon as variant scheduling classes are added to the x86 models. The tablegen SubtargetEmitter changes teaches how to query latency profile information using a object that derives from TargetSubtargetInfo. Note that this should really have been part of r333286. To avoid code duplication, the logic that "resolves" variant scheduling classes for MCInst, has been moved to a common place in MC. That logic is used by the "resolveVariantSchedClass" methods redefined in override by the tablegen'd GenSubtargetInfo classes. Differential Revision: https://reviews.llvm.org/D47536 llvm-svn: 333650
2018-05-31 21:30:42 +08:00
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include <type_traits>
using namespace llvm;
static_assert(std::is_pod<MCSchedModel>::value,
"We shouldn't have a static constructor here");
const MCSchedModel MCSchedModel::Default = {DefaultIssueWidth,
DefaultMicroOpBufferSize,
DefaultLoopMicroOpBufferSize,
DefaultLoadLatency,
DefaultHighLatency,
DefaultMispredictPenalty,
false,
true,
0,
nullptr,
nullptr,
0,
0,
nullptr,
nullptr};
int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI,
const MCSchedClassDesc &SCDesc) {
int Latency = 0;
for (unsigned DefIdx = 0, DefEnd = SCDesc.NumWriteLatencyEntries;
DefIdx != DefEnd; ++DefIdx) {
// Lookup the definition's write latency in SubtargetInfo.
const MCWriteLatencyEntry *WLEntry =
STI.getWriteLatencyEntry(&SCDesc, DefIdx);
// Early exit if we found an invalid latency.
if (WLEntry->Cycles < 0)
return WLEntry->Cycles;
Latency = std::max(Latency, static_cast<int>(WLEntry->Cycles));
}
return Latency;
}
int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI,
unsigned SchedClass) const {
const MCSchedClassDesc &SCDesc = *getSchedClassDesc(SchedClass);
if (!SCDesc.isValid())
return 0;
if (!SCDesc.isVariant())
return MCSchedModel::computeInstrLatency(STI, SCDesc);
llvm_unreachable("unsupported variant scheduling class");
}
[MCSchedule] Add the ability to compute the latency and throughput information for MCInst. This patch extends the MCSchedModel API with new methods that can be used to obtain the latency and reciprocal througput information for an MCInst. Scheduling models have recently gained the ability to resolve variant scheduling classes associated with MCInst objects. Before, models were only able to resolve a variant scheduling class from a MachineInstr object. This patch is mainly required by D47374 to avoid regressing a pair of x86 specific -print-schedule tests for btver2. Patch D47374 introduces a new variant class to teach the btver scheduling model (x86 target) how to correctly compute the latency profile for some zero-idioms using the new scheduling predicates. The new methods added by this patch would be mainly used by llc when flag -print-schedule is specified. In particular, tests that contain inline assembly require that code is parsed at code emission stage into a sequence of MCInst. That forces the print-schedule functionality to query the latency/rthroughput information for MCInst instructions too. If we don't expose this new API, then we lose "-print-schedule" test coverage as soon as variant scheduling classes are added to the x86 models. The tablegen SubtargetEmitter changes teaches how to query latency profile information using a object that derives from TargetSubtargetInfo. Note that this should really have been part of r333286. To avoid code duplication, the logic that "resolves" variant scheduling classes for MCInst, has been moved to a common place in MC. That logic is used by the "resolveVariantSchedClass" methods redefined in override by the tablegen'd GenSubtargetInfo classes. Differential Revision: https://reviews.llvm.org/D47536 llvm-svn: 333650
2018-05-31 21:30:42 +08:00
int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI,
const MCInstrInfo &MCII,
const MCInst &Inst) const {
unsigned SchedClass = MCII.get(Inst.getOpcode()).getSchedClass();
const MCSchedClassDesc *SCDesc = getSchedClassDesc(SchedClass);
if (!SCDesc->isValid())
return 0;
unsigned CPUID = getProcessorID();
while (SCDesc->isVariant()) {
SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, CPUID);
SCDesc = getSchedClassDesc(SchedClass);
}
if (SchedClass)
return MCSchedModel::computeInstrLatency(STI, *SCDesc);
llvm_unreachable("unsupported variant scheduling class");
}
double
MCSchedModel::getReciprocalThroughput(const MCSubtargetInfo &STI,
const MCSchedClassDesc &SCDesc) {
Optional<double> Throughput;
const MCSchedModel &SM = STI.getSchedModel();
const MCWriteProcResEntry *I = STI.getWriteProcResBegin(&SCDesc);
const MCWriteProcResEntry *E = STI.getWriteProcResEnd(&SCDesc);
for (; I != E; ++I) {
if (!I->Cycles)
continue;
unsigned NumUnits = SM.getProcResource(I->ProcResourceIdx)->NumUnits;
double Temp = NumUnits * 1.0 / I->Cycles;
Throughput = Throughput ? std::min(Throughput.getValue(), Temp) : Temp;
}
if (Throughput.hasValue())
return 1.0 / Throughput.getValue();
// If no throughput value was calculated, assume that we can execute at the
// maximum issue width scaled by number of micro-ops for the schedule class.
return ((double)SCDesc.NumMicroOps) / SM.IssueWidth;
}
double
[MCSchedule] Add the ability to compute the latency and throughput information for MCInst. This patch extends the MCSchedModel API with new methods that can be used to obtain the latency and reciprocal througput information for an MCInst. Scheduling models have recently gained the ability to resolve variant scheduling classes associated with MCInst objects. Before, models were only able to resolve a variant scheduling class from a MachineInstr object. This patch is mainly required by D47374 to avoid regressing a pair of x86 specific -print-schedule tests for btver2. Patch D47374 introduces a new variant class to teach the btver scheduling model (x86 target) how to correctly compute the latency profile for some zero-idioms using the new scheduling predicates. The new methods added by this patch would be mainly used by llc when flag -print-schedule is specified. In particular, tests that contain inline assembly require that code is parsed at code emission stage into a sequence of MCInst. That forces the print-schedule functionality to query the latency/rthroughput information for MCInst instructions too. If we don't expose this new API, then we lose "-print-schedule" test coverage as soon as variant scheduling classes are added to the x86 models. The tablegen SubtargetEmitter changes teaches how to query latency profile information using a object that derives from TargetSubtargetInfo. Note that this should really have been part of r333286. To avoid code duplication, the logic that "resolves" variant scheduling classes for MCInst, has been moved to a common place in MC. That logic is used by the "resolveVariantSchedClass" methods redefined in override by the tablegen'd GenSubtargetInfo classes. Differential Revision: https://reviews.llvm.org/D47536 llvm-svn: 333650
2018-05-31 21:30:42 +08:00
MCSchedModel::getReciprocalThroughput(const MCSubtargetInfo &STI,
const MCInstrInfo &MCII,
const MCInst &Inst) const {
unsigned SchedClass = MCII.get(Inst.getOpcode()).getSchedClass();
const MCSchedClassDesc *SCDesc = getSchedClassDesc(SchedClass);
// If there's no valid class, assume that the instruction executes/completes
// at the maximum issue width.
[MCSchedule] Add the ability to compute the latency and throughput information for MCInst. This patch extends the MCSchedModel API with new methods that can be used to obtain the latency and reciprocal througput information for an MCInst. Scheduling models have recently gained the ability to resolve variant scheduling classes associated with MCInst objects. Before, models were only able to resolve a variant scheduling class from a MachineInstr object. This patch is mainly required by D47374 to avoid regressing a pair of x86 specific -print-schedule tests for btver2. Patch D47374 introduces a new variant class to teach the btver scheduling model (x86 target) how to correctly compute the latency profile for some zero-idioms using the new scheduling predicates. The new methods added by this patch would be mainly used by llc when flag -print-schedule is specified. In particular, tests that contain inline assembly require that code is parsed at code emission stage into a sequence of MCInst. That forces the print-schedule functionality to query the latency/rthroughput information for MCInst instructions too. If we don't expose this new API, then we lose "-print-schedule" test coverage as soon as variant scheduling classes are added to the x86 models. The tablegen SubtargetEmitter changes teaches how to query latency profile information using a object that derives from TargetSubtargetInfo. Note that this should really have been part of r333286. To avoid code duplication, the logic that "resolves" variant scheduling classes for MCInst, has been moved to a common place in MC. That logic is used by the "resolveVariantSchedClass" methods redefined in override by the tablegen'd GenSubtargetInfo classes. Differential Revision: https://reviews.llvm.org/D47536 llvm-svn: 333650
2018-05-31 21:30:42 +08:00
if (!SCDesc->isValid())
return 1.0 / IssueWidth;
[MCSchedule] Add the ability to compute the latency and throughput information for MCInst. This patch extends the MCSchedModel API with new methods that can be used to obtain the latency and reciprocal througput information for an MCInst. Scheduling models have recently gained the ability to resolve variant scheduling classes associated with MCInst objects. Before, models were only able to resolve a variant scheduling class from a MachineInstr object. This patch is mainly required by D47374 to avoid regressing a pair of x86 specific -print-schedule tests for btver2. Patch D47374 introduces a new variant class to teach the btver scheduling model (x86 target) how to correctly compute the latency profile for some zero-idioms using the new scheduling predicates. The new methods added by this patch would be mainly used by llc when flag -print-schedule is specified. In particular, tests that contain inline assembly require that code is parsed at code emission stage into a sequence of MCInst. That forces the print-schedule functionality to query the latency/rthroughput information for MCInst instructions too. If we don't expose this new API, then we lose "-print-schedule" test coverage as soon as variant scheduling classes are added to the x86 models. The tablegen SubtargetEmitter changes teaches how to query latency profile information using a object that derives from TargetSubtargetInfo. Note that this should really have been part of r333286. To avoid code duplication, the logic that "resolves" variant scheduling classes for MCInst, has been moved to a common place in MC. That logic is used by the "resolveVariantSchedClass" methods redefined in override by the tablegen'd GenSubtargetInfo classes. Differential Revision: https://reviews.llvm.org/D47536 llvm-svn: 333650
2018-05-31 21:30:42 +08:00
unsigned CPUID = getProcessorID();
while (SCDesc->isVariant()) {
SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, CPUID);
SCDesc = getSchedClassDesc(SchedClass);
}
if (SchedClass)
return MCSchedModel::getReciprocalThroughput(STI, *SCDesc);
llvm_unreachable("unsupported variant scheduling class");
}
double
MCSchedModel::getReciprocalThroughput(unsigned SchedClass,
const InstrItineraryData &IID) {
Optional<double> Throughput;
const InstrStage *I = IID.beginStage(SchedClass);
const InstrStage *E = IID.endStage(SchedClass);
for (; I != E; ++I) {
if (!I->getCycles())
continue;
double Temp = countPopulation(I->getUnits()) * 1.0 / I->getCycles();
Throughput = Throughput ? std::min(Throughput.getValue(), Temp) : Temp;
}
if (Throughput.hasValue())
return 1.0 / Throughput.getValue();
// If there are no execution resources specified for this class, then assume
// that it can execute at the maximum default issue width.
return 1.0 / DefaultIssueWidth;
}