diff options
| author | James Molloy <jmolloy@google.com> | 2019-08-30 19:50:49 +0000 |
|---|---|---|
| committer | James Molloy <jmolloy@google.com> | 2019-08-30 19:50:49 +0000 |
| commit | 6ccd67320631e7ab26d6746bdc77eabfa03730e0 (patch) | |
| tree | b4452776d36c0e57cc004442edb4f103021eb230 /llvm/utils | |
| parent | a707ced18fab078b0beb3765c966383cd9027c05 (diff) | |
| download | bcm5719-llvm-6ccd67320631e7ab26d6746bdc77eabfa03730e0.tar.gz bcm5719-llvm-6ccd67320631e7ab26d6746bdc77eabfa03730e0.zip | |
[DFAPacketizer] Allow namespacing of automata per-itinerary
The Hexagon itineraries are cunningly crafted such that functional units between
itineraries do not clash. Because all itineraries are bundled into the same DFA,
a functional unit index clash would cause an incorrect DFA to be generated.
A workaround for this is to ensure all itineraries declare the universe of all
possible functional units, but this isn't ideal for three reasons:
1) We only have a limited number of FUs we can encode in the packetizer, and
using the universe causes us to hit the limit without care.
2) Silent codegen faults are bad, and careful triage of the FU list shouldn't
be required.
3) Smooshing all itineraries into the same automaton allows combinations of
instruction classes that cannot exist, which bloats the table.
A simple solution is to allow "namespacing" packetizers.
Differential Revision: https://reviews.llvm.org/D66940
llvm-svn: 370508
Diffstat (limited to 'llvm/utils')
| -rw-r--r-- | llvm/utils/TableGen/DFAPacketizerEmitter.cpp | 65 |
1 files changed, 41 insertions, 24 deletions
diff --git a/llvm/utils/TableGen/DFAPacketizerEmitter.cpp b/llvm/utils/TableGen/DFAPacketizerEmitter.cpp index 0d6bcfe428c..19a6580c1d4 100644 --- a/llvm/utils/TableGen/DFAPacketizerEmitter.cpp +++ b/llvm/utils/TableGen/DFAPacketizerEmitter.cpp @@ -29,6 +29,7 @@ #include <map> #include <set> #include <string> +#include <unordered_map> #include <vector> using namespace llvm; @@ -154,6 +155,11 @@ public: int &maxStages, raw_ostream &OS); + // Emit code for a subset of itineraries. + void emitForItineraries(raw_ostream &OS, + std::vector<Record *> &ProcItinList, + std::string DFAName); + void run(raw_ostream &OS); }; @@ -545,14 +551,6 @@ void DFA::writeTableAndAPI(raw_ostream &OS, const std::string &TargetName, 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 <Input, NextState> for all valid\n"; OS << "// transitions.\n"; @@ -626,21 +624,7 @@ void DFA::writeTableAndAPI(raw_ostream &OS, const std::string &TargetName, // 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 @@ int DFAPacketizerEmitter::collectAllInsnClasses(const std::string &ProcName, // 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<Record*> ProcItinList = Records.getAllDerivedDefinitions("ProcessorItineraries"); + std::unordered_map<std::string, std::vector<Record*>> 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<Record *> &ProcItinList, + std::string DFAName) { // // Collect the Functional units. // @@ -982,8 +988,19 @@ void DFAPacketizerEmitter::run(raw_ostream &OS) { } // 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 { |

