changeset 1351:8d501abecd24

Initial (but disabled) fix for ticket #294 , the actual part that fixes the bug is in a #if 0 block as I'm afraid it will cause regressions. I'm most likely not going to be around tonight, and maybe not tomorrow as well, so I'm pushing it in case someone wants to run some serious testing/investigate the problem noted in llvmhelpers.cpp : realignOffset .
author Tomas Lindquist Olsen <tomas.l.olsen gmail com>
date Thu, 14 May 2009 17:20:17 +0200
parents 15e9762bb620
children b9f5f7c5db73
files gen/llvmhelpers.cpp gen/llvmhelpers.h gen/toir.cpp ir/irclass.cpp ir/irstruct.cpp ir/irtypeclass.cpp ir/irtypestruct.cpp
diffstat 7 files changed, 49 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/gen/llvmhelpers.cpp	Thu May 14 13:26:40 2009 +0200
+++ b/gen/llvmhelpers.cpp	Thu May 14 17:20:17 2009 +0200
@@ -1440,3 +1440,40 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
+
+size_t realignOffset(size_t offset, Type* type)
+{
+    size_t alignsize = type->alignsize();
+    size_t alignedoffset = (offset + alignsize - 1) & ~(alignsize - 1);
+
+    // if the aligned offset already matches the input offset
+    // don't waste time checking things are ok!
+    if (alignedoffset == offset)
+        return alignedoffset;
+
+    // disabled since this can fail for opaques. if the check above is not in place
+    // it does so for gcx.d!!!
+    // this needs to be investigated, but I don't have time right now!
+#if 0
+    // if not, we have to make sure it agrees with what llvm thinks is the alignment
+    // sometimes this is different from what we really need (in case of unions, see #294)
+    // so if there we get different results we don't realign the offset at all and instead
+    // just return the original offset, and rely on the users to insert padding manually.
+    IF_LOG Logger::cout() << "getting alignment for type " << type->toChars()
+        << " with llvm type " << *DtoType(type) << std::endl;
+    size_t alignsize2 = gTargetData->getABITypeAlignment(DtoType(type));
+
+    if (alignsize != alignsize2)
+    {
+        assert(alignsize > alignsize2 && "this is not good, the D and LLVM "
+            "type alignments differ, but LLVM's is bigger! This will break "
+            "the type mapping algorithms");
+        // don't try and align the offset, and let the mappers pad 100% manually
+        return offset;
+    }
+#endif
+
+    return alignedoffset;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/llvmhelpers.h	Thu May 14 13:26:40 2009 +0200
+++ b/gen/llvmhelpers.h	Thu May 14 17:20:17 2009 +0200
@@ -141,6 +141,10 @@
 /// Create the IrModule if necessary and returns it.
 IrModule* getIrModule(Module* M);
 
+/// Update an offset to make sure it follows both the D and LLVM alignments.
+/// Returns the offset rounded up to the closest safely aligned offset.
+size_t realignOffset(size_t offset, Type* type);
+
 ////////////////////////////////////////////
 // gen/tocall.cpp stuff below
 ////////////////////////////////////////////
--- a/gen/toir.cpp	Thu May 14 13:26:40 2009 +0200
+++ b/gen/toir.cpp	Thu May 14 17:20:17 2009 +0200
@@ -2459,8 +2459,7 @@
         size_t alignedoffset = offset;
         if (!packed)
         {
-            size_t alignsize = vd->type->alignsize();
-            alignedoffset = (offset + alignsize - 1) & ~(alignsize - 1);
+            alignedoffset = realignOffset(alignedoffset, vd->type);
         }
 
         // insert explicit padding?
--- a/ir/irclass.cpp	Thu May 14 13:26:40 2009 +0200
+++ b/ir/irclass.cpp	Thu May 14 17:20:17 2009 +0200
@@ -222,8 +222,7 @@
         assert(vd->offset >= offset && "default fields not sorted by offset");
 
         // get next aligned offset for this type
-        size_t alignsize = vd->type->alignsize();
-        size_t alignedoffset = (offset + alignsize - 1) & ~(alignsize - 1);
+        size_t alignedoffset = realignOffset(offset, vd->type);
 
         // insert explicit padding?
         if (alignedoffset < vd->offset)
--- a/ir/irstruct.cpp	Thu May 14 13:26:40 2009 +0200
+++ b/ir/irstruct.cpp	Thu May 14 17:20:17 2009 +0200
@@ -169,8 +169,7 @@
         size_t alignedoffset = offset;
         if (!packed)
         {
-            size_t alignsize = vd->type->alignsize();
-            alignedoffset = (offset + alignsize - 1) & ~(alignsize - 1);
+            alignedoffset = realignOffset(alignedoffset, vd->type);
         }
 
         // insert explicit padding?
@@ -355,8 +354,7 @@
         size_t alignedoffset = offset;
         if (!packed)
         {
-            size_t alignsize = vd->type->alignsize();
-            alignedoffset = (offset + alignsize - 1) & ~(alignsize - 1);
+            alignedoffset = realignOffset(alignedoffset, vd->type);
         }
 
         // insert explicit padding?
--- a/ir/irtypeclass.cpp	Thu May 14 13:26:40 2009 +0200
+++ b/ir/irtypeclass.cpp	Thu May 14 17:20:17 2009 +0200
@@ -9,6 +9,7 @@
 #include "gen/logger.h"
 #include "gen/tollvm.h"
 #include "gen/utils.h"
+#include "gen/llvmhelpers.h"
 #include "ir/irtypeclass.h"
 
 //////////////////////////////////////////////////////////////////////////////
@@ -143,8 +144,7 @@
             default_fields.push_back(vd);
 
         // get next aligned offset for this type
-        size_t alignsize = vd->type->alignsize();
-        size_t alignedoffset = (offset + alignsize - 1) & ~(alignsize - 1);
+        size_t alignedoffset = realignOffset(offset, vd->type);
 
         // insert explicit padding?
         if (alignedoffset < vd->offset)
--- a/ir/irtypestruct.cpp	Thu May 14 13:26:40 2009 +0200
+++ b/ir/irtypestruct.cpp	Thu May 14 17:20:17 2009 +0200
@@ -8,6 +8,7 @@
 #include "gen/tollvm.h"
 #include "gen/logger.h"
 #include "gen/utils.h"
+#include "gen/llvmhelpers.h"
 #include "ir/irtypestruct.h"
 
 //////////////////////////////////////////////////////////////////////////////
@@ -192,8 +193,7 @@
         size_t alignedoffset = offset;
         if (!packed)
         {
-            size_t alignsize = vd->type->alignsize();
-            alignedoffset = (offset + alignsize - 1) & ~(alignsize - 1);
+            alignedoffset = realignOffset(alignedoffset, vd->type);
         }
 
         // insert explicit padding?