forked from OSchip/llvm-project
Refactor and speed up DFA generator.
Patch by Ivan Llopard! llvm-svn: 159281
This commit is contained in:
parent
b7f5a9c5cd
commit
20013f1368
|
|
@ -94,7 +94,12 @@ class State {
|
||||||
// PossibleStates is the set of valid resource states that ensue from valid
|
// PossibleStates is the set of valid resource states that ensue from valid
|
||||||
// transitions.
|
// transitions.
|
||||||
//
|
//
|
||||||
bool canAddInsnClass(unsigned InsnClass, std::set<unsigned> &PossibleStates);
|
bool canAddInsnClass(unsigned InsnClass) const;
|
||||||
|
//
|
||||||
|
// AddInsnClass - Return all combinations of resource reservation
|
||||||
|
// which are possible from this state (PossibleStates).
|
||||||
|
//
|
||||||
|
void AddInsnClass(unsigned InsnClass, std::set<unsigned> &PossibleStates);
|
||||||
};
|
};
|
||||||
} // End anonymous namespace.
|
} // End anonymous namespace.
|
||||||
|
|
||||||
|
|
@ -120,6 +125,10 @@ namespace {
|
||||||
struct ltState {
|
struct ltState {
|
||||||
bool operator()(const State *s1, const State *s2) const;
|
bool operator()(const State *s1, const State *s2) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ltTransition {
|
||||||
|
bool operator()(const Transition *s1, const Transition *s2) const;
|
||||||
|
};
|
||||||
} // End anonymous namespace.
|
} // End anonymous namespace.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -135,7 +144,8 @@ public:
|
||||||
std::set<State*, ltState> states;
|
std::set<State*, ltState> states;
|
||||||
|
|
||||||
// Map from a state to the list of transitions with that state as source.
|
// Map from a state to the list of transitions with that state as source.
|
||||||
std::map<State*, SmallVector<Transition*, 16>, ltState> stateTransitions;
|
std::map<State*, std::set<Transition*, ltTransition>, ltState>
|
||||||
|
stateTransitions;
|
||||||
State *currentState;
|
State *currentState;
|
||||||
|
|
||||||
// Highest valued Input seen.
|
// Highest valued Input seen.
|
||||||
|
|
@ -193,21 +203,19 @@ bool ltState::operator()(const State *s1, const State *s2) const {
|
||||||
return (s1->stateNum < s2->stateNum);
|
return (s1->stateNum < s2->stateNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ltTransition::operator()(const Transition *s1, const Transition *s2) const {
|
||||||
|
return (s1->input < s2->input);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// canAddInsnClass - Returns true if an instruction of type InsnClass is a
|
// AddInsnClass - Return all combinations of resource reservation
|
||||||
// valid transition from this state i.e., can an instruction of type InsnClass
|
// which are possible from this state (PossibleStates).
|
||||||
// be added to the packet represented by this state.
|
|
||||||
//
|
//
|
||||||
// PossibleStates is the set of valid resource states that ensue from valid
|
void State::AddInsnClass(unsigned InsnClass,
|
||||||
// transitions.
|
|
||||||
//
|
|
||||||
bool State::canAddInsnClass(unsigned InsnClass,
|
|
||||||
std::set<unsigned> &PossibleStates) {
|
std::set<unsigned> &PossibleStates) {
|
||||||
//
|
//
|
||||||
// Iterate over all resource states in currentState.
|
// Iterate over all resource states in currentState.
|
||||||
//
|
//
|
||||||
bool AddedState = false;
|
|
||||||
|
|
||||||
for (std::set<unsigned>::iterator SI = stateInfo.begin();
|
for (std::set<unsigned>::iterator SI = stateInfo.begin();
|
||||||
SI != stateInfo.end(); ++SI) {
|
SI != stateInfo.end(); ++SI) {
|
||||||
|
|
@ -240,13 +248,26 @@ bool State::canAddInsnClass(unsigned InsnClass,
|
||||||
(VisitedResourceStates.count(ResultingResourceState) == 0)) {
|
(VisitedResourceStates.count(ResultingResourceState) == 0)) {
|
||||||
VisitedResourceStates.insert(ResultingResourceState);
|
VisitedResourceStates.insert(ResultingResourceState);
|
||||||
PossibleStates.insert(ResultingResourceState);
|
PossibleStates.insert(ResultingResourceState);
|
||||||
AddedState = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return AddedState;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// canAddInsnClass - Quickly verifies if an instruction of type InsnClass is a
|
||||||
|
// valid transition from this state i.e., can an instruction of type InsnClass
|
||||||
|
// be added to the packet represented by this state.
|
||||||
|
//
|
||||||
|
bool State::canAddInsnClass(unsigned InsnClass) const {
|
||||||
|
for (std::set<unsigned>::iterator SI = stateInfo.begin();
|
||||||
|
SI != stateInfo.end(); ++SI) {
|
||||||
|
if (~*SI & InsnClass)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -267,7 +288,8 @@ void DFA::addTransition(Transition *T) {
|
||||||
LargestInput = T->input;
|
LargestInput = T->input;
|
||||||
|
|
||||||
// Add the new transition.
|
// Add the new transition.
|
||||||
stateTransitions[T->from].push_back(T);
|
bool Added = stateTransitions[T->from].insert(T).second;
|
||||||
|
assert(Added && "Cannot have multiple states for the same input");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -281,11 +303,13 @@ State *DFA::getTransition(State *From, unsigned I) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Do we have a transition from state From with Input I?
|
// Do we have a transition from state From with Input I?
|
||||||
for (SmallVector<Transition*, 16>::iterator VI =
|
Transition TVal(NULL, I, NULL);
|
||||||
stateTransitions[From].begin();
|
// Do not count this temporal instance
|
||||||
VI != stateTransitions[From].end(); ++VI)
|
Transition::currentTransitionNum--;
|
||||||
if ((*VI)->input == I)
|
std::set<Transition*, ltTransition>::iterator T =
|
||||||
return (*VI)->to;
|
stateTransitions[From].find(&TVal);
|
||||||
|
if (T != stateTransitions[From].end())
|
||||||
|
return (*T)->to;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -331,11 +355,12 @@ void DFA::writeTableAndAPI(raw_ostream &OS, const std::string &TargetName) {
|
||||||
StateEntry[i] = ValidTransitions;
|
StateEntry[i] = ValidTransitions;
|
||||||
for (unsigned j = 0; j <= LargestInput; ++j) {
|
for (unsigned j = 0; j <= LargestInput; ++j) {
|
||||||
assert (((*SI)->stateNum == (int) i) && "Mismatch in state numbers");
|
assert (((*SI)->stateNum == (int) i) && "Mismatch in state numbers");
|
||||||
if (!isValidTransition(*SI, j))
|
State *To = getTransition(*SI, j);
|
||||||
|
if (To == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
OS << "{" << j << ", "
|
OS << "{" << j << ", "
|
||||||
<< getTransition(*SI, j)->stateNum
|
<< To->stateNum
|
||||||
<< "}, ";
|
<< "}, ";
|
||||||
++ValidTransitions;
|
++ValidTransitions;
|
||||||
}
|
}
|
||||||
|
|
@ -514,8 +539,10 @@ void DFAPacketizerEmitter::run(raw_ostream &OS) {
|
||||||
// and the state can accommodate this InsnClass, create a transition.
|
// and the state can accommodate this InsnClass, create a transition.
|
||||||
//
|
//
|
||||||
if (!D.getTransition(current, InsnClass) &&
|
if (!D.getTransition(current, InsnClass) &&
|
||||||
current->canAddInsnClass(InsnClass, NewStateResources)) {
|
current->canAddInsnClass(InsnClass)) {
|
||||||
State *NewState = NULL;
|
State *NewState = NULL;
|
||||||
|
current->AddInsnClass(InsnClass, NewStateResources);
|
||||||
|
assert(NewStateResources.size() && "New states must be generated");
|
||||||
|
|
||||||
//
|
//
|
||||||
// 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.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue