unsigned MicroOpFactor; // Multiply to normalize microops to resource units.
unsigned ResourceLCM; // Resource units per cycle. Latency normalization factor.
public:
- TargetSchedModel(): STI(nullptr), TII(nullptr) {}
+ TargetSchedModel(): SchedModel(MCSchedModel::GetDefaultSchedModel()), STI(nullptr), TII(nullptr) {}
/// \brief Initialize the machine model for instruction scheduling.
///
///
class InstrItineraryData {
public:
- const MCSchedModel *SchedModel; ///< Basic machine properties.
+ MCSchedModel SchedModel; ///< Basic machine properties.
const InstrStage *Stages; ///< Array of stages selected
const unsigned *OperandCycles; ///< Array of operand cycles selected
const unsigned *Forwardings; ///< Array of pipeline forwarding pathes
/// Ctors.
///
- InstrItineraryData() : SchedModel(&MCSchedModel::DefaultSchedModel),
+ InstrItineraryData() : SchedModel(MCSchedModel::GetDefaultSchedModel()),
Stages(nullptr), OperandCycles(nullptr),
Forwardings(nullptr), Itineraries(nullptr) {}
- InstrItineraryData(const MCSchedModel *SM, const InstrStage *S,
+ InstrItineraryData(const MCSchedModel &SM, const InstrStage *S,
const unsigned *OS, const unsigned *F)
: SchedModel(SM), Stages(S), OperandCycles(OS), Forwardings(F),
- Itineraries(SchedModel->InstrItineraries) {}
+ Itineraries(SchedModel.InstrItineraries) {}
/// isEmpty - Returns true if there are no itineraries.
///
/// provides a detailed reservation table describing each cycle of instruction
/// execution. Subtargets may define any or all of the above categories of data
/// depending on the type of CPU and selected scheduler.
-class MCSchedModel {
-public:
- static MCSchedModel DefaultSchedModel; // For unknown processors.
-
+struct MCSchedModel {
// IssueWidth is the maximum number of instructions that may be scheduled in
// the same per-cycle group.
unsigned IssueWidth;
bool CompleteModel;
-private:
unsigned ProcID;
const MCProcResourceDesc *ProcResourceTable;
const MCSchedClassDesc *SchedClassTable;
friend class InstrItineraryData;
const InstrItinerary *InstrItineraries;
-public:
- // Default's must be specified as static const literals so that tablegenerated
- // target code can use it in static initializers. The defaults need to be
- // initialized in this default ctor because some clients directly instantiate
- // MCSchedModel instead of using a generated itinerary.
- MCSchedModel(): IssueWidth(DefaultIssueWidth),
- MicroOpBufferSize(DefaultMicroOpBufferSize),
- LoopMicroOpBufferSize(DefaultLoopMicroOpBufferSize),
- LoadLatency(DefaultLoadLatency),
- HighLatency(DefaultHighLatency),
- MispredictPenalty(DefaultMispredictPenalty),
- PostRAScheduler(false), CompleteModel(true),
- ProcID(0), ProcResourceTable(nullptr),
- SchedClassTable(nullptr), NumProcResourceKinds(0),
- NumSchedClasses(0), InstrItineraries(nullptr) {
- (void)NumProcResourceKinds;
- (void)NumSchedClasses;
- }
-
- // Table-gen driven ctor.
- MCSchedModel(unsigned iw, int mbs, int lmbs, unsigned ll, unsigned hl,
- unsigned mp, bool postRASched, bool cm, unsigned pi,
- const MCProcResourceDesc *pr, const MCSchedClassDesc *sc,
- unsigned npr, unsigned nsc, const InstrItinerary *ii):
- IssueWidth(iw), MicroOpBufferSize(mbs), LoopMicroOpBufferSize(lmbs),
- LoadLatency(ll), HighLatency(hl),
- MispredictPenalty(mp), PostRAScheduler(postRASched),
- CompleteModel(cm), ProcID(pi),
- ProcResourceTable(pr), SchedClassTable(sc), NumProcResourceKinds(npr),
- NumSchedClasses(nsc), InstrItineraries(ii) {}
-
unsigned getProcessorID() const { return ProcID; }
/// Does this machine model include instruction-level scheduling.
assert(SchedClassIdx < NumSchedClasses && "bad scheduling class idx");
return &SchedClassTable[SchedClassIdx];
}
+
+ // /\brief Returns a default initialiszed mdoel. Used for unknown processors.
+ static MCSchedModel GetDefaultSchedModel() {
+ return { DefaultIssueWidth,
+ DefaultMicroOpBufferSize,
+ DefaultLoopMicroOpBufferSize,
+ DefaultLoadLatency,
+ DefaultHighLatency,
+ DefaultMispredictPenalty,
+ false,
+ true,
+ 0,
+ nullptr,
+ nullptr,
+ 0,
+ 0,
+ nullptr
+ };
+ }
};
} // End llvm namespace
const MCWriteProcResEntry *WriteProcResTable;
const MCWriteLatencyEntry *WriteLatencyTable;
const MCReadAdvanceEntry *ReadAdvanceTable;
- const MCSchedModel *CPUSchedModel;
+ MCSchedModel CPUSchedModel;
const InstrStage *Stages; // Instruction itinerary stages
const unsigned *OperandCycles; // Itinerary operand cycles
/// getSchedModelForCPU - Get the machine model of a CPU.
///
- const MCSchedModel *getSchedModelForCPU(StringRef CPU) const;
+ MCSchedModel getSchedModelForCPU(StringRef CPU) const;
/// getSchedModel - Get the machine model for this subtarget's CPU.
///
- const MCSchedModel *getSchedModel() const { return CPUSchedModel; }
+ const MCSchedModel &getSchedModel() const { return CPUSchedModel; }
/// Return an iterator at the first process resource consumed by the given
/// scheduling class.
class MachineRegisterInfo;
class MDNode;
class MCInst;
-class MCSchedModel;
+struct MCSchedModel;
class MCSymbolRefExpr;
class SDNode;
class ScheduleHazardRecognizer;
SDNode *Node) const;
/// Return the default expected latency for a def based on it's opcode.
- unsigned defaultDefLatency(const MCSchedModel *SchedModel,
+ unsigned defaultDefLatency(const MCSchedModel &SchedModel,
const MachineInstr *DefMI) const;
int computeDefOperandLatency(const InstrItineraryData *ItinData,
const TargetSubtargetInfo *ST = &TM->getSubtarget<TargetSubtargetInfo>();
if (PartialUnrollingThreshold.getNumOccurrences() > 0)
MaxOps = PartialUnrollingThreshold;
- else if (ST->getSchedModel()->LoopMicroOpBufferSize > 0)
- MaxOps = ST->getSchedModel()->LoopMicroOpBufferSize;
+ else if (ST->getSchedModel().LoopMicroOpBufferSize > 0)
+ MaxOps = ST->getSchedModel().LoopMicroOpBufferSize;
else
return;
class EarlyIfConverter : public MachineFunctionPass {
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
- const MCSchedModel *SchedModel;
+ MCSchedModel SchedModel;
MachineRegisterInfo *MRI;
MachineDominatorTree *DomTree;
MachineLoopInfo *Loops;
FBBTrace.getCriticalPath());
// Set a somewhat arbitrary limit on the critical path extension we accept.
- unsigned CritLimit = SchedModel->MispredictPenalty/2;
+ unsigned CritLimit = SchedModel.MispredictPenalty/2;
// If-conversion only makes sense when there is unexploited ILP. Compute the
// maximum-ILP resource length of the trace after if-conversion. Compare it
const TargetSubtargetInfo &ST =
MF.getTarget().getSubtarget<TargetSubtargetInfo>();
- SchedModel.init(*ST.getSchedModel(), &ST, TII);
+ SchedModel.init(ST.getSchedModel(), &ST, TII);
if (!TII) return false;
class MachineCombiner : public MachineFunctionPass {
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
- const MCSchedModel *SchedModel;
+ MCSchedModel SchedModel;
MachineRegisterInfo *MRI;
MachineTraceMetrics *Traces;
MachineTraceMetrics::Ensemble *MinInstr;
for (auto *InstrPtr : Instrs) {
unsigned Opc = InstrPtr->getOpcode();
unsigned Idx = TII->get(Opc).getSchedClass();
- const MCSchedClassDesc *SC = SchedModel->getSchedClassDesc(Idx);
+ const MCSchedClassDesc *SC = SchedModel.getSchedClassDesc(Idx);
InstrsSC.push_back(SC);
}
}
TII = STI.getInstrInfo();
TRI = STI.getRegisterInfo();
SchedModel = STI.getSchedModel();
- TSchedModel.init(*SchedModel, &STI, TII);
+ TSchedModel.init(SchedModel, &STI, TII);
MRI = &MF.getRegInfo();
Traces = &getAnalysis<MachineTraceMetrics>();
MinInstr = 0;
Loops = &getAnalysis<MachineLoopInfo>();
const TargetSubtargetInfo &ST =
MF->getTarget().getSubtarget<TargetSubtargetInfo>();
- SchedModel.init(*ST.getSchedModel(), &ST, TII);
+ SchedModel.init(ST.getSchedModel(), &ST, TII);
BlockInfo.resize(MF->getNumBlockIDs());
ProcResourceCycles.resize(MF->getNumBlockIDs() *
SchedModel.getNumProcResourceKinds());
"Virtual registers must be removed prior to PostRA scheduling");
const TargetSubtargetInfo &ST = TM.getSubtarget<TargetSubtargetInfo>();
- SchedModel.init(*ST.getSchedModel(), &ST, TII);
+ SchedModel.init(ST.getSchedModel(), &ST, TII);
}
/// getUnderlyingObjectFromInt - This is the function that does the work of
DEBUG(dbgs() << "Disabled scoreboard hazard recognizer\n");
else {
// A nonempty itinerary must have a SchedModel.
- IssueWidth = ItinData->SchedModel->IssueWidth;
+ IssueWidth = ItinData->SchedModel.IssueWidth;
DEBUG(dbgs() << "Using scoreboard hazard recognizer: Depth = "
<< ScoreboardDepth << '\n');
}
// If packet is now full, reset the state so in the next cycle
// we start fresh.
- if (Packet.size() >= InstrItins->SchedModel->IssueWidth) {
+ if (Packet.size() >= InstrItins->SchedModel.IssueWidth) {
ResourcesModel->clearResources();
Packet.clear();
}
}
/// Return the default expected latency for a def based on it's opcode.
-unsigned TargetInstrInfo::defaultDefLatency(const MCSchedModel *SchedModel,
+unsigned TargetInstrInfo::defaultDefLatency(const MCSchedModel &SchedModel,
const MachineInstr *DefMI) const {
if (DefMI->isTransient())
return 0;
if (DefMI->mayLoad())
- return SchedModel->LoadLatency;
+ return SchedModel.LoadLatency;
if (isHighLatencyDef(DefMI->getOpcode()))
- return SchedModel->HighLatency;
+ return SchedModel.HighLatency;
return 1;
}
const MachineInstr *UseMI, unsigned UseOperIdx) const {
if (!hasInstrSchedModel() && !hasInstrItineraries())
- return TII->defaultDefLatency(&SchedModel, DefMI);
+ return TII->defaultDefLatency(SchedModel, DefMI);
if (hasInstrItineraries()) {
int OperLatency = 0;
// applicable to the InstrItins model. InstrSchedModel should model all
// special cases without TII hooks.
InstrLatency = std::max(InstrLatency,
- TII->defaultDefLatency(&SchedModel, DefMI));
+ TII->defaultDefLatency(SchedModel, DefMI));
return InstrLatency;
}
// hasInstrSchedModel()
// FIXME: Automatically giving all implicit defs defaultDefLatency is
// undesirable. We should only do it for defs that are known to the MC
// desc like flags. Truly implicit defs should get 1 cycle latency.
- return DefMI->isTransient() ? 0 : TII->defaultDefLatency(&SchedModel, DefMI);
+ return DefMI->isTransient() ? 0 : TII->defaultDefLatency(SchedModel, DefMI);
}
unsigned TargetSchedModel::computeInstrLatency(unsigned Opcode) const {
return Latency;
}
}
- return TII->defaultDefLatency(&SchedModel, MI);
+ return TII->defaultDefLatency(SchedModel, MI);
}
unsigned TargetSchedModel::
static int getLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
// Try to compute scheduling information.
const MCSubtargetInfo *STI = DC->getSubtargetInfo();
- const MCSchedModel *SCModel = STI->getSchedModel();
+ const MCSchedModel SCModel = STI->getSchedModel();
const int NoInformationAvailable = -1;
// Check if we have a scheduling model for instructions.
- if (!SCModel || !SCModel->hasInstrSchedModel())
- // Try to fall back to the itinerary model if we do not have a
- // scheduling model.
+ if (!SCModel.hasInstrSchedModel())
+ // Try to fall back to the itinerary model if the scheduling model doesn't
+ // have a scheduling table. Note the default does not have a table.
return getItineraryLatency(DC, Inst);
// Get the scheduling class of the requested instruction.
const MCInstrDesc& Desc = DC->getInstrInfo()->get(Inst.getOpcode());
unsigned SCClass = Desc.getSchedClass();
- const MCSchedClassDesc *SCDesc = SCModel->getSchedClassDesc(SCClass);
+ const MCSchedClassDesc *SCDesc = SCModel.getSchedClassDesc(SCClass);
// Resolving the variant SchedClass requires an MI to pass to
// SubTargetInfo::resolveSchedClass.
if (!SCDesc || !SCDesc->isValid() || SCDesc->isVariant())
using namespace llvm;
-MCSchedModel MCSchedModel::DefaultSchedModel; // For unknown processors.
-
/// InitMCProcessorInfo - Set or change the CPU (optionally supplemented
/// with feature string). Recompute feature bits and scheduling model.
void
if (!CPU.empty())
CPUSchedModel = getSchedModelForCPU(CPU);
else
- CPUSchedModel = &MCSchedModel::DefaultSchedModel;
+ CPUSchedModel = MCSchedModel::GetDefaultSchedModel();
}
void
}
-const MCSchedModel *
+MCSchedModel
MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const {
assert(ProcSchedModels && "Processor machine model not available!");
errs() << "'" << CPU
<< "' is not a recognized processor for this target"
<< " (ignoring processor)\n";
- return &MCSchedModel::DefaultSchedModel;
+ return MCSchedModel::GetDefaultSchedModel();
}
assert(Found->Value && "Missing processor SchedModel value");
- return (const MCSchedModel *)Found->Value;
+ return *(const MCSchedModel *)Found->Value;
}
InstrItineraryData
MCSubtargetInfo::getInstrItineraryForCPU(StringRef CPU) const {
- const MCSchedModel *SchedModel = getSchedModelForCPU(CPU);
+ const MCSchedModel SchedModel = getSchedModelForCPU(CPU);
return InstrItineraryData(SchedModel, Stages, OperandCycles, ForwardingPaths);
}
class AArch64ConditionalCompares : public MachineFunctionPass {
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
- const MCSchedModel *SchedModel;
+ MCSchedModel SchedModel;
// Does the proceeded function has Oz attribute.
bool MinSize;
MachineRegisterInfo *MRI;
// the cost of a misprediction.
//
// Set a limit on the delay we will accept.
- unsigned DelayLimit = SchedModel->MispredictPenalty * 3 / 4;
+ unsigned DelayLimit = SchedModel.MispredictPenalty * 3 / 4;
// Instruction depths can be computed for all trace instructions above CmpBB.
unsigned HeadDepth =
MRI = &MF->getRegInfo();
const TargetSubtargetInfo &ST =
MF->getTarget().getSubtarget<TargetSubtargetInfo>();
- SchedModel.init(*ST.getSchedModel(), &ST, TII);
+ SchedModel.init(ST.getSchedModel(), &ST, TII);
Traces = &getAnalysis<MachineTraceMetrics>();
MinInstr = nullptr;
}
unsigned ARMSubtarget::getMispredictionPenalty() const {
- return SchedModel->MispredictPenalty;
+ return SchedModel.MispredictPenalty;
}
bool ARMSubtarget::hasSinCos() const {
Triple TargetTriple;
/// SchedModel - Processor specific instruction costs.
- const MCSchedModel *SchedModel;
+ MCSchedModel SchedModel;
/// Selected instruction itineraries (one entry per itinerary class.)
InstrItineraryData InstrItins;
}
bool TargetSubtargetInfo::enablePostMachineScheduler() const {
- return getSchedModel()->PostRAScheduler;
+ return getSchedModel().PostRAScheduler;
}
bool TargetSubtargetInfo::useAA() const {
// Begin processor itinerary properties
OS << "\n";
- OS << "static const llvm::MCSchedModel " << PI->ModelName << "(\n";
+ OS << "static const llvm::MCSchedModel " << PI->ModelName << " = {\n";
EmitProcessorProp(OS, PI->ModelDef, "IssueWidth", ',');
EmitProcessorProp(OS, PI->ModelDef, "MicroOpBufferSize", ',');
EmitProcessorProp(OS, PI->ModelDef, "LoopMicroOpBufferSize", ',');
- SchedModels.schedClassBegin()) << ",\n";
else
OS << " 0, 0, 0, 0, // No instruction-level machine model.\n";
- if (SchedModels.hasItineraries())
- OS << " " << PI->ItinsDef->getName() << ");\n";
+ if (PI->hasItineraries())
+ OS << " " << PI->ItinsDef->getName() << "};\n";
else
- OS << " 0); // No Itinerary\n";
+ OS << " nullptr}; // No Itinerary\n";
}
}