[SelectionDAG] Add a SDTCisSameSizeAs type constraint that can be used to ensure...
[oota-llvm.git] / utils / TableGen / CodeGenSchedule.cpp
index 79d60ac171b84ba6b9425e247729248ae505aea4..c98f62345342db67143204b2be37a72d5e4661eb 100644 (file)
@@ -24,15 +24,9 @@ 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) {
-    dbgs() << V[i] << ", ";
-  }
-}
-static void dumpIdxVec(const SmallVectorImpl<unsigned> &V) {
-  for (unsigned i = 0, e = V.size(); i < e; ++i) {
-    dbgs() << V[i] << ", ";
-  }
+static void dumpIdxVec(ArrayRef<unsigned> V) {
+  for (unsigned Idx : V)
+    dbgs() << Idx << ", ";
 }
 #endif
 
@@ -74,11 +68,10 @@ struct InstRegexOp : public SetTheory::Operator {
       }
       RegexList.push_back(Regex(pat));
     }
-    for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
-           E = Target.inst_end(); I != E; ++I) {
+    for (const CodeGenInstruction *Inst : Target.instructions()) {
       for (auto &R : RegexList) {
-        if (R.match((*I)->TheDef->getName()))
-          Elts.insert((*I)->TheDef);
+        if (R.match(Inst->TheDef->getName()))
+          Elts.insert(Inst->TheDef);
       }
     }
   }
@@ -94,8 +87,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<InstrsOp>());
+  Sets.addOperator("instregex", llvm::make_unique<InstRegexOp>(Target));
 
   // Instantiate a CodeGenProcModel for each SchedMachineModel with the values
   // that are explicitly referenced in tablegen records. Resources associated
