summaryrefslogtreecommitdiffstats
path: root/llvm/utils
diff options
context:
space:
mode:
authorJames Molloy <jmolloy@google.com>2019-08-30 19:50:49 +0000
committerJames Molloy <jmolloy@google.com>2019-08-30 19:50:49 +0000
commit6ccd67320631e7ab26d6746bdc77eabfa03730e0 (patch)
treeb4452776d36c0e57cc004442edb4f103021eb230 /llvm/utils
parenta707ced18fab078b0beb3765c966383cd9027c05 (diff)
downloadbcm5719-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.cpp65
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 {
OpenPOWER on IntegriCloud