diff --git a/utils/TableGen/CodeGenSchedule.cpp b/utils/TableGen/CodeGenSchedule.cpp
index d9095d7..9f59e19 100644
--- a/utils/TableGen/CodeGenSchedule.cpp
+++ b/utils/TableGen/CodeGenSchedule.cpp
@@ -27,6 +27,11 @@
     dbgs() << V[i] << ", ";
   }
 }
+static void dumpIdxVec(const SmallVectorImpl<unsigned> &V) {
+  for (unsigned i = 0, e = V.size(); i < e; ++i) {
+    dbgs() << V[i] << ", ";
+  }
+}
 #endif
 
 /// CodeGenModels ctor interprets machine model records and populates maps.
@@ -63,6 +68,12 @@
   // Find ItinRW records for each processor and itinerary class.
   // (For per-operand resources mapped to itinerary classes).
   collectProcItinRW();
+
+  // Infer new SchedClasses from SchedVariant.
+  inferSchedClasses();
+
+  DEBUG(for (unsigned i = 0; i < SchedClasses.size(); ++i)
+          SchedClasses[i].dump(this));
 }
 
 /// Gather all processor models.
@@ -289,6 +300,57 @@
   }
 }
 
+void CodeGenSchedModels::expandRWSequence(unsigned RWIdx, IdxVec &RWSeq,
+                                          bool IsRead) const {
+  const CodeGenSchedRW &SchedRW = getSchedRW(RWIdx, IsRead);
+  if (!SchedRW.IsSequence) {
+    RWSeq.push_back(RWIdx);
+    return;
+  }
+  int Repeat =
+    SchedRW.TheDef ? SchedRW.TheDef->getValueAsInt("Repeat") : 1;
+  for (int i = 0; i < Repeat; ++i) {
+    for (IdxIter I = SchedRW.Sequence.begin(), E = SchedRW.Sequence.end();
+         I != E; ++I) {
+      expandRWSequence(*I, RWSeq, IsRead);
+    }
+  }
+}
+
+// Find the existing SchedWrite that models this sequence of writes.
+unsigned CodeGenSchedModels::findRWForSequence(const IdxVec &Seq,
+                                               bool IsRead) {
+  std::vector<CodeGenSchedRW> &RWVec = IsRead ? SchedReads : SchedWrites;
+
+  for (std::vector<CodeGenSchedRW>::iterator I = RWVec.begin(), E = RWVec.end();
+       I != E; ++I) {
+    if (I->Sequence == Seq)
+      return I - RWVec.begin();
+  }
+  // Index zero reserved for invalid RW.
+  return 0;
+}
+
+/// Add this ReadWrite if it doesn't already exist.
+unsigned CodeGenSchedModels::findOrInsertRW(ArrayRef<unsigned> Seq,
+                                            bool IsRead) {
+  assert(!Seq.empty() && "cannot insert empty sequence");
+  if (Seq.size() == 1)
+    return Seq.back();
+
+  unsigned Idx = findRWForSequence(Seq, IsRead);
+  if (Idx)
+    return Idx;
+
+  CodeGenSchedRW SchedRW(Seq, genRWName(Seq, IsRead));
+  if (IsRead) {
+    SchedReads.push_back(SchedRW);
+    return SchedReads.size() - 1;
+  }
+  SchedWrites.push_back(SchedRW);
+  return SchedWrites.size() - 1;
+}
+
 /// Visit all the instruction definitions for this target to gather and
 /// enumerate the itinerary classes. These are the explicitly specified
 /// SchedClasses. More SchedClasses may be inferred.
@@ -619,6 +681,409 @@
   }
 }
 