@@ -146,8 +139,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 +157,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 +172,7 @@ void CodeGenSchedModels::addProcModel(Record *ProcDef) {
 // Recursively find all reachable SchedReadWrite records.
 static void scanSchedRW(Record *RWDef, RecVec &RWDefs,
                         SmallPtrSet<Record*, 16> &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 +204,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 +272,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<CodeGenSchedRW>::iterator WI = SchedWrites.begin(),
@@ -331,9 +320,9 @@ void CodeGenSchedModels::collectSchedRW() {
 }
 
 /// Compute a SchedWrite name from a sequence of writes.
-std::string CodeGenSchedModels::genRWName(const IdxVec& Seq, bool IsRead) {
+std::string CodeGenSchedModels::genRWName(ArrayRef<unsigned> Seq, bool IsRead) {
   std::string Name("(");
-  for (IdxIter I = Seq.begin(), E = Seq.end(); I != E; ++I) {
+  for (auto I = Seq.begin(), E = Seq.end(); I != E; ++I) {
     if (I != Seq.begin())
       Name += '_';
     Name += getSchedRW(*I, IsRead).Name;
@@ -462,13 +451,13 @@ void CodeGenSchedModels::expandRWSeqForProc(
 }
 
 // Find the existing SchedWrite that models this sequence of writes.
-unsigned CodeGenSchedModels::findRWForSequence(const IdxVec &Seq,
+unsigned CodeGenSchedModels::findRWForSequence(ArrayRef<unsigned> 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)
+    if (makeArrayRef(I->Sequence) == Seq)
       return I - RWVec.begin();
   }
   // Index zero reserved for invalid RW.
@@ -509,18 +498,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 +523,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 +570,7 @@ void CodeGenSchedModels::collectSchedClasses() {
     for (std::vector<CodeGenProcModel>::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';
     }
   }
@@ -593,11 +579,11 @@ void CodeGenSchedModels::collectSchedClasses() {
 /// Find an SchedClass that has been inferred from a per-operand list of
 /// SchedWrites and SchedReads.
 unsigned CodeGenSchedModels::findSchedClassIdx(Record *ItinClassDef,
-                                               const IdxVec &Writes,
-                                               const IdxVec &Reads) const {
+                                               ArrayRef<unsigned> Writes,
+                                               ArrayRef<unsigned> Reads) const {
   for (SchedClassIter I = schedClassBegin(), E = schedClassEnd(); I != E; ++I) {
-    if (I->ItinClassDef == ItinClassDef
-        && I->Writes == Writes && I->Reads == Reads) {
+    if (I->ItinClassDef == ItinClassDef && makeArrayRef(I->Writes) == Writes &&
+        makeArrayRef(I->Reads) == Reads) {
       return I - schedClassBegin();
     }
   }
@@ -611,20 +597,22 @@ unsigned CodeGenSchedModels::getSchedClassIdx(
   return InstrClassMap.lookup(Inst.TheDef);
 }
 
-std::string CodeGenSchedModels::createSchedClassName(
-  Record *ItinClassDef, const IdxVec &OperWrites, const IdxVec &OperReads) {
+std::string
+CodeGenSchedModels::createSchedClassName(Record *ItinClassDef,
+                                         ArrayRef<unsigned> OperWrites,
+                                         ArrayRef<unsigned> OperReads) {
 
   std::string Name;
   if (ItinClassDef && ItinClassDef->getName() != "NoItinerary")
     Name = ItinClassDef->getName();
-  for (IdxIter WI = OperWrites.begin(), WE = OperWrites.end(); WI != WE; ++WI) {
+  for (unsigned Idx : OperWrites) {
     if (!Name.empty())
       Name += '_';
-    Name += SchedWrites[*WI].Name;
+    Name += SchedWrites[Idx].Name;
   }
-  for (IdxIter RI = OperReads.begin(), RE = OperReads.end(); RI != RE; ++RI) {
+  for (unsigned Idx : OperReads) {
     Name += '_';
-    Name += SchedReads[*RI].Name;
+    Name += SchedReads[Idx].Name;
   }
   return Name;
 }
@@ -644,10 +632,9 @@ std::string CodeGenSchedModels::createSchedClassName(const RecVec &InstDefs) {
 /// SchedWrites and SchedReads. ProcIndices contains the set of IDs of
 /// processors that may utilize this class.
 unsigned CodeGenSchedModels::addSchedClass(Record *ItinClassDef,
-                                           const IdxVec &OperWrites,
-                                           const IdxVec &OperReads,
-                                           const IdxVec &ProcIndices)
-{
+                                           ArrayRef<unsigned> OperWrites,
+                                           ArrayRef<unsigned> OperReads,
+                                           ArrayRef<unsigned> ProcIndices) {
   assert(!ProcIndices.empty() && "expect at least one ProcIdx");
 
   unsigned Idx = findSchedClassIdx(ItinClassDef, OperWrites, OperReads);
@@ -751,7 +738,7 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
     for (ArrayRef<Record*>::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 +768,7 @@ bool CodeGenSchedModels::hasItineraries() const {
 
 // Gather the processor itineraries.
 void CodeGenSchedModels::collectProcItins() {
-  for (std::vector<CodeGenProcModel>::iterator PI = ProcModels.begin(),
-         PE = ProcModels.end(); PI != PE; ++PI) {
-    CodeGenProcModel &ProcModel = *PI;
+  for (CodeGenProcModel &ProcModel : ProcModels) {
     if (!ProcModel.hasItineraries())
       continue;
 
@@ -1332,10 +1317,10 @@ static void inferFromTransitions(ArrayRef<PredTransition> LastTransitions,
 // Create new SchedClasses for the given ReadWrite list. If any of the
 // ReadWrites refers to a SchedVariant, create a new SchedClass for each variant
 // of the ReadWrite list, following Aliases if necessary.
-void CodeGenSchedModels::inferFromRW(const IdxVec &OperWrites,
-                                     const IdxVec &OperReads,
+void CodeGenSchedModels::inferFromRW(ArrayRef<unsigned> OperWrites,
+                                     ArrayRef<unsigned> OperReads,
                                      unsigned FromClassIdx,
-                                     const IdxVec &ProcIndices) {
+                                     ArrayRef<unsigned> ProcIndices) {
   DEBUG(dbgs() << "INFER RW proc("; dumpIdxVec(ProcIndices); dbgs() << ") ");
 
   // Create a seed transition with an empty PredTerm and the expanded sequences
@@ -1345,9 +1330,9 @@ void CodeGenSchedModels::inferFromRW(const IdxVec &OperWrites,
   LastTransitions.back().ProcIndices.append(ProcIndices.begin(),
                                             ProcIndices.end());
 
-  for (IdxIter I = OperWrites.begin(), E = OperWrites.end(); I != E; ++I) {
+  for (unsigned WriteIdx : OperWrites) {
     IdxVec WriteSeq;
-    expandRWSequence(*I, WriteSeq, /*IsRead=*/false);
+    expandRWSequence(WriteIdx, WriteSeq, /*IsRead=*/false);
     unsigned Idx = LastTransitions[0].WriteSequences.size();
     LastTransitions[0].WriteSequences.resize(Idx + 1);
     SmallVectorImpl<unsigned> &Seq = LastTransitions[0].WriteSequences[Idx];
@@ -1356,9 +1341,9 @@ void CodeGenSchedModels::inferFromRW(const IdxVec &OperWrites,
     DEBUG(dbgs() << "("; dumpIdxVec(Seq); dbgs() << ") ");
   }
   DEBUG(dbgs() << " Reads: ");
-  for (IdxIter I = OperReads.begin(), E = OperReads.end(); I != E; ++I) {
+  for (unsigned ReadIdx : OperReads) {
     IdxVec ReadSeq;
-    expandRWSequence(*I, ReadSeq, /*IsRead=*/true);
+    expandRWSequence(ReadIdx, ReadSeq, /*IsRead=*/true);
     unsigned Idx = LastTransitions[0].ReadSequences.size();
     LastTransitions[0].ReadSequences.resize(Idx + 1);
     SmallVectorImpl<unsigned> &Seq = LastTransitions[0].ReadSequences[Idx];
@@ -1502,8 +1487,7 @@ void CodeGenSchedModels::collectProcResources() {
       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(),
@@ -1563,20 +1547,16 @@ void CodeGenSchedModels::collectItinProcResources(Record *ItinClassDef) {
 }
 
 void CodeGenSchedModels::collectRWResources(unsigned RWIdx, bool IsRead,
-                                            const IdxVec &ProcIndices) {
+                                            ArrayRef<unsigned> ProcIndices) {
   const CodeGenSchedRW &SchedRW = getSchedRW(RWIdx, IsRead);
   if (SchedRW.TheDef) {
     if (!IsRead && SchedRW.TheDef->isSubClassOf("SchedWriteRes")) {
-      for (IdxIter PI = ProcIndices.begin(), PE = ProcIndices.end();
-           PI != PE; ++PI) {
-        addWriteRes(SchedRW.TheDef, *PI);
-      }
+      for (unsigned Idx : ProcIndices)
+        addWriteRes(SchedRW.TheDef, Idx);
     }
     else if (IsRead && SchedRW.TheDef->isSubClassOf("SchedReadAdvance")) {
-      for (IdxIter PI = ProcIndices.begin(), PE = ProcIndices.end();
-           PI != PE; ++PI) {
-        addReadAdvance(SchedRW.TheDef, *PI);
-      }
+      for (unsigned Idx : ProcIndices)
+        addReadAdvance(SchedRW.TheDef, Idx);
     }
   }
   for (RecIter AI = SchedRW.Aliases.begin(), AE = SchedRW.Aliases.end();
@@ -1601,15 +1581,15 @@ void CodeGenSchedModels::collectRWResources(unsigned RWIdx, bool IsRead,
 }
 
 // Collect resources for a set of read/write types and processor indices.
-void CodeGenSchedModels::collectRWResources(const IdxVec &Writes,
-                                            const IdxVec &Reads,
-                                            const IdxVec &ProcIndices) {
+void CodeGenSchedModels::collectRWResources(ArrayRef<unsigned> Writes,
+                                            ArrayRef<unsigned> Reads,
+                                            ArrayRef<unsigned> ProcIndices) {
 
-  for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI)
-    collectRWResources(*WI, /*IsRead=*/false, ProcIndices);
+  for (unsigned Idx : Writes)
+    collectRWResources(Idx, /*IsRead=*/false, ProcIndices);
 
-  for (IdxIter RI = Reads.begin(), RE = Reads.end(); RI != RE; ++RI)
-    collectRWResources(*RI, /*IsRead=*/true, ProcIndices);
+  for (unsigned Idx : Reads)
+    collectRWResources(Idx, /*IsRead=*/true, ProcIndices);
 }