Change MCSchedModel to be a struct of statically initialized data.

This removes static initializers from the backends which generate this data, and also makes this struct match the other Tablegen generated structs in behaviour

Reviewed by Andy Trick and Chandler C

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216919 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Pete Cooper 2014-09-02 17:43:54 +00:00
parent ac31076b11
commit 6de6c6aae4
23 changed files with 69 additions and 87 deletions

View File

@ -41,7 +41,7 @@ class TargetSchedModel {
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.
///

View File

@ -110,7 +110,7 @@ struct InstrItinerary {
///
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
@ -118,14 +118,14 @@ public:
/// 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.
///

View File

@ -133,10 +133,7 @@ struct MCSchedClassDesc {
/// 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;
@ -191,7 +188,6 @@ public:
bool CompleteModel;
private:
unsigned ProcID;
const MCProcResourceDesc *ProcResourceTable;
const MCSchedClassDesc *SchedClassTable;
@ -201,37 +197,6 @@ private:
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.
@ -258,6 +223,25 @@ public:
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

View File

@ -36,7 +36,7 @@ class MCSubtargetInfo {
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
@ -86,11 +86,11 @@ public:
/// 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.

View File

@ -31,7 +31,7 @@ class MachineMemOperand;
class MachineRegisterInfo;
class MDNode;
class MCInst;
class MCSchedModel;
struct MCSchedModel;
class MCSymbolRefExpr;
class SDNode;
class ScheduleHazardRecognizer;
@ -1032,7 +1032,7 @@ public:
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,

View File

@ -229,8 +229,8 @@ void BasicTTI::getUnrollingPreferences(Loop *L,
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;

View File

@ -580,7 +580,7 @@ namespace {
class EarlyIfConverter : public MachineFunctionPass {
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
const MCSchedModel *SchedModel;
MCSchedModel SchedModel;
MachineRegisterInfo *MRI;
MachineDominatorTree *DomTree;
MachineLoopInfo *Loops;
@ -688,7 +688,7 @@ bool EarlyIfConverter::shouldConvertIf() {
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

View File

@ -281,7 +281,7 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
const TargetSubtargetInfo &ST =
MF.getTarget().getSubtarget<TargetSubtargetInfo>();
SchedModel.init(*ST.getSchedModel(), &ST, TII);
SchedModel.init(ST.getSchedModel(), &ST, TII);
if (!TII) return false;

View File

@ -38,7 +38,7 @@ namespace {
class MachineCombiner : public MachineFunctionPass {
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
const MCSchedModel *SchedModel;
MCSchedModel SchedModel;
MachineRegisterInfo *MRI;
MachineTraceMetrics *Traces;
MachineTraceMetrics::Ensemble *MinInstr;
@ -260,7 +260,7 @@ void MachineCombiner::instr2instrSC(
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);
}
}
@ -411,7 +411,7 @@ bool MachineCombiner::runOnMachineFunction(MachineFunction &MF) {
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;

View File

@ -58,7 +58,7 @@ bool MachineTraceMetrics::runOnMachineFunction(MachineFunction &Func) {
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());

View File

@ -63,7 +63,7 @@ ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf,
"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

View File

@ -78,7 +78,7 @@ ScoreboardHazardRecognizer(const InstrItineraryData *II,
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');
}

View File

@ -320,7 +320,7 @@ void ResourcePriorityQueue::reserveResources(SUnit *SU) {
// 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();
}

View File

@ -746,14 +746,14 @@ TargetInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData,
}
/// 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;
}

View File

@ -157,7 +157,7 @@ unsigned TargetSchedModel::computeOperandLatency(
const MachineInstr *UseMI, unsigned UseOperIdx) const {
if (!hasInstrSchedModel() && !hasInstrItineraries())
return TII->defaultDefLatency(&SchedModel, DefMI);
return TII->defaultDefLatency(SchedModel, DefMI);
if (hasInstrItineraries()) {
int OperLatency = 0;
@ -181,7 +181,7 @@ unsigned TargetSchedModel::computeOperandLatency(
// 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()
@ -222,7 +222,7 @@ unsigned TargetSchedModel::computeOperandLatency(
// 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 {
@ -270,7 +270,7 @@ TargetSchedModel::computeInstrLatency(const MachineInstr *MI,
return Latency;
}
}
return TII->defaultDefLatency(&SchedModel, MI);
return TII->defaultDefLatency(SchedModel, MI);
}
unsigned TargetSchedModel::

View File

@ -202,19 +202,19 @@ static int getItineraryLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
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())

View File

@ -17,8 +17,6 @@
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
@ -33,7 +31,7 @@ MCSubtargetInfo::InitCPUSchedModel(StringRef CPU) {
if (!CPU.empty())
CPUSchedModel = getSchedModelForCPU(CPU);
else
CPUSchedModel = &MCSchedModel::DefaultSchedModel;
CPUSchedModel = MCSchedModel::GetDefaultSchedModel();
}
void
@ -78,7 +76,7 @@ uint64_t MCSubtargetInfo::ToggleFeature(StringRef FS) {
}
const MCSchedModel *
MCSchedModel
MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const {
assert(ProcSchedModels && "Processor machine model not available!");
@ -97,15 +95,15 @@ MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const {
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);
}

View File

@ -723,7 +723,7 @@ namespace {
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;
@ -845,7 +845,7 @@ bool AArch64ConditionalCompares::shouldConvert() {
// 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 =

View File

@ -123,7 +123,7 @@ bool AArch64StorePairSuppress::runOnMachineFunction(MachineFunction &mf) {
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;

View File

@ -415,7 +415,7 @@ ARMSubtarget::GVIsIndirectSymbol(const GlobalValue *GV,
}
unsigned ARMSubtarget::getMispredictionPenalty() const {
return SchedModel->MispredictPenalty;
return SchedModel.MispredictPenalty;
}
bool ARMSubtarget::hasSinCos() const {

View File

@ -219,7 +219,7 @@ protected:
Triple TargetTriple;
/// SchedModel - Processor specific instruction costs.
const MCSchedModel *SchedModel;
MCSchedModel SchedModel;
/// Selected instruction itineraries (one entry per itinerary class.)
InstrItineraryData InstrItins;

View File

@ -53,7 +53,7 @@ bool TargetSubtargetInfo::enableRALocalReassignment(
}
bool TargetSubtargetInfo::enablePostMachineScheduler() const {
return getSchedModel()->PostRAScheduler;
return getSchedModel().PostRAScheduler;
}
bool TargetSubtargetInfo::useAA() const {

View File

@ -1192,7 +1192,7 @@ void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) {
// 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", ',');
@ -1217,10 +1217,10 @@ void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) {
- 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";
}
}