changeset 291:068cb3c60afb trunk

[svn r312] Changed assert codegen to insert an unreachable terminator after the call to the assert function, which currently calls abort(). Changed array comparison runtime support to pass the array typeinfo instead of the element typeinfo. This allows a cleaner and faster implementation.
author lindquist
date Sat, 21 Jun 2008 21:16:26 +0200
parents ebaf65fc4726
children a92ec67eabe7
files gen/arrays.cpp gen/llvmhelpers.cpp gen/toir.cpp tango/lib/compiler/llvmdc/adi.d tangotests/arrays2.d test/calls1.d
diffstat 6 files changed, 53 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/gen/arrays.cpp	Sat Jun 21 17:57:36 2008 +0200
+++ b/gen/arrays.cpp	Sat Jun 21 21:16:26 2008 +0200
@@ -782,9 +782,9 @@
     args.push_back(DtoBitCast(lmem,pt));
     args.push_back(DtoBitCast(rmem,pt));
 
-    // pass element typeinfo ?
+    // pass array typeinfo ?
     if (useti) {
-        Type* t = DtoDType(l->getType())->next;
+        Type* t = l->getType();
         LLValue* tival = DtoTypeInfoOf(t);
         // DtoTypeInfoOf only does declare, not enough in this case :/
         DtoForceConstInitDsymbol(t->vtinfo);
--- a/gen/llvmhelpers.cpp	Sat Jun 21 17:57:36 2008 +0200
+++ b/gen/llvmhelpers.cpp	Sat Jun 21 21:16:26 2008 +0200
@@ -98,6 +98,7 @@
     llvm::PAListPtr palist;
     int idx = 1;
 
+    // FIXME: every assert creates a global for the filename !!!
     c = DtoConstString(loc->filename);
 
     // msg param
@@ -144,6 +145,9 @@
     // call
     llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb());
     call->setParamAttrs(palist);
+
+    // after assert is always unreachable
+    gIR->ir->CreateUnreachable();
 }
 
 /****************************************************************************************/
--- a/gen/toir.cpp	Sat Jun 21 17:57:36 2008 +0200
+++ b/gen/toir.cpp	Sat Jun 21 21:16:26 2008 +0200
@@ -2063,8 +2063,9 @@
     p->scope() = IRScope(assertbb,endbb);
     DtoAssert(&loc, msg ? msg->toElem(p) : NULL);
 
-    if (!gIR->scopereturned())
-        llvm::BranchInst::Create(endbb, p->scopebb());
+    // assert inserts unreachable terminator
+//     if (!gIR->scopereturned())
+//         llvm::BranchInst::Create(endbb, p->scopebb());
 
     // rewrite the scope
     p->scope() = IRScope(endbb,oldend);
@@ -2243,10 +2244,9 @@
 #else
     // call the new (?) trap intrinsic
     p->ir->CreateCall(GET_INTRINSIC_DECL(trap),"");
+    new llvm::UnreachableInst(p->scopebb());
 #endif
 
-    new llvm::UnreachableInst(p->scopebb());
-
     // this terminated the basicblock, start a new one
     // this is sensible, since someone might goto behind the assert
     // and prevents compiler errors if a terminator follows the assert
--- a/tango/lib/compiler/llvmdc/adi.d	Sat Jun 21 17:57:36 2008 +0200
+++ b/tango/lib/compiler/llvmdc/adi.d	Sat Jun 21 21:16:26 2008 +0200
@@ -378,29 +378,14 @@
 extern (C) int _adEq(Array a1, Array a2, TypeInfo ti)
 {
     debug(adi) printf("_adEq(a1.length = %d, a2.length = %d)\n", a1.length, a2.length);
+
     if (a1.length != a2.length)
         return 0;               // not equal
-    auto sz = ti.tsize();
-    auto p1 = a1.ptr;
-    auto p2 = a2.ptr;
-
-/+
-    for (int i = 0; i < a1.length; i++)
-    {
-        printf("%4x %4x\n", (cast(short*)p1)[i], (cast(short*)p2)[i]);
-    }
-+/
+    else if (a1.ptr == a2.ptr)
+        return 1;               // equal
 
-    if (sz == 1)
-        // We should really have a ti.isPOD() check for this
-        return (memcmp(p1, p2, a1.length) == 0);
-
-    for (size_t i = 0; i < a1.length; i++)
-    {
-        if (!ti.equals(p1 + i * sz, p2 + i * sz))
-            return 0;           // not equal
-    }
-    return 1;                   // equal
+    // let typeinfo decide
+    return ti.equals(&a1, &a2);
 }
 
 unittest
@@ -423,31 +408,17 @@
 extern (C) int _adCmp(Array a1, Array a2, TypeInfo ti)
 {
     debug(adi) printf("adCmp()\n");
+
+    if (a1.ptr == a2.ptr &&
+        a1.length == a2.length)
+        return 0;
+
     auto len = a1.length;
     if (a2.length < len)
         len = a2.length;
-    auto sz = ti.tsize();
-    void *p1 = a1.ptr;
-    void *p2 = a2.ptr;
 
-    if (sz == 1)
-    {   // We should really have a ti.isPOD() check for this
-        auto c = memcmp(p1, p2, len);
-        if (c)
-            return c;
-    }
-    else
-    {
-        for (size_t i = 0; i < len; i++)
-        {
-            auto c = ti.compare(p1 + i * sz, p2 + i * sz);
-            if (c)
-                return c;
-        }
-    }
-    if (a1.length == a2.length)
-        return 0;
-    return (a1.length > a2.length) ? 1 : -1;
+    // let typeinfo decide
+    return ti.compare(&a1, &a2);
 }
 
 unittest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tangotests/arrays2.d	Sat Jun 21 21:16:26 2008 +0200
@@ -0,0 +1,30 @@
+module tangotests.arrays2;
+
+void main()
+{
+    intarrays!(byte)();
+    intarrays!(ubyte)();
+    intarrays!(short)();
+    intarrays!(ushort)();
+    intarrays!(int)();
+    intarrays!(uint)();
+    intarrays!(long)();
+    intarrays!(ulong)();
+}
+
+void intarrays(T)()
+{
+    T[] ia = [cast(T)1,2,3,4];
+    T[] ib = [cast(T)1,2,3,4];
+    T[] ic = [cast(T)1,2,3];
+    T[] id = [cast(T)1,2,3,4,5];
+
+    assert(ia == ia);
+    assert(ia == ib);
+    assert(ia != ic);
+    assert(ia != id);
+    assert(ia > ic);
+    assert(ia !< ic);
+    assert(ia < id);
+    assert(ia !> id);
+}
--- a/test/calls1.d	Sat Jun 21 17:57:36 2008 +0200
+++ b/test/calls1.d	Sat Jun 21 21:16:26 2008 +0200
@@ -1,5 +1,6 @@
 module calls1;
 import tango.core.Vararg;
+extern(C) int printf(char*, ...);
 void main()
 {
     {int a = byVal1(3);}