[llvm] r371198 - [DFAPacketizer] Track resources for packetized instructions
James Molloy via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 6 05:20:08 PDT 2019
Author: jamesm
Date: Fri Sep 6 05:20:08 2019
New Revision: 371198
URL: http://llvm.org/viewvc/llvm-project?rev=371198&view=rev
Log:
[DFAPacketizer] Track resources for packetized instructions
This patch allows the DFAPacketizer to be queried after a packet is formed to work out which
resources were allocated to the packetized instructions.
This is particularly important for targets that do their own bundle packing - it's not
sufficient to know simply that instructions can share a packet; which slots are used is
also required for encoding.
This extends the emitter to emit a side-table containing resource usage diffs for each
state transition. The packetizer maintains a set of all possible resource states in its
current state. After packetization is complete, all remaining resource states are
possible packetization strategies.
The sidetable is only ~500K for Hexagon, but the extra tracking is disabled by default
(most uses of the packetizer like MachinePipeliner don't care and don't need the extra
maintained state).
Differential Revision: https://reviews.llvm.org/D66936
Added:
llvm/trunk/test/CodeGen/Hexagon/packetizer-resources.ll
Modified:
llvm/trunk/include/llvm/CodeGen/DFAPacketizer.h
llvm/trunk/lib/CodeGen/DFAPacketizer.cpp
llvm/trunk/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
llvm/trunk/utils/TableGen/DFAPacketizerEmitter.cpp
Modified: llvm/trunk/include/llvm/CodeGen/DFAPacketizer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DFAPacketizer.h?rev=371198&r1=371197&r2=371198&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/DFAPacketizer.h (original)
+++ llvm/trunk/include/llvm/CodeGen/DFAPacketizer.h Fri Sep 6 05:20:08 2019
@@ -82,20 +82,53 @@ private:
int CurrentState = 0;
const DFAStateInput (*DFAStateInputTable)[2];
const unsigned *DFAStateEntryTable;
+ const std::pair<unsigned, unsigned> *DFAResourceTransitionTable;
+ const unsigned *DFAResourceTransitionEntryTable;
// CachedTable is a map from <FromState, Input> to ToState.
DenseMap<UnsignPair, unsigned> CachedTable;
+ // CachedResourceTransitions is a map from <FromState, Input> to a list of
+ // resource transitions.
+ DenseMap<UnsignPair, ArrayRef<std::pair<unsigned, unsigned>>>
+ CachedResourceTransitions;
// Read the DFA transition table and update CachedTable.
void ReadTable(unsigned state);
+ bool TrackResources = false;
+ // State for the current packet. Every entry is a possible packing of the
+ // bundle, indexed by cumulative resource state. Each entry is a list of the
+ // cumulative resource states after packing each instruction. For example if
+ // we pack I0: [0x4] and I1: [0x2] we will end up with:
+ // ResourceStates[0x6] = [0x4, 0x6]
+ DenseMap<unsigned, SmallVector<unsigned, 8>> ResourceStates;
+
public:
DFAPacketizer(const InstrItineraryData *I, const DFAStateInput (*SIT)[2],
- const unsigned *SET);
+ const unsigned *SET,
+ const std::pair<unsigned, unsigned> *RTT = nullptr,
+ const unsigned *RTET = nullptr);
// Reset the current state to make all resources available.
void clearResources() {
CurrentState = 0;
+ ResourceStates.clear();
+ ResourceStates[0] = {};
+ }
+
+ // Set whether this packetizer should track not just whether instructions
+ // can be packetized, but also which functional units each instruction ends up
+ // using after packetization.
+ void setTrackResources(bool Track) {
+ if (Track != TrackResources) {
+ TrackResources = Track;
+ if (Track) {
+ CachedTable.clear();
+ assert(DFAResourceTransitionEntryTable);
+ assert(DFAResourceTransitionTable);
+ }
+ }
+ assert(CurrentState == 0 && "Can only change TrackResources on an empty packetizer!");
}
// Return the DFAInput for an instruction class.
@@ -120,6 +153,15 @@ public:
// current state to reflect that change.
void reserveResources(MachineInstr &MI);
+ // Return the resources used by the InstIdx'th instruction added to this
+ // packet. The resources are returned as a bitvector of functional units.
+ //
+ // Note that a bundle may be packed in multiple valid ways. This function
+ // returns one arbitary valid packing.
+ //
+ // Requires setTrackResources(true) to have been called.
+ unsigned getUsedResources(unsigned InstIdx);
+
const InstrItineraryData *getInstrItins() const { return InstrItins; }
};
Modified: llvm/trunk/lib/CodeGen/DFAPacketizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DFAPacketizer.cpp?rev=371198&r1=371197&r2=371198&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/DFAPacketizer.cpp (original)
+++ llvm/trunk/lib/CodeGen/DFAPacketizer.cpp Fri Sep 6 05:20:08 2019
@@ -23,6 +23,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/DFAPacketizer.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
@@ -72,9 +73,11 @@ static DFAInput getDFAInsnInput(const st
// --------------------------------------------------------------------
DFAPacketizer::DFAPacketizer(const InstrItineraryData *I,
- const DFAStateInput (*SIT)[2],
- const unsigned *SET):
- InstrItins(I), DFAStateInputTable(SIT), DFAStateEntryTable(SET) {
+ const DFAStateInput (*SIT)[2], const unsigned *SET,
+ const std::pair<unsigned, unsigned> *RTT,
+ const unsigned *RTET)
+ : InstrItins(I), DFAStateInputTable(SIT), DFAStateEntryTable(SET),
+ DFAResourceTransitionTable(RTT), DFAResourceTransitionEntryTable(RTET) {
// Make sure DFA types are large enough for the number of terms & resources.
static_assert((DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) <=
(8 * sizeof(DFAInput)),
@@ -82,6 +85,7 @@ DFAPacketizer::DFAPacketizer(const Instr
static_assert(
(DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) <= (8 * sizeof(DFAStateInput)),
"(DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) too big for DFAStateInput");
+ clearResources();
}
// Read the DFA transition table and update CachedTable.
@@ -93,16 +97,26 @@ DFAPacketizer::DFAPacketizer(const Instr
// for the ith state
//
void DFAPacketizer::ReadTable(unsigned int state) {
- unsigned ThisState = DFAStateEntryTable[state];
- unsigned NextStateInTable = DFAStateEntryTable[state+1];
+ unsigned ThisStateIdx = DFAStateEntryTable[state];
+ unsigned NextStateIdxInTable = DFAStateEntryTable[state + 1];
// Early exit in case CachedTable has already contains this
// state's transitions.
- if (CachedTable.count(UnsignPair(state, DFAStateInputTable[ThisState][0])))
+ if (CachedTable.count(UnsignPair(state, DFAStateInputTable[ThisStateIdx][0])))
return;
- for (unsigned i = ThisState; i < NextStateInTable; i++)
- CachedTable[UnsignPair(state, DFAStateInputTable[i][0])] =
- DFAStateInputTable[i][1];
+ for (unsigned TransitionIdx = ThisStateIdx;
+ TransitionIdx < NextStateIdxInTable; TransitionIdx++) {
+ auto TransitionPair =
+ UnsignPair(state, DFAStateInputTable[TransitionIdx][0]);
+ CachedTable[TransitionPair] = DFAStateInputTable[TransitionIdx][1];
+
+ if (TrackResources) {
+ unsigned I = DFAResourceTransitionEntryTable[TransitionIdx];
+ unsigned E = DFAResourceTransitionEntryTable[TransitionIdx + 1];
+ CachedResourceTransitions[TransitionPair] = makeArrayRef(
+ &DFAResourceTransitionTable[I], &DFAResourceTransitionTable[E]);
+ }
+ }
}
// Return the DFAInput for an instruction class.
@@ -141,6 +155,16 @@ void DFAPacketizer::reserveResources(con
DFAInput InsnInput = getInsnInput(InsnClass);
UnsignPair StateTrans = UnsignPair(CurrentState, InsnInput);
ReadTable(CurrentState);
+
+ if (TrackResources) {
+ DenseMap<unsigned, SmallVector<unsigned, 8>> NewResourceStates;
+ for (const auto &KV : CachedResourceTransitions[StateTrans]) {
+ assert(ResourceStates.count(KV.first));
+ NewResourceStates[KV.second] = ResourceStates[KV.first];
+ NewResourceStates[KV.second].push_back(KV.second);
+ }
+ ResourceStates = NewResourceStates;
+ }
assert(CachedTable.count(StateTrans) != 0);
CurrentState = CachedTable[StateTrans];
}
@@ -159,6 +183,21 @@ void DFAPacketizer::reserveResources(Mac
reserveResources(&MID);
}
+unsigned DFAPacketizer::getUsedResources(unsigned InstIdx) {
+ assert(TrackResources && "getUsedResources requires resource tracking!");
+ // Assert that there is at least one example of a valid bundle format.
+ assert(!ResourceStates.empty() && "Invalid bundle!");
+ SmallVectorImpl<unsigned> &RS = ResourceStates.begin()->second;
+
+ // RS stores the cumulative resources used up to and including the I'th
+ // instruction. The 0th instruction is the base case.
+ if (InstIdx == 0)
+ return RS[0];
+ // Return the difference between the cumulative resources used by InstIdx and
+ // its predecessor.
+ return RS[InstIdx] ^ RS[InstIdx - 1];
+}
+
namespace llvm {
// This class extends ScheduleDAGInstrs and overrides the schedule method
@@ -210,6 +249,7 @@ VLIWPacketizerList::VLIWPacketizerList(M
MachineLoopInfo &mli, AliasAnalysis *aa)
: MF(mf), TII(mf.getSubtarget().getInstrInfo()), AA(aa) {
ResourceTracker = TII->CreateTargetScheduleState(MF.getSubtarget());
+ ResourceTracker->setTrackResources(true);
VLIWScheduler = new DefaultVLIWScheduler(MF, mli, AA);
}
@@ -224,8 +264,11 @@ void VLIWPacketizerList::endPacket(Machi
LLVM_DEBUG({
if (!CurrentPacketMIs.empty()) {
dbgs() << "Finalizing packet:\n";
- for (MachineInstr *MI : CurrentPacketMIs)
- dbgs() << " * " << *MI;
+ unsigned Idx = 0;
+ for (MachineInstr *MI : CurrentPacketMIs) {
+ unsigned R = ResourceTracker->getUsedResources(Idx++);
+ dbgs() << " * [res:0x" << utohexstr(R) << "] " << *MI;
+ }
}
});
if (CurrentPacketMIs.size() > 1) {
Modified: llvm/trunk/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp?rev=371198&r1=371197&r2=371198&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp Fri Sep 6 05:20:08 2019
@@ -24,6 +24,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
@@ -1763,6 +1764,16 @@ HexagonPacketizerList::addToPacket(Machi
void HexagonPacketizerList::endPacket(MachineBasicBlock *MBB,
MachineBasicBlock::iterator EndMI) {
// Replace VLIWPacketizerList::endPacket(MBB, EndMI).
+ LLVM_DEBUG({
+ if (!CurrentPacketMIs.empty()) {
+ dbgs() << "Finalizing packet:\n";
+ unsigned Idx = 0;
+ for (MachineInstr *MI : CurrentPacketMIs) {
+ unsigned R = ResourceTracker->getUsedResources(Idx++);
+ dbgs() << " * [res:0x" << utohexstr(R) << "] " << *MI;
+ }
+ }
+ });
bool memShufDisabled = getmemShufDisabled();
if (memShufDisabled && !foundLSInPacket()) {
Added: llvm/trunk/test/CodeGen/Hexagon/packetizer-resources.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/packetizer-resources.ll?rev=371198&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/packetizer-resources.ll (added)
+++ llvm/trunk/test/CodeGen/Hexagon/packetizer-resources.ll Fri Sep 6 05:20:08 2019
@@ -0,0 +1,29 @@
+; RUN: llc -O2 -march=hexagon < %s -debug-only=packets 2>&1 | FileCheck %s
+; REQUIRES: asserts
+
+; CHECK: Finalizing packet:
+; CHECK-NEXT: * [res:0x8] renamable $r1 = S2_vsplatrb renamable $r0
+; CHECK-NEXT: * [res:0x4] renamable $d1 = S2_vsplatrh killed renamable $r0
+
+target triple = "hexagon"
+
+; Function Attrs: nounwind readnone
+define i64 @f0(i64 %a0) #0 {
+b0:
+ %v0 = trunc i64 %a0 to i32
+ %v1 = and i32 %v0, 65535
+ %v2 = tail call i64 @llvm.hexagon.S2.vsplatrh(i32 %v1)
+ %v3 = and i32 %v0, 255
+ %v4 = tail call i32 @llvm.hexagon.S2.vsplatrb(i32 %v3)
+ %v5 = sext i32 %v4 to i64
+ %v6 = add nsw i64 %v5, %v2
+ ret i64 %v6
+}
+
+; Function Attrs: nounwind readnone
+declare i64 @llvm.hexagon.S2.vsplatrh(i32) #0
+
+; Function Attrs: nounwind readnone
+declare i32 @llvm.hexagon.S2.vsplatrb(i32) #0
+
+attributes #0 = { nounwind readnone }
Modified: llvm/trunk/utils/TableGen/DFAPacketizerEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DFAPacketizerEmitter.cpp?rev=371198&r1=371197&r2=371198&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DFAPacketizerEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DFAPacketizerEmitter.cpp Fri Sep 6 05:20:08 2019
@@ -192,7 +192,14 @@ class State {
const int stateNum;
mutable bool isInitial;
mutable std::set<unsigned> stateInfo;
- typedef std::map<std::vector<unsigned>, const State *> TransitionMap;
+
+ struct TransitionInfo {
+ // Maps from a resource bitmask in this state to the equivalent resource
+ // bitmap in the transitioned-to state. This is a 1-to-N mapping.
+ std::vector<std::pair<unsigned, unsigned>> ResourceTransitions;
+ const State *S;
+ };
+ using TransitionMap = std::map<std::vector<unsigned>, TransitionInfo>;
mutable TransitionMap Transitions;
State();
@@ -221,9 +228,14 @@ class State {
// PossibleStates is the set of valid resource states that ensue from valid
// transitions.
//
- void AddInsnClass(std::vector<unsigned> &InsnClass,
- std::map<unsigned, unsigned> &ComboBitToBitsMap,
- std::set<unsigned> &PossibleStates) const;
+ // TransitionInfo maps from a resource bitmask B in this state to a resource
+ // bitmask B' in PossibleStates. This is a one-to-many (or none) mapping.
+ //
+ void AddInsnClass(
+ std::vector<unsigned> &InsnClass,
+ std::map<unsigned, unsigned> &ComboBitToBitsMap,
+ std::set<unsigned> &PossibleStates,
+ std::vector<std::pair<unsigned, unsigned>> &TransitionInfo) const;
//
// AddInsnClassStages - Return all combinations of resource reservation
@@ -231,16 +243,17 @@ class State {
// which are possible from this state (PossibleStates).
//
void AddInsnClassStages(std::vector<unsigned> &InsnClass,
- std::map<unsigned, unsigned> &ComboBitToBitsMap,
- unsigned chkstage, unsigned numstages,
- unsigned prevState, unsigned origState,
- DenseSet<unsigned> &VisitedResourceStates,
- std::set<unsigned> &PossibleStates) const;
+ std::map<unsigned, unsigned> &ComboBitToBitsMap,
+ unsigned chkstage, unsigned numstages,
+ unsigned prevState, unsigned origState,
+ DenseSet<unsigned> &VisitedResourceStates) const;
//
- // addTransition - Add a transition from this state given the input InsnClass
+ // addTransition - Add a transition from this state given the input InsnClass.
//
- void addTransition(std::vector<unsigned> InsnClass, const State *To) const;
+ void addTransition(
+ std::vector<unsigned> InsnClass, const State *To,
+ const std::vector<std::pair<unsigned, unsigned>> &TransitionInfo) const;
//
// hasTransition - Returns true if there is a transition from this state
@@ -329,11 +342,12 @@ State::State() :
//
// addTransition - Add a transition from this state given the input InsnClass
//
-void State::addTransition(std::vector<unsigned> InsnClass, const State *To)
- const {
+void State::addTransition(
+ std::vector<unsigned> InsnClass, const State *To,
+ const std::vector<std::pair<unsigned, unsigned>> &TransitionInfo) const {
assert(!Transitions.count(InsnClass) &&
"Cannot have multiple transitions for the same input");
- Transitions[InsnClass] = To;
+ Transitions[InsnClass] = {TransitionInfo, To};
}
//
@@ -351,9 +365,11 @@ bool State::hasTransition(std::vector<un
// PossibleStates is the set of valid resource states that ensue from valid
// transitions.
//
-void State::AddInsnClass(std::vector<unsigned> &InsnClass,
- std::map<unsigned, unsigned> &ComboBitToBitsMap,
- std::set<unsigned> &PossibleStates) const {
+void State::AddInsnClass(
+ std::vector<unsigned> &InsnClass,
+ std::map<unsigned, unsigned> &ComboBitToBitsMap,
+ std::set<unsigned> &PossibleStates,
+ std::vector<std::pair<unsigned, unsigned>> &TransitionInfo) const {
//
// Iterate over all resource states in currentState.
//
@@ -362,25 +378,26 @@ void State::AddInsnClass(std::vector<uns
for (std::set<unsigned>::iterator SI = stateInfo.begin();
SI != stateInfo.end(); ++SI) {
- unsigned thisState = *SI;
+ unsigned ThisState = *SI;
DenseSet<unsigned> VisitedResourceStates;
- LLVM_DEBUG(dbgs() << " thisState: 0x" << Twine::utohexstr(thisState)
+ LLVM_DEBUG(dbgs() << " thisState: 0x" << Twine::utohexstr(ThisState)
<< "\n");
- AddInsnClassStages(InsnClass, ComboBitToBitsMap,
- numstages - 1, numstages,
- thisState, thisState,
- VisitedResourceStates, PossibleStates);
+ AddInsnClassStages(InsnClass, ComboBitToBitsMap, numstages - 1, numstages,
+ ThisState, ThisState, VisitedResourceStates);
+ for (unsigned NewState : VisitedResourceStates) {
+ PossibleStates.insert(NewState);
+ TransitionInfo.emplace_back(ThisState, NewState);
+ }
}
}
-void State::AddInsnClassStages(std::vector<unsigned> &InsnClass,
- std::map<unsigned, unsigned> &ComboBitToBitsMap,
- unsigned chkstage, unsigned numstages,
- unsigned prevState, unsigned origState,
- DenseSet<unsigned> &VisitedResourceStates,
- std::set<unsigned> &PossibleStates) const {
+void State::AddInsnClassStages(
+ std::vector<unsigned> &InsnClass,
+ std::map<unsigned, unsigned> &ComboBitToBitsMap, unsigned chkstage,
+ unsigned numstages, unsigned prevState, unsigned origState,
+ DenseSet<unsigned> &VisitedResourceStates) const {
assert((chkstage < numstages) && "AddInsnClassStages: stage out of range");
unsigned thisStage = InsnClass[chkstage];
@@ -438,7 +455,6 @@ void State::AddInsnClassStages(std::vect
if (ResultingResourceState != prevState) {
if (VisitedResourceStates.count(ResultingResourceState) == 0) {
VisitedResourceStates.insert(ResultingResourceState);
- PossibleStates.insert(ResultingResourceState);
LLVM_DEBUG(dbgs()
<< "\tResultingResourceState: 0x"
<< Twine::utohexstr(ResultingResourceState) << "\n");
@@ -456,10 +472,9 @@ void State::AddInsnClassStages(std::vect
//
if (ResultingResourceState != prevState) {
LLVM_DEBUG(dbgs() << "\n");
- AddInsnClassStages(InsnClass, ComboBitToBitsMap,
- chkstage - 1, numstages,
- ResultingResourceState, origState,
- VisitedResourceStates, PossibleStates);
+ AddInsnClassStages(InsnClass, ComboBitToBitsMap, chkstage - 1,
+ numstages, ResultingResourceState, origState,
+ VisitedResourceStates);
} else {
LLVM_DEBUG(dbgs() << "\tSkipped Add - no resources available\n");
}
@@ -578,17 +593,10 @@ void DFA::writeTableAndAPI(raw_ostream &
II = SI->Transitions.begin(), IE = SI->Transitions.end();
II != IE; ++II) {
OS << "{0x" << Twine::utohexstr(getDFAInsnInput(II->first)) << ", "
- << II->second->stateNum << "},\t";
+ << II->second.S->stateNum << "},\t";
}
ValidTransitions += SI->Transitions.size();
- // If there are no valid transitions from this stage, we need a sentinel
- // transition.
- if (ValidTransitions == StateEntry[i]) {
- OS << SentinelEntry << ",\t";
- ++ValidTransitions;
- }
-
OS << " // state " << i << ": " << StateEntry[i];
if (StateEntry[i] != (ValidTransitions-1)) { // More than one transition.
OS << "-" << (ValidTransitions-1);
@@ -610,8 +618,6 @@ void DFA::writeTableAndAPI(raw_ostream &
OS << "// " << numStates << " states\n";
OS << "const unsigned int " << TargetName << "DFAStateEntryTable[] = {\n";
- // Multiply i by 2 since each entry in DFAStateInputTable is a set of
- // two numbers.
unsigned lastState = 0;
for (unsigned i = 0; i < numStates; ++i) {
if (i && ((i % 10) == 0)) {
@@ -620,11 +626,44 @@ void DFA::writeTableAndAPI(raw_ostream &
}
OS << StateEntry[i] << ", ";
}
-
// Print out the index to the sentinel entry in StateInputTable
OS << ValidTransitions << ", ";
OS << " // states " << (lastState+1) << ":" << numStates << "\n";
OS << "};\n";
+
+ // Generate the resource transition table.
+ OS << "const std::pair<unsigned, unsigned> " << TargetName
+ << "DFAResourceTransitionTable[] = { \n";
+ int N = 0;
+ StateEntry.clear();
+ for (const State &S : states) {
+ for (auto &KV : S.Transitions) {
+ StateEntry.push_back(N);
+ for (std::pair<unsigned, unsigned> &T : KV.second.ResourceTransitions) {
+ OS << "{0x" << utohexstr(T.first) << ", 0x" << utohexstr(T.second)
+ << "}, ";
+ ++N;
+ }
+ }
+ OS << "\n ";
+ }
+ // Add a sentinel entry to terminate the search.
+ StateEntry.push_back(N);
+ OS << "\n {~0U,~0U}\n};\n\n";
+
+ OS << "// " << TargetName << "DFAResourceTransitionEntryTable[i] = "
+ << "Index of the first entry in DFAResourceTransitionTable for\n";
+ OS << "// the ith transition.\n";
+ OS << "const unsigned int " << TargetName
+ << "DFAResourceTransitionEntryTable[] = { \n";
+
+ N = 0;
+ for (int S : StateEntry) {
+ OS << S << ",";
+ if (N++ % 10 == 0)
+ OS << "\n ";
+ }
+ OS << "\n ~0U\n};\n";
}
//
@@ -946,7 +985,9 @@ void DFAPacketizerEmitter::emitForItiner
if (!current->hasTransition(InsnClass) &&
current->canMaybeAddInsnClass(InsnClass, ComboBitToBitsMap)) {
const State *NewState = nullptr;
- current->AddInsnClass(InsnClass, ComboBitToBitsMap, NewStateResources);
+ std::vector<std::pair<unsigned, unsigned>> TransitionInfo;
+ current->AddInsnClass(InsnClass, ComboBitToBitsMap, NewStateResources,
+ TransitionInfo);
if (NewStateResources.empty()) {
LLVM_DEBUG(dbgs() << " Skipped - no new states generated\n");
continue;
@@ -982,7 +1023,7 @@ void DFAPacketizerEmitter::emitForItiner
});
}
- current->addTransition(InsnClass, NewState);
+ current->addTransition(InsnClass, NewState, TransitionInfo);
}
}
}
@@ -1000,7 +1041,10 @@ void DFAPacketizerEmitter::emitForItiner
<< "DFAPacketizer(const InstrItineraryData *IID) const {\n"
<< " return new DFAPacketizer(IID, " << TargetName << DFAName
<< "DFAStateInputTable, " << TargetName << DFAName
- << "DFAStateEntryTable);\n}\n\n";
+ << "DFAStateEntryTable, " << TargetName << DFAName
+ << "DFAResourceTransitionTable, " << TargetName << DFAName
+ << "DFAResourceTransitionEntryTable"
+ << ");\n}\n\n";
}
namespace llvm {
More information about the llvm-commits
mailing list