[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