<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Tue, Dec 13, 2016 at 11:41 AM Matthias Braun via Phabricator <<a href="mailto:reviews@reviews.llvm.org">reviews@reviews.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">MatzeB created this revision.<br class="gmail_msg">
MatzeB added reviewers: chandlerc, dblaikie, echristo.<br class="gmail_msg">
MatzeB added a subscriber: llvm-commits.<br class="gmail_msg">
MatzeB set the repository for this revision to rL LLVM.<br class="gmail_msg">
Herald added subscribers: mehdi_amini, mcrosier.<br class="gmail_msg">
<br class="gmail_msg">
Statistics should be fast enough that we can enable them in release builds without compiletime impact. This does not work today because the lazy initialization in use today puts a memory fence on every increment operation!<br class="gmail_msg">
<br class="gmail_msg">
The obvious solution for this is initializing the statistic variable in the constructor. Which is easy to do and works better in every way than todays code IMO except that introduce additional static constructors </blockquote><div><br></div><div>Tihs is a fairly big 'except'. LLVM is (reasonably) pretty averse to global ctors - due to its use as a library, global ctors place a strong burden on our users.<br><br>I'm not sure we'd want to add more, probably not.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">into llvm which in this specific instance look fine to me; the alternative of forbidding global variables for statistic variables appears arguably worse.<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
Repository:<br class="gmail_msg">
  rL LLVM<br class="gmail_msg">
<br class="gmail_msg">
<a href="https://reviews.llvm.org/D27724" rel="noreferrer" class="gmail_msg" target="_blank">https://reviews.llvm.org/D27724</a><br class="gmail_msg">
<br class="gmail_msg">
Files:<br class="gmail_msg">
  include/llvm/ADT/Statistic.h<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
Index: include/llvm/ADT/Statistic.h<br class="gmail_msg">
===================================================================<br class="gmail_msg">
--- include/llvm/ADT/Statistic.h<br class="gmail_msg">
+++ include/llvm/ADT/Statistic.h<br class="gmail_msg">
@@ -42,7 +42,7 @@<br class="gmail_msg">
   const char *Name;<br class="gmail_msg">
   const char *Desc;<br class="gmail_msg">
   std::atomic<unsigned> Value;<br class="gmail_msg">
-  bool Initialized;<br class="gmail_msg">
+  bool Initialized = false;<br class="gmail_msg">
<br class="gmail_msg">
   unsigned getValue() const { return Value.load(std::memory_order_relaxed); }<br class="gmail_msg">
   const char *getDebugType() const { return DebugType; }<br class="gmail_msg">
@@ -62,46 +62,51 @@<br class="gmail_msg">
   operator unsigned() const { return getValue(); }<br class="gmail_msg">
<br class="gmail_msg">
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)<br class="gmail_msg">
-   const Statistic &operator=(unsigned Val) {<br class="gmail_msg">
+  Statistic(const char *DebugType, const char *Name, const char *Desc)<br class="gmail_msg">
+      : DebugType(DebugType), Name(Name), Desc(Desc) {<br class="gmail_msg">
+    init();<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  const Statistic &operator=(unsigned Val) {<br class="gmail_msg">
     Value.store(Val, std::memory_order_relaxed);<br class="gmail_msg">
-    return init();<br class="gmail_msg">
+    return *this;<br class="gmail_msg">
   }<br class="gmail_msg">
<br class="gmail_msg">
   const Statistic &operator++() {<br class="gmail_msg">
     Value.fetch_add(1, std::memory_order_relaxed);<br class="gmail_msg">
-    return init();<br class="gmail_msg">
+    return *this;<br class="gmail_msg">
   }<br class="gmail_msg">
<br class="gmail_msg">
   unsigned operator++(int) {<br class="gmail_msg">
-    init();<br class="gmail_msg">
     return Value.fetch_add(1, std::memory_order_relaxed);<br class="gmail_msg">
   }<br class="gmail_msg">
<br class="gmail_msg">
   const Statistic &operator--() {<br class="gmail_msg">
     Value.fetch_sub(1, std::memory_order_relaxed);<br class="gmail_msg">
-    return init();<br class="gmail_msg">
+    return *this;<br class="gmail_msg">
   }<br class="gmail_msg">
<br class="gmail_msg">
   unsigned operator--(int) {<br class="gmail_msg">
-    init();<br class="gmail_msg">
     return Value.fetch_sub(1, std::memory_order_relaxed);<br class="gmail_msg">
   }<br class="gmail_msg">
<br class="gmail_msg">
   const Statistic &operator+=(unsigned V) {<br class="gmail_msg">
     if (V == 0)<br class="gmail_msg">
       return *this;<br class="gmail_msg">
     Value.fetch_add(V, std::memory_order_relaxed);<br class="gmail_msg">
-    return init();<br class="gmail_msg">
+    return *this;<br class="gmail_msg">
   }<br class="gmail_msg">
<br class="gmail_msg">
   const Statistic &operator-=(unsigned V) {<br class="gmail_msg">
     if (V == 0)<br class="gmail_msg">
       return *this;<br class="gmail_msg">
     Value.fetch_sub(V, std::memory_order_relaxed);<br class="gmail_msg">
-    return init();<br class="gmail_msg">
+    return *this;<br class="gmail_msg">
   }<br class="gmail_msg">
<br class="gmail_msg">
 #else  // Statistics are disabled in release builds.<br class="gmail_msg">
+  Statistic(const char *, const char *, const char *)<br class="gmail_msg">
+      : DebugType(nullptr), Name(nullptr), Desc(nullptr) {}<br class="gmail_msg">
<br class="gmail_msg">
   const Statistic &operator=(unsigned Val) {<br class="gmail_msg">
     return *this;<br class="gmail_msg">
@@ -148,7 +153,7 @@<br class="gmail_msg">
 // STATISTIC - A macro to make definition of statistics really simple.  This<br class="gmail_msg">
 // automatically passes the DEBUG_TYPE of the file into the statistic.<br class="gmail_msg">
 #define STATISTIC(VARNAME, DESC)                                               \<br class="gmail_msg">
-  static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC, {0}, false}<br class="gmail_msg">
+  static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC}<br class="gmail_msg">
<br class="gmail_msg">
 /// \brief Enable the collection and printing of statistics.<br class="gmail_msg">
 void EnableStatistics(bool PrintOnExit = true);<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
</blockquote></div></div>