[llvm] r206807 - Store State objects by value in TableGen's DFAPacketizerEmitter

David Blaikie dblaikie at gmail.com
Mon Apr 21 15:35:11 PDT 2014


Author: dblaikie
Date: Mon Apr 21 17:35:11 2014
New Revision: 206807

URL: http://llvm.org/viewvc/llvm-project?rev=206807&view=rev
Log:
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.

Modified:
    llvm/trunk/utils/TableGen/DFAPacketizerEmitter.cpp

Modified: llvm/trunk/utils/TableGen/DFAPacketizerEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DFAPacketizerEmitter.cpp?rev=206807&r1=206806&r2=206807&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DFAPacketizerEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DFAPacketizerEmitter.cpp Mon Apr 21 17:35:11 2014
@@ -82,11 +82,13 @@ namespace {
 class State {
  public:
   static int currentStateNum;
-  int stateNum;
-  bool isInitial;
-  std::set<unsigned> stateInfo;
-  typedef std::map<unsigned, State *> TransitionMap;
-  TransitionMap Transitions;
+  // stateNum is the only member used for equality/ordering, all other members
+  // can be mutated even in const State objects.
+  const int stateNum;
+  mutable bool isInitial;
+  mutable std::set<unsigned> stateInfo;
+  typedef std::map<unsigned, const State *> TransitionMap;
+  mutable TransitionMap Transitions;
 
   State();
   State(const State &S);
@@ -108,16 +110,16 @@ class State {
   // AddInsnClass - Return all combinations of resource reservation
   // 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
   //
-  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
   // given the input InsnClass
   //
-  bool hasTransition(unsigned InsnClass);
+  bool hasTransition(unsigned InsnClass) const;
 };
 } // End anonymous namespace.
 
@@ -128,10 +130,9 @@ namespace {
 class DFA {
 public:
   DFA();
-  ~DFA();
 
   // 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;
 
   State *currentState;
@@ -139,7 +140,7 @@ public:
   //
   // Modify the DFA.
   //
-  void addState(State *);
+  const State &newState();
 
   //
   // writeTable: Print out a table representing the DFA.
@@ -162,14 +163,10 @@ State::State(const State &S) :
 
 DFA::DFA(): currentState(nullptr) {}
 
-DFA::~DFA() {
-  DeleteContainerPointers(states);
-}
-
 // 
 // 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) &&
       "Cannot have multiple transitions for the same input");
   Transitions[InsnClass] = To;
@@ -179,7 +176,7 @@ void State::addTransition(unsigned InsnC
 // hasTransition - Returns true if there is a transition from this state
 // given the input InsnClass
 //
-bool State::hasTransition(unsigned InsnClass) {
+bool State::hasTransition(unsigned InsnClass) const {
   return Transitions.count(InsnClass) > 0;
 }
 
@@ -188,7 +185,7 @@ bool State::hasTransition(unsigned InsnC
 // which are possible from this state (PossibleStates).
 //
 void State::AddInsnClass(unsigned InsnClass,
-                            std::set<unsigned> &PossibleStates) {
+                            std::set<unsigned> &PossibleStates) const {
   //
   // Iterate over all resource states in currentState.
   //
@@ -247,9 +244,10 @@ bool State::canAddInsnClass(unsigned Ins
 }
 
 
-void DFA::addState(State *S) {
-  assert(!states.count(S) && "State already exists");
-  states.insert(S);
+const State &DFA::newState() {
+  auto IterPair = states.emplace();
+  assert(IterPair.second && "State already exists");
+  return *IterPair.first;
 }
 
 
@@ -285,16 +283,16 @@ void DFA::writeTableAndAPI(raw_ostream &
   // to construct the StateEntry table.
   int ValidTransitions = 0;
   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;
     for (State::TransitionMap::iterator
-        II = (*SI)->Transitions.begin(), IE = (*SI)->Transitions.end();
+        II = SI->Transitions.begin(), IE = SI->Transitions.end();
         II != IE; ++II) {
       OS << "{" << II->first << ", "
          << II->second->stateNum
          << "},    ";
     }
-    ValidTransitions += (*SI)->Transitions.size();
+    ValidTransitions += SI->Transitions.size();
 
     // If there are no valid transitions from this stage, we need a sentinel
     // transition.
@@ -440,12 +438,11 @@ void DFAPacketizerEmitter::run(raw_ostre
   // Run a worklist algorithm to generate the DFA.
   //
   DFA D;
-  State *Initial = new State;
+  const State *Initial = &D.newState();
   Initial->isInitial = true;
   Initial->stateInfo.insert(0x0);
-  D.addState(Initial);
-  SmallVector<State*, 32> WorkList;
-  std::map<std::set<unsigned>, State*> Visited;
+  SmallVector<const State*, 32> WorkList;
+  std::map<std::set<unsigned>, const State*> Visited;
 
   WorkList.push_back(Initial);
 
@@ -467,7 +464,7 @@ void DFAPacketizerEmitter::run(raw_ostre
   //             Add S' to Visited
   //
   while (!WorkList.empty()) {
-    State *current = WorkList.pop_back_val();
+    const State *current = WorkList.pop_back_val();
     for (DenseSet<unsigned>::iterator CI = allInsnClasses.begin(),
            CE = allInsnClasses.end(); CI != CE; ++CI) {
       unsigned InsnClass = *CI;
@@ -479,7 +476,7 @@ void DFAPacketizerEmitter::run(raw_ostre
       //
       if (!current->hasTransition(InsnClass) &&
           current->canAddInsnClass(InsnClass)) {
-        State *NewState = nullptr;
+        const State *NewState;
         current->AddInsnClass(InsnClass, NewStateResources);
         assert(NewStateResources.size() && "New states must be generated");
 
@@ -487,13 +484,12 @@ void DFAPacketizerEmitter::run(raw_ostre
         // If we have seen this state before, then do not create a new state.
         //
         //
-        std::map<std::set<unsigned>, State*>::iterator VI;
-        if ((VI = Visited.find(NewStateResources)) != Visited.end())
+        auto VI = Visited.find(NewStateResources);
+        if (VI != Visited.end())
           NewState = VI->second;
         else {
-          NewState = new State;
+          NewState = &D.newState();
           NewState->stateInfo = NewStateResources;
-          D.addState(NewState);
           Visited[NewStateResources] = NewState;
           WorkList.push_back(NewState);
         }





More information about the llvm-commits mailing list