Turn a leaked object into a stack variable instead.
[oota-llvm.git] / utils / TableGen / DFAPacketizerEmitter.cpp
index 8de624234142804bf739d3c0169ac116bc297f70..ea14cb973ebcde3f7f7ae2ffc7ee6b10f7d8d4a9 100644 (file)
@@ -82,14 +82,15 @@ 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);
 
   bool operator<(const State &s) const {
     return stateNum < s.stateNum;
@@ -108,16 +109,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 +129,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,8 +139,7 @@ public:
   //
   // Modify the DFA.
   //
-  void initialize();
-  void addState(State *);
+  const State &newState();
 
   //
   // writeTable: Print out a table representing the DFA.
@@ -156,21 +155,12 @@ public:
 State::State() :
   stateNum(currentStateNum++), isInitial(false) {}
 
-
-State::State(const State &S) :
-  stateNum(currentStateNum++), isInitial(S.isInitial),
-  stateInfo(S.stateInfo) {}
-
 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;
@@ -180,7 +170,7 @@ void State::addTransition(unsigned InsnClass, State *To) {
 // 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;
 }
 
@@ -189,7 +179,7 @@ bool State::hasTransition(unsigned InsnClass) {
 // 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.
   //
@@ -248,15 +238,10 @@ bool State::canAddInsnClass(unsigned InsnClass) const {
 }
 
 
-void DFA::initialize() {
-  assert(currentState && "Missing current state");
-  currentState->isInitial = true;
-}
-
-
-void DFA::addState(State *S) {
-  assert(!states.count(S) && "State already exists");
-  states.insert(S);
+const State &DFA::newState() {
+  auto IterPair = states.insert(State());
+  assert(IterPair.second && "State already exists");
+  return *IterPair.first;
 }
 
 
@@ -292,16 +277,16 @@ void DFA::writeTableAndAPI(raw_ostream &OS, const std::string &TargetName) {
   // 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.
@@ -447,12 +432,11 @@ void DFAPacketizerEmitter::run(raw_ostream &OS) {
   // 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);
 
@@ -474,7 +458,7 @@ void DFAPacketizerEmitter::run(raw_ostream &OS) {
   //             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;
@@ -486,7 +470,7 @@ void DFAPacketizerEmitter::run(raw_ostream &OS) {
       //
       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");
 
@@ -494,13 +478,12 @@ void DFAPacketizerEmitter::run(raw_ostream &OS) {
         // 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);
         }