[llvm] 041f35c - [Automaton] Make Automaton thread-safe

James Molloy via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 5 14:57:54 PST 2019


Author: James Molloy
Date: 2019-11-05T22:57:44Z
New Revision: 041f35c468088d315bae6c2a71ec901a12cca1b5

URL: https://github.com/llvm/llvm-project/commit/041f35c468088d315bae6c2a71ec901a12cca1b5
DIFF: https://github.com/llvm/llvm-project/commit/041f35c468088d315bae6c2a71ec901a12cca1b5.diff

LOG: [Automaton] Make Automaton thread-safe

In an optimization to improve performance (rL375240) we added a std::shared_ptr
around the main table map. This is safe, but we also ended up making the
transcriber object a std::shared_ptr too. This has mutable state, so must be
copied when we copy the Automaton object. This is very cheap; the main optimization
was about the map `M` only.

Reported by Dan Palermo. No test as triggering this is rather hard from a unit test.

Added: 
    

Modified: 
    llvm/include/llvm/Support/Automaton.h

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Support/Automaton.h b/llvm/include/llvm/Support/Automaton.h
index 7c13a698e492..c2b921311a8c 100644
--- a/llvm/include/llvm/Support/Automaton.h
+++ b/llvm/include/llvm/Support/Automaton.h
@@ -117,6 +117,10 @@ class NfaTranscriber {
     reset();
   }
 
+  ArrayRef<NfaStatePair> getTransitionInfo() const {
+    return TransitionInfo;
+  }
+
   void reset() {
     Paths.clear();
     Heads.clear();
@@ -198,7 +202,13 @@ template <typename ActionT> class Automaton {
       M->emplace(std::make_pair(I.FromDfaState, I.Action),
                  std::make_pair(I.ToDfaState, I.InfoIdx));
   }
-  Automaton(const Automaton &) = default;
+  Automaton(const Automaton &Other)
+      : M(Other.M), State(Other.State), Transcribe(Other.Transcribe) {
+    // Transcriber is not thread-safe, so create a new instance on copy.
+    if (Other.Transcriber)
+      Transcriber = std::make_shared<internal::NfaTranscriber>(
+          Other.Transcriber->getTransitionInfo());
+  }
 
   /// Reset the automaton to its initial state.
   void reset() {


        


More information about the llvm-commits mailing list