[llvm-commits] [llvm] r165179 - in /llvm/trunk/utils/TableGen: CodeGenSchedule.cpp CodeGenSchedule.h SubtargetEmitter.cpp

Andrew Trick atrick at apple.com
Wed Oct 3 16:06:28 PDT 2012


Author: atrick
Date: Wed Oct  3 18:06:28 2012
New Revision: 165179

URL: http://llvm.org/viewvc/llvm-project?rev=165179&view=rev
Log:
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.

Modified:
    llvm/trunk/utils/TableGen/CodeGenSchedule.cpp
    llvm/trunk/utils/TableGen/CodeGenSchedule.h
    llvm/trunk/utils/TableGen/SubtargetEmitter.cpp

Modified: llvm/trunk/utils/TableGen/CodeGenSchedule.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenSchedule.cpp?rev=165179&r1=165178&r2=165179&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenSchedule.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenSchedule.cpp Wed Oct  3 18:06:28 2012
@@ -225,12 +225,12 @@
   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 @@
   }
 }
 
+// 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 @@
   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 @@
 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 @@
 
 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 @@
   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 @@
 
   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 @@
   }
 }
 
-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 @@
         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 ");

Modified: llvm/trunk/utils/TableGen/CodeGenSchedule.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenSchedule.h?rev=165179&r1=165178&r2=165179&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenSchedule.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenSchedule.h Wed Oct  3 18:06:28 2012
@@ -43,8 +43,10 @@
 /// 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 @@
   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 @@
     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 @@
   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 @@
   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);

Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetEmitter.cpp?rev=165179&r1=165178&r2=165179&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/SubtargetEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/SubtargetEmitter.cpp Wed Oct  3 18:06:28 2012
@@ -664,15 +664,16 @@
   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 @@
        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 @@
         }
       }
       if (RWDef) {
+        Writes.clear();
+        Reads.clear();
         SchedModels.findRWs(RWDef->getValueAsListOfDefs("OperandReadWrites"),
                             Writes, Reads);
       }
@@ -844,7 +849,8 @@
     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;





More information about the llvm-commits mailing list