llvm.org GIT mirror llvm / c37ae28
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 David Blaikie 6 years ago
1 changed file(s) with 30 addition(s) and 34 deletion(s). Raw diff Collapse all Expand all
8181 class State {
8282 public:
8383 static int currentStateNum;
84 int stateNum;
85 bool isInitial;
86 std::set stateInfo;
87 typedef std::map TransitionMap;
88 TransitionMap Transitions;
84 // stateNum is the only member used for equality/ordering, all other members
85 // can be mutated even in const State objects.
86 const int stateNum;
87 mutable bool isInitial;
88 mutable std::set stateInfo;
89 typedef std::map TransitionMap;
90 mutable TransitionMap Transitions;
8991
9092 State();
9193 State(const State &S);
107109 // AddInsnClass - Return all combinations of resource reservation
108110 // which are possible from this state (PossibleStates).
109111 //
110 void AddInsnClass(unsigned InsnClass, std::set &PossibleStates);
112 void AddInsnClass(unsigned InsnClass, std::set &PossibleStates) const;
111113 //
112114 // addTransition - Add a transition from this state given the input InsnClass
113115 //
114 void addTransition(unsigned InsnClass, State *To);
116 void addTransition(unsigned InsnClass, const State *To) const;
115117 //
116118 // hasTransition - Returns true if there is a transition from this state
117119 // given the input InsnClass
118120 //
119 bool hasTransition(unsigned InsnClass);
121 bool hasTransition(unsigned InsnClass) const;
120122 };
121123 } // End anonymous namespace.
122124
127129 class DFA {
128130 public:
129131 DFA();
130 ~DFA();
131132
132133 // Set of states. Need to keep this sorted to emit the transition table.
133 typedef std::set *, less_ptr > StateSet;
134 typedef std::set> StateSet;
134135 StateSet states;
135136
136137 State *currentState;
138139 //
139140 // Modify the DFA.
140141 //
141 void addState(State *);
142 const State &newState();
142143
143144 //
144145 // writeTable: Print out a table representing the DFA.
161162
162163 DFA::DFA(): currentState(nullptr) {}
163164
164 DFA::~DFA() {
165 DeleteContainerPointers(states);
166 }
167
168165 //
169166 // addTransition - Add a transition from this state given the input InsnClass
170167 //
171 void State::addTransition(unsigned InsnClass, State *To) {
168 void State::addTransition(unsigned InsnClass, const State *To) const {
172169 assert(!Transitions.count(InsnClass) &&
173170 "Cannot have multiple transitions for the same input");
174171 Transitions[InsnClass] = To;
178175 // hasTransition - Returns true if there is a transition from this state
179176 // given the input InsnClass
180177 //
181 bool State::hasTransition(unsigned InsnClass) {
178 bool State::hasTransition(unsigned InsnClass) const {
182179 return Transitions.count(InsnClass) > 0;
183180 }
184181
187184 // which are possible from this state (PossibleStates).
188185 //
189186 void State::AddInsnClass(unsigned InsnClass,
190 std::set &PossibleStates) {
187 std::set &PossibleStates) const {
191188 //
192189 // Iterate over all resource states in currentState.
193190 //
246243 }
247244
248245
249 void DFA::addState(State *S) {
250 assert(!states.count(S) && "State already exists");
251 states.insert(S);
246 const State &DFA::newState() {
247 auto IterPair = states.emplace();
248 assert(IterPair.second && "State already exists");
249 return *IterPair.first;
252250 }
253251
254252
284282 // to construct the StateEntry table.
285283 int ValidTransitions = 0;
286284 for (unsigned i = 0; i < states.size(); ++i, ++SI) {
287 assert (((*SI)->stateNum == (int) i) && "Mismatch in state numbers");
285 assert ((SI->stateNum == (int) i) && "Mismatch in state numbers");
288286 StateEntry[i] = ValidTransitions;
289287 for (State::TransitionMap::iterator
290 II = (*SI)->Transitions.begin(), IE = (*SI)->Transitions.end();
288 II = SI->Transitions.begin(), IE = SI->Transitions.end();
291289 II != IE; ++II) {
292290 OS << "{" << II->first << ", "
293291 << II->second->stateNum
294292 << "}, ";
295293 }
296 ValidTransitions += (*SI)->Transitions.size();
294 ValidTransitions += SI->Transitions.size();
297295
298296 // If there are no valid transitions from this stage, we need a sentinel
299297 // transition.
439437 // Run a worklist algorithm to generate the DFA.
440438 //
441439 DFA D;
442 State *Initial = new State;
440 const State *Initial = &D.newState();
443441 Initial->isInitial = true;
444442 Initial->stateInfo.insert(0x0);
445 D.addState(Initial);
446 SmallVector WorkList;
447 std::map, State*> Visited;
443 SmallVector WorkList;
444 std::map, const State*> Visited;
448445
449446 WorkList.push_back(Initial);
450447
466463 // Add S' to Visited
467464 //
468465 while (!WorkList.empty()) {
469 State *current = WorkList.pop_back_val();
466 const State *current = WorkList.pop_back_val();
470467 for (DenseSet::iterator CI = allInsnClasses.begin(),
471468 CE = allInsnClasses.end(); CI != CE; ++CI) {
472469 unsigned InsnClass = *CI;
478475 //
479476 if (!current->hasTransition(InsnClass) &&
480477 current->canAddInsnClass(InsnClass)) {
481 State *NewState = nullptr;
478 const State *NewState;
482479 current->AddInsnClass(InsnClass, NewStateResources);
483480 assert(NewStateResources.size() && "New states must be generated");
484481
486483 // If we have seen this state before, then do not create a new state.
487484 //
488485 //
489 std::map, State*>::iterator VI;
490 if ((VI = Visited.find(NewStateResources)) != Visited.end())
486 auto VI = Visited.find(NewStateResources);
487 if (VI != Visited.end())
491488 NewState = VI->second;
492489 else {
493 NewState = new State;
490 NewState = &D.newState();
494491 NewState->stateInfo = NewStateResources;
495 D.addState(NewState);
496492 Visited[NewStateResources] = NewState;
497493 WorkList.push_back(NewState);
498494 }