Index: llvm/trunk/include/llvm/Target/TargetItinerary.td =================================================================== --- llvm/trunk/include/llvm/Target/TargetItinerary.td +++ llvm/trunk/include/llvm/Target/TargetItinerary.td @@ -127,6 +127,17 @@ list FU = fu; list BP = bp; list IID = iid; + // The packetizer automaton to use for this itinerary. By default all + // itineraries for a target are bundled up into the same automaton. This only + // works correctly when there are no conflicts in functional unit IDs between + // itineraries. For example, given two itineraries A<[SLOT_A]>, B<[SLOT_B]>, + // SLOT_A and SLOT_B will be assigned the same functional unit index, and + // the generated packetizer will confuse instructions referencing these slots. + // + // To avoid this, setting PacketizerNamespace to non-"" will cause this + // itinerary to be generated in a different automaton. The subtarget will need + // to declare a method "create##Namespace##DFAPacketizer()". + string PacketizerNamespace = ""; } // NoItineraries - A marker that can be used by processors without schedule Index: llvm/trunk/utils/TableGen/DFAPacketizerEmitter.cpp =================================================================== --- llvm/trunk/utils/TableGen/DFAPacketizerEmitter.cpp +++ llvm/trunk/utils/TableGen/DFAPacketizerEmitter.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include using namespace llvm; @@ -154,6 +155,11 @@ int &maxStages, raw_ostream &OS); + // Emit code for a subset of itineraries. + void emitForItineraries(raw_ostream &OS, + std::vector &ProcItinList, + std::string DFAName); + void run(raw_ostream &OS); }; @@ -545,14 +551,6 @@ LLVM_DEBUG(dbgs() << "writeTableAndAPI\n"); LLVM_DEBUG(dbgs() << "Total states: " << numStates << "\n"); - OS << "namespace llvm {\n"; - - OS << "\n// Input format:\n"; - OS << "#define DFA_MAX_RESTERMS " << DFA_MAX_RESTERMS - << "\t// maximum AND'ed resource terms\n"; - OS << "#define DFA_MAX_RESOURCES " << DFA_MAX_RESOURCES - << "\t// maximum resource bits in one term\n"; - OS << "\n// " << TargetName << "DFAStateInputTable[][2] = " << "pairs of for all valid\n"; OS << "// transitions.\n"; @@ -626,21 +624,7 @@ // Print out the index to the sentinel entry in StateInputTable OS << ValidTransitions << ", "; OS << " // states " << (lastState+1) << ":" << numStates << "\n"; - OS << "};\n"; - OS << "} // end namespace llvm\n"; - - // - // Emit DFA Packetizer tables if the target is a VLIW machine. - // - std::string SubTargetClassName = TargetName + "GenSubtargetInfo"; - OS << "\n" << "#include \"llvm/CodeGen/DFAPacketizer.h\"\n"; - OS << "namespace llvm {\n"; - OS << "DFAPacketizer *" << SubTargetClassName << "::" - << "createDFAPacketizer(const InstrItineraryData *IID) const {\n" - << " return new DFAPacketizer(IID, " << TargetName - << "DFAStateInputTable, " << TargetName << "DFAStateEntryTable);\n}\n\n"; - OS << "} // end namespace llvm\n"; } // @@ -837,10 +821,32 @@ // Run the worklist algorithm to generate the DFA. // void DFAPacketizerEmitter::run(raw_ostream &OS) { + OS << "\n" + << "#include \"llvm/CodeGen/DFAPacketizer.h\"\n"; + OS << "namespace llvm {\n"; + + OS << "\n// Input format:\n"; + OS << "#define DFA_MAX_RESTERMS " << DFA_MAX_RESTERMS + << "\t// maximum AND'ed resource terms\n"; + OS << "#define DFA_MAX_RESOURCES " << DFA_MAX_RESOURCES + << "\t// maximum resource bits in one term\n"; + // Collect processor iteraries. std::vector ProcItinList = Records.getAllDerivedDefinitions("ProcessorItineraries"); + std::unordered_map> ItinsByNamespace; + for (Record *R : ProcItinList) + ItinsByNamespace[R->getValueAsString("PacketizerNamespace")].push_back(R); + + for (auto &KV : ItinsByNamespace) + emitForItineraries(OS, KV.second, KV.first); + OS << "} // end namespace llvm\n"; +} + +void DFAPacketizerEmitter::emitForItineraries( + raw_ostream &OS, std::vector &ProcItinList, + std::string DFAName) { // // Collect the Functional units. // @@ -982,8 +988,19 @@ } // Print out the table. - D.writeTableAndAPI(OS, TargetName, - numInsnClasses, maxResources, numCombos, maxStages); + D.writeTableAndAPI(OS, TargetName + DFAName, numInsnClasses, maxResources, + numCombos, maxStages); + + OS << "} // end namespace llvm\n"; + + std::string SubTargetClassName = TargetName + "GenSubtargetInfo"; + OS << "namespace llvm {\n"; + OS << "DFAPacketizer *" << SubTargetClassName << "::" + << "create" << DFAName + << "DFAPacketizer(const InstrItineraryData *IID) const {\n" + << " return new DFAPacketizer(IID, " << TargetName << DFAName + << "DFAStateInputTable, " << TargetName << DFAName + << "DFAStateEntryTable);\n}\n\n"; } namespace llvm {