mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-10 20:33:15 +00:00
Store State objects by value in TableGen's DFAPacketizerEmitter
Removes some extra manual dynamic memory allocation/management. It does get a bit quirky having to make State's members mutable and pointers/references to const rather than non-const, but that's a necessary workaround to dealing with the std::set elements. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206807 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
32eba65e0c
commit
c37ae28d93
@ -82,11 +82,13 @@ namespace {
|
|||||||
class State {
|
class State {
|
||||||
public:
|
public:
|
||||||
static int currentStateNum;
|
static int currentStateNum;
|
||||||
int stateNum;
|
// stateNum is the only member used for equality/ordering, all other members
|
||||||
bool isInitial;
|
// can be mutated even in const State objects.
|
||||||
std::set<unsigned> stateInfo;
|
const int stateNum;
|
||||||
typedef std::map<unsigned, State *> TransitionMap;
|
mutable bool isInitial;
|
||||||
TransitionMap Transitions;
|
mutable std::set<unsigned> stateInfo;
|
||||||
|
typedef std::map<unsigned, const State *> TransitionMap;
|
||||||
|
mutable TransitionMap Transitions;
|
||||||
|
|
||||||
State();
|
State();
|
||||||
State(const State &S);
|
State(const State &S);
|
||||||
@ -108,16 +110,16 @@ class State {
|
|||||||
// AddInsnClass - Return all combinations of resource reservation
|
// AddInsnClass - Return all combinations of resource reservation
|
||||||
// which are possible from this state (PossibleStates).
|
// which are possible from this state (PossibleStates).
|
||||||
//
|
//
|
||||||
void AddInsnClass(unsigned InsnClass, std::set<unsigned> &PossibleStates);
|
void AddInsnClass(unsigned InsnClass, std::set<unsigned> &PossibleStates) 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(unsigned InsnClass, State *To);
|
void addTransition(unsigned InsnClass, const State *To) const;
|
||||||
//
|
//
|
||||||
// hasTransition - Returns true if there is a transition from this state
|
// hasTransition - Returns true if there is a transition from this state
|
||||||
// given the input InsnClass
|
// given the input InsnClass
|
||||||
//
|
//
|
||||||
bool hasTransition(unsigned InsnClass);
|
bool hasTransition(unsigned InsnClass) const;
|
||||||
};
|
};
|
||||||
} // End anonymous namespace.
|
} // End anonymous namespace.
|
||||||
|
|
||||||
@ -128,10 +130,9 @@ namespace {
|
|||||||
class DFA {
|
class DFA {
|
||||||
public:
|
public:
|
||||||
DFA();
|
DFA();
|
||||||
~DFA();
|
|
||||||
|
|
||||||
// Set of states. Need to keep this sorted to emit the transition table.
|
// Set of states. Need to keep this sorted to emit the transition table.
|
||||||
typedef std::set<State *, less_ptr<State> > StateSet;
|
typedef std::set<State> StateSet;
|
||||||
StateSet states;
|
StateSet states;
|
||||||
|
|
||||||
State *currentState;
|
State *currentState;
|
||||||
@ -139,7 +140,7 @@ public:
|
|||||||
//
|
//
|
||||||
// Modify the DFA.
|
// Modify the DFA.
|
||||||
//
|
//
|
||||||
void addState(State *);
|
const State &newState();
|
||||||
|
|
||||||
//
|
//
|
||||||
// writeTable: Print out a table representing the DFA.
|
// writeTable: Print out a table representing the DFA.
|
||||||
@ -162,14 +163,10 @@ State::State(const State &S) :
|
|||||||
|
|
||||||
DFA::DFA(): currentState(nullptr) {}
|
DFA::DFA(): currentState(nullptr) {}
|
||||||
|
|
||||||
DFA::~DFA() {
|
|
||||||
DeleteContainerPointers(states);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// addTransition - Add a transition from this state given the input InsnClass
|
// addTransition - Add a transition from this state given the input InsnClass
|
||||||
//
|
//
|
||||||
void State::addTransition(unsigned InsnClass, State *To) {
|
void State::addTransition(unsigned InsnClass, const State *To) const {
|
||||||
assert(!Transitions.count(InsnClass) &&
|
assert(!Transitions.count(InsnClass) &&
|
||||||
"Cannot have multiple transitions for the same input");
|
"Cannot have multiple transitions for the same input");
|
||||||
Transitions[InsnClass] = To;
|
Transitions[InsnClass] = To;
|
||||||
@ -179,7 +176,7 @@ void State::addTransition(unsigned InsnClass, State *To) {
|
|||||||
// hasTransition - Returns true if there is a transition from this state
|
// hasTransition - Returns true if there is a transition from this state
|
||||||
// given the input InsnClass
|
// given the input InsnClass
|
||||||
//
|
//
|
||||||
bool State::hasTransition(unsigned InsnClass) {
|
bool State::hasTransition(unsigned InsnClass) const {
|
||||||
return Transitions.count(InsnClass) > 0;
|
return Transitions.count(InsnClass) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +185,7 @@ bool State::hasTransition(unsigned InsnClass) {
|
|||||||
// which are possible from this state (PossibleStates).
|
// which are possible from this state (PossibleStates).
|
||||||
//
|
//
|
||||||
void State::AddInsnClass(unsigned InsnClass,
|
void State::AddInsnClass(unsigned InsnClass,
|
||||||
std::set<unsigned> &PossibleStates) {
|
std::set<unsigned> &PossibleStates) const {
|
||||||
//
|
//
|
||||||
// Iterate over all resource states in currentState.
|
// Iterate over all resource states in currentState.
|
||||||
//
|
//
|
||||||
@ -247,9 +244,10 @@ bool State::canAddInsnClass(unsigned InsnClass) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DFA::addState(State *S) {
|
const State &DFA::newState() {
|
||||||
assert(!states.count(S) && "State already exists");
|
auto IterPair = states.emplace();
|
||||||
states.insert(S);
|
assert(IterPair.second && "State already exists");
|
||||||
|
return *IterPair.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -285,16 +283,16 @@ void DFA::writeTableAndAPI(raw_ostream &OS, const std::string &TargetName) {
|
|||||||
// to construct the StateEntry table.
|
// to construct the StateEntry table.
|
||||||
int ValidTransitions = 0;
|
int ValidTransitions = 0;
|
||||||
for (unsigned i = 0; i < states.size(); ++i, ++SI) {
|
for (unsigned i = 0; i < states.size(); ++i, ++SI) {
|
||||||
assert (((*SI)->stateNum == (int) i) && "Mismatch in state numbers");
|
assert ((SI->stateNum == (int) i) && "Mismatch in state numbers");
|
||||||
StateEntry[i] = ValidTransitions;
|
StateEntry[i] = ValidTransitions;
|
||||||
for (State::TransitionMap::iterator
|
for (State::TransitionMap::iterator
|
||||||
II = (*SI)->Transitions.begin(), IE = (*SI)->Transitions.end();
|
II = SI->Transitions.begin(), IE = SI->Transitions.end();
|
||||||
II != IE; ++II) {
|
II != IE; ++II) {
|
||||||
OS << "{" << II->first << ", "
|
OS << "{" << II->first << ", "
|
||||||
<< II->second->stateNum
|
<< II->second->stateNum
|
||||||
<< "}, ";
|
<< "}, ";
|
||||||
}
|
}
|
||||||
ValidTransitions += (*SI)->Transitions.size();
|
ValidTransitions += SI->Transitions.size();
|
||||||
|
|
||||||
// If there are no valid transitions from this stage, we need a sentinel
|
// If there are no valid transitions from this stage, we need a sentinel
|
||||||
// transition.
|
// transition.
|
||||||
@ -440,12 +438,11 @@ void DFAPacketizerEmitter::run(raw_ostream &OS) {
|
|||||||
// Run a worklist algorithm to generate the DFA.
|
// Run a worklist algorithm to generate the DFA.
|
||||||
//
|
//
|
||||||
DFA D;
|
DFA D;
|
||||||
State *Initial = new State;
|
const State *Initial = &D.newState();
|
||||||
Initial->isInitial = true;
|
Initial->isInitial = true;
|
||||||
Initial->stateInfo.insert(0x0);
|
Initial->stateInfo.insert(0x0);
|
||||||
D.addState(Initial);
|
SmallVector<const State*, 32> WorkList;
|
||||||
SmallVector<State*, 32> WorkList;
|
std::map<std::set<unsigned>, const State*> Visited;
|
||||||
std::map<std::set<unsigned>, State*> Visited;
|
|
||||||
|
|
||||||
WorkList.push_back(Initial);
|
WorkList.push_back(Initial);
|
||||||
|
|
||||||
@ -467,7 +464,7 @@ void DFAPacketizerEmitter::run(raw_ostream &OS) {
|
|||||||
// Add S' to Visited
|
// Add S' to Visited
|
||||||
//
|
//
|
||||||
while (!WorkList.empty()) {
|
while (!WorkList.empty()) {
|
||||||
State *current = WorkList.pop_back_val();
|
const State *current = WorkList.pop_back_val();
|
||||||
for (DenseSet<unsigned>::iterator CI = allInsnClasses.begin(),
|
for (DenseSet<unsigned>::iterator CI = allInsnClasses.begin(),
|
||||||
CE = allInsnClasses.end(); CI != CE; ++CI) {
|
CE = allInsnClasses.end(); CI != CE; ++CI) {
|
||||||
unsigned InsnClass = *CI;
|
unsigned InsnClass = *CI;
|
||||||
@ -479,7 +476,7 @@ void DFAPacketizerEmitter::run(raw_ostream &OS) {
|
|||||||
//
|
//
|
||||||
if (!current->hasTransition(InsnClass) &&
|
if (!current->hasTransition(InsnClass) &&
|
||||||
current->canAddInsnClass(InsnClass)) {
|
current->canAddInsnClass(InsnClass)) {
|
||||||
State *NewState = nullptr;
|
const State *NewState;
|
||||||
current->AddInsnClass(InsnClass, NewStateResources);
|
current->AddInsnClass(InsnClass, NewStateResources);
|
||||||
assert(NewStateResources.size() && "New states must be generated");
|
assert(NewStateResources.size() && "New states must be generated");
|
||||||
|
|
||||||
@ -487,13 +484,12 @@ void DFAPacketizerEmitter::run(raw_ostream &OS) {
|
|||||||
// If we have seen this state before, then do not create a new state.
|
// If we have seen this state before, then do not create a new state.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
std::map<std::set<unsigned>, State*>::iterator VI;
|
auto VI = Visited.find(NewStateResources);
|
||||||
if ((VI = Visited.find(NewStateResources)) != Visited.end())
|
if (VI != Visited.end())
|
||||||
NewState = VI->second;
|
NewState = VI->second;
|
||||||
else {
|
else {
|
||||||
NewState = new State;
|
NewState = &D.newState();
|
||||||
NewState->stateInfo = NewStateResources;
|
NewState->stateInfo = NewStateResources;
|
||||||
D.addState(NewState);
|
|
||||||
Visited[NewStateResources] = NewState;
|
Visited[NewStateResources] = NewState;
|
||||||
WorkList.push_back(NewState);
|
WorkList.push_back(NewState);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user