+/// Infer new classes from existing classes. In the process, this may create new
+/// SchedWrites from sequences of existing SchedWrites.
+void CodeGenSchedModels::inferSchedClasses() {
+  // Visit all existing classes and newly created classes.
+  for (unsigned Idx = 0; Idx != SchedClasses.size(); ++Idx) {
+    if (SchedClasses[Idx].ItinClassDef)
+      inferFromItinClass(SchedClasses[Idx].ItinClassDef, Idx);
+    else if (!SchedClasses[Idx].InstRWs.empty())
+      inferFromInstRWs(Idx);
+    else {
+      inferFromRW(SchedClasses[Idx].Writes, SchedClasses[Idx].Reads,
+                  Idx, SchedClasses[Idx].ProcIndices);
+    }
+    assert(SchedClasses.size() < (NumInstrSchedClasses*6) &&
+           "too many SchedVariants");
+  }
+}
+
+/// Infer classes from per-processor itinerary resources.
+void CodeGenSchedModels::inferFromItinClass(Record *ItinClassDef,
+                                            unsigned FromClassIdx) {
+  for (unsigned PIdx = 0, PEnd = ProcModels.size(); PIdx != PEnd; ++PIdx) {
+    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");
+      if (!std::count(Matched.begin(), Matched.end(), ItinClassDef))
+        continue;
+      if (HasMatch)
+        throw TGError((*II)->getLoc(), "Duplicate itinerary class "
+                      + ItinClassDef->getName()
+                      + " in ItinResources for " + PM.ModelName);
+      HasMatch = true;
+      IdxVec Writes, Reads;
+      findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads);
+      IdxVec ProcIndices(1, PIdx);
+      inferFromRW(Writes, Reads, FromClassIdx, ProcIndices);
+    }
+  }
+}
+
+/// 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) {
+    RecVec Instrs = (*RWI)->getValueAsListOfDefs("Instrs");
+    RecIter II = Instrs.begin(), IE = Instrs.end();
+    for (; II != IE; ++II) {
+      if (InstrClassMap[*II] == SCIdx)
+        break;
+    }
+    // If this class no longer has any instructions mapped to it, it has become
+    // irrelevant.
+    if (II == IE)
+      continue;
+    IdxVec Writes, Reads;
+    findRWs((*RWI)->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads);
+    unsigned PIdx = getProcModel((*RWI)->getValueAsDef("SchedModel")).Index;
+    IdxVec ProcIndices(1, PIdx);
+    inferFromRW(Writes, Reads, SCIdx, ProcIndices);
+  }
+}
+
+namespace {
+// Associate a predicate with the SchedReadWrite that it guards.
+// RWIdx is the index of the read/write variant.
+struct PredCheck {
+  bool IsRead;
+  unsigned RWIdx;
+  Record *Predicate;
+
+  PredCheck(bool r, unsigned w, Record *p): IsRead(r), RWIdx(w), Predicate(p) {}
+};
+
+// A Predicate transition is a list of RW sequences guarded by a PredTerm.
+struct PredTransition {
+  // A predicate term is a conjunction of PredChecks.
+  SmallVector<PredCheck, 4> PredTerm;
+  SmallVector<SmallVector<unsigned,4>, 16> WriteSequences;
+  SmallVector<SmallVector<unsigned,4>, 16> ReadSequences;
+};
+
+// Encapsulate a set of partially constructed transitions.
+// The results are built by repeated calls to substituteVariants.
+class PredTransitions {
+  CodeGenSchedModels &SchedModels;
+
+public:
+  std::vector<PredTransition> TransVec;
+
+  PredTransitions(CodeGenSchedModels &sm): SchedModels(sm) {}
+
+  void substituteVariantOperand(const SmallVectorImpl<unsigned> &RWSeq,
+                                bool IsRead, unsigned StartIdx);
+
+  void substituteVariants(const PredTransition &Trans);
+
+#ifndef NDEBUG
+  void dump() const;
+#endif
+
+private:
+  bool mutuallyExclusive(Record *PredDef, ArrayRef<PredCheck> Term);
+  void pushVariant(unsigned SchedRW, Record *Variant, PredTransition &Trans,
+                   bool IsRead);
+};
+} // anonymous
+
+// Return true if this predicate is mutually exclusive with a PredTerm. This
+// degenerates into checking if the predicate is mutually exclusive with any
+// predicate in the Term's conjunction.
+//
+// All predicates associated with a given SchedRW are considered mutually
+// exclusive. This should work even if the conditions expressed by the
+// predicates are not exclusive because the predicates for a given SchedWrite
+// are always checked in the order they are defined in the .td file. Later
+// conditions implicitly negate any prior condition.
+bool PredTransitions::mutuallyExclusive(Record *PredDef,
+                                        ArrayRef<PredCheck> Term) {
+
+  for (ArrayRef<PredCheck>::iterator I = Term.begin(), E = Term.end();
+       I != E; ++I) {
+    if (I->Predicate == PredDef)
+      return false;
+
+    const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(I->RWIdx, I->IsRead);
+    assert(SchedRW.HasVariants && "PredCheck must refer to a SchedVariant");
+    RecVec Variants = SchedRW.TheDef->getValueAsListOfDefs("Variants");
+    for (RecIter VI = Variants.begin(), VE = Variants.end(); VI != VE; ++VI) {
+      if ((*VI)->getValueAsDef("Predicate") == PredDef)
+        return true;
+    }
+  }
+  return false;
+}
+
+// Push the Reads/Writes selected by this variant onto the given PredTransition.
+void PredTransitions::pushVariant(unsigned RWIdx, Record *Variant,
+                                  PredTransition &Trans, bool IsRead) {
+  Trans.PredTerm.push_back(
+    PredCheck(IsRead, RWIdx, Variant->getValueAsDef("Predicate")));
+  RecVec SelectedDefs = Variant->getValueAsListOfDefs("Selected");
+  IdxVec SelectedRWs;
+  SchedModels.findRWs(SelectedDefs, SelectedRWs, IsRead);
+
+  const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(RWIdx, IsRead);
+
+  SmallVectorImpl<SmallVector<unsigned,4> > &RWSequences = IsRead
+    ? Trans.ReadSequences : Trans.WriteSequences;
+  if (SchedRW.IsVariadic) {
+    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) {
+      RWSequences.push_back(RWSequences[OperIdx]);
+    }
+    // Push each of the N elements of the SelectedRWs onto a copy of the last
+    // sequence (split the current operand into N operands).
+    // Note that write sequences should be expanded within this loop--the entire
+    // sequence belongs to a single operand.
+    for (IdxIter RWI = SelectedRWs.begin(), RWE = SelectedRWs.end();
+         RWI != RWE; ++RWI, ++OperIdx) {
+      IdxVec ExpandedRWs;
+      if (IsRead)
+        ExpandedRWs.push_back(*RWI);
+      else
+        SchedModels.expandRWSequence(*RWI, ExpandedRWs, IsRead);
+      RWSequences[OperIdx].insert(RWSequences[OperIdx].end(),
+                                  ExpandedRWs.begin(), ExpandedRWs.end());
+    }
+    assert(OperIdx == RWSequences.size() && "missed a sequence");
+  }
+  else {
+    // Push this transition's expanded sequence onto this transition's last
+    // sequence (add to the current operand's sequence).
+    SmallVectorImpl<unsigned> &Seq = RWSequences.back();
+    IdxVec ExpandedRWs;
+    for (IdxIter RWI = SelectedRWs.begin(), RWE = SelectedRWs.end();
+         RWI != RWE; ++RWI) {
+      if (IsRead)
+        ExpandedRWs.push_back(*RWI);
+      else
+        SchedModels.expandRWSequence(*RWI, ExpandedRWs, IsRead);
+    }
+    Seq.insert(Seq.end(), ExpandedRWs.begin(), ExpandedRWs.end());
+  }
+}
+
+// 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 tranistions between StartIdx and the end
+// of TransVec.
+void PredTransitions::substituteVariantOperand(
+  const SmallVectorImpl<unsigned> &RWSeq, bool IsRead, unsigned StartIdx) {
+
+  // Visit each original RW within the current sequence.
+  for (SmallVectorImpl<unsigned>::const_iterator
+         RWI = RWSeq.begin(), RWE = RWSeq.end(); RWI != RWE; ++RWI) {
+    const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(*RWI, IsRead);
+    // Push this RW on all partial PredTransitions or distribute variants.
+    // New PredTransitions may be pushed within this loop which should not be
+    // revisited (TransEnd must be loop invariant).
+    for (unsigned TransIdx = StartIdx, TransEnd = TransVec.size();
+         TransIdx != TransEnd; ++TransIdx) {
+      // In the common case, push RW onto the current operand's sequence.
+      if (!SchedRW.HasVariants) {
+        if (IsRead)
+          TransVec[TransIdx].ReadSequences.back().push_back(*RWI);
+        else
+          TransVec[TransIdx].WriteSequences.back().push_back(*RWI);
+        continue;
+      }
+      // Distribute this partial PredTransition across intersecting variants.
+      RecVec Variants = SchedRW.TheDef->getValueAsListOfDefs("Variants");
+      std::vector<std::pair<Record*,unsigned> > IntersectingVariants;
+      for (RecIter VI = Variants.begin(), VE = Variants.end(); VI != VE; ++VI) {
+        Record *PredDef = (*VI)->getValueAsDef("Predicate");
+        if (mutuallyExclusive(PredDef, TransVec[TransIdx].PredTerm))
+          continue;
+        if (IntersectingVariants.empty())
+          // The first variant builds on the existing transition.
+          IntersectingVariants.push_back(std::make_pair(*VI, TransIdx));
+        else {
+          // Push another copy of the current transition for more variants.
+          IntersectingVariants.push_back(
+            std::make_pair(*VI, TransVec.size()));
+          TransVec.push_back(TransVec[TransIdx]);
+        }
+      }
+      // Now expand each variant on top of its copy of the transition.
+      for (std::vector<std::pair<Record*, unsigned> >::const_iterator
+             IVI = IntersectingVariants.begin(),
+             IVE = IntersectingVariants.end();
+           IVI != IVE; ++IVI)
+        pushVariant(*RWI, IVI->first, TransVec[IVI->second], IsRead);
+    }
+  }
+}
+
+// For each variant of a Read/Write in Trans, substitute the sequence of
+// Read/Writes guarded by the variant. This is exponential in the number of
+// variant Read/Writes, but in practice detection of mutually exclusive
+// predicates should result in linear growth in the total number variants.
+//
+// This is one step in a breadth-first search of nested variants.
+void PredTransitions::substituteVariants(const PredTransition &Trans) {
+  // Build up a set of partial results starting at the back of
+  // PredTransitions. Remember the first new transition.
+  unsigned StartIdx = TransVec.size();
+  TransVec.resize(TransVec.size() + 1);
+  TransVec.back().PredTerm = Trans.PredTerm;
+
+  // Visit each original write sequence.
+  for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
+         WSI = Trans.WriteSequences.begin(), WSE = Trans.WriteSequences.end();
+       WSI != WSE; ++WSI) {
+    // Push a new (empty) write sequence onto all partial Transitions.
+    for (std::vector<PredTransition>::iterator I =
+           TransVec.begin() + StartIdx, E = TransVec.end(); I != E; ++I) {
+      I->WriteSequences.resize(I->WriteSequences.size() + 1);
+    }
+    substituteVariantOperand(*WSI, /*IsRead=*/false, StartIdx);
+  }
+  // Visit each original read sequence.
+  for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
+         RSI = Trans.ReadSequences.begin(), RSE = Trans.ReadSequences.end();
+       RSI != RSE; ++RSI) {
+    // Push a new (empty) read sequence onto all partial Transitions.
+    for (std::vector<PredTransition>::iterator I =
+           TransVec.begin() + StartIdx, E = TransVec.end(); I != E; ++I) {
+      I->ReadSequences.resize(I->ReadSequences.size() + 1);
+    }
+    substituteVariantOperand(*RSI, /*IsRead=*/true, StartIdx);
+  }
+}
+
+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 (SchedModels.getSchedWrite(*WI).HasVariants)
+          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 (SchedModels.getSchedRead(*RI).HasVariants)
+          return true;
+      }
+    }
+  }
+  return false;
+}
+
+// Create a new SchedClass for each variant found by inferFromRW. Pass
+// ProcIndices by copy to avoid referencing anything from SchedClasses.
+static void inferFromTransitions(ArrayRef<PredTransition> LastTransitions,
+                                 unsigned FromClassIdx, IdxVec ProcIndices,
+                                 CodeGenSchedModels &SchedModels) {
+  // For each PredTransition, create a new CodeGenSchedTransition, which usually
+  // requires creating a new SchedClass.
+  for (ArrayRef<PredTransition>::iterator
+         I = LastTransitions.begin(), E = LastTransitions.end(); I != E; ++I) {
+    IdxVec OperWritesVariant;
+    for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
+           WSI = I->WriteSequences.begin(), WSE = I->WriteSequences.end();
+         WSI != WSE; ++WSI) {
+      // Create a new write representing the expanded sequence.
+      OperWritesVariant.push_back(
+        SchedModels.findOrInsertRW(*WSI, /*IsRead=*/false));
+    }
+    IdxVec OperReadsVariant;
+    for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
+           RSI = I->ReadSequences.begin(), RSE = I->ReadSequences.end();
+         RSI != RSE; ++RSI) {
+      // Create a new write representing the expanded sequence.
+      OperReadsVariant.push_back(
+        SchedModels.findOrInsertRW(*RSI, /*IsRead=*/true));
+    }
+    CodeGenSchedTransition SCTrans;
+    SCTrans.ToClassIdx =
+      SchedModels.addSchedClass(OperWritesVariant, OperReadsVariant,
+                                ProcIndices);
+    SCTrans.ProcIndices = ProcIndices;
+    // The final PredTerm is unique set of predicates guarding the transition.
+    RecVec Preds;
+    for (SmallVectorImpl<PredCheck>::const_iterator
+           PI = I->PredTerm.begin(), PE = I->PredTerm.end(); PI != PE; ++PI) {
+      Preds.push_back(PI->Predicate);
+    }
+    RecIter PredsEnd = std::unique(Preds.begin(), Preds.end());
+    Preds.resize(PredsEnd - Preds.begin());
+    SCTrans.PredTerm = Preds;
+    SchedModels.getSchedClass(FromClassIdx).Transitions.push_back(SCTrans);
+  }
+}
+
+/// Find each variant write that OperWrites or OperaReads refers to and create a
+/// new SchedClass for each variant.
+void CodeGenSchedModels::inferFromRW(const IdxVec &OperWrites,
+                                     const IdxVec &OperReads,
+                                     unsigned FromClassIdx,
+                                     const IdxVec &ProcIndices) {
+  DEBUG(dbgs() << "INFERRW Writes: ");
+
+  // Create a seed transition with an empty PredTerm and the expanded sequences
+  // of SchedWrites for the current SchedClass.
+  std::vector<PredTransition> LastTransitions;
+  LastTransitions.resize(1);
+  for (IdxIter I = OperWrites.begin(), E = OperWrites.end(); I != E; ++I) {
+    IdxVec WriteSeq;
+    expandRWSequence(*I, WriteSeq, /*IsRead=*/false);
+    unsigned Idx = LastTransitions[0].WriteSequences.size();
+    LastTransitions[0].WriteSequences.resize(Idx + 1);
+    SmallVectorImpl<unsigned> &Seq = LastTransitions[0].WriteSequences[Idx];
+    for (IdxIter WI = WriteSeq.begin(), WE = WriteSeq.end(); WI != WE; ++WI)
+      Seq.push_back(*WI);
+    DEBUG(dbgs() << "("; dumpIdxVec(Seq); dbgs() << ") ");
+  }
+  DEBUG(dbgs() << " Reads: ");
+  for (IdxIter I = OperReads.begin(), E = OperReads.end(); I != E; ++I) {
+    IdxVec ReadSeq;
+    expandRWSequence(*I, ReadSeq, /*IsRead=*/true);
+    unsigned Idx = LastTransitions[0].ReadSequences.size();
+    LastTransitions[0].ReadSequences.resize(Idx + 1);
+    SmallVectorImpl<unsigned> &Seq = LastTransitions[0].ReadSequences[Idx];
+    for (IdxIter RI = ReadSeq.begin(), RE = ReadSeq.end(); RI != RE; ++RI)
+      Seq.push_back(*RI);
+    DEBUG(dbgs() << "("; dumpIdxVec(Seq); dbgs() << ") ");
+  }
+  DEBUG(dbgs() << '\n');
+
+  // Collect all PredTransitions for individual operands.
+  // Iterate until no variant writes remain.
+  while (hasVariant(LastTransitions, *this)) {
+    PredTransitions Transitions(*this);
+    for (std::vector<PredTransition>::const_iterator
+           I = LastTransitions.begin(), E = LastTransitions.end();
+         I != E; ++I) {
+      Transitions.substituteVariants(*I);
+    }
+    DEBUG(Transitions.dump());
+    LastTransitions.swap(Transitions.TransVec);
+  }
+  // If the first transition has no variants, nothing to do.
+  if (LastTransitions[0].PredTerm.empty())
+    return;
+
+  // WARNING: We are about to mutate the SchedClasses vector. Do not refer to
+  // OperWrites, OperReads, or ProcIndices after calling inferFromTransitions.
+  inferFromTransitions(LastTransitions, FromClassIdx, ProcIndices, *this);
+}
+
 #ifndef NDEBUG
 void CodeGenProcModel::dump() const {
   dbgs() << Index << ": " << ModelName << " "
@@ -655,4 +1120,34 @@
   }
   dbgs() << "\n  ProcIdx: "; dumpIdxVec(ProcIndices); dbgs() << '\n';
 }
