X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FCodeGenSchedule.cpp;h=bc27481869fe8291184238c78c68c53121c6b7e3;hb=2515069180b0b99872f6358a16316a9d29ef5340;hp=f2af7edbb2efa54a1ffbca8909775424b2fad4c5;hpb=d7aad34bcbf90aa389f1cb73ade5a21897a73869;p=oota-llvm.git diff --git a/utils/TableGen/CodeGenSchedule.cpp b/utils/TableGen/CodeGenSchedule.cpp index f2af7edbb2e..bc27481869f 100644 --- a/utils/TableGen/CodeGenSchedule.cpp +++ b/utils/TableGen/CodeGenSchedule.cpp @@ -7,13 +7,11 @@ // //===----------------------------------------------------------------------===// // -// This file defines structures to encapsulate the machine model as decribed in +// This file defines structures to encapsulate the machine model as described in // the target description. // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "subtarget-emitter" - #include "CodeGenSchedule.h" #include "CodeGenTarget.h" #include "llvm/ADT/STLExtras.h" @@ -23,6 +21,8 @@ using namespace llvm; +#define DEBUG_TYPE "subtarget-emitter" + #ifndef NDEBUG static void dumpIdxVec(const IdxVec &V) { for (unsigned i = 0, e = V.size(); i < e; ++i) { @@ -36,10 +36,11 @@ static void dumpIdxVec(const SmallVectorImpl &V) { } #endif +namespace { // (instrs a, b, ...) Evaluate and union all arguments. Identical to AddOp. struct InstrsOp : public SetTheory::Operator { void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts, - ArrayRef Loc) { + ArrayRef Loc) override { ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts, Loc); } }; @@ -57,8 +58,8 @@ struct InstRegexOp : public SetTheory::Operator { InstRegexOp(const CodeGenTarget &t): Target(t) {} void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts, - ArrayRef Loc) { - SmallVector RegexList; + ArrayRef Loc) override { + SmallVector RegexList; for (DagInit::const_arg_iterator AI = Expr->arg_begin(), AE = Expr->arg_end(); AI != AE; ++AI) { StringInit *SI = dyn_cast(*AI); @@ -71,19 +72,17 @@ struct InstRegexOp : public SetTheory::Operator { pat.insert(0, "^("); pat.insert(pat.end(), ')'); } - RegexList.push_back(new Regex(pat)); - } - for (CodeGenTarget::inst_iterator I = Target.inst_begin(), - E = Target.inst_end(); I != E; ++I) { - for (SmallVectorImpl::iterator - RI = RegexList.begin(), RE = RegexList.end(); RI != RE; ++RI) { - if ((*RI)->match((*I)->TheDef->getName())) - Elts.insert((*I)->TheDef); + RegexList.push_back(Regex(pat)); + } + for (const CodeGenInstruction *Inst : Target.instructions()) { + for (auto &R : RegexList) { + if (R.match(Inst->TheDef->getName())) + Elts.insert(Inst->TheDef); } } - DeleteContainerPointers(RegexList); } }; +} // end anonymous namespace /// CodeGenModels ctor interprets machine model records and populates maps. CodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK, @@ -94,8 +93,8 @@ CodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK, // Allow Set evaluation to recognize the dags used in InstRW records: // (instrs Op1, Op1...) - Sets.addOperator("instrs", new InstrsOp); - Sets.addOperator("instregex", new InstRegexOp(Target)); + Sets.addOperator("instrs", llvm::make_unique()); + Sets.addOperator("instregex", llvm::make_unique(Target)); // Instantiate a CodeGenProcModel for each SchedMachineModel with the values // that are explicitly referenced in tablegen records. Resources associated @@ -146,8 +145,7 @@ void CodeGenSchedModels::collectProcModels() { // Use idx=0 for NoModel/NoItineraries. Record *NoModelDef = Records.getDef("NoSchedModel"); Record *NoItinsDef = Records.getDef("NoItineraries"); - ProcModels.push_back(CodeGenProcModel(0, "NoSchedModel", - NoModelDef, NoItinsDef)); + ProcModels.emplace_back(0, "NoSchedModel", NoModelDef, NoItinsDef); ProcModelMap[NoModelDef] = 0; // For each processor, find a unique machine model. @@ -165,16 +163,14 @@ void CodeGenSchedModels::addProcModel(Record *ProcDef) { std::string Name = ModelKey->getName(); if (ModelKey->isSubClassOf("SchedMachineModel")) { Record *ItinsDef = ModelKey->getValueAsDef("Itineraries"); - ProcModels.push_back( - CodeGenProcModel(ProcModels.size(), Name, ModelKey, ItinsDef)); + ProcModels.emplace_back(ProcModels.size(), Name, ModelKey, ItinsDef); } else { // An itinerary is defined without a machine model. Infer a new model. if (!ModelKey->getValueAsListOfDefs("IID").empty()) Name = Name + "Model"; - ProcModels.push_back( - CodeGenProcModel(ProcModels.size(), Name, - ProcDef->getValueAsDef("SchedModel"), ModelKey)); + ProcModels.emplace_back(ProcModels.size(), Name, + ProcDef->getValueAsDef("SchedModel"), ModelKey); } DEBUG(ProcModels.back().dump()); } @@ -182,7 +178,7 @@ void CodeGenSchedModels::addProcModel(Record *ProcDef) { // Recursively find all reachable SchedReadWrite records. static void scanSchedRW(Record *RWDef, RecVec &RWDefs, SmallPtrSet &RWSet) { - if (!RWSet.insert(RWDef)) + if (!RWSet.insert(RWDef).second) return; RWDefs.push_back(RWDef); // Reads don't current have sequence records, but it can be added later. @@ -214,9 +210,8 @@ void CodeGenSchedModels::collectSchedRW() { // Find all SchedReadWrites referenced by instruction defs. RecVec SWDefs, SRDefs; - for (CodeGenTarget::inst_iterator I = Target.inst_begin(), - E = Target.inst_end(); I != E; ++I) { - Record *SchedDef = (*I)->TheDef; + for (const CodeGenInstruction *Inst : Target.instructions()) { + Record *SchedDef = Inst->TheDef; if (SchedDef->isValueUnset("SchedRW")) continue; RecVec RWs = SchedDef->getValueAsListOfDefs("SchedRW"); @@ -283,12 +278,12 @@ void CodeGenSchedModels::collectSchedRW() { std::sort(SWDefs.begin(), SWDefs.end(), LessRecord()); for (RecIter SWI = SWDefs.begin(), SWE = SWDefs.end(); SWI != SWE; ++SWI) { assert(!getSchedRWIdx(*SWI, /*IsRead=*/false) && "duplicate SchedWrite"); - SchedWrites.push_back(CodeGenSchedRW(SchedWrites.size(), *SWI)); + SchedWrites.emplace_back(SchedWrites.size(), *SWI); } std::sort(SRDefs.begin(), SRDefs.end(), LessRecord()); for (RecIter SRI = SRDefs.begin(), SRE = SRDefs.end(); SRI != SRE; ++SRI) { assert(!getSchedRWIdx(*SRI, /*IsRead-*/true) && "duplicate SchedWrite"); - SchedReads.push_back(CodeGenSchedRW(SchedReads.size(), *SRI)); + SchedReads.emplace_back(SchedReads.size(), *SRI); } // Initialize WriteSequence vectors. for (std::vector::iterator WI = SchedWrites.begin(), @@ -427,7 +422,7 @@ void CodeGenSchedModels::expandRWSeqForProc( const CodeGenProcModel &ProcModel) const { const CodeGenSchedRW &SchedWrite = getSchedRW(RWIdx, IsRead); - Record *AliasDef = 0; + Record *AliasDef = nullptr; for (RecIter AI = SchedWrite.Aliases.begin(), AE = SchedWrite.Aliases.end(); AI != AE; ++AI) { const CodeGenSchedRW &AliasRW = getSchedRW((*AI)->getValueAsDef("AliasRW")); @@ -509,18 +504,17 @@ void CodeGenSchedModels::collectSchedClasses() { // Create a SchedClass for each unique combination of itinerary class and // SchedRW list. - for (CodeGenTarget::inst_iterator I = Target.inst_begin(), - E = Target.inst_end(); I != E; ++I) { - Record *ItinDef = (*I)->TheDef->getValueAsDef("Itinerary"); + for (const CodeGenInstruction *Inst : Target.instructions()) { + Record *ItinDef = Inst->TheDef->getValueAsDef("Itinerary"); IdxVec Writes, Reads; - if (!(*I)->TheDef->isValueUnset("SchedRW")) - findRWs((*I)->TheDef->getValueAsListOfDefs("SchedRW"), Writes, Reads); + if (!Inst->TheDef->isValueUnset("SchedRW")) + findRWs(Inst->TheDef->getValueAsListOfDefs("SchedRW"), Writes, Reads); // ProcIdx == 0 indicates the class applies to all processors. IdxVec ProcIndices(1, 0); unsigned SCIdx = addSchedClass(ItinDef, Writes, Reads, ProcIndices); - InstrClassMap[(*I)->TheDef] = SCIdx; + InstrClassMap[Inst->TheDef] = SCIdx; } // Create classes for InstRW defs. RecVec InstRWDefs = Records.getAllDerivedDefinitions("InstRW"); @@ -535,18 +529,16 @@ void CodeGenSchedModels::collectSchedClasses() { if (!EnableDump) return; - for (CodeGenTarget::inst_iterator I = Target.inst_begin(), - E = Target.inst_end(); I != E; ++I) { - - std::string InstName = (*I)->TheDef->getName(); - unsigned SCIdx = InstrClassMap.lookup((*I)->TheDef); + for (const CodeGenInstruction *Inst : Target.instructions()) { + std::string InstName = Inst->TheDef->getName(); + unsigned SCIdx = InstrClassMap.lookup(Inst->TheDef); if (!SCIdx) { - dbgs() << "No machine model for " << (*I)->TheDef->getName() << '\n'; + dbgs() << "No machine model for " << Inst->TheDef->getName() << '\n'; continue; } CodeGenSchedClass &SC = getSchedClass(SCIdx); if (SC.ProcIndices[0] != 0) - PrintFatalError((*I)->TheDef->getLoc(), "Instruction's sched class " + PrintFatalError(Inst->TheDef->getLoc(), "Instruction's sched class " "must not be subtarget specific."); IdxVec ProcIndices; @@ -584,7 +576,7 @@ void CodeGenSchedModels::collectSchedClasses() { for (std::vector::iterator PI = ProcModels.begin(), PE = ProcModels.end(); PI != PE; ++PI) { if (!std::count(ProcIndices.begin(), ProcIndices.end(), PI->Index)) - dbgs() << "No machine model for " << (*I)->TheDef->getName() + dbgs() << "No machine model for " << Inst->TheDef->getName() << " on processor " << PI->ModelName << '\n'; } } @@ -751,7 +743,7 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) { for (ArrayRef::const_iterator II = InstDefs.begin(), IE = InstDefs.end(); II != IE; ++II) { unsigned OldSCIdx = InstrClassMap[*II]; - if (OldSCIdx && RemappedClassIDs.insert(OldSCIdx)) { + if (OldSCIdx && RemappedClassIDs.insert(OldSCIdx).second) { for (RecIter RI = SchedClasses[OldSCIdx].InstRWs.begin(), RE = SchedClasses[OldSCIdx].InstRWs.end(); RI != RE; ++RI) { if ((*RI)->getValueAsDef("SchedModel") == RWModelDef) { @@ -781,9 +773,7 @@ bool CodeGenSchedModels::hasItineraries() const { // Gather the processor itineraries. void CodeGenSchedModels::collectProcItins() { - for (std::vector::iterator PI = ProcModels.begin(), - PE = ProcModels.end(); PI != PE; ++PI) { - CodeGenProcModel &ProcModel = *PI; + for (CodeGenProcModel &ProcModel : ProcModels) { if (!ProcModel.hasItineraries()) continue; @@ -890,9 +880,10 @@ void CodeGenSchedModels::inferFromItinClass(Record *ItinClassDef, /// Infer classes from per-processor InstReadWrite definitions. void CodeGenSchedModels::inferFromInstRWs(unsigned SCIdx) { - const RecVec &RWDefs = SchedClasses[SCIdx].InstRWs; - for (RecIter RWI = RWDefs.begin(), RWE = RWDefs.end(); RWI != RWE; ++RWI) { - const RecVec *InstDefs = Sets.expand(*RWI); + 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 RecVec *InstDefs = Sets.expand(Rec); RecIter II = InstDefs->begin(), IE = InstDefs->end(); for (; II != IE; ++II) { if (InstrClassMap[*II] == SCIdx) @@ -903,10 +894,10 @@ void CodeGenSchedModels::inferFromInstRWs(unsigned SCIdx) { if (II == IE) continue; IdxVec Writes, Reads; - findRWs((*RWI)->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads); - unsigned PIdx = getProcModel((*RWI)->getValueAsDef("SchedModel")).Index; + findRWs(Rec->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads); + unsigned PIdx = getProcModel(Rec->getValueAsDef("SchedModel")).Index; IdxVec ProcIndices(1, PIdx); - inferFromRW(Writes, Reads, SCIdx, ProcIndices); + inferFromRW(Writes, Reads, SCIdx, ProcIndices); // May mutate SchedClasses. } } @@ -1101,7 +1092,7 @@ void PredTransitions::getIntersectingVariants( TransVariant &Variant = Variants[VIdx]; // Don't expand variants if the processor models don't intersect. // A zero processor index means any processor. - SmallVector &ProcIndices = TransVec[TransIdx].ProcIndices; + SmallVectorImpl &ProcIndices = TransVec[TransIdx].ProcIndices; if (ProcIndices[0] && Variants[VIdx].ProcIdx) { unsigned Cnt = std::count(ProcIndices.begin(), ProcIndices.end(), Variant.ProcIdx); @@ -1172,6 +1163,8 @@ pushVariant(const TransVariant &VInfo, bool IsRead) { unsigned OperIdx = RWSequences.size()-1; // Make N-1 copies of this transition's last sequence. for (unsigned i = 1, e = SelectedRWs.size(); i != e; ++i) { + // Create a temporary copy the vector could reallocate. + RWSequences.reserve(RWSequences.size() + 1); RWSequences.push_back(RWSequences[OperIdx]); } // Push each of the N elements of the SelectedRWs onto a copy of the last @@ -1310,7 +1303,7 @@ static void inferFromTransitions(ArrayRef LastTransitions, IdxVec ProcIndices(I->ProcIndices.begin(), I->ProcIndices.end()); CodeGenSchedTransition SCTrans; SCTrans.ToClassIdx = - SchedModels.addSchedClass(/*ItinClassDef=*/0, OperWritesVariant, + SchedModels.addSchedClass(/*ItinClassDef=*/nullptr, OperWritesVariant, OperReadsVariant, ProcIndices); SCTrans.ProcIndices = ProcIndices; // The final PredTerm is unique set of predicates guarding the transition. @@ -1468,14 +1461,38 @@ void CodeGenSchedModels::collectProcResources() { Record *ModelDef = (*WRI)->getValueAsDef("SchedModel"); addWriteRes(*WRI, getProcModel(ModelDef).Index); } + RecVec SWRDefs = Records.getAllDerivedDefinitions("SchedWriteRes"); + for (RecIter WRI = SWRDefs.begin(), WRE = SWRDefs.end(); WRI != WRE; ++WRI) { + Record *ModelDef = (*WRI)->getValueAsDef("SchedModel"); + addWriteRes(*WRI, getProcModel(ModelDef).Index); + } RecVec RADefs = Records.getAllDerivedDefinitions("ReadAdvance"); for (RecIter RAI = RADefs.begin(), RAE = RADefs.end(); RAI != RAE; ++RAI) { Record *ModelDef = (*RAI)->getValueAsDef("SchedModel"); addReadAdvance(*RAI, getProcModel(ModelDef).Index); } + RecVec SRADefs = Records.getAllDerivedDefinitions("SchedReadAdvance"); + for (RecIter RAI = SRADefs.begin(), RAE = SRADefs.end(); RAI != RAE; ++RAI) { + if ((*RAI)->getValueInit("SchedModel")->isComplete()) { + Record *ModelDef = (*RAI)->getValueAsDef("SchedModel"); + addReadAdvance(*RAI, 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 (RecIter RI = ProcResGroups.begin(), RE = ProcResGroups.end(); + RI != RE; ++RI) { + if (!(*RI)->getValueInit("SchedModel")->isComplete()) + continue; + CodeGenProcModel &PM = getProcModel((*RI)->getValueAsDef("SchedModel")); + RecIter I = std::find(PM.ProcResourceDefs.begin(), + PM.ProcResourceDefs.end(), *RI); + if (I == PM.ProcResourceDefs.end()) + PM.ProcResourceDefs.push_back(*RI); + } // Finalize each ProcModel by sorting the record arrays. - for (unsigned PIdx = 0, PEnd = ProcModels.size(); PIdx != PEnd; ++PIdx) { - CodeGenProcModel &PM = ProcModels[PIdx]; + for (CodeGenProcModel &PM : ProcModels) { std::sort(PM.WriteResDefs.begin(), PM.WriteResDefs.end(), LessRecord()); std::sort(PM.ReadAdvanceDefs.begin(), PM.ReadAdvanceDefs.end(), @@ -1591,7 +1608,7 @@ Record *CodeGenSchedModels::findProcResUnits(Record *ProcResKind, if (ProcResKind->isSubClassOf("ProcResourceUnits")) return ProcResKind; - Record *ProcUnitDef = 0; + Record *ProcUnitDef = nullptr; RecVec ProcResourceDefs = Records.getAllDerivedDefinitions("ProcResourceUnits");