Skip to content

Commit 6ccd673

Browse files
author
James Molloy
committed
[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
1 parent a707ced commit 6ccd673

File tree

2 files changed

+52
-24
lines changed

2 files changed

+52
-24
lines changed

llvm/include/llvm/Target/TargetItinerary.td

+11
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,17 @@ class ProcessorItineraries<list<FuncUnit> fu, list<Bypass> bp,
127127
list<FuncUnit> FU = fu;
128128
list<Bypass> BP = bp;
129129
list<InstrItinData> IID = iid;
130+
// The packetizer automaton to use for this itinerary. By default all
131+
// itineraries for a target are bundled up into the same automaton. This only
132+
// works correctly when there are no conflicts in functional unit IDs between
133+
// itineraries. For example, given two itineraries A<[SLOT_A]>, B<[SLOT_B]>,
134+
// SLOT_A and SLOT_B will be assigned the same functional unit index, and
135+
// the generated packetizer will confuse instructions referencing these slots.
136+
//
137+
// To avoid this, setting PacketizerNamespace to non-"" will cause this
138+
// itinerary to be generated in a different automaton. The subtarget will need
139+
// to declare a method "create##Namespace##DFAPacketizer()".
140+
string PacketizerNamespace = "";
130141
}
131142

132143
// NoItineraries - A marker that can be used by processors without schedule

llvm/utils/TableGen/DFAPacketizerEmitter.cpp

+41-24
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <map>
3030
#include <set>
3131
#include <string>
32+
#include <unordered_map>
3233
#include <vector>
3334

3435
using namespace llvm;
@@ -154,6 +155,11 @@ class DFAPacketizerEmitter {
154155
int &maxStages,
155156
raw_ostream &OS);
156157

158+
// Emit code for a subset of itineraries.
159+
void emitForItineraries(raw_ostream &OS,
160+
std::vector<Record *> &ProcItinList,
161+
std::string DFAName);
162+
157163
void run(raw_ostream &OS);
158164
};
159165

@@ -545,14 +551,6 @@ void DFA::writeTableAndAPI(raw_ostream &OS, const std::string &TargetName,
545551
LLVM_DEBUG(dbgs() << "writeTableAndAPI\n");
546552
LLVM_DEBUG(dbgs() << "Total states: " << numStates << "\n");
547553

548-
OS << "namespace llvm {\n";
549-
550-
OS << "\n// Input format:\n";
551-
OS << "#define DFA_MAX_RESTERMS " << DFA_MAX_RESTERMS
552-
<< "\t// maximum AND'ed resource terms\n";
553-
OS << "#define DFA_MAX_RESOURCES " << DFA_MAX_RESOURCES
554-
<< "\t// maximum resource bits in one term\n";
555-
556554
OS << "\n// " << TargetName << "DFAStateInputTable[][2] = "
557555
<< "pairs of <Input, NextState> for all valid\n";
558556
OS << "// transitions.\n";
@@ -626,21 +624,7 @@ void DFA::writeTableAndAPI(raw_ostream &OS, const std::string &TargetName,
626624
// Print out the index to the sentinel entry in StateInputTable
627625
OS << ValidTransitions << ", ";
628626
OS << " // states " << (lastState+1) << ":" << numStates << "\n";
629-
630627
OS << "};\n";
631-
OS << "} // end namespace llvm\n";
632-
633-
//
634-
// Emit DFA Packetizer tables if the target is a VLIW machine.
635-
//
636-
std::string SubTargetClassName = TargetName + "GenSubtargetInfo";
637-
OS << "\n" << "#include \"llvm/CodeGen/DFAPacketizer.h\"\n";
638-
OS << "namespace llvm {\n";
639-
OS << "DFAPacketizer *" << SubTargetClassName << "::"
640-
<< "createDFAPacketizer(const InstrItineraryData *IID) const {\n"
641-
<< " return new DFAPacketizer(IID, " << TargetName
642-
<< "DFAStateInputTable, " << TargetName << "DFAStateEntryTable);\n}\n\n";
643-
OS << "} // end namespace llvm\n";
644628
}
645629

646630
//
@@ -837,10 +821,32 @@ int DFAPacketizerEmitter::collectAllInsnClasses(const std::string &ProcName,
837821
// Run the worklist algorithm to generate the DFA.
838822
//
839823
void DFAPacketizerEmitter::run(raw_ostream &OS) {
824+
OS << "\n"
825+
<< "#include \"llvm/CodeGen/DFAPacketizer.h\"\n";
826+
OS << "namespace llvm {\n";
827+
828+
OS << "\n// Input format:\n";
829+
OS << "#define DFA_MAX_RESTERMS " << DFA_MAX_RESTERMS
830+
<< "\t// maximum AND'ed resource terms\n";
831+
OS << "#define DFA_MAX_RESOURCES " << DFA_MAX_RESOURCES
832+
<< "\t// maximum resource bits in one term\n";
833+
840834
// Collect processor iteraries.
841835
std::vector<Record*> ProcItinList =
842836
Records.getAllDerivedDefinitions("ProcessorItineraries");
843837

838+
std::unordered_map<std::string, std::vector<Record*>> ItinsByNamespace;
839+
for (Record *R : ProcItinList)
840+
ItinsByNamespace[R->getValueAsString("PacketizerNamespace")].push_back(R);
841+
842+
for (auto &KV : ItinsByNamespace)
843+
emitForItineraries(OS, KV.second, KV.first);
844+
OS << "} // end namespace llvm\n";
845+
}
846+
847+
void DFAPacketizerEmitter::emitForItineraries(
848+
raw_ostream &OS, std::vector<Record *> &ProcItinList,
849+
std::string DFAName) {
844850
//
845851
// Collect the Functional units.
846852
//
@@ -982,8 +988,19 @@ void DFAPacketizerEmitter::run(raw_ostream &OS) {
982988
}
983989

984990
// Print out the table.
985-
D.writeTableAndAPI(OS, TargetName,
986-
numInsnClasses, maxResources, numCombos, maxStages);
991+
D.writeTableAndAPI(OS, TargetName + DFAName, numInsnClasses, maxResources,
992+
numCombos, maxStages);
993+
994+
OS << "} // end namespace llvm\n";
995+
996+
std::string SubTargetClassName = TargetName + "GenSubtargetInfo";
997+
OS << "namespace llvm {\n";
998+
OS << "DFAPacketizer *" << SubTargetClassName << "::"
999+
<< "create" << DFAName
1000+
<< "DFAPacketizer(const InstrItineraryData *IID) const {\n"
1001+
<< " return new DFAPacketizer(IID, " << TargetName << DFAName
1002+
<< "DFAStateInputTable, " << TargetName << DFAName
1003+
<< "DFAStateEntryTable);\n}\n\n";
9871004
}
9881005

9891006
namespace llvm {

0 commit comments

Comments
 (0)