+
+void PredTransitions::dump() const {
+  dbgs() << "Expanded Variants:\n";
+  for (std::vector<PredTransition>::const_iterator
+         TI = TransVec.begin(), TE = TransVec.end(); TI != TE; ++TI) {
+    dbgs() << "{";
+    for (SmallVectorImpl<PredCheck>::const_iterator
+           PCI = TI->PredTerm.begin(), PCE = TI->PredTerm.end();
+         PCI != PCE; ++PCI) {
+      if (PCI != TI->PredTerm.begin())
+        dbgs() << ", ";
+      dbgs() << SchedModels.getSchedRW(PCI->RWIdx, PCI->IsRead).Name
+             << ":" << PCI->Predicate->getName();
+    }
+    dbgs() << "},\n  => {";
+    for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
+           WSI = TI->WriteSequences.begin(), WSE = TI->WriteSequences.end();
+         WSI != WSE; ++WSI) {
+      dbgs() << "(";
+      for (SmallVectorImpl<unsigned>::const_iterator
+             WI = WSI->begin(), WE = WSI->end(); WI != WE; ++WI) {
+        if (WI != WSI->begin())
+          dbgs() << ", ";
+        dbgs() << SchedModels.getSchedWrite(*WI).Name;
+      }
+      dbgs() << "),";
+    }
+    dbgs() << "}\n";
+  }
+}
 #endif // NDEBUG
