<div dir="ltr">I had to add a missing <atomic> include in r231277 for MSVC.</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 4, 2015 at 10:57 AM, Erik Eckstein <span dir="ltr"><<a href="mailto:eeckstein@apple.com" target="_blank">eeckstein@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: eeckstein<br>
Date: Wed Mar  4 12:57:11 2015<br>
New Revision: 231276<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=231276&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=231276&view=rev</a><br>
Log:<br>
Add a lock() function in PassRegistry to speed up multi-thread synchronization.<br>
<br>
When calling lock() after all passes are registered, the PassRegistry doesn't need a mutex anymore to look up passes.<br>
This speeds up multithreaded llvm execution by ~5% (tested with 4 threads).<br>
In an asserts build of llvm this has an even bigger impact.<br>
<br>
Note that it's not required to use the lock function.<br>
<br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/PassRegistry.h<br>
    llvm/trunk/lib/IR/PassRegistry.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/PassRegistry.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/PassRegistry.h?rev=231276&r1=231275&r2=231276&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/PassRegistry.h?rev=231276&r1=231275&r2=231276&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/PassRegistry.h (original)<br>
+++ llvm/trunk/include/llvm/PassRegistry.h Wed Mar  4 12:57:11 2015<br>
@@ -41,6 +41,9 @@ struct PassRegistrationListener;<br>
 class PassRegistry {<br>
   mutable sys::SmartRWMutex<true> Lock;<br>
<br>
+  /// Only if false, synchronization must use the Lock mutex.<br>
+  std::atomic<bool> locked;<br>
+<br>
   /// PassInfoMap - Keep track of the PassInfo object for each registered pass.<br>
   typedef DenseMap<const void *, const PassInfo *> MapType;<br>
   MapType PassInfoMap;<br>
@@ -52,7 +55,7 @@ class PassRegistry {<br>
   std::vector<PassRegistrationListener *> Listeners;<br>
<br>
 public:<br>
-  PassRegistry() {}<br>
+  PassRegistry() : locked(false) {}<br>
   ~PassRegistry();<br>
<br>
   /// getPassRegistry - Access the global registry object, which is<br>
@@ -60,6 +63,10 @@ public:<br>
   /// llvm_shutdown.<br>
   static PassRegistry *getPassRegistry();<br>
<br>
+  /// Enables fast thread synchronization in getPassInfo().<br>
+  /// After calling lock() no more passes may be registered.<br>
+  void lock() { locked = true; }<br>
+<br>
   /// getPassInfo - Look up a pass' corresponding PassInfo, indexed by the pass'<br>
   /// type identifier (&MyPass::ID).<br>
   const PassInfo *getPassInfo(const void *TI) const;<br>
<br>
Modified: llvm/trunk/lib/IR/PassRegistry.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/PassRegistry.cpp?rev=231276&r1=231275&r2=231276&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/PassRegistry.cpp?rev=231276&r1=231275&r2=231276&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/PassRegistry.cpp (original)<br>
+++ llvm/trunk/lib/IR/PassRegistry.cpp Wed Mar  4 12:57:11 2015<br>
@@ -13,6 +13,7 @@<br>
 //===----------------------------------------------------------------------===//<br>
<br>
 #include "llvm/PassRegistry.h"<br>
+#include "llvm/ADT/Optional.h"<br>
 #include "llvm/IR/Function.h"<br>
 #include "llvm/PassSupport.h"<br>
 #include "llvm/Support/Compiler.h"<br>
@@ -39,13 +40,23 @@ PassRegistry *PassRegistry::getPassRegis<br>
 PassRegistry::~PassRegistry() {}<br>
<br>
 const PassInfo *PassRegistry::getPassInfo(const void *TI) const {<br>
-  sys::SmartScopedReader<true> Guard(Lock);<br>
+  // We don't need thread synchronization after the PassRegistry is locked<br>
+  // (that means: is read-only).<br>
+  Optional<sys::SmartScopedReader<true>> Guard;<br>
+  if (!locked)<br>
+    Guard.emplace(Lock);<br>
+<br>
   MapType::const_iterator I = PassInfoMap.find(TI);<br>
   return I != PassInfoMap.end() ? I->second : nullptr;<br>
 }<br>
<br>
 const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {<br>
-  sys::SmartScopedReader<true> Guard(Lock);<br>
+  // We don't need thread synchronization after the PassRegistry is locked<br>
+  // (that means: is read-only).<br>
+  Optional<sys::SmartScopedReader<true>> Guard;<br>
+  if (!locked)<br>
+    Guard.emplace(Lock);<br>
+<br>
   StringMapType::const_iterator I = PassInfoStringMap.find(Arg);<br>
   return I != PassInfoStringMap.end() ? I->second : nullptr;<br>
 }<br>
@@ -55,6 +66,9 @@ const PassInfo *PassRegistry::getPassInf<br>
 //<br>
<br>
 void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) {<br>
+<br>
+  assert(!locked && "Trying to register a pass in a locked PassRegistry");<br>
+<br>
   sys::SmartScopedWriter<true> Guard(Lock);<br>
   bool Inserted =<br>
       PassInfoMap.insert(std::make_pair(PI.getTypeInfo(), &PI)).second;<br>
@@ -68,6 +82,8 @@ void PassRegistry::registerPass(const Pa<br>
<br>
   if (ShouldFree)<br>
     ToFree.push_back(std::unique_ptr<const PassInfo>(&PI));<br>
+<br>
+  assert(!locked && "PassRegistry locked during registering a pass");<br>
 }<br>
<br>
 void PassRegistry::enumerateWith(PassRegistrationListener *L) {<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>