Make processor FUs unique for given itinerary. This extends the limit of 32
FU per CPU arch to 32 per intinerary allowing precise modelling of quite
complex pipelines in the future.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101754 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp
index fb86a70..b04eaf8 100644
--- a/utils/TableGen/SubtargetEmitter.cpp
+++ b/utils/TableGen/SubtargetEmitter.cpp
@@ -203,7 +203,8 @@
 // data initialization for the specified itinerary.  N is the number
 // of stages.
 //
-void SubtargetEmitter::FormItineraryStageString(Record *ItinData,
+void SubtargetEmitter::FormItineraryStageString(const std::string &Name,
+                                                Record *ItinData,
                                                 std::string &ItinString,
                                                 unsigned &NStages) {
   // Get states list
@@ -226,7 +227,7 @@
     // For each unit
     for (unsigned j = 0, M = UnitList.size(); j < M;) {
       // Add name and bitwise or
-      ItinString += UnitList[j]->getName();
+      ItinString += Name + "FU::" + UnitList[j]->getName();
       if (++j < M) ItinString += " | ";
     }
     
@@ -279,8 +280,28 @@
   // If just no itinerary then don't bother
   if (ProcItinList.size() < 2) return;
 
+  // Emit functional units for all the itineraries.
+  for (unsigned i = 0, N = ProcItinList.size(); i < N; ++i) {
+    // Next record
+    Record *Proc = ProcItinList[i];
+
+    std::vector<Record*> FUs = Proc->getValueAsListOfDefs("FU");
+    if (FUs.empty())
+      continue;
+
+    const std::string &Name = Proc->getName();
+    OS << "\n// Functional units for itineraries \"" << Name << "\"\n"
+       << "namespace " << Name << "FU {\n";
+
+    for (unsigned j = 0, FUN = FUs.size(); j < FUN; ++j)
+      OS << "  const unsigned " << FUs[j]->getName()
+         << " = 1 << " << j << ";\n";
+
+    OS << "}\n";
+  }
+
   // Begin stages table
-  std::string StageTable = "static const llvm::InstrStage Stages[] = {\n";
+  std::string StageTable = "\nstatic const llvm::InstrStage Stages[] = {\n";
   StageTable += "  { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n";
         
   // Begin operand cycle table
@@ -315,7 +336,7 @@
       // Get string and stage count
       std::string ItinStageString;
       unsigned NStages;
-      FormItineraryStageString(ItinData, ItinStageString, NStages);
+      FormItineraryStageString(Name, ItinData, ItinStageString, NStages);
 
       // Get string and operand cycle count
       std::string ItinOperandCycleString;
@@ -567,9 +588,9 @@
   OS << "#include \"llvm/Support/raw_ostream.h\"\n";
   OS << "#include \"llvm/Target/SubtargetFeature.h\"\n";
   OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n";
-  
-  Enumeration(OS, "FuncUnit", true);
-  OS<<"\n";
+
+//  Enumeration(OS, "FuncUnit", true);
+//  OS<<"\n";
 //  Enumeration(OS, "InstrItinClass", false);
 //  OS<<"\n";
   Enumeration(OS, "SubtargetFeature", true);