diff --git a/utils/TableGen/CodeGenSchedule.h b/utils/TableGen/CodeGenSchedule.h
index 5e8b711..e9c8359 100644
--- a/utils/TableGen/CodeGenSchedule.h
+++ b/utils/TableGen/CodeGenSchedule.h
@@ -83,6 +83,13 @@
 #endif
 };
 
+/// Represent a transition between SchedClasses induced by SchedWriteVariant.
+struct CodeGenSchedTransition {
+  unsigned ToClassIdx;
+  IdxVec ProcIndices;
+  RecVec PredTerm;
+};
+
 /// Scheduling class.
 ///
 /// Each instruction description will be mapped to a scheduling class. There are
@@ -116,6 +123,8 @@
   // Sorted list of ProcIdx, where ProcIdx==0 implies any processor.
   IdxVec ProcIndices;
 
+  std::vector<CodeGenSchedTransition> Transitions;
+
   // InstReadWrite records associated with this class. Any Instrs that the
   // definitions refer to that are not mapped to this class should be ignored.
   RecVec InstRWs;
@@ -308,6 +317,7 @@
 
   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;
 
   unsigned addSchedClass(const IdxVec &OperWrites, const IdxVec &OperReads,
                          const IdxVec &ProcIndices);
@@ -337,6 +347,13 @@
   void collectProcItins();
 
   void collectProcItinRW();
+
+  void inferSchedClasses();
+
+  void inferFromRW(const IdxVec &OperWrites, const IdxVec &OperReads,
+                   unsigned FromClassIdx, const IdxVec &ProcIndices);
+  void inferFromItinClass(Record *ItinClassDef, unsigned FromClassIdx);
+  void inferFromInstRWs(unsigned SCIdx);
 };
 
 } // namespace llvm
