OSDN Git Service

Ensure NoDefinitions gets initialized only at first use.
authorNicolas Capens <capn@google.com>
Thu, 8 Sep 2016 16:47:42 +0000 (12:47 -0400)
committerNicolas Capens <nicolascapens@google.com>
Fri, 9 Sep 2016 14:13:28 +0000 (14:13 +0000)
As a global, NoDefinitions could get initialized at program startup,
which happens specifically with Visual Studio. This causes the
progam to abort because its initialization depends on a TLS variable
to be (manually) initialized first. Since there's only one use of
NoDefinitions, it can be moved to that location and since it's at
function scope it only gets constructed at first use.

BUG=swiftshader:7

Change-Id: I30801ad0d0ab380ead33069f174bb78dc1b230ab
Reviewed-on: https://chromium-review.googlesource.com/379955
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Jim Stichnoth <stichnot@chromium.org>
src/IceOperand.cpp
src/IceOperand.h

index adc1689..043583e 100644 (file)
@@ -509,8 +509,17 @@ const Inst *VariablesMetadata::getFirstDefinition(const Variable *Var) const {
 const InstDefList &
 VariablesMetadata::getLatterDefinitions(const Variable *Var) const {
   assert(Kind == VMK_All);
-  if (!isTracked(Var))
-    return NoDefinitions;
+  if (!isTracked(Var)) {
+    // NoDefinitions has to be initialized after we've had a chance to set the
+    // CfgAllocator, so it can't be a static global object. Also, while C++11
+    // guarantees the initialization of static local objects to be thread-safe,
+    // we use a pointer to it so we can avoid frequent  mutex locking overhead.
+    if (NoDefinitions == nullptr) {
+      static const InstDefList NoDefinitionsInstance;
+      NoDefinitions = &NoDefinitionsInstance;
+    }
+    return *NoDefinitions;
+  }
   SizeT VarNum = Var->getIndex();
   return Metadata[VarNum].getLatterDefinitions();
 }
@@ -529,7 +538,7 @@ RegWeight VariablesMetadata::getUseWeight(const Variable *Var) const {
   return Metadata[VarNum].getUseWeight();
 }
 
-const InstDefList VariablesMetadata::NoDefinitions;
+const InstDefList *VariablesMetadata::NoDefinitions = nullptr;
 
 // ======================== dump routines ======================== //
 
index 107b33b..fd68834 100644 (file)
@@ -1075,7 +1075,7 @@ private:
   const Cfg *Func;
   MetadataKind Kind;
   CfgVector<VariableTracking> Metadata;
-  const static InstDefList NoDefinitions;
+  static const InstDefList *NoDefinitions;
 };
 
 /// BooleanVariable represents a variable that was the zero-extended result of a