[pkg-d-commits] [ldc] 37/149: Fix alignment and size of target critical section (#1956)

Matthias Klumpp mak at moszumanska.debian.org
Sun Apr 23 22:36:55 UTC 2017


This is an automated email from the git hooks/post-receive script.

mak pushed a commit to annotated tag v1.2.0
in repository ldc.

commit bb3e16481c14cf2bf161d9ff0e396500ab373ddb
Author: kinke <kinke at users.noreply.github.com>
Date:   Fri Jan 13 21:44:28 2017 +0100

    Fix alignment and size of target critical section (#1956)
    
    The missing alignment is a front-end bug; this is a combined backport
    of dlang/dmd at b9aa6ed and dlang/dmd at a93fa3c.
    
    For POSIX targets, the critical section size was assumed to be identical
    to the host compiler's, which generally isn't true when cross-compiling.
    
    DtoMutexType() wasn't used anywhere, so I removed it.
---
 ddmd/statement.d       |  9 ++++++
 gen/irstate.cpp        |  1 -
 gen/irstate.h          |  1 -
 gen/target.cpp         | 67 +++++++++++++++++++++++++++++--------------
 gen/tollvm.cpp         | 77 --------------------------------------------------
 gen/tollvm.h           |  1 -
 tests/codegen/gh1955.d | 25 ++++++++++++++++
 7 files changed, 80 insertions(+), 101 deletions(-)

diff --git a/ddmd/statement.d b/ddmd/statement.d
index d3c757e..15133e3 100644
--- a/ddmd/statement.d
+++ b/ddmd/statement.d
@@ -5104,7 +5104,16 @@ public:
             cs.push(s);
 
             s = new CompoundStatement(loc, cs);
+          version(IN_LLVM) // backport alignment fix for issue #1955
+          {
+            s = s.semantic(sc);
+            tmp.alignment = Target.ptrsize; // must be set after semantic()
+            return s;
+          }
+          else
+          {
             return s.semantic(sc);
+          }
         }
     Lbody:
         if (_body)
diff --git a/gen/irstate.cpp b/gen/irstate.cpp
index 87863c5..5296e23 100644
--- a/gen/irstate.cpp
+++ b/gen/irstate.cpp
@@ -36,7 +36,6 @@ IRScope &IRScope::operator=(const IRScope &rhs) {
 ////////////////////////////////////////////////////////////////////////////////
 IRState::IRState(const char *name, llvm::LLVMContext &context)
     : module(name, context), DBuilder(this) {
-  mutexType = nullptr;
   moduleRefType = nullptr;
 
   dmodule = nullptr;
diff --git a/gen/irstate.h b/gen/irstate.h
index d81da7f..c1390fb 100644
--- a/gen/irstate.h
+++ b/gen/irstate.h
@@ -117,7 +117,6 @@ struct IRState {
 
   Module *dmodule;
 
-  LLStructType *mutexType;
   LLStructType *moduleRefType;
 
   // Stack of currently codegen'd functions (more than one for lambdas or other
diff --git a/gen/target.cpp b/gen/target.cpp
index fd48639..afe7b03 100644
--- a/gen/target.cpp
+++ b/gen/target.cpp
@@ -64,30 +64,55 @@ unsigned Target::alignsize(Type *type) {
  */
 unsigned Target::fieldalign(Type *type) { return DtoAlignment(type); }
 
-// sizes based on those from tollvm.cpp:DtoMutexType()
+/******************************
+ * Return size of alias Mutex in druntime/src/rt/monitor_.d, or, more precisely,
+ * the size of the native critical section as 2nd field in struct
+ * D_CRITICAL_SECTION (after a pointer). D_CRITICAL_SECTION is pointer-size
+ * aligned, so the returned field size is a multiple of pointer-size.
+ */
 unsigned Target::critsecsize() {
-#if defined(_MSC_VER)
-  // Return sizeof(RTL_CRITICAL_SECTION)
-  return global.params.is64bit ? 40 : 24;
-#else
-  if (global.params.targetTriple->isOSWindows()) {
-    return global.params.is64bit ? 40 : 24;
-  }
-  if (global.params.targetTriple->isOSFreeBSD() ||
-#if LDC_LLVM_VER > 305
-    global.params.targetTriple->isOSNetBSD() ||
-    global.params.targetTriple->isOSOpenBSD() ||
-    global.params.targetTriple->isOSDragonFly()
-#else
-    global.params.targetTriple->getOS() == llvm::Triple::NetBSD ||
-    global.params.targetTriple->getOS() == llvm::Triple::OpenBSD ||
-    global.params.targetTriple->getOS() == llvm::Triple::DragonFly
-#endif
-     ) {
-    return sizeof(size_t);
+  const bool is64bit = global.params.is64bit;
+
+  // Windows: sizeof(CRITICAL_SECTION)
+  if (global.params.isWindows)
+    return is64bit ? 40 : 24;
+
+  // POSIX: sizeof(pthread_mutex_t)
+  // based on druntime/src/core/sys/posix/sys/types.d
+  const auto &triple = *global.params.targetTriple;
+  const auto arch = triple.getArch();
+  switch (triple.getOS()) {
+  case llvm::Triple::Linux:
+    if (triple.getEnvironment() == llvm::Triple::Android)
+      return Target::ptrsize; // 32-bit integer rounded up to pointer size
+    if (arch == llvm::Triple::aarch64 || arch == llvm::Triple::aarch64_be)
+      return 48;
+    return is64bit ? 40 : 24;
+
+  case llvm::Triple::MacOSX:
+    return is64bit ? 64 : 44;
+
+  case llvm::Triple::FreeBSD:
+  case llvm::Triple::NetBSD:
+  case llvm::Triple::OpenBSD:
+  case llvm::Triple::DragonFly:
+    return Target::ptrsize;
+
+  case llvm::Triple::Solaris:
+    return 24;
+
+  default:
+    break;
   }
-  return sizeof(pthread_mutex_t);
 
+#ifndef _MSC_VER
+  unsigned hostSize = sizeof(pthread_mutex_t);
+  warning(Loc(), "Assuming critical section size = %u bytes", hostSize);
+  return hostSize;
+#else
+  error(Loc(), "Unknown critical section size");
+  fatal();
+  return 0;
 #endif
 }
 
diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp
index 85e0cc0..f41a705 100644
--- a/gen/tollvm.cpp
+++ b/gen/tollvm.cpp
@@ -666,83 +666,6 @@ unsigned int getABITypeAlign(LLType *t) {
 
 ////////////////////////////////////////////////////////////////////////////////
 
-LLStructType *DtoMutexType() {
-  if (gIR->mutexType) {
-    return gIR->mutexType;
-  }
-
-  // The structures defined here must be the same as in
-  // druntime/src/rt/critical.c
-
-  // Windows
-  if (global.params.targetTriple->isOSWindows()) {
-    llvm::Type *VoidPtrTy = llvm::Type::getInt8PtrTy(gIR->context());
-    llvm::Type *Int32Ty = llvm::Type::getInt32Ty(gIR->context());
-
-    // Build RTL_CRITICAL_SECTION; size is 24 (32bit) or 40 (64bit)
-    LLType *rtl_types[] = {
-        VoidPtrTy, // Pointer to DebugInfo
-        Int32Ty,   // LockCount
-        Int32Ty,   // RecursionCount
-        VoidPtrTy, // Handle of OwningThread
-        VoidPtrTy, // Handle of LockSemaphore
-        VoidPtrTy  // SpinCount
-    };
-    LLStructType *rtl =
-        LLStructType::create(gIR->context(), rtl_types, "RTL_CRITICAL_SECTION");
-
-    // Build D_CRITICAL_SECTION; size is 28 (32bit) or 48 (64bit)
-    LLStructType *mutex =
-        LLStructType::create(gIR->context(), "D_CRITICAL_SECTION");
-    LLType *types[] = {getPtrToType(mutex), rtl};
-    mutex->setBody(types);
-
-    // Cache type
-    gIR->mutexType = mutex;
-
-    return mutex;
-  }
-
-  // FreeBSD, NetBSD, OpenBSD, DragonFly
-  if (global.params.targetTriple->isOSFreeBSD() ||
-#if LDC_LLVM_VER > 305
-      global.params.targetTriple->isOSNetBSD() ||
-      global.params.targetTriple->isOSOpenBSD() ||
-      global.params.targetTriple->isOSDragonFly()
-#else
-      global.params.targetTriple->getOS() == llvm::Triple::NetBSD ||
-      global.params.targetTriple->getOS() == llvm::Triple::OpenBSD ||
-      global.params.targetTriple->getOS() == llvm::Triple::DragonFly
-#endif
-          ) {
-    // Just a pointer
-    return LLStructType::get(gIR->context(), DtoSize_t());
-  }
-
-  // pthread_fastlock
-  LLType *types2[] = {DtoSize_t(), LLType::getInt32Ty(gIR->context())};
-  LLStructType *fastlock = LLStructType::get(gIR->context(), types2, false);
-
-  // pthread_mutex
-  LLType *types1[] = {LLType::getInt32Ty(gIR->context()),
-                      LLType::getInt32Ty(gIR->context()), getVoidPtrType(),
-                      LLType::getInt32Ty(gIR->context()), fastlock};
-  LLStructType *pmutex = LLStructType::get(gIR->context(), types1, false);
-
-  // D_CRITICAL_SECTION
-  LLStructType *mutex =
-      LLStructType::create(gIR->context(), "D_CRITICAL_SECTION");
-  LLType *types[] = {getPtrToType(mutex), pmutex};
-  mutex->setBody(types);
-
-  // Cache type
-  gIR->mutexType = mutex;
-
-  return pmutex;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
 LLStructType *DtoModuleReferenceType() {
   if (gIR->moduleRefType) {
     return gIR->moduleRefType;
diff --git a/gen/tollvm.h b/gen/tollvm.h
index 25feba4..24d037f 100644
--- a/gen/tollvm.h
+++ b/gen/tollvm.h
@@ -71,7 +71,6 @@ void setLinkage(Dsymbol *sym, llvm::GlobalObject *obj);
 
 // some types
 LLIntegerType *DtoSize_t();
-LLStructType *DtoMutexType();
 LLStructType *DtoModuleReferenceType();
 
 // getelementptr helpers
diff --git a/tests/codegen/gh1955.d b/tests/codegen/gh1955.d
new file mode 100644
index 0000000..b5da72b
--- /dev/null
+++ b/tests/codegen/gh1955.d
@@ -0,0 +1,25 @@
+// RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
+
+import rt.monitor_ : Mutex;
+
+struct D_CRITICAL_SECTION // private symbol in rt.critical_
+{
+    D_CRITICAL_SECTION* next;
+    Mutex mtx;
+}
+
+void main()
+{
+    /* The synchronized-block uses a global buffer for the D_CRITICAL_SECTION.
+     * Match its size and alignment.
+     */
+    // CHECK: __critsec{{[0-9Gg]+}} = global {{\[}}[[SIZEOF:[0-9]+]] x i8{{\]}} zeroinitializer
+    // CHECK-SAME: align [[ALIGNOF:[0-9]+]]
+    synchronized {}
+
+    /* Verify size and alignment of the global against a manual D_CRITICAL_SECTION.
+     */
+    // CHECK: %cs = alloca %gh1955.D_CRITICAL_SECTION, align [[ALIGNOF]]
+    // CHECK-SAME: size/byte = [[SIZEOF]]
+    D_CRITICAL_SECTION cs;
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git



More information about the pkg-d-commits mailing list