mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 01:06:06 +00:00
[LLVM][TableGen] Change CodeGenSchedule to use const RecordKeeper (#108617)
Change CodeGenSchedule to use const RecordKeeper. This is a part of effort to have better const correctness in TableGen backends: https://discourse.llvm.org/t/psa-planned-changes-to-tablegen-getallderiveddefinitions-api-potential-downstream-breakages/81089
This commit is contained in:
parent
8837898b8d
commit
3ae71d154e
@ -1912,6 +1912,9 @@ public:
|
||||
/// vector of records, throwing an exception if the field does not exist or
|
||||
/// if the value is not the right type.
|
||||
std::vector<Record*> getValueAsListOfDefs(StringRef FieldName) const;
|
||||
// Temporary function to help staged migration to const Record pointers.
|
||||
std::vector<const Record *>
|
||||
getValueAsListOfConstDefs(StringRef FieldName) const;
|
||||
|
||||
/// This method looks up the specified field and returns its value as a
|
||||
/// vector of integers, throwing an exception if the field does not exist or
|
||||
|
@ -3027,6 +3027,21 @@ Record::getValueAsListOfDefs(StringRef FieldName) const {
|
||||
return Defs;
|
||||
}
|
||||
|
||||
std::vector<const Record *>
|
||||
Record::getValueAsListOfConstDefs(StringRef FieldName) const {
|
||||
ListInit *List = getValueAsListInit(FieldName);
|
||||
std::vector<const Record *> Defs;
|
||||
for (const Init *I : List->getValues()) {
|
||||
if (const DefInit *DI = dyn_cast<DefInit>(I))
|
||||
Defs.push_back(DI->getDef());
|
||||
else
|
||||
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
|
||||
FieldName +
|
||||
"' list is not entirely DefInit!");
|
||||
}
|
||||
return Defs;
|
||||
}
|
||||
|
||||
int64_t Record::getValueAsInt(StringRef FieldName) const {
|
||||
const RecordVal *R = getValue(FieldName);
|
||||
if (!R || !R->getValue())
|
||||
|
@ -182,7 +182,7 @@ struct InstRegexOp : public SetTheory::Operator {
|
||||
} // end anonymous namespace
|
||||
|
||||
/// CodeGenModels ctor interprets machine model records and populates maps.
|
||||
CodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK,
|
||||
CodeGenSchedModels::CodeGenSchedModels(const RecordKeeper &RK,
|
||||
const CodeGenTarget &TGT)
|
||||
: Records(RK), Target(TGT) {
|
||||
|
||||
@ -256,8 +256,7 @@ void CodeGenSchedModels::checkSTIPredicates() const {
|
||||
DenseMap<StringRef, const Record *> Declarations;
|
||||
|
||||
// There cannot be multiple declarations with the same name.
|
||||
const RecVec Decls = Records.getAllDerivedDefinitions("STIPredicateDecl");
|
||||
for (const Record *R : Decls) {
|
||||
for (const Record *R : Records.getAllDerivedDefinitions("STIPredicateDecl")) {
|
||||
StringRef Name = R->getValueAsString("Name");
|
||||
const auto It = Declarations.find(Name);
|
||||
if (It == Declarations.end()) {
|
||||
@ -270,9 +269,8 @@ void CodeGenSchedModels::checkSTIPredicates() const {
|
||||
}
|
||||
|
||||
// Disallow InstructionEquivalenceClasses with an empty instruction list.
|
||||
const RecVec Defs =
|
||||
Records.getAllDerivedDefinitions("InstructionEquivalenceClass");
|
||||
for (const Record *R : Defs) {
|
||||
for (const Record *R :
|
||||
Records.getAllDerivedDefinitions("InstructionEquivalenceClass")) {
|
||||
RecVec Opcodes = R->getValueAsListOfDefs("Opcodes");
|
||||
if (Opcodes.empty()) {
|
||||
PrintFatalError(R->getLoc(), "Invalid InstructionEquivalenceClass "
|
||||
@ -417,9 +415,7 @@ void CodeGenSchedModels::collectSTIPredicates() {
|
||||
// Map STIPredicateDecl records to elements of vector
|
||||
// CodeGenSchedModels::STIPredicates.
|
||||
DenseMap<const Record *, unsigned> Decl2Index;
|
||||
|
||||
RecVec RV = Records.getAllDerivedDefinitions("STIPredicate");
|
||||
for (const Record *R : RV) {
|
||||
for (const Record *R : Records.getAllDerivedDefinitions("STIPredicate")) {
|
||||
const Record *Decl = R->getValueAsDef("Declaration");
|
||||
|
||||
const auto It = Decl2Index.find(Decl);
|
||||
@ -454,13 +450,10 @@ void OpcodeInfo::addPredicateForProcModel(const llvm::APInt &CpuMask,
|
||||
}
|
||||
|
||||
void CodeGenSchedModels::checkMCInstPredicates() const {
|
||||
RecVec MCPredicates = Records.getAllDerivedDefinitions("TIIPredicate");
|
||||
if (MCPredicates.empty())
|
||||
return;
|
||||
|
||||
// A target cannot have multiple TIIPredicate definitions with a same name.
|
||||
llvm::StringMap<const Record *> TIIPredicates(MCPredicates.size());
|
||||
for (const Record *TIIPred : MCPredicates) {
|
||||
llvm::StringMap<const Record *> TIIPredicates;
|
||||
for (const Record *TIIPred :
|
||||
Records.getAllDerivedDefinitions("TIIPredicate")) {
|
||||
StringRef Name = TIIPred->getValueAsString("FunctionName");
|
||||
StringMap<const Record *>::const_iterator It = TIIPredicates.find(Name);
|
||||
if (It == TIIPredicates.end()) {
|
||||
@ -476,9 +469,8 @@ void CodeGenSchedModels::checkMCInstPredicates() const {
|
||||
}
|
||||
|
||||
void CodeGenSchedModels::collectRetireControlUnits() {
|
||||
RecVec Units = Records.getAllDerivedDefinitions("RetireControlUnit");
|
||||
|
||||
for (Record *RCU : Units) {
|
||||
for (const Record *RCU :
|
||||
Records.getAllDerivedDefinitions("RetireControlUnit")) {
|
||||
CodeGenProcModel &PM = getProcModel(RCU->getValueAsDef("SchedModel"));
|
||||
if (PM.RetireControlUnit) {
|
||||
PrintError(RCU->getLoc(),
|
||||
@ -491,9 +483,7 @@ void CodeGenSchedModels::collectRetireControlUnits() {
|
||||
}
|
||||
|
||||
void CodeGenSchedModels::collectLoadStoreQueueInfo() {
|
||||
RecVec Queues = Records.getAllDerivedDefinitions("MemoryQueue");
|
||||
|
||||
for (Record *Queue : Queues) {
|
||||
for (const Record *Queue : Records.getAllDerivedDefinitions("MemoryQueue")) {
|
||||
CodeGenProcModel &PM = getProcModel(Queue->getValueAsDef("SchedModel"));
|
||||
if (Queue->isSubClassOf("LoadQueue")) {
|
||||
if (PM.LoadQueue) {
|
||||
@ -533,7 +523,8 @@ void CodeGenSchedModels::collectOptionalProcessorInfo() {
|
||||
|
||||
/// Gather all processor models.
|
||||
void CodeGenSchedModels::collectProcModels() {
|
||||
RecVec ProcRecords = Records.getAllDerivedDefinitions("Processor");
|
||||
std::vector<const Record *> ProcRecords =
|
||||
Records.getAllDerivedDefinitions("Processor");
|
||||
|
||||
// Sort and check duplicate Processor name.
|
||||
sortAndReportDuplicates(ProcRecords, "Processor");
|
||||
@ -549,14 +540,14 @@ void CodeGenSchedModels::collectProcModels() {
|
||||
|
||||
// For each processor, find a unique machine model.
|
||||
LLVM_DEBUG(dbgs() << "+++ PROCESSOR MODELs (addProcModel) +++\n");
|
||||
for (Record *ProcRecord : ProcRecords)
|
||||
for (const Record *ProcRecord : ProcRecords)
|
||||
addProcModel(ProcRecord);
|
||||
}
|
||||
|
||||
/// Get a unique processor model based on the defined MachineModel and
|
||||
/// ProcessorItineraries.
|
||||
void CodeGenSchedModels::addProcModel(Record *ProcDef) {
|
||||
Record *ModelKey = getModelOrItinDef(ProcDef);
|
||||
void CodeGenSchedModels::addProcModel(const Record *ProcDef) {
|
||||
const Record *ModelKey = getModelOrItinDef(ProcDef);
|
||||
if (!ProcModelMap.insert(std::pair(ModelKey, ProcModels.size())).second)
|
||||
return;
|
||||
|
||||
@ -575,20 +566,18 @@ void CodeGenSchedModels::addProcModel(Record *ProcDef) {
|
||||
}
|
||||
|
||||
// Recursively find all reachable SchedReadWrite records.
|
||||
static void scanSchedRW(Record *RWDef, RecVec &RWDefs,
|
||||
SmallPtrSet<Record *, 16> &RWSet) {
|
||||
static void scanSchedRW(const Record *RWDef, ConstRecVec &RWDefs,
|
||||
SmallPtrSet<const Record *, 16> &RWSet) {
|
||||
if (!RWSet.insert(RWDef).second)
|
||||
return;
|
||||
RWDefs.push_back(RWDef);
|
||||
// Reads don't currently have sequence records, but it can be added later.
|
||||
if (RWDef->isSubClassOf("WriteSequence")) {
|
||||
RecVec Seq = RWDef->getValueAsListOfDefs("Writes");
|
||||
for (Record *WSRec : Seq)
|
||||
for (const Record *WSRec : RWDef->getValueAsListOfDefs("Writes"))
|
||||
scanSchedRW(WSRec, RWDefs, RWSet);
|
||||
} else if (RWDef->isSubClassOf("SchedVariant")) {
|
||||
// Visit each variant (guarded by a different predicate).
|
||||
RecVec Vars = RWDef->getValueAsListOfDefs("Variants");
|
||||
for (Record *Variant : Vars) {
|
||||
for (const Record *Variant : RWDef->getValueAsListOfDefs("Variants")) {
|
||||
// Visit each RW in the sequence selected by the current variant.
|
||||
RecVec Selected = Variant->getValueAsListOfDefs("Selected");
|
||||
for (Record *SelDef : Selected)
|
||||
@ -604,10 +593,10 @@ void CodeGenSchedModels::collectSchedRW() {
|
||||
SchedWrites.resize(1);
|
||||
SchedReads.resize(1);
|
||||
|
||||
SmallPtrSet<Record *, 16> RWSet;
|
||||
SmallPtrSet<const Record *, 16> RWSet;
|
||||
|
||||
// Find all SchedReadWrites referenced by instruction defs.
|
||||
RecVec SWDefs, SRDefs;
|
||||
ConstRecVec SWDefs, SRDefs;
|
||||
for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
|
||||
const Record *SchedDef = Inst->TheDef;
|
||||
if (SchedDef->isValueUnset("SchedRW"))
|
||||
@ -623,8 +612,7 @@ void CodeGenSchedModels::collectSchedRW() {
|
||||
}
|
||||
}
|
||||
// Find all ReadWrites referenced by InstRW.
|
||||
RecVec InstRWDefs = Records.getAllDerivedDefinitions("InstRW");
|
||||
for (Record *InstRWDef : InstRWDefs) {
|
||||
for (const Record *InstRWDef : Records.getAllDerivedDefinitions("InstRW")) {
|
||||
// For all OperandReadWrites.
|
||||
RecVec RWDefs = InstRWDef->getValueAsListOfDefs("OperandReadWrites");
|
||||
for (Record *RWDef : RWDefs) {
|
||||
@ -637,8 +625,7 @@ void CodeGenSchedModels::collectSchedRW() {
|
||||
}
|
||||
}
|
||||
// Find all ReadWrites referenced by ItinRW.
|
||||
RecVec ItinRWDefs = Records.getAllDerivedDefinitions("ItinRW");
|
||||
for (Record *ItinRWDef : ItinRWDefs) {
|
||||
for (const Record *ItinRWDef : Records.getAllDerivedDefinitions("ItinRW")) {
|
||||
// For all OperandReadWrites.
|
||||
RecVec RWDefs = ItinRWDef->getValueAsListOfDefs("OperandReadWrites");
|
||||
for (Record *RWDef : RWDefs) {
|
||||
@ -651,12 +638,13 @@ void CodeGenSchedModels::collectSchedRW() {
|
||||
}
|
||||
}
|
||||
// Find all ReadWrites referenced by SchedAlias. AliasDefs needs to be sorted
|
||||
// for the loop below that initializes Alias vectors.
|
||||
RecVec AliasDefs = Records.getAllDerivedDefinitions("SchedAlias");
|
||||
llvm::sort(AliasDefs, LessRecord());
|
||||
for (Record *ADef : AliasDefs) {
|
||||
Record *MatchDef = ADef->getValueAsDef("MatchRW");
|
||||
Record *AliasDef = ADef->getValueAsDef("AliasRW");
|
||||
// for the loop below that initializes Alias vectors (which they already
|
||||
// are by RecordKeeper::getAllDerivedDefinitions).
|
||||
ArrayRef<const Record *> AliasDefs =
|
||||
Records.getAllDerivedDefinitions("SchedAlias");
|
||||
for (const Record *ADef : AliasDefs) {
|
||||
const Record *MatchDef = ADef->getValueAsDef("MatchRW");
|
||||
const Record *AliasDef = ADef->getValueAsDef("AliasRW");
|
||||
if (MatchDef->isSubClassOf("SchedWrite")) {
|
||||
if (!AliasDef->isSubClassOf("SchedWrite"))
|
||||
PrintFatalError(ADef->getLoc(), "SchedWrite Alias must be SchedWrite");
|
||||
@ -671,12 +659,12 @@ void CodeGenSchedModels::collectSchedRW() {
|
||||
// Sort and add the SchedReadWrites directly referenced by instructions or
|
||||
// itinerary resources. Index reads and writes in separate domains.
|
||||
llvm::sort(SWDefs, LessRecord());
|
||||
for (Record *SWDef : SWDefs) {
|
||||
for (const Record *SWDef : SWDefs) {
|
||||
assert(!getSchedRWIdx(SWDef, /*IsRead=*/false) && "duplicate SchedWrite");
|
||||
SchedWrites.emplace_back(SchedWrites.size(), SWDef);
|
||||
}
|
||||
llvm::sort(SRDefs, LessRecord());
|
||||
for (Record *SRDef : SRDefs) {
|
||||
for (const Record *SRDef : SRDefs) {
|
||||
assert(!getSchedRWIdx(SRDef, /*IsRead-*/ true) && "duplicate SchedWrite");
|
||||
SchedReads.emplace_back(SchedReads.size(), SRDef);
|
||||
}
|
||||
@ -688,7 +676,7 @@ void CodeGenSchedModels::collectSchedRW() {
|
||||
/*IsRead=*/false);
|
||||
}
|
||||
// Initialize Aliases vectors.
|
||||
for (Record *ADef : AliasDefs) {
|
||||
for (const Record *ADef : AliasDefs) {
|
||||
Record *AliasDef = ADef->getValueAsDef("AliasRW");
|
||||
getSchedRW(AliasDef).IsAlias = true;
|
||||
Record *MatchDef = ADef->getValueAsDef("MatchRW");
|
||||
@ -708,9 +696,8 @@ void CodeGenSchedModels::collectSchedRW() {
|
||||
dbgs() << RIdx << ": ";
|
||||
SchedReads[RIdx].dump();
|
||||
dbgs() << '\n';
|
||||
} RecVec RWDefs = Records.getAllDerivedDefinitions("SchedReadWrite");
|
||||
for (Record *RWDef
|
||||
: RWDefs) {
|
||||
} for (const Record *RWDef
|
||||
: Records.getAllDerivedDefinitions("SchedReadWrite")) {
|
||||
if (!getSchedRWIdx(RWDef, RWDef->isSubClassOf("SchedRead"))) {
|
||||
StringRef Name = RWDef->getName();
|
||||
if (Name != "NoWrite" && Name != "ReadDefault")
|
||||
@ -791,9 +778,8 @@ void CodeGenSchedModels::expandRWSequence(unsigned RWIdx, IdxVec &RWSeq,
|
||||
void CodeGenSchedModels::expandRWSeqForProc(
|
||||
unsigned RWIdx, IdxVec &RWSeq, bool IsRead,
|
||||
const CodeGenProcModel &ProcModel) const {
|
||||
|
||||
const CodeGenSchedRW &SchedWrite = getSchedRW(RWIdx, IsRead);
|
||||
Record *AliasDef = nullptr;
|
||||
const Record *AliasDef = nullptr;
|
||||
for (const Record *Rec : SchedWrite.Aliases) {
|
||||
const CodeGenSchedRW &AliasRW = getSchedRW(Rec->getValueAsDef("AliasRW"));
|
||||
if (Rec->getValueInit("SchedModel")->isComplete()) {
|
||||
@ -880,10 +866,8 @@ void CodeGenSchedModels::collectSchedClasses() {
|
||||
InstrClassMap[Inst->TheDef] = SCIdx;
|
||||
}
|
||||
// Create classes for InstRW defs.
|
||||
RecVec InstRWDefs = Records.getAllDerivedDefinitions("InstRW");
|
||||
llvm::sort(InstRWDefs, LessRecord());
|
||||
LLVM_DEBUG(dbgs() << "\n+++ SCHED CLASSES (createInstRWClass) +++\n");
|
||||
for (Record *RWDef : InstRWDefs)
|
||||
for (const Record *RWDef : Records.getAllDerivedDefinitions("InstRW"))
|
||||
createInstRWClass(RWDef);
|
||||
|
||||
NumInstrSchedClasses = SchedClasses.size();
|
||||
@ -929,8 +913,7 @@ void CodeGenSchedModels::collectSchedClasses() {
|
||||
dbgs() << '\n';
|
||||
});
|
||||
}
|
||||
const RecVec &RWDefs = SchedClasses[SCIdx].InstRWs;
|
||||
for (Record *RWDef : RWDefs) {
|
||||
for (const Record *RWDef : SchedClasses[SCIdx].InstRWs) {
|
||||
const CodeGenProcModel &ProcModel =
|
||||
getProcModel(RWDef->getValueAsDef("SchedModel"));
|
||||
ProcIndices.push_back(ProcModel.Index);
|
||||
@ -1034,7 +1017,7 @@ unsigned CodeGenSchedModels::addSchedClass(Record *ItinClassDef,
|
||||
|
||||
// Create classes for each set of opcodes that are in the same InstReadWrite
|
||||
// definition across all processors.
|
||||
void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
|
||||
void CodeGenSchedModels::createInstRWClass(const Record *InstRWDef) {
|
||||
// ClassInstrs will hold an entry for each subset of Instrs in InstRWDef that
|
||||
// intersects with an existing class via a previous InstRWDef. Instrs that do
|
||||
// not intersect with an existing class refer back to their former class as
|
||||
@ -1060,7 +1043,7 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
|
||||
// If the all instrs in the current class are accounted for, then leave
|
||||
// them mapped to their old class.
|
||||
if (OldSCIdx) {
|
||||
const RecVec &RWDefs = SchedClasses[OldSCIdx].InstRWs;
|
||||
const ConstRecVec &RWDefs = SchedClasses[OldSCIdx].InstRWs;
|
||||
if (!RWDefs.empty()) {
|
||||
const ConstRecVec *OrigInstDefs = Sets.expand(RWDefs[0]);
|
||||
unsigned OrigNumInstrs =
|
||||
@ -1073,7 +1056,7 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
|
||||
Record *RWModelDef = InstRWDef->getValueAsDef("SchedModel");
|
||||
// Make sure we didn't already have a InstRW containing this
|
||||
// instruction on this model.
|
||||
for (Record *RWD : RWDefs) {
|
||||
for (const Record *RWD : RWDefs) {
|
||||
if (RWD->getValueAsDef("SchedModel") == RWModelDef &&
|
||||
RWModelDef->getValueAsBit("FullInstRWOverlapCheck")) {
|
||||
assert(!InstDefs.empty()); // Checked at function start.
|
||||
@ -1109,8 +1092,8 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
|
||||
SC.ProcIndices.push_back(0);
|
||||
// If we had an old class, copy it's InstRWs to this new class.
|
||||
if (OldSCIdx) {
|
||||
Record *RWModelDef = InstRWDef->getValueAsDef("SchedModel");
|
||||
for (Record *OldRWDef : SchedClasses[OldSCIdx].InstRWs) {
|
||||
const Record *RWModelDef = InstRWDef->getValueAsDef("SchedModel");
|
||||
for (const Record *OldRWDef : SchedClasses[OldSCIdx].InstRWs) {
|
||||
if (OldRWDef->getValueAsDef("SchedModel") == RWModelDef) {
|
||||
assert(!InstDefs.empty()); // Checked at function start.
|
||||
PrintError(
|
||||
@ -1188,12 +1171,10 @@ void CodeGenSchedModels::collectProcItins() {
|
||||
|
||||
// Gather the read/write types for each itinerary class.
|
||||
void CodeGenSchedModels::collectProcItinRW() {
|
||||
RecVec ItinRWDefs = Records.getAllDerivedDefinitions("ItinRW");
|
||||
llvm::sort(ItinRWDefs, LessRecord());
|
||||
for (Record *RWDef : ItinRWDefs) {
|
||||
for (const Record *RWDef : Records.getAllDerivedDefinitions("ItinRW")) {
|
||||
if (!RWDef->getValueInit("SchedModel")->isComplete())
|
||||
PrintFatalError(RWDef->getLoc(), "SchedModel is undefined");
|
||||
Record *ModelDef = RWDef->getValueAsDef("SchedModel");
|
||||
const Record *ModelDef = RWDef->getValueAsDef("SchedModel");
|
||||
ProcModelMapTy::const_iterator I = ProcModelMap.find(ModelDef);
|
||||
if (I == ProcModelMap.end()) {
|
||||
PrintFatalError(RWDef->getLoc(),
|
||||
@ -1262,7 +1243,7 @@ void CodeGenSchedModels::inferFromItinClass(Record *ItinClassDef,
|
||||
void CodeGenSchedModels::inferFromInstRWs(unsigned SCIdx) {
|
||||
for (unsigned I = 0, E = SchedClasses[SCIdx].InstRWs.size(); I != E; ++I) {
|
||||
assert(SchedClasses[SCIdx].InstRWs.size() == E && "InstrRWs was mutated!");
|
||||
Record *Rec = SchedClasses[SCIdx].InstRWs[I];
|
||||
const Record *Rec = SchedClasses[SCIdx].InstRWs[I];
|
||||
const std::vector<const Record *> *InstDefs = Sets.expand(Rec);
|
||||
ConstRecIter II = InstDefs->begin(), IE = InstDefs->end();
|
||||
for (; II != IE; ++II) {
|
||||
@ -1285,12 +1266,12 @@ namespace {
|
||||
|
||||
// Helper for substituteVariantOperand.
|
||||
struct TransVariant {
|
||||
Record *VarOrSeqDef; // Variant or sequence.
|
||||
const Record *VarOrSeqDef; // Variant or sequence.
|
||||
unsigned RWIdx; // Index of this variant or sequence's matched type.
|
||||
unsigned ProcIdx; // Processor model index or zero for any.
|
||||
unsigned TransVecIdx; // Index into PredTransitions::TransVec.
|
||||
|
||||
TransVariant(Record *def, unsigned rwi, unsigned pi, unsigned ti)
|
||||
TransVariant(const Record *def, unsigned rwi, unsigned pi, unsigned ti)
|
||||
: VarOrSeqDef(def), RWIdx(rwi), ProcIdx(pi), TransVecIdx(ti) {}
|
||||
};
|
||||
|
||||
@ -1299,7 +1280,7 @@ struct TransVariant {
|
||||
struct PredCheck {
|
||||
bool IsRead;
|
||||
unsigned RWIdx;
|
||||
Record *Predicate;
|
||||
const Record *Predicate;
|
||||
|
||||
PredCheck(bool r, unsigned w, Record *p)
|
||||
: IsRead(r), RWIdx(w), Predicate(p) {}
|
||||
@ -1440,7 +1421,7 @@ void PredTransitions::getIntersectingVariants(
|
||||
GenericRW = true;
|
||||
}
|
||||
}
|
||||
for (RecIter AI = SchedRW.Aliases.begin(), AE = SchedRW.Aliases.end();
|
||||
for (ConstRecIter AI = SchedRW.Aliases.begin(), AE = SchedRW.Aliases.end();
|
||||
AI != AE; ++AI) {
|
||||
// If either the SchedAlias itself or the SchedReadWrite that it aliases
|
||||
// to is defined within a processor model, constrain all variants to
|
||||
@ -1644,7 +1625,7 @@ static void addSequences(CodeGenSchedModels &SchedModels,
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
static void dumpRecVec(const RecVec &RV) {
|
||||
static void dumpRecVec(const ConstRecVec &RV) {
|
||||
for (const Record *R : RV)
|
||||
dbgs() << R->getName() << ", ";
|
||||
}
|
||||
@ -1653,7 +1634,7 @@ static void dumpRecVec(const RecVec &RV) {
|
||||
static void dumpTransition(const CodeGenSchedModels &SchedModels,
|
||||
const CodeGenSchedClass &FromSC,
|
||||
const CodeGenSchedTransition &SCTrans,
|
||||
const RecVec &Preds) {
|
||||
const ConstRecVec &Preds) {
|
||||
LLVM_DEBUG(dbgs() << "Adding transition from " << FromSC.Name << "("
|
||||
<< FromSC.Index << ") to "
|
||||
<< SchedModels.getSchedClass(SCTrans.ToClassIdx).Name << "("
|
||||
@ -1690,7 +1671,7 @@ static void inferFromTransitions(ArrayRef<PredTransition> LastTransitions,
|
||||
OperReadsVariant, LastTransition.ProcIndex);
|
||||
|
||||
// The final PredTerm is unique set of predicates guarding the transition.
|
||||
RecVec Preds;
|
||||
ConstRecVec Preds;
|
||||
transform(LastTransition.PredTerm, std::back_inserter(Preds),
|
||||
[](const PredCheck &P) { return P.Predicate; });
|
||||
Preds.erase(llvm::unique(Preds), Preds.end());
|
||||
@ -1781,7 +1762,7 @@ void CodeGenSchedModels::inferFromRW(ArrayRef<unsigned> OperWrites,
|
||||
// Check if any processor resource group contains all resource records in
|
||||
// SubUnits.
|
||||
bool CodeGenSchedModels::hasSuperGroup(RecVec &SubUnits, CodeGenProcModel &PM) {
|
||||
for (Record *ProcResourceDef : PM.ProcResourceDefs) {
|
||||
for (const Record *ProcResourceDef : PM.ProcResourceDefs) {
|
||||
if (!ProcResourceDef->isSubClassOf("ProcResGroup"))
|
||||
continue;
|
||||
RecVec SuperUnits = ProcResourceDef->getValueAsListOfDefs("Resources");
|
||||
@ -1827,10 +1808,8 @@ void CodeGenSchedModels::verifyProcResourceGroups(CodeGenProcModel &PM) {
|
||||
|
||||
// Collect all the RegisterFile definitions available in this target.
|
||||
void CodeGenSchedModels::collectRegisterFiles() {
|
||||
RecVec RegisterFileDefs = Records.getAllDerivedDefinitions("RegisterFile");
|
||||
|
||||
// RegisterFiles is the vector of CodeGenRegisterFile.
|
||||
for (Record *RF : RegisterFileDefs) {
|
||||
for (const Record *RF : Records.getAllDerivedDefinitions("RegisterFile")) {
|
||||
// For each register file definition, construct a CodeGenRegisterFile object
|
||||
// and add it to the appropriate scheduling model.
|
||||
CodeGenProcModel &PM = getProcModel(RF->getValueAsDef("SchedModel"));
|
||||
@ -1883,7 +1862,7 @@ void CodeGenSchedModels::collectProcResources() {
|
||||
|
||||
// This class may have a default ReadWrite list which can be overriden by
|
||||
// InstRW definitions.
|
||||
for (Record *RW : SC.InstRWs) {
|
||||
for (const Record *RW : SC.InstRWs) {
|
||||
Record *RWModelDef = RW->getValueAsDef("SchedModel");
|
||||
unsigned PIdx = getProcModel(RWModelDef).Index;
|
||||
IdxVec Writes, Reads;
|
||||
@ -1894,32 +1873,28 @@ void CodeGenSchedModels::collectProcResources() {
|
||||
collectRWResources(SC.Writes, SC.Reads, SC.ProcIndices);
|
||||
}
|
||||
// Add resources separately defined by each subtarget.
|
||||
RecVec WRDefs = Records.getAllDerivedDefinitions("WriteRes");
|
||||
for (Record *WR : WRDefs) {
|
||||
Record *ModelDef = WR->getValueAsDef("SchedModel");
|
||||
for (const Record *WR : Records.getAllDerivedDefinitions("WriteRes")) {
|
||||
const Record *ModelDef = WR->getValueAsDef("SchedModel");
|
||||
addWriteRes(WR, getProcModel(ModelDef).Index);
|
||||
}
|
||||
RecVec SWRDefs = Records.getAllDerivedDefinitions("SchedWriteRes");
|
||||
for (Record *SWR : SWRDefs) {
|
||||
Record *ModelDef = SWR->getValueAsDef("SchedModel");
|
||||
for (const Record *SWR : Records.getAllDerivedDefinitions("SchedWriteRes")) {
|
||||
const Record *ModelDef = SWR->getValueAsDef("SchedModel");
|
||||
addWriteRes(SWR, getProcModel(ModelDef).Index);
|
||||
}
|
||||
RecVec RADefs = Records.getAllDerivedDefinitions("ReadAdvance");
|
||||
for (Record *RA : RADefs) {
|
||||
Record *ModelDef = RA->getValueAsDef("SchedModel");
|
||||
for (const Record *RA : Records.getAllDerivedDefinitions("ReadAdvance")) {
|
||||
const Record *ModelDef = RA->getValueAsDef("SchedModel");
|
||||
addReadAdvance(RA, getProcModel(ModelDef).Index);
|
||||
}
|
||||
RecVec SRADefs = Records.getAllDerivedDefinitions("SchedReadAdvance");
|
||||
for (Record *SRA : SRADefs) {
|
||||
for (const Record *SRA :
|
||||
Records.getAllDerivedDefinitions("SchedReadAdvance")) {
|
||||
if (SRA->getValueInit("SchedModel")->isComplete()) {
|
||||
Record *ModelDef = SRA->getValueAsDef("SchedModel");
|
||||
const Record *ModelDef = SRA->getValueAsDef("SchedModel");
|
||||
addReadAdvance(SRA, getProcModel(ModelDef).Index);
|
||||
}
|
||||
}
|
||||
// Add ProcResGroups that are defined within this processor model, which may
|
||||
// not be directly referenced but may directly specify a buffer size.
|
||||
RecVec ProcResGroups = Records.getAllDerivedDefinitions("ProcResGroup");
|
||||
for (Record *PRG : ProcResGroups) {
|
||||
for (const Record *PRG : Records.getAllDerivedDefinitions("ProcResGroup")) {
|
||||
if (!PRG->getValueInit("SchedModel")->isComplete())
|
||||
continue;
|
||||
CodeGenProcModel &PM = getProcModel(PRG->getValueAsDef("SchedModel"));
|
||||
@ -1927,7 +1902,8 @@ void CodeGenSchedModels::collectProcResources() {
|
||||
PM.ProcResourceDefs.push_back(PRG);
|
||||
}
|
||||
// Add ProcResourceUnits unconditionally.
|
||||
for (Record *PRU : Records.getAllDerivedDefinitions("ProcResourceUnits")) {
|
||||
for (const Record *PRU :
|
||||
Records.getAllDerivedDefinitions("ProcResourceUnits")) {
|
||||
if (!PRU->getValueInit("SchedModel")->isComplete())
|
||||
continue;
|
||||
CodeGenProcModel &PM = getProcModel(PRU->getValueAsDef("SchedModel"));
|
||||
@ -1947,7 +1923,7 @@ void CodeGenSchedModels::collectProcResources() {
|
||||
else
|
||||
dbgs() << WriteResDef->getName() << " ";
|
||||
} dbgs() << "\nReadAdvanceDefs: ";
|
||||
for (Record *ReadAdvanceDef
|
||||
for (const Record *ReadAdvanceDef
|
||||
: PM.ReadAdvanceDefs) {
|
||||
if (ReadAdvanceDef->isSubClassOf("ReadAdvance"))
|
||||
dbgs() << ReadAdvanceDef->getValueAsDef("ReadType")->getName()
|
||||
@ -1956,7 +1932,7 @@ void CodeGenSchedModels::collectProcResources() {
|
||||
dbgs() << ReadAdvanceDef->getName() << " ";
|
||||
} dbgs()
|
||||
<< "\nProcResourceDefs: ";
|
||||
for (Record *ProcResourceDef
|
||||
for (const Record *ProcResourceDef
|
||||
: PM.ProcResourceDefs) {
|
||||
dbgs() << ProcResourceDef->getName() << " ";
|
||||
} dbgs()
|
||||
@ -1998,7 +1974,7 @@ void CodeGenSchedModels::checkCompleteness() {
|
||||
SC.ItinClassDef->getName() != "NoItinerary")
|
||||
continue;
|
||||
|
||||
const RecVec &InstRWs = SC.InstRWs;
|
||||
const ConstRecVec &InstRWs = SC.InstRWs;
|
||||
auto I = find_if(InstRWs, [&ProcModel](const Record *R) {
|
||||
return R->getValueAsDef("SchedModel") == ProcModel.ModelDef;
|
||||
});
|
||||
@ -2033,18 +2009,17 @@ void CodeGenSchedModels::collectItinProcResources(Record *ItinClassDef) {
|
||||
const CodeGenProcModel &PM = ProcModels[PIdx];
|
||||
// For all ItinRW entries.
|
||||
bool HasMatch = false;
|
||||
for (RecIter II = PM.ItinRWDefs.begin(), IE = PM.ItinRWDefs.end(); II != IE;
|
||||
++II) {
|
||||
RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses");
|
||||
for (const Record *R : PM.ItinRWDefs) {
|
||||
RecVec Matched = R->getValueAsListOfDefs("MatchedItinClasses");
|
||||
if (!llvm::is_contained(Matched, ItinClassDef))
|
||||
continue;
|
||||
if (HasMatch)
|
||||
PrintFatalError((*II)->getLoc(),
|
||||
PrintFatalError(R->getLoc(),
|
||||
"Duplicate itinerary class " + ItinClassDef->getName() +
|
||||
" in ItinResources for " + PM.ModelName);
|
||||
HasMatch = true;
|
||||
IdxVec Writes, Reads;
|
||||
findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads);
|
||||
findRWs(R->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads);
|
||||
collectRWResources(Writes, Reads, PIdx);
|
||||
}
|
||||
}
|
||||
@ -2092,17 +2067,17 @@ void CodeGenSchedModels::collectRWResources(ArrayRef<unsigned> Writes,
|
||||
}
|
||||
|
||||
// Find the processor's resource units for this kind of resource.
|
||||
Record *CodeGenSchedModels::findProcResUnits(Record *ProcResKind,
|
||||
const CodeGenProcModel &PM,
|
||||
ArrayRef<SMLoc> Loc) const {
|
||||
const Record *CodeGenSchedModels::findProcResUnits(const Record *ProcResKind,
|
||||
const CodeGenProcModel &PM,
|
||||
ArrayRef<SMLoc> Loc) const {
|
||||
if (ProcResKind->isSubClassOf("ProcResourceUnits"))
|
||||
return ProcResKind;
|
||||
|
||||
Record *ProcUnitDef = nullptr;
|
||||
const Record *ProcUnitDef = nullptr;
|
||||
assert(!ProcResourceDefs.empty());
|
||||
assert(!ProcResGroups.empty());
|
||||
|
||||
for (Record *ProcResDef : ProcResourceDefs) {
|
||||
for (const Record *ProcResDef : ProcResourceDefs) {
|
||||
if (ProcResDef->getValueAsDef("Kind") == ProcResKind &&
|
||||
ProcResDef->getValueAsDef("SchedModel") == PM.ModelDef) {
|
||||
if (ProcUnitDef) {
|
||||
@ -2113,7 +2088,7 @@ Record *CodeGenSchedModels::findProcResUnits(Record *ProcResKind,
|
||||
ProcUnitDef = ProcResDef;
|
||||
}
|
||||
}
|
||||
for (Record *ProcResGroup : ProcResGroups) {
|
||||
for (const Record *ProcResGroup : ProcResGroups) {
|
||||
if (ProcResGroup == ProcResKind &&
|
||||
ProcResGroup->getValueAsDef("SchedModel") == PM.ModelDef) {
|
||||
if (ProcUnitDef) {
|
||||
@ -2132,11 +2107,11 @@ Record *CodeGenSchedModels::findProcResUnits(Record *ProcResKind,
|
||||
}
|
||||
|
||||
// Iteratively add a resource and its super resources.
|
||||
void CodeGenSchedModels::addProcResource(Record *ProcResKind,
|
||||
void CodeGenSchedModels::addProcResource(const Record *ProcResKind,
|
||||
CodeGenProcModel &PM,
|
||||
ArrayRef<SMLoc> Loc) {
|
||||
while (true) {
|
||||
Record *ProcResUnits = findProcResUnits(ProcResKind, PM, Loc);
|
||||
const Record *ProcResUnits = findProcResUnits(ProcResKind, PM, Loc);
|
||||
|
||||
// See if this ProcResource is already associated with this processor.
|
||||
if (is_contained(PM.ProcResourceDefs, ProcResUnits))
|
||||
@ -2154,23 +2129,24 @@ void CodeGenSchedModels::addProcResource(Record *ProcResKind,
|
||||
}
|
||||
|
||||
// Add resources for a SchedWrite to this processor if they don't exist.
|
||||
void CodeGenSchedModels::addWriteRes(Record *ProcWriteResDef, unsigned PIdx) {
|
||||
void CodeGenSchedModels::addWriteRes(const Record *ProcWriteResDef,
|
||||
unsigned PIdx) {
|
||||
assert(PIdx && "don't add resources to an invalid Processor model");
|
||||
|
||||
RecVec &WRDefs = ProcModels[PIdx].WriteResDefs;
|
||||
ConstRecVec &WRDefs = ProcModels[PIdx].WriteResDefs;
|
||||
if (is_contained(WRDefs, ProcWriteResDef))
|
||||
return;
|
||||
WRDefs.push_back(ProcWriteResDef);
|
||||
|
||||
// Visit ProcResourceKinds referenced by the newly discovered WriteRes.
|
||||
RecVec ProcResDefs = ProcWriteResDef->getValueAsListOfDefs("ProcResources");
|
||||
for (auto *ProcResDef : ProcResDefs) {
|
||||
for (const Record *ProcResDef : ProcResDefs) {
|
||||
addProcResource(ProcResDef, ProcModels[PIdx], ProcWriteResDef->getLoc());
|
||||
}
|
||||
}
|
||||
|
||||
// Add resources for a ReadAdvance to this processor if they don't exist.
|
||||
void CodeGenSchedModels::addReadAdvance(Record *ProcReadAdvanceDef,
|
||||
void CodeGenSchedModels::addReadAdvance(const Record *ProcReadAdvanceDef,
|
||||
unsigned PIdx) {
|
||||
for (const Record *ValidWrite :
|
||||
ProcReadAdvanceDef->getValueAsListOfDefs("ValidWrites"))
|
||||
@ -2181,14 +2157,14 @@ void CodeGenSchedModels::addReadAdvance(Record *ProcReadAdvanceDef,
|
||||
"any instruction (" +
|
||||
ValidWrite->getName() + ")");
|
||||
|
||||
RecVec &RADefs = ProcModels[PIdx].ReadAdvanceDefs;
|
||||
ConstRecVec &RADefs = ProcModels[PIdx].ReadAdvanceDefs;
|
||||
if (is_contained(RADefs, ProcReadAdvanceDef))
|
||||
return;
|
||||
RADefs.push_back(ProcReadAdvanceDef);
|
||||
}
|
||||
|
||||
unsigned CodeGenProcModel::getProcResourceIdx(Record *PRDef) const {
|
||||
RecIter PRPos = find(ProcResourceDefs, PRDef);
|
||||
unsigned CodeGenProcModel::getProcResourceIdx(const Record *PRDef) const {
|
||||
ConstRecIter PRPos = find(ProcResourceDefs, PRDef);
|
||||
if (PRPos == ProcResourceDefs.end())
|
||||
PrintFatalError(PRDef->getLoc(), "ProcResource def is not included in "
|
||||
"the ProcResources list for " +
|
||||
@ -2208,7 +2184,7 @@ bool CodeGenProcModel::isUnsupported(const CodeGenInstruction &Inst) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CodeGenProcModel::hasReadOfWrite(Record *WriteDef) const {
|
||||
bool CodeGenProcModel::hasReadOfWrite(const Record *WriteDef) const {
|
||||
for (auto &RADef : ReadAdvanceDefs) {
|
||||
RecVec ValidWrites = RADef->getValueAsListOfDefs("ValidWrites");
|
||||
if (is_contained(ValidWrites, WriteDef))
|
||||
|
@ -51,19 +51,19 @@ using IdxIter = IdxVec::const_iterator;
|
||||
struct CodeGenSchedRW {
|
||||
unsigned Index;
|
||||
std::string Name;
|
||||
Record *TheDef;
|
||||
const Record *TheDef;
|
||||
bool IsRead;
|
||||
bool IsAlias;
|
||||
bool HasVariants;
|
||||
bool IsVariadic;
|
||||
bool IsSequence;
|
||||
IdxVec Sequence;
|
||||
RecVec Aliases;
|
||||
ConstRecVec Aliases;
|
||||
|
||||
CodeGenSchedRW()
|
||||
: Index(0), TheDef(nullptr), IsRead(false), IsAlias(false),
|
||||
HasVariants(false), IsVariadic(false), IsSequence(false) {}
|
||||
CodeGenSchedRW(unsigned Idx, Record *Def)
|
||||
CodeGenSchedRW(unsigned Idx, const Record *Def)
|
||||
: Index(Idx), TheDef(Def), IsAlias(false), IsVariadic(false) {
|
||||
Name = std::string(Def->getName());
|
||||
IsRead = Def->isSubClassOf("SchedRead");
|
||||
@ -102,7 +102,7 @@ struct CodeGenSchedRW {
|
||||
struct CodeGenSchedTransition {
|
||||
unsigned ToClassIdx;
|
||||
unsigned ProcIndex;
|
||||
RecVec PredTerm;
|
||||
ConstRecVec PredTerm;
|
||||
};
|
||||
|
||||
/// Scheduling class.
|
||||
@ -145,7 +145,7 @@ struct CodeGenSchedClass {
|
||||
// Instruction no longer mapped to this class by InstrClassMap. These
|
||||
// Instructions should be ignored by this class because they have been split
|
||||
// off to join another inferred class.
|
||||
RecVec InstRWs;
|
||||
ConstRecVec InstRWs;
|
||||
// InstRWs processor indices. Filled in inferFromInstRWs
|
||||
DenseSet<unsigned> InstRWProcIndices;
|
||||
|
||||
@ -189,14 +189,14 @@ struct CodeGenRegisterCost {
|
||||
/// stalls due to register pressure.
|
||||
struct CodeGenRegisterFile {
|
||||
std::string Name;
|
||||
Record *RegisterFileDef;
|
||||
const Record *RegisterFileDef;
|
||||
unsigned MaxMovesEliminatedPerCycle;
|
||||
bool AllowZeroMoveEliminationOnly;
|
||||
|
||||
unsigned NumPhysRegs;
|
||||
std::vector<CodeGenRegisterCost> Costs;
|
||||
|
||||
CodeGenRegisterFile(StringRef name, Record *def,
|
||||
CodeGenRegisterFile(StringRef name, const Record *def,
|
||||
unsigned MaxMoveElimPerCy = 0,
|
||||
bool AllowZeroMoveElimOnly = false)
|
||||
: Name(name), RegisterFileDef(def),
|
||||
@ -223,8 +223,8 @@ struct CodeGenRegisterFile {
|
||||
struct CodeGenProcModel {
|
||||
unsigned Index;
|
||||
std::string ModelName;
|
||||
Record *ModelDef;
|
||||
Record *ItinsDef;
|
||||
const Record *ModelDef;
|
||||
const Record *ItinsDef;
|
||||
|
||||
// Derived members...
|
||||
|
||||
@ -235,30 +235,31 @@ struct CodeGenProcModel {
|
||||
|
||||
// Map itinerary classes to per-operand resources.
|
||||
// This list is empty if no ItinRW refers to this Processor.
|
||||
RecVec ItinRWDefs;
|
||||
ConstRecVec ItinRWDefs;
|
||||
|
||||
// List of unsupported feature.
|
||||
// This list is empty if the Processor has no UnsupportedFeatures.
|
||||
RecVec UnsupportedFeaturesDefs;
|
||||
|
||||
// All read/write resources associated with this processor.
|
||||
RecVec WriteResDefs;
|
||||
RecVec ReadAdvanceDefs;
|
||||
ConstRecVec WriteResDefs;
|
||||
ConstRecVec ReadAdvanceDefs;
|
||||
|
||||
// Per-operand machine model resources associated with this processor.
|
||||
RecVec ProcResourceDefs;
|
||||
ConstRecVec ProcResourceDefs;
|
||||
|
||||
// List of Register Files.
|
||||
std::vector<CodeGenRegisterFile> RegisterFiles;
|
||||
|
||||
// Optional Retire Control Unit definition.
|
||||
Record *RetireControlUnit;
|
||||
const Record *RetireControlUnit;
|
||||
|
||||
// Load/Store queue descriptors.
|
||||
Record *LoadQueue;
|
||||
Record *StoreQueue;
|
||||
const Record *LoadQueue;
|
||||
const Record *StoreQueue;
|
||||
|
||||
CodeGenProcModel(unsigned Idx, std::string Name, Record *MDef, Record *IDef)
|
||||
CodeGenProcModel(unsigned Idx, std::string Name, const Record *MDef,
|
||||
const Record *IDef)
|
||||
: Index(Idx), ModelName(std::move(Name)), ModelDef(MDef), ItinsDef(IDef),
|
||||
RetireControlUnit(nullptr), LoadQueue(nullptr), StoreQueue(nullptr) {}
|
||||
|
||||
@ -275,12 +276,12 @@ struct CodeGenProcModel {
|
||||
!RegisterFiles.empty();
|
||||
}
|
||||
|
||||
unsigned getProcResourceIdx(Record *PRDef) const;
|
||||
unsigned getProcResourceIdx(const Record *PRDef) const;
|
||||
|
||||
bool isUnsupported(const CodeGenInstruction &Inst) const;
|
||||
|
||||
// Return true if the given write record is referenced by a ReadAdvance.
|
||||
bool hasReadOfWrite(Record *WriteDef) const;
|
||||
bool hasReadOfWrite(const Record *WriteDef) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void dump() const;
|
||||
@ -421,7 +422,7 @@ using ProcModelMapTy = DenseMap<const Record *, unsigned>;
|
||||
|
||||
/// Top level container for machine model data.
|
||||
class CodeGenSchedModels {
|
||||
RecordKeeper &Records;
|
||||
const RecordKeeper &Records;
|
||||
const CodeGenTarget &Target;
|
||||
|
||||
// Map dag expressions to Instruction lists.
|
||||
@ -443,8 +444,8 @@ class CodeGenSchedModels {
|
||||
// Any inferred SchedClass has an index greater than NumInstrSchedClassses.
|
||||
unsigned NumInstrSchedClasses;
|
||||
|
||||
RecVec ProcResourceDefs;
|
||||
RecVec ProcResGroups;
|
||||
ConstRecVec ProcResourceDefs;
|
||||
ConstRecVec ProcResGroups;
|
||||
|
||||
// Map each instruction to its unique SchedClass index considering the
|
||||
// combination of it's itinerary class, SchedRW list, and InstRW records.
|
||||
@ -455,7 +456,7 @@ class CodeGenSchedModels {
|
||||
std::vector<unsigned> getAllProcIndices() const;
|
||||
|
||||
public:
|
||||
CodeGenSchedModels(RecordKeeper &RK, const CodeGenTarget &TGT);
|
||||
CodeGenSchedModels(const RecordKeeper &RK, const CodeGenTarget &TGT);
|
||||
|
||||
// iterator access to the scheduling classes.
|
||||
using class_iterator = std::vector<CodeGenSchedClass>::iterator;
|
||||
@ -477,9 +478,9 @@ public:
|
||||
return make_range(classes_begin(), classes_begin() + NumInstrSchedClasses);
|
||||
}
|
||||
|
||||
Record *getModelOrItinDef(Record *ProcDef) const {
|
||||
Record *ModelDef = ProcDef->getValueAsDef("SchedModel");
|
||||
Record *ItinsDef = ProcDef->getValueAsDef("ProcItin");
|
||||
const Record *getModelOrItinDef(const Record *ProcDef) const {
|
||||
const Record *ModelDef = ProcDef->getValueAsDef("SchedModel");
|
||||
const Record *ItinsDef = ProcDef->getValueAsDef("ProcItin");
|
||||
if (!ItinsDef->getValueAsListOfDefs("IID").empty()) {
|
||||
assert(ModelDef->getValueAsBit("NoModel") &&
|
||||
"Itineraries must be defined within SchedMachineModel");
|
||||
@ -489,18 +490,18 @@ public:
|
||||
}
|
||||
|
||||
const CodeGenProcModel &getModelForProc(Record *ProcDef) const {
|
||||
Record *ModelDef = getModelOrItinDef(ProcDef);
|
||||
const Record *ModelDef = getModelOrItinDef(ProcDef);
|
||||
ProcModelMapTy::const_iterator I = ProcModelMap.find(ModelDef);
|
||||
assert(I != ProcModelMap.end() && "missing machine model");
|
||||
return ProcModels[I->second];
|
||||
}
|
||||
|
||||
CodeGenProcModel &getProcModel(Record *ModelDef) {
|
||||
CodeGenProcModel &getProcModel(const Record *ModelDef) {
|
||||
ProcModelMapTy::const_iterator I = ProcModelMap.find(ModelDef);
|
||||
assert(I != ProcModelMap.end() && "missing machine model");
|
||||
return ProcModels[I->second];
|
||||
}
|
||||
const CodeGenProcModel &getProcModel(Record *ModelDef) const {
|
||||
const CodeGenProcModel &getProcModel(const Record *ModelDef) const {
|
||||
return const_cast<CodeGenSchedModels *>(this)->getProcModel(ModelDef);
|
||||
}
|
||||
|
||||
@ -575,8 +576,9 @@ public:
|
||||
|
||||
unsigned findOrInsertRW(ArrayRef<unsigned> Seq, bool IsRead);
|
||||
|
||||
Record *findProcResUnits(Record *ProcResKind, const CodeGenProcModel &PM,
|
||||
ArrayRef<SMLoc> Loc) const;
|
||||
const Record *findProcResUnits(const Record *ProcResKind,
|
||||
const CodeGenProcModel &PM,
|
||||
ArrayRef<SMLoc> Loc) const;
|
||||
|
||||
ArrayRef<STIPredicateFunction> getSTIPredicates() const {
|
||||
return STIPredicates;
|
||||
@ -586,7 +588,7 @@ private:
|
||||
void collectProcModels();
|
||||
|
||||
// Initialize a new processor model if it is unique.
|
||||
void addProcModel(Record *ProcDef);
|
||||
void addProcModel(const Record *ProcDef);
|
||||
|
||||
void collectSchedRW();
|
||||
|
||||
@ -605,7 +607,7 @@ private:
|
||||
ArrayRef<unsigned> OperWrites,
|
||||
ArrayRef<unsigned> OperReads);
|
||||
std::string createSchedClassName(const ConstRecVec &InstDefs);
|
||||
void createInstRWClass(Record *InstRWDef);
|
||||
void createInstRWClass(const Record *InstRWDef);
|
||||
|
||||
void collectProcItins();
|
||||
|
||||
@ -643,12 +645,12 @@ private:
|
||||
void collectRWResources(ArrayRef<unsigned> Writes, ArrayRef<unsigned> Reads,
|
||||
ArrayRef<unsigned> ProcIndices);
|
||||
|
||||
void addProcResource(Record *ProcResourceKind, CodeGenProcModel &PM,
|
||||
void addProcResource(const Record *ProcResourceKind, CodeGenProcModel &PM,
|
||||
ArrayRef<SMLoc> Loc);
|
||||
|
||||
void addWriteRes(Record *ProcWriteResDef, unsigned PIdx);
|
||||
void addWriteRes(const Record *ProcWriteResDef, unsigned PIdx);
|
||||
|
||||
void addReadAdvance(Record *ProcReadAdvanceDef, unsigned PIdx);
|
||||
void addReadAdvance(const Record *ProcReadAdvanceDef, unsigned PIdx);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
@ -27,7 +27,7 @@ struct LessRecordFieldNameAndID {
|
||||
|
||||
/// Sort an array of Records on the "Name" field, and check for records with
|
||||
/// duplicate "Name" field. If duplicates are found, report a fatal error.
|
||||
void llvm::sortAndReportDuplicates(MutableArrayRef<Record *> Records,
|
||||
void llvm::sortAndReportDuplicates(MutableArrayRef<const Record *> Records,
|
||||
StringRef ObjectName) {
|
||||
llvm::sort(Records, LessRecordFieldNameAndID());
|
||||
|
||||
|
@ -17,7 +17,7 @@ class Record;
|
||||
|
||||
/// Sort an array of Records on the "Name" field, and check for records with
|
||||
/// duplicate "Name" field. If duplicates are found, report a fatal error.
|
||||
void sortAndReportDuplicates(MutableArrayRef<Record *> Records,
|
||||
void sortAndReportDuplicates(MutableArrayRef<const Record *> Records,
|
||||
StringRef ObjectName);
|
||||
|
||||
} // namespace llvm
|
||||
|
@ -100,13 +100,13 @@ int DFAPacketizerEmitter::collectAllFuncUnits(
|
||||
LLVM_DEBUG(dbgs() << "collectAllFuncUnits");
|
||||
LLVM_DEBUG(dbgs() << " (" << ProcModels.size() << " itineraries)\n");
|
||||
|
||||
std::set<Record *> ProcItinList;
|
||||
std::set<const Record *> ProcItinList;
|
||||
for (const CodeGenProcModel *Model : ProcModels)
|
||||
ProcItinList.insert(Model->ItinsDef);
|
||||
|
||||
int totalFUs = 0;
|
||||
// Parse functional units for all the itineraries.
|
||||
for (Record *Proc : ProcItinList) {
|
||||
for (const Record *Proc : ProcItinList) {
|
||||
std::vector<Record *> FUs = Proc->getValueAsListOfDefs("FU");
|
||||
|
||||
LLVM_DEBUG(dbgs() << " FU:"
|
||||
|
@ -115,11 +115,12 @@ class SubtargetEmitter {
|
||||
raw_ostream &OS);
|
||||
void EmitProcessorResources(const CodeGenProcModel &ProcModel,
|
||||
raw_ostream &OS);
|
||||
Record *FindWriteResources(const CodeGenSchedRW &SchedWrite,
|
||||
const CodeGenProcModel &ProcModel);
|
||||
Record *FindReadAdvance(const CodeGenSchedRW &SchedRead,
|
||||
const CodeGenProcModel &ProcModel);
|
||||
void ExpandProcResources(RecVec &PRVec, std::vector<int64_t> &ReleaseAtCycles,
|
||||
const Record *FindWriteResources(const CodeGenSchedRW &SchedWrite,
|
||||
const CodeGenProcModel &ProcModel);
|
||||
const Record *FindReadAdvance(const CodeGenSchedRW &SchedRead,
|
||||
const CodeGenProcModel &ProcModel);
|
||||
void ExpandProcResources(ConstRecVec &PRVec,
|
||||
std::vector<int64_t> &ReleaseAtCycles,
|
||||
std::vector<int64_t> &AcquireAtCycles,
|
||||
const CodeGenProcModel &ProcModel);
|
||||
void GenSchedClassTables(const CodeGenProcModel &ProcModel,
|
||||
@ -251,8 +252,9 @@ void SubtargetEmitter::EmitSubtargetInfoMacroCalls(raw_ostream &OS) {
|
||||
//
|
||||
unsigned SubtargetEmitter::FeatureKeyValues(
|
||||
raw_ostream &OS, const DenseMap<Record *, unsigned> &FeatureMap) {
|
||||
std::vector<Record *> FeatureList =
|
||||
Records.getAllDerivedDefinitions("SubtargetFeature");
|
||||
const RecordKeeper &RCConst = Records;
|
||||
std::vector<const Record *> FeatureList =
|
||||
RCConst.getAllDerivedDefinitions("SubtargetFeature");
|
||||
|
||||
// Remove features with empty name.
|
||||
llvm::erase_if(FeatureList, [](const Record *Rec) {
|
||||
@ -434,7 +436,7 @@ void SubtargetEmitter::FormItineraryBypassString(const std::string &Name,
|
||||
void SubtargetEmitter::EmitStageAndOperandCycleData(
|
||||
raw_ostream &OS, std::vector<std::vector<InstrItinerary>> &ProcItinLists) {
|
||||
// Multiple processor models may share an itinerary record. Emit it once.
|
||||
SmallPtrSet<Record *, 8> ItinsDefSet;
|
||||
SmallPtrSet<const Record *, 8> ItinsDefSet;
|
||||
|
||||
// Emit functional units for all the itineraries.
|
||||
for (const CodeGenProcModel &ProcModel : SchedModels.procModels()) {
|
||||
@ -610,7 +612,7 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(
|
||||
void SubtargetEmitter::EmitItineraries(
|
||||
raw_ostream &OS, std::vector<std::vector<InstrItinerary>> &ProcItinLists) {
|
||||
// Multiple processor models may share an itinerary record. Emit it once.
|
||||
SmallPtrSet<Record *, 8> ItinsDefSet;
|
||||
SmallPtrSet<const Record *, 8> ItinsDefSet;
|
||||
|
||||
// For each processor's machine model
|
||||
std::vector<std::vector<InstrItinerary>>::iterator ProcItinListsIter =
|
||||
@ -619,7 +621,7 @@ void SubtargetEmitter::EmitItineraries(
|
||||
PE = SchedModels.procModelEnd();
|
||||
PI != PE; ++PI, ++ProcItinListsIter) {
|
||||
|
||||
Record *ItinsDef = PI->ItinsDef;
|
||||
const Record *ItinsDef = PI->ItinsDef;
|
||||
if (!ItinsDefSet.insert(ItinsDef).second)
|
||||
continue;
|
||||
|
||||
@ -677,12 +679,12 @@ void SubtargetEmitter::EmitProcessorResourceSubUnits(
|
||||
<< " 0, // Invalid\n";
|
||||
|
||||
for (unsigned i = 0, e = ProcModel.ProcResourceDefs.size(); i < e; ++i) {
|
||||
Record *PRDef = ProcModel.ProcResourceDefs[i];
|
||||
const Record *PRDef = ProcModel.ProcResourceDefs[i];
|
||||
if (!PRDef->isSubClassOf("ProcResGroup"))
|
||||
continue;
|
||||
RecVec ResUnits = PRDef->getValueAsListOfDefs("Resources");
|
||||
for (Record *RUDef : ResUnits) {
|
||||
Record *const RU =
|
||||
for (const Record *RUDef : ResUnits) {
|
||||
const Record *RU =
|
||||
SchedModels.findProcResUnits(RUDef, ProcModel, PRDef->getLoc());
|
||||
for (unsigned J = 0; J < RU->getValueAsInt("NumUnits"); ++J) {
|
||||
OS << " " << ProcModel.getProcResourceIdx(RU) << ", ";
|
||||
@ -696,7 +698,7 @@ void SubtargetEmitter::EmitProcessorResourceSubUnits(
|
||||
static void EmitRetireControlUnitInfo(const CodeGenProcModel &ProcModel,
|
||||
raw_ostream &OS) {
|
||||
int64_t ReorderBufferSize = 0, MaxRetirePerCycle = 0;
|
||||
if (Record *RCU = ProcModel.RetireControlUnit) {
|
||||
if (const Record *RCU = ProcModel.RetireControlUnit) {
|
||||
ReorderBufferSize =
|
||||
std::max(ReorderBufferSize, RCU->getValueAsInt("ReorderBufferSize"));
|
||||
MaxRetirePerCycle =
|
||||
@ -832,9 +834,9 @@ void SubtargetEmitter::EmitProcessorResources(const CodeGenProcModel &ProcModel,
|
||||
|
||||
unsigned SubUnitsOffset = 1;
|
||||
for (unsigned i = 0, e = ProcModel.ProcResourceDefs.size(); i < e; ++i) {
|
||||
Record *PRDef = ProcModel.ProcResourceDefs[i];
|
||||
const Record *PRDef = ProcModel.ProcResourceDefs[i];
|
||||
|
||||
Record *SuperDef = nullptr;
|
||||
const Record *SuperDef = nullptr;
|
||||
unsigned SuperIdx = 0;
|
||||
unsigned NumUnits = 0;
|
||||
const unsigned SubUnitsBeginOffset = SubUnitsOffset;
|
||||
@ -875,7 +877,7 @@ void SubtargetEmitter::EmitProcessorResources(const CodeGenProcModel &ProcModel,
|
||||
|
||||
// Find the WriteRes Record that defines processor resources for this
|
||||
// SchedWrite.
|
||||
Record *
|
||||
const Record *
|
||||
SubtargetEmitter::FindWriteResources(const CodeGenSchedRW &SchedWrite,
|
||||
const CodeGenProcModel &ProcModel) {
|
||||
|
||||
@ -884,12 +886,12 @@ SubtargetEmitter::FindWriteResources(const CodeGenSchedRW &SchedWrite,
|
||||
if (SchedWrite.TheDef->isSubClassOf("SchedWriteRes"))
|
||||
return SchedWrite.TheDef;
|
||||
|
||||
Record *AliasDef = nullptr;
|
||||
for (Record *A : SchedWrite.Aliases) {
|
||||
const Record *AliasDef = nullptr;
|
||||
for (const Record *A : SchedWrite.Aliases) {
|
||||
const CodeGenSchedRW &AliasRW =
|
||||
SchedModels.getSchedRW(A->getValueAsDef("AliasRW"));
|
||||
if (AliasRW.TheDef->getValueInit("SchedModel")->isComplete()) {
|
||||
Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel");
|
||||
const Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel");
|
||||
if (&SchedModels.getProcModel(ModelDef) != &ProcModel)
|
||||
continue;
|
||||
}
|
||||
@ -905,11 +907,11 @@ SubtargetEmitter::FindWriteResources(const CodeGenSchedRW &SchedWrite,
|
||||
return AliasDef;
|
||||
|
||||
// Check this processor's list of write resources.
|
||||
Record *ResDef = nullptr;
|
||||
for (Record *WR : ProcModel.WriteResDefs) {
|
||||
const Record *ResDef = nullptr;
|
||||
for (const Record *WR : ProcModel.WriteResDefs) {
|
||||
if (!WR->isSubClassOf("WriteRes"))
|
||||
continue;
|
||||
Record *WRDef = WR->getValueAsDef("WriteType");
|
||||
const Record *WRDef = WR->getValueAsDef("WriteType");
|
||||
if (AliasDef == WRDef || SchedWrite.TheDef == WRDef) {
|
||||
if (ResDef) {
|
||||
PrintFatalError(WR->getLoc(), "Resources are defined for both "
|
||||
@ -936,19 +938,20 @@ SubtargetEmitter::FindWriteResources(const CodeGenSchedRW &SchedWrite,
|
||||
|
||||
/// Find the ReadAdvance record for the given SchedRead on this processor or
|
||||
/// return NULL.
|
||||
Record *SubtargetEmitter::FindReadAdvance(const CodeGenSchedRW &SchedRead,
|
||||
const CodeGenProcModel &ProcModel) {
|
||||
const Record *
|
||||
SubtargetEmitter::FindReadAdvance(const CodeGenSchedRW &SchedRead,
|
||||
const CodeGenProcModel &ProcModel) {
|
||||
// Check for SchedReads that directly specify a ReadAdvance.
|
||||
if (SchedRead.TheDef->isSubClassOf("SchedReadAdvance"))
|
||||
return SchedRead.TheDef;
|
||||
|
||||
// Check this processor's list of aliases for SchedRead.
|
||||
Record *AliasDef = nullptr;
|
||||
for (Record *A : SchedRead.Aliases) {
|
||||
const Record *AliasDef = nullptr;
|
||||
for (const Record *A : SchedRead.Aliases) {
|
||||
const CodeGenSchedRW &AliasRW =
|
||||
SchedModels.getSchedRW(A->getValueAsDef("AliasRW"));
|
||||
if (AliasRW.TheDef->getValueInit("SchedModel")->isComplete()) {
|
||||
Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel");
|
||||
const Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel");
|
||||
if (&SchedModels.getProcModel(ModelDef) != &ProcModel)
|
||||
continue;
|
||||
}
|
||||
@ -964,11 +967,11 @@ Record *SubtargetEmitter::FindReadAdvance(const CodeGenSchedRW &SchedRead,
|
||||
return AliasDef;
|
||||
|
||||
// Check this processor's ReadAdvanceList.
|
||||
Record *ResDef = nullptr;
|
||||
for (Record *RA : ProcModel.ReadAdvanceDefs) {
|
||||
const Record *ResDef = nullptr;
|
||||
for (const Record *RA : ProcModel.ReadAdvanceDefs) {
|
||||
if (!RA->isSubClassOf("ReadAdvance"))
|
||||
continue;
|
||||
Record *RADef = RA->getValueAsDef("ReadType");
|
||||
const Record *RADef = RA->getValueAsDef("ReadType");
|
||||
if (AliasDef == RADef || SchedRead.TheDef == RADef) {
|
||||
if (ResDef) {
|
||||
PrintFatalError(RA->getLoc(), "Resources are defined for both "
|
||||
@ -996,25 +999,25 @@ Record *SubtargetEmitter::FindReadAdvance(const CodeGenSchedRW &SchedRead,
|
||||
// Expand an explicit list of processor resources into a full list of implied
|
||||
// resource groups and super resources that cover them.
|
||||
void SubtargetEmitter::ExpandProcResources(
|
||||
RecVec &PRVec, std::vector<int64_t> &ReleaseAtCycles,
|
||||
ConstRecVec &PRVec, std::vector<int64_t> &ReleaseAtCycles,
|
||||
std::vector<int64_t> &AcquireAtCycles, const CodeGenProcModel &PM) {
|
||||
assert(PRVec.size() == ReleaseAtCycles.size() && "failed precondition");
|
||||
for (unsigned i = 0, e = PRVec.size(); i != e; ++i) {
|
||||
Record *PRDef = PRVec[i];
|
||||
RecVec SubResources;
|
||||
const Record *PRDef = PRVec[i];
|
||||
ConstRecVec SubResources;
|
||||
if (PRDef->isSubClassOf("ProcResGroup"))
|
||||
SubResources = PRDef->getValueAsListOfDefs("Resources");
|
||||
SubResources = PRDef->getValueAsListOfConstDefs("Resources");
|
||||
else {
|
||||
SubResources.push_back(PRDef);
|
||||
PRDef = SchedModels.findProcResUnits(PRDef, PM, PRDef->getLoc());
|
||||
for (Record *SubDef = PRDef;
|
||||
for (const Record *SubDef = PRDef;
|
||||
SubDef->getValueInit("Super")->isComplete();) {
|
||||
if (SubDef->isSubClassOf("ProcResGroup")) {
|
||||
// Disallow this for simplicitly.
|
||||
PrintFatalError(SubDef->getLoc(), "Processor resource group "
|
||||
" cannot be a super resources.");
|
||||
}
|
||||
Record *SuperDef = SchedModels.findProcResUnits(
|
||||
const Record *SuperDef = SchedModels.findProcResUnits(
|
||||
SubDef->getValueAsDef("Super"), PM, SubDef->getLoc());
|
||||
PRVec.push_back(SuperDef);
|
||||
ReleaseAtCycles.push_back(ReleaseAtCycles[i]);
|
||||
@ -1022,11 +1025,11 @@ void SubtargetEmitter::ExpandProcResources(
|
||||
SubDef = SuperDef;
|
||||
}
|
||||
}
|
||||
for (Record *PR : PM.ProcResourceDefs) {
|
||||
for (const Record *PR : PM.ProcResourceDefs) {
|
||||
if (PR == PRDef || !PR->isSubClassOf("ProcResGroup"))
|
||||
continue;
|
||||
RecVec SuperResources = PR->getValueAsListOfDefs("Resources");
|
||||
RecIter SubI = SubResources.begin(), SubE = SubResources.end();
|
||||
ConstRecIter SubI = SubResources.begin(), SubE = SubResources.end();
|
||||
for (; SubI != SubE; ++SubI) {
|
||||
if (!is_contained(SuperResources, *SubI)) {
|
||||
break;
|
||||
@ -1091,9 +1094,9 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
|
||||
if (!SC.InstRWs.empty()) {
|
||||
// This class has a default ReadWrite list which can be overridden by
|
||||
// InstRW definitions.
|
||||
Record *RWDef = nullptr;
|
||||
for (Record *RW : SC.InstRWs) {
|
||||
Record *RWModelDef = RW->getValueAsDef("SchedModel");
|
||||
const Record *RWDef = nullptr;
|
||||
for (const Record *RW : SC.InstRWs) {
|
||||
const Record *RWModelDef = RW->getValueAsDef("SchedModel");
|
||||
if (&ProcModel == &SchedModels.getProcModel(RWModelDef)) {
|
||||
RWDef = RW;
|
||||
break;
|
||||
@ -1108,7 +1111,7 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
|
||||
}
|
||||
if (Writes.empty()) {
|
||||
// Check this processor's itinerary class resources.
|
||||
for (Record *I : ProcModel.ItinRWDefs) {
|
||||
for (const Record *I : ProcModel.ItinRWDefs) {
|
||||
RecVec Matched = I->getValueAsListOfDefs("MatchedItinClasses");
|
||||
if (is_contained(Matched, SC.ItinClassDef)) {
|
||||
SchedModels.findRWs(I->getValueAsListOfDefs("OperandReadWrites"),
|
||||
@ -1144,8 +1147,7 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
|
||||
WLEntry.WriteResourceID = WriteID;
|
||||
|
||||
for (unsigned WS : WriteSeq) {
|
||||
|
||||
Record *WriteRes =
|
||||
const Record *WriteRes =
|
||||
FindWriteResources(SchedModels.getSchedWrite(WS), ProcModel);
|
||||
|
||||
// Mark the parent class as invalid for unsupported write types.
|
||||
@ -1162,7 +1164,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
|
||||
SCDesc.RetireOOO |= WriteRes->getValueAsBit("RetireOOO");
|
||||
|
||||
// Create an entry for each ProcResource listed in WriteRes.
|
||||
RecVec PRVec = WriteRes->getValueAsListOfDefs("ProcResources");
|
||||
ConstRecVec PRVec =
|
||||
WriteRes->getValueAsListOfConstDefs("ProcResources");
|
||||
std::vector<int64_t> ReleaseAtCycles =
|
||||
WriteRes->getValueAsListOfInts("ReleaseAtCycles");
|
||||
|
||||
@ -1261,7 +1264,7 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
|
||||
// Entries must be sorted first by UseIdx then by WriteResourceID.
|
||||
for (unsigned UseIdx = 0, EndIdx = Reads.size(); UseIdx != EndIdx;
|
||||
++UseIdx) {
|
||||
Record *ReadAdvance =
|
||||
const Record *ReadAdvance =
|
||||
FindReadAdvance(SchedModels.getSchedRead(Reads[UseIdx]), ProcModel);
|
||||
if (!ReadAdvance)
|
||||
continue;
|
||||
|
Loading…
x
Reference in New Issue
Block a user