From 2062b1260fa9df3e69e7b4d24a657a0ebb7f8710 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Wed, 3 Oct 2012 23:06:28 +0000 Subject: TableGen subtarget emitter, nearly first class support for SchedAlias. A processor can now arbitrarily alias one SchedWrite onto another. Only the SchedAlias definition need be within the processor model. The aliased SchedWrite may be a SchedVariant, WriteSequence, or transitively refer to another alias. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165179 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenSchedule.cpp | 311 +++++++++++++++++++++++------------- utils/TableGen/CodeGenSchedule.h | 26 +-- utils/TableGen/SubtargetEmitter.cpp | 22 ++- 3 files changed, 229 insertions(+), 130 deletions(-) diff --git a/utils/TableGen/CodeGenSchedule.cpp b/utils/TableGen/CodeGenSchedule.cpp index 15af7a8ae2..90bc5b4e15 100644 --- a/utils/TableGen/CodeGenSchedule.cpp +++ b/utils/TableGen/CodeGenSchedule.cpp @@ -225,12 +225,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(*SWI)); + SchedWrites.push_back(CodeGenSchedRW(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(*SRI)); + SchedReads.push_back(CodeGenSchedRW(SchedReads.size(), *SRI)); } // Initialize WriteSequence vectors. for (std::vector::iterator WI = SchedWrites.begin(), @@ -362,6 +362,47 @@ void CodeGenSchedModels::expandRWSequence(unsigned RWIdx, IdxVec &RWSeq, } } +// Expand a SchedWrite as a sequence following any aliases that coincide with +// the given processor model. +void CodeGenSchedModels::expandRWSeqForProc( + unsigned RWIdx, IdxVec &RWSeq, bool IsRead, + const CodeGenProcModel &ProcModel) const { + + const CodeGenSchedRW &SchedWrite = getSchedRW(RWIdx, IsRead); + Record *AliasDef = 0; + for (RecIter AI = SchedWrite.Aliases.begin(), AE = SchedWrite.Aliases.end(); + AI != AE; ++AI) { + const CodeGenSchedRW &AliasRW = getSchedRW((*AI)->getValueAsDef("AliasRW")); + if ((*AI)->getValueInit("SchedModel")->isComplete()) { + Record *ModelDef = (*AI)->getValueAsDef("SchedModel"); + if (&getProcModel(ModelDef) != &ProcModel) + continue; + } + if (AliasDef) + throw TGError(AliasRW.TheDef->getLoc(), "Multiple aliases " + "defined for processor " + ProcModel.ModelName + + " Ensure only one SchedAlias exists per RW."); + AliasDef = AliasRW.TheDef; + } + if (AliasDef) { + expandRWSeqForProc(getSchedRWIdx(AliasDef, IsRead), + RWSeq, IsRead,ProcModel); + return; + } + if (!SchedWrite.IsSequence) { + RWSeq.push_back(RWIdx); + return; + } + int Repeat = + SchedWrite.TheDef ? SchedWrite.TheDef->getValueAsInt("Repeat") : 1; + for (int i = 0; i < Repeat; ++i) { + for (IdxIter I = SchedWrite.Sequence.begin(), E = SchedWrite.Sequence.end(); + I != E; ++I) { + expandRWSeqForProc(*I, RWSeq, IsRead, ProcModel); + } + } +} + // Find the existing SchedWrite that models this sequence of writes. unsigned CodeGenSchedModels::findRWForSequence(const IdxVec &Seq, bool IsRead) { @@ -387,13 +428,13 @@ unsigned CodeGenSchedModels::findOrInsertRW(ArrayRef Seq, if (Idx) return Idx; - CodeGenSchedRW SchedRW(Seq, genRWName(Seq, IsRead)); - if (IsRead) { + unsigned RWIdx = IsRead ? SchedReads.size() : SchedWrites.size(); + CodeGenSchedRW SchedRW(RWIdx, IsRead, Seq, genRWName(Seq, IsRead)); + if (IsRead) SchedReads.push_back(SchedRW); - return SchedReads.size() - 1; - } - SchedWrites.push_back(SchedRW); - return SchedWrites.size() - 1; + else + SchedWrites.push_back(SchedRW); + return RWIdx; } /// Visit all the instruction definitions for this target to gather and @@ -794,13 +835,13 @@ void CodeGenSchedModels::inferFromInstRWs(unsigned SCIdx) { namespace { // Helper for substituteVariantOperand. struct TransVariant { - Record *VariantDef; - unsigned RWIdx; // Index of this variant's matched type. + 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): - VariantDef(def), RWIdx(rwi), ProcIdx(pi), TransVecIdx(ti) {} + VarOrSeqDef(def), RWIdx(rwi), ProcIdx(pi), TransVecIdx(ti) {} }; // Associate a predicate with the SchedReadWrite that it guards. @@ -843,6 +884,9 @@ public: private: bool mutuallyExclusive(Record *PredDef, ArrayRef Term); + void getIntersectingVariants( + const CodeGenSchedRW &SchedRW, unsigned TransIdx, + std::vector &IntersectingVariants); void pushVariant(const TransVariant &VInfo, bool IsRead); }; } // anonymous @@ -875,6 +919,137 @@ bool PredTransitions::mutuallyExclusive(Record *PredDef, return false; } +static bool hasAliasedVariants(const CodeGenSchedRW &RW, + CodeGenSchedModels &SchedModels) { + if (RW.HasVariants) + return true; + + for (RecIter I = RW.Aliases.begin(), E = RW.Aliases.end(); I != E; ++I) { + const CodeGenSchedRW &AliasRW = + SchedModels.getSchedRW((*I)->getValueAsDef("AliasRW")); + if (AliasRW.HasVariants) + return true; + if (AliasRW.IsSequence) { + IdxVec ExpandedRWs; + SchedModels.expandRWSequence(AliasRW.Index, ExpandedRWs, AliasRW.IsRead); + for (IdxIter SI = ExpandedRWs.begin(), SE = ExpandedRWs.end(); + SI != SE; ++SI) { + if (hasAliasedVariants(SchedModels.getSchedRW(*SI, AliasRW.IsRead), + SchedModels)) { + return true; + } + } + } + } + return false; +} + +static bool hasVariant(ArrayRef Transitions, + CodeGenSchedModels &SchedModels) { + for (ArrayRef::iterator + PTI = Transitions.begin(), PTE = Transitions.end(); + PTI != PTE; ++PTI) { + for (SmallVectorImpl >::const_iterator + WSI = PTI->WriteSequences.begin(), WSE = PTI->WriteSequences.end(); + WSI != WSE; ++WSI) { + for (SmallVectorImpl::const_iterator + WI = WSI->begin(), WE = WSI->end(); WI != WE; ++WI) { + if (hasAliasedVariants(SchedModels.getSchedWrite(*WI), SchedModels)) + return true; + } + } + for (SmallVectorImpl >::const_iterator + RSI = PTI->ReadSequences.begin(), RSE = PTI->ReadSequences.end(); + RSI != RSE; ++RSI) { + for (SmallVectorImpl::const_iterator + RI = RSI->begin(), RE = RSI->end(); RI != RE; ++RI) { + if (hasAliasedVariants(SchedModels.getSchedRead(*RI), SchedModels)) + return true; + } + } + } + return false; +} + +// Populate IntersectingVariants with any variants or aliased sequences of the +// given SchedRW whose processor indices and predicates are not mutually +// exclusive with the given transition, +void PredTransitions::getIntersectingVariants( + const CodeGenSchedRW &SchedRW, unsigned TransIdx, + std::vector &IntersectingVariants) { + + std::vector Variants; + if (SchedRW.HasVariants) { + unsigned VarProcIdx = 0; + if (SchedRW.TheDef->getValueInit("SchedModel")->isComplete()) { + Record *ModelDef = SchedRW.TheDef->getValueAsDef("SchedModel"); + VarProcIdx = SchedModels.getProcModel(ModelDef).Index; + } + // Push each variant. Assign TransVecIdx later. + const RecVec VarDefs = SchedRW.TheDef->getValueAsListOfDefs("Variants"); + for (RecIter RI = VarDefs.begin(), RE = VarDefs.end(); RI != RE; ++RI) + Variants.push_back(TransVariant(*RI, SchedRW.Index, VarProcIdx, 0)); + } + for (RecIter 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 + // that processor. + unsigned AliasProcIdx = 0; + if ((*AI)->getValueInit("SchedModel")->isComplete()) { + Record *ModelDef = (*AI)->getValueAsDef("SchedModel"); + AliasProcIdx = SchedModels.getProcModel(ModelDef).Index; + } + const CodeGenSchedRW &AliasRW = + SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW")); + + if (AliasRW.HasVariants) { + const RecVec VarDefs = AliasRW.TheDef->getValueAsListOfDefs("Variants"); + for (RecIter RI = VarDefs.begin(), RE = VarDefs.end(); RI != RE; ++RI) + Variants.push_back(TransVariant(*RI, AliasRW.Index, AliasProcIdx, 0)); + } + if (AliasRW.IsSequence) { + Variants.push_back( + TransVariant(AliasRW.TheDef, SchedRW.Index, AliasProcIdx, 0)); + } + } + for (unsigned VIdx = 0, VEnd = Variants.size(); VIdx != VEnd; ++VIdx) { + 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; + if (ProcIndices[0] && Variants[VIdx].ProcIdx) { + unsigned Cnt = std::count(ProcIndices.begin(), ProcIndices.end(), + Variant.ProcIdx); + if (!Cnt) + continue; + if (Cnt > 1) { + const CodeGenProcModel &PM = + *(SchedModels.procModelBegin() + Variant.ProcIdx); + throw TGError(Variant.VarOrSeqDef->getLoc(), + "Multiple variants defined for processor " + PM.ModelName + + " Ensure only one SchedAlias exists per RW."); + } + } + if (Variant.VarOrSeqDef->isSubClassOf("SchedVar")) { + Record *PredDef = Variant.VarOrSeqDef->getValueAsDef("Predicate"); + if (mutuallyExclusive(PredDef, TransVec[TransIdx].PredTerm)) + continue; + } + if (IntersectingVariants.empty()) { + // The first variant builds on the existing transition. + Variant.TransVecIdx = TransIdx; + IntersectingVariants.push_back(Variant); + } + else { + // Push another copy of the current transition for more variants. + Variant.TransVecIdx = TransVec.size(); + IntersectingVariants.push_back(Variant); + TransVec.push_back(TransVec[TransIdx]); + } + } +} + // Push the Reads/Writes selected by this variant onto the PredTransition // specified by VInfo. void PredTransitions:: @@ -882,17 +1057,23 @@ pushVariant(const TransVariant &VInfo, bool IsRead) { PredTransition &Trans = TransVec[VInfo.TransVecIdx]; - Record *PredDef = VInfo.VariantDef->getValueAsDef("Predicate"); - Trans.PredTerm.push_back(PredCheck(IsRead, VInfo.RWIdx,PredDef)); - // If this operand transition is reached through a processor-specific alias, // then the whole transition is specific to this processor. if (VInfo.ProcIdx != 0) Trans.ProcIndices.assign(1, VInfo.ProcIdx); - RecVec SelectedDefs = VInfo.VariantDef->getValueAsListOfDefs("Selected"); IdxVec SelectedRWs; - SchedModels.findRWs(SelectedDefs, SelectedRWs, IsRead); + if (VInfo.VarOrSeqDef->isSubClassOf("SchedVar")) { + Record *PredDef = VInfo.VarOrSeqDef->getValueAsDef("Predicate"); + Trans.PredTerm.push_back(PredCheck(IsRead, VInfo.RWIdx,PredDef)); + RecVec SelectedDefs = VInfo.VarOrSeqDef->getValueAsListOfDefs("Selected"); + SchedModels.findRWs(SelectedDefs, SelectedRWs, IsRead); + } + else { + assert(VInfo.VarOrSeqDef->isSubClassOf("WriteSequence") && + "variant must be a SchedVariant or aliased WriteSequence"); + SelectedRWs.push_back(SchedModels.getSchedRWIdx(VInfo.VarOrSeqDef, IsRead)); + } const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(VInfo.RWIdx, IsRead); @@ -936,45 +1117,6 @@ pushVariant(const TransVariant &VInfo, bool IsRead) { } } -static bool hasAliasedVariants(const CodeGenSchedRW &RW, - CodeGenSchedModels &SchedModels) { - if (RW.HasVariants) - return true; - - for (RecIter I = RW.Aliases.begin(), E = RW.Aliases.end(); I != E; ++I) { - if (SchedModels.getSchedRW((*I)->getValueAsDef("AliasRW")).HasVariants) - return true; - } - return false; -} - -static bool hasVariant(ArrayRef Transitions, - CodeGenSchedModels &SchedModels) { - for (ArrayRef::iterator - PTI = Transitions.begin(), PTE = Transitions.end(); - PTI != PTE; ++PTI) { - for (SmallVectorImpl >::const_iterator - WSI = PTI->WriteSequences.begin(), WSE = PTI->WriteSequences.end(); - WSI != WSE; ++WSI) { - for (SmallVectorImpl::const_iterator - WI = WSI->begin(), WE = WSI->end(); WI != WE; ++WI) { - if (hasAliasedVariants(SchedModels.getSchedWrite(*WI), SchedModels)) - return true; - } - } - for (SmallVectorImpl >::const_iterator - RSI = PTI->ReadSequences.begin(), RSE = PTI->ReadSequences.end(); - RSI != RSE; ++RSI) { - for (SmallVectorImpl::const_iterator - RI = RSI->begin(), RE = RSI->end(); RI != RE; ++RI) { - if (hasAliasedVariants(SchedModels.getSchedRead(*RI), SchedModels)) - return true; - } - } - } - return false; -} - // RWSeq is a sequence of all Reads or all Writes for the next read or write // operand. StartIdx is an index into TransVec where partial results // starts. RWSeq must be applied to all transitions between StartIdx and the end @@ -1000,64 +1142,9 @@ void PredTransitions::substituteVariantOperand( continue; } // Distribute this partial PredTransition across intersecting variants. - RecVec Variants; - if (SchedRW.HasVariants) - Variants = SchedRW.TheDef->getValueAsListOfDefs("Variants"); - IdxVec VarRWIds(Variants.size(), *RWI); - IdxVec VarProcModels(Variants.size(), 0); - for (RecIter AI = SchedRW.Aliases.begin(), AE = SchedRW.Aliases.end(); - AI != AE; ++AI) { - unsigned AIdx; - const CodeGenSchedRW &AliasRW = - SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW"), AIdx); - if (!AliasRW.HasVariants) - continue; - - RecVec AliasVars = AliasRW.TheDef->getValueAsListOfDefs("Variants"); - Variants.insert(Variants.end(), AliasVars.begin(), AliasVars.end()); - - VarRWIds.resize(Variants.size(), AIdx); - - Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel"); - VarProcModels.resize(Variants.size(), - SchedModels.getProcModel(ModelDef).Index); - } + // This will push a copies of TransVec[TransIdx] on the back of TransVec. std::vector IntersectingVariants; - for (unsigned VIdx = 0, VEnd = Variants.size(); VIdx != VEnd; ++VIdx) { - Record *PredDef = Variants[VIdx]->getValueAsDef("Predicate"); - - // Don't expand variants if the processor models don't intersect. - // A zero processor index means any processor. - SmallVector &ProcIndices = TransVec[TransIdx].ProcIndices; - if (ProcIndices[0] != 0 && VarProcModels[VIdx] != 0) { - unsigned Cnt = std::count(ProcIndices.begin(), ProcIndices.end(), - VarProcModels[VIdx]); - if (!Cnt) - continue; - if (Cnt > 1) { - const CodeGenProcModel &PM = - *(SchedModels.procModelBegin() + VarProcModels[VIdx]); - throw TGError(Variants[VIdx]->getLoc(), "Multiple variants defined " - "for processor " + PM.ModelName + - " Ensure only one SchedAlias exists per RW."); - } - } - if (mutuallyExclusive(PredDef, TransVec[TransIdx].PredTerm)) - continue; - if (IntersectingVariants.empty()) { - // The first variant builds on the existing transition. - IntersectingVariants.push_back( - TransVariant(Variants[VIdx], VarRWIds[VIdx], VarProcModels[VIdx], - TransIdx)); - } - else { - // Push another copy of the current transition for more variants. - IntersectingVariants.push_back( - TransVariant(Variants[VIdx], VarRWIds[VIdx], VarProcModels[VIdx], - TransVec.size())); - TransVec.push_back(TransVec[TransIdx]); - } - } + getIntersectingVariants(SchedRW, TransIdx, IntersectingVariants); if (IntersectingVariants.empty()) throw TGError(SchedRW.TheDef->getLoc(), "No variant of this type has a " "matching predicate on any processor "); diff --git a/utils/TableGen/CodeGenSchedule.h b/utils/TableGen/CodeGenSchedule.h index 226c3aed5c..211c05c8c6 100644 --- a/utils/TableGen/CodeGenSchedule.h +++ b/utils/TableGen/CodeGenSchedule.h @@ -43,8 +43,10 @@ void splitSchedReadWrites(const RecVec &RWDefs, /// IsVariadic controls whether the variants are expanded into multiple operands /// or a sequence of writes on one operand. struct CodeGenSchedRW { + unsigned Index; std::string Name; Record *TheDef; + bool IsRead; bool IsAlias; bool HasVariants; bool IsVariadic; @@ -52,10 +54,12 @@ struct CodeGenSchedRW { IdxVec Sequence; RecVec Aliases; - CodeGenSchedRW(): TheDef(0), IsAlias(false), HasVariants(false), + CodeGenSchedRW(): Index(0), TheDef(0), IsAlias(false), HasVariants(false), IsVariadic(false), IsSequence(false) {} - CodeGenSchedRW(Record *Def): TheDef(Def), IsAlias(false), IsVariadic(false) { + CodeGenSchedRW(unsigned Idx, Record *Def): Index(Idx), TheDef(Def), + IsAlias(false), IsVariadic(false) { Name = Def->getName(); + IsRead = Def->isSubClassOf("SchedRead"); HasVariants = Def->isSubClassOf("SchedVariant"); if (HasVariants) IsVariadic = Def->getValueAsBit("Variadic"); @@ -66,9 +70,10 @@ struct CodeGenSchedRW { IsSequence = Def->isSubClassOf("WriteSequence"); } - CodeGenSchedRW(const IdxVec &Seq, const std::string &Name): - Name(Name), TheDef(0), IsAlias(false), HasVariants(false), - IsVariadic(false), IsSequence(true), Sequence(Seq) { + CodeGenSchedRW(unsigned Idx, bool Read, const IdxVec &Seq, + const std::string &Name): + Index(Idx), Name(Name), TheDef(0), IsRead(Read), IsAlias(false), + HasVariants(false), IsVariadic(false), IsSequence(true), Sequence(Seq) { assert(Sequence.size() > 1 && "implied sequence needs >1 RWs"); } @@ -286,15 +291,14 @@ public: const CodeGenSchedRW &getSchedRW(unsigned Idx, bool IsRead) const { return IsRead ? getSchedRead(Idx) : getSchedWrite(Idx); } - CodeGenSchedRW &getSchedRW(Record *Def, unsigned &Idx) { + CodeGenSchedRW &getSchedRW(Record *Def) { bool IsRead = Def->isSubClassOf("SchedRead"); - Idx = getSchedRWIdx(Def, IsRead); + unsigned Idx = getSchedRWIdx(Def, IsRead); return const_cast( IsRead ? getSchedRead(Idx) : getSchedWrite(Idx)); } - CodeGenSchedRW &getSchedRW(Record *Def) { - unsigned Idx; - return getSchedRW(Def, Idx); + const CodeGenSchedRW &getSchedRW(Record*Def) const { + return const_cast(*this).getSchedRW(Def); } unsigned getSchedRWIdx(Record *Def, bool IsRead, unsigned After = 0) const; @@ -340,6 +344,8 @@ public: void findRWs(const RecVec &RWDefs, IdxVec &Writes, IdxVec &Reads) const; void findRWs(const RecVec &RWDefs, IdxVec &RWs, bool IsRead) const; void expandRWSequence(unsigned RWIdx, IdxVec &RWSeq, bool IsRead) const; + void expandRWSeqForProc(unsigned RWIdx, IdxVec &RWSeq, bool IsRead, + const CodeGenProcModel &ProcModel) const; unsigned addSchedClass(const IdxVec &OperWrites, const IdxVec &OperReads, const IdxVec &ProcIndices); diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp index f115af1016..6ffdeb45e1 100644 --- a/utils/TableGen/SubtargetEmitter.cpp +++ b/utils/TableGen/SubtargetEmitter.cpp @@ -664,15 +664,16 @@ Record *SubtargetEmitter::FindWriteResources( if (SchedWrite.TheDef->isSubClassOf("SchedWriteRes")) return SchedWrite.TheDef; - // Check this processor's list of aliases for SchedWrite. Record *AliasDef = 0; for (RecIter AI = SchedWrite.Aliases.begin(), AE = SchedWrite.Aliases.end(); AI != AE; ++AI) { const CodeGenSchedRW &AliasRW = SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW")); - Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel"); - if (&SchedModels.getProcModel(ModelDef) != &ProcModel) - continue; + if (AliasRW.TheDef->getValueInit("SchedModel")->isComplete()) { + Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel"); + if (&SchedModels.getProcModel(ModelDef) != &ProcModel) + continue; + } if (AliasDef) throw TGError(AliasRW.TheDef->getLoc(), "Multiple aliases " "defined for processor " + ProcModel.ModelName + @@ -722,9 +723,11 @@ Record *SubtargetEmitter::FindReadAdvance(const CodeGenSchedRW &SchedRead, AI != AE; ++AI) { const CodeGenSchedRW &AliasRW = SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW")); - Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel"); - if (&SchedModels.getProcModel(ModelDef) != &ProcModel) - continue; + if (AliasRW.TheDef->getValueInit("SchedModel")->isComplete()) { + Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel"); + if (&SchedModels.getProcModel(ModelDef) != &ProcModel) + continue; + } if (AliasDef) throw TGError(AliasRW.TheDef->getLoc(), "Multiple aliases " "defined for processor " + ProcModel.ModelName + @@ -833,6 +836,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel, } } if (RWDef) { + Writes.clear(); + Reads.clear(); SchedModels.findRWs(RWDef->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads); } @@ -844,7 +849,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel, std::vector ReadAdvanceEntries; for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI) { IdxVec WriteSeq; - SchedModels.expandRWSequence(*WI, WriteSeq, /*IsRead=*/false); + SchedModels.expandRWSeqForProc(*WI, WriteSeq, /*IsRead=*/false, + ProcModel); // For each operand, create a latency entry. MCWriteLatencyEntry WLEntry; -- cgit v1.2.3