summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2012-10-03 23:06:28 +0000
committerAndrew Trick <atrick@apple.com>2012-10-03 23:06:28 +0000
commit2062b1260fa9df3e69e7b4d24a657a0ebb7f8710 (patch)
treeb34ff5dc391ba749e1ae3bf6fb29db3acd142cc3 /utils
parentfe05d98c253676d1ae6e0f03efde6b75fdae105d (diff)
downloadllvm-2062b1260fa9df3e69e7b4d24a657a0ebb7f8710.tar.gz
llvm-2062b1260fa9df3e69e7b4d24a657a0ebb7f8710.tar.bz2
llvm-2062b1260fa9df3e69e7b4d24a657a0ebb7f8710.tar.xz
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
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/CodeGenSchedule.cpp311
-rw-r--r--utils/TableGen/CodeGenSchedule.h26
-rw-r--r--utils/TableGen/SubtargetEmitter.cpp22
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<CodeGenSchedRW>::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<unsigned> 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<PredCheck> Term);
+ void getIntersectingVariants(
+ const CodeGenSchedRW &SchedRW, unsigned TransIdx,
+ std::vector<TransVariant> &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<PredTransition> Transitions,
+ CodeGenSchedModels &SchedModels) {
+ for (ArrayRef<PredTransition>::iterator
+ PTI = Transitions.begin(), PTE = Transitions.end();
+ PTI != PTE; ++PTI) {
+ for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
+ WSI = PTI->WriteSequences.begin(), WSE = PTI->WriteSequences.end();
+ WSI != WSE; ++WSI) {
+ for (SmallVectorImpl<unsigned>::const_iterator
+ WI = WSI->begin(), WE = WSI->end(); WI != WE; ++WI) {
+ if (hasAliasedVariants(SchedModels.getSchedWrite(*WI), SchedModels))
+ return true;
+ }
+ }
+ for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
+ RSI = PTI->ReadSequences.begin(), RSE = PTI->ReadSequences.end();
+ RSI != RSE; ++RSI) {
+ for (SmallVectorImpl<unsigned>::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<TransVariant> &IntersectingVariants) {
+
+ std::vector<TransVariant> 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<unsigned, 4> &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<PredTransition> Transitions,
- CodeGenSchedModels &SchedModels) {
- for (ArrayRef<PredTransition>::iterator
- PTI = Transitions.begin(), PTE = Transitions.end();
- PTI != PTE; ++PTI) {
- for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
- WSI = PTI->WriteSequences.begin(), WSE = PTI->WriteSequences.end();
- WSI != WSE; ++WSI) {
- for (SmallVectorImpl<unsigned>::const_iterator
- WI = WSI->begin(), WE = WSI->end(); WI != WE; ++WI) {
- if (hasAliasedVariants(SchedModels.getSchedWrite(*WI), SchedModels))
- return true;
- }
- }
- for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
- RSI = PTI->ReadSequences.begin(), RSE = PTI->ReadSequences.end();
- RSI != RSE; ++RSI) {
- for (SmallVectorImpl<unsigned>::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<TransVariant> 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<unsigned, 4> &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<CodeGenSchedRW&>(
IsRead ? getSchedRead(Idx) : getSchedWrite(Idx));
}
- CodeGenSchedRW &getSchedRW(Record *Def) {
- unsigned Idx;
- return getSchedRW(Def, Idx);
+ const CodeGenSchedRW &getSchedRW(Record*Def) const {
+ return const_cast<CodeGenSchedModels&>(*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<MCReadAdvanceEntry> 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;