#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include "llvm/Support/Debug.h"
#include <queue>
using namespace llvm;
+// --------------------------------------------------------------------
+// Definitions shared between DFAPacketizer.cpp and DFAPacketizerEmitter.cpp
+
+// DFA_MAX_RESTERMS * DFA_MAX_RESOURCES must fit within sizeof DFAInput.
+// This is verified in DFAPacketizer.cpp:DFAPacketizer::DFAPacketizer.
+//
+// e.g. terms x resource bit combinations that fit in uint32_t:
+// 4 terms x 8 bits = 32 bits
+// 3 terms x 10 bits = 30 bits
+// 2 terms x 16 bits = 32 bits
+//
+// e.g. terms x resource bit combinations that fit in uint64_t:
+// 8 terms x 8 bits = 64 bits
+// 7 terms x 9 bits = 63 bits
+// 6 terms x 10 bits = 60 bits
+// 5 terms x 12 bits = 60 bits
+// 4 terms x 16 bits = 64 bits <--- current
+// 3 terms x 21 bits = 63 bits
+// 2 terms x 32 bits = 64 bits
+//
+#define DFA_MAX_RESTERMS 4 // The max # of AND'ed resource terms.
+#define DFA_MAX_RESOURCES 16 // The max # of resource bits in one term.
+
+typedef uint64_t DFAInput;
+typedef int64_t DFAStateInput;
+#define DFA_TBLTYPE "int64_t" // For generating DFAStateInputTable.
+
+namespace {
+ DFAInput addDFAFuncUnits(DFAInput Inp, unsigned FuncUnits) {
+ return (Inp << DFA_MAX_RESOURCES) | FuncUnits;
+ }
+
+ /// Return the DFAInput for an instruction class input vector.
+ /// This function is used in both DFAPacketizer.cpp and in
+ /// DFAPacketizerEmitter.cpp.
+ DFAInput getDFAInsnInput(const std::vector<unsigned> &InsnClass) {
+ DFAInput InsnInput = 0;
+ assert ((InsnClass.size() <= DFA_MAX_RESTERMS) &&
+ "Exceeded maximum number of DFA terms");
+ for (auto U : InsnClass)
+ InsnInput = addDFAFuncUnits(InsnInput, U);
+ return InsnInput;
+ }
+}
+// --------------------------------------------------------------------
+
+#ifndef NDEBUG
// To enable debugging, run llvm-tblgen with: "-debug-only dfa-emitter".
//
// dbgsInsnClass - When debugging, print instruction class stages.
// dbgsIndent - When debugging, indent by the specified amount.
//
void dbgsIndent(unsigned indent);
+#endif
//
// class DFAPacketizerEmitter: class that generates and prints out the DFA
};
} // End anonymous namespace.
+#ifndef NDEBUG
// To enable debugging, run llvm-tblgen with: "-debug-only dfa-emitter".
//
// dbgsInsnClass - When debugging, print instruction class stages.
}
DEBUG(dbgs() << "0x" << utohexstr(InsnClass[i]));
}
- DFAInput InsnInput = DFAPacketizer::getInsnInput(InsnClass);
+ DFAInput InsnInput = getDFAInsnInput(InsnClass);
DEBUG(dbgs() << " (input: 0x" << utohexstr(InsnInput) << ")");
}
DEBUG(dbgs() << " ");
}
}
+#endif
//
// Constructors and destructors for State and DFA
assert((chkstage < numstages) && "AddInsnClassStages: stage out of range");
unsigned thisStage = InsnClass[chkstage];
- dbgsIndent((1 + numstages - chkstage) << 1);
- DEBUG(dbgs() << "AddInsnClassStages " << chkstage
- << " (0x" << utohexstr(thisStage) << ") from ");
- dbgsInsnClass(InsnClass);
- DEBUG(dbgs() << "\n");
+ DEBUG({
+ dbgsIndent((1 + numstages - chkstage) << 1);
+ dbgs() << "AddInsnClassStages " << chkstage << " (0x"
+ << utohexstr(thisStage) << ") from ";
+ dbgsInsnClass(InsnClass);
+ dbgs() << "\n";
+ });
//
// Iterate over all possible resources used in thisStage.
// resource state if that resource was used.
//
unsigned ResultingResourceState = prevState | resourceMask | combo;
- dbgsIndent((2 + numstages - chkstage) << 1);
- DEBUG(dbgs() << "0x" << utohexstr(prevState)
- << " | 0x" << utohexstr(resourceMask));
- if (combo) {
- DEBUG(dbgs() << " | 0x" << utohexstr(combo));
- }
- DEBUG(dbgs() << " = 0x" << utohexstr(ResultingResourceState) << " ");
+ DEBUG({
+ dbgsIndent((2 + numstages - chkstage) << 1);
+ dbgs() << "0x" << utohexstr(prevState)
+ << " | 0x" << utohexstr(resourceMask);
+ if (combo)
+ dbgs() << " | 0x" << utohexstr(combo);
+ dbgs() << " = 0x" << utohexstr(ResultingResourceState) << " ";
+ });
//
// If this is the final stage for this class
for (State::TransitionMap::iterator
II = SI->Transitions.begin(), IE = SI->Transitions.end();
II != IE; ++II) {
- OS << "{0x" << utohexstr(DFAPacketizer::getInsnInput(II->first)) << ", "
+ OS << "{0x" << utohexstr(getDFAInsnInput(II->first)) << ", "
<< II->second->stateNum
<< "},\t";
}
// Parse functional units for all the itineraries.
for (unsigned i = 0, N = ProcItinList.size(); i < N; ++i) {
Record *Proc = ProcItinList[i];
- const std::string &ProcName = Proc->getName();
std::vector<Record*> FUs = Proc->getValueAsListOfDefs("FU");
DEBUG(dbgs() << " FU:" << i
<< " (" << FUs.size() << " FUs) "
- << ProcName);
+ << Proc->getName());
// Convert macros to bits for each stage.
int numCombos = 0;
for (unsigned i = 0, N = ComboFuncList.size(); i < N; ++i) {
Record *Func = ComboFuncList[i];
- const std::string &ProcName = Func->getName();
std::vector<Record*> FUs = Func->getValueAsListOfDefs("CFD");
DEBUG(dbgs() << " CFD:" << i
<< " (" << FUs.size() << " combo FUs) "
- << ProcName << "\n");
+ << Func->getName() << "\n");
// Convert macros to bits for each stage.
for (unsigned j = 0, N = FUs.size(); j < N; ++j) {
std::map<std::string, unsigned> &FUNameToBitsMap,
Record *ItinData,
raw_ostream &OS) {
- // Collect instruction classes.
- Record *ItinDef = ItinData->getValueAsDef("TheClass");
-
const std::vector<Record*> &StageList =
ItinData->getValueAsListOfDefs("Stages");
// The number of stages.
unsigned NStages = StageList.size();
- DEBUG(dbgs() << " " << ItinDef->getName()
+ DEBUG(dbgs() << " " << ItinData->getValueAsDef("TheClass")->getName()
<< "\n");
std::vector<unsigned> UnitBits;
if (UnitBits.size() > 0)
allInsnClasses.push_back(UnitBits);
- DEBUG(dbgs() << " ");
- dbgsInsnClass(UnitBits);
- DEBUG(dbgs() << "\n");
+ DEBUG({
+ dbgs() << " ";
+ dbgsInsnClass(UnitBits);
+ dbgs() << "\n";
+ });
return NStages;
}
//
while (!WorkList.empty()) {
const State *current = WorkList.pop_back_val();
- DEBUG(dbgs() << "---------------------\n");
- DEBUG(dbgs() << "Processing state: " << current->stateNum << " - ");
- dbgsStateInfo(current->stateInfo);
- DEBUG(dbgs() << "\n");
+ DEBUG({
+ dbgs() << "---------------------\n";
+ dbgs() << "Processing state: " << current->stateNum << " - ";
+ dbgsStateInfo(current->stateInfo);
+ dbgs() << "\n";
+ });
for (unsigned i = 0; i < allInsnClasses.size(); i++) {
std::vector<unsigned> InsnClass = allInsnClasses[i];
- DEBUG(dbgs() << i << " ");
- dbgsInsnClass(InsnClass);
- DEBUG(dbgs() << "\n");
+ DEBUG({
+ dbgs() << i << " ";
+ dbgsInsnClass(InsnClass);
+ dbgs() << "\n";
+ });
std::set<unsigned> NewStateResources;
//
continue;
}
- DEBUG(dbgs() << "\t");
- dbgsStateInfo(NewStateResources);
- DEBUG(dbgs() << "\n");
+ DEBUG({
+ dbgs() << "\t";
+ dbgsStateInfo(NewStateResources);
+ dbgs() << "\n";
+ });
//
// If we have seen this state before, then do not create a new state.
auto VI = Visited.find(NewStateResources);
if (VI != Visited.end()) {
NewState = VI->second;
- DEBUG(dbgs() << "\tFound existing state: "
- << NewState->stateNum << " - ");
- dbgsStateInfo(NewState->stateInfo);
- DEBUG(dbgs() << "\n");
+ DEBUG({
+ dbgs() << "\tFound existing state: " << NewState->stateNum
+ << " - ";
+ dbgsStateInfo(NewState->stateInfo);
+ dbgs() << "\n";
+ });
} else {
NewState = &D.newState();
NewState->stateInfo = NewStateResources;
Visited[NewStateResources] = NewState;
WorkList.push_back(NewState);
- DEBUG(dbgs() << "\tAccepted new state: "
- << NewState->stateNum << " - ");
- dbgsStateInfo(NewState->stateInfo);
- DEBUG(dbgs() << "\n");
+ DEBUG({
+ dbgs() << "\tAccepted new state: " << NewState->stateNum << " - ";
+ dbgsStateInfo(NewState->stateInfo);
+ dbgs() << "\n";
+ });
}
current->addTransition(InsnClass, NewState);