From 33b9d4348c91d9d349c23783bb1a172729652c37 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Sat, 21 Jun 2008 21:16:26 +0200 Subject: [PATCH] [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. --- gen/arrays.cpp | 4 +-- gen/llvmhelpers.cpp | 4 +++ gen/toir.cpp | 8 ++--- tango/lib/compiler/llvmdc/adi.d | 53 ++++++++------------------------- tangotests/arrays2.d | 30 +++++++++++++++++++ test/calls1.d | 1 + 6 files changed, 53 insertions(+), 47 deletions(-) create mode 100644 tangotests/arrays2.d diff --git a/gen/arrays.cpp b/gen/arrays.cpp index ba23cdcf..c7cb4363 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -782,9 +782,9 @@ static LLValue* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool 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); diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index ab821f6a..a8b3b196 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -98,6 +98,7 @@ void DtoAssert(Loc* loc, DValue* msg) 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 @@ void DtoAssert(Loc* loc, DValue* msg) // 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(); } /****************************************************************************************/ diff --git a/gen/toir.cpp b/gen/toir.cpp index 87388ef7..2ff59d36 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -2063,8 +2063,9 @@ DValue* AssertExp::toElem(IRState* p) 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,9 +2244,8 @@ DValue* HaltExp::toElem(IRState* p) #else // call the new (?) trap intrinsic p->ir->CreateCall(GET_INTRINSIC_DECL(trap),""); -#endif - new llvm::UnreachableInst(p->scopebb()); +#endif // this terminated the basicblock, start a new one // this is sensible, since someone might goto behind the assert diff --git a/tango/lib/compiler/llvmdc/adi.d b/tango/lib/compiler/llvmdc/adi.d index 428ee0df..8ff15ba0 100644 --- a/tango/lib/compiler/llvmdc/adi.d +++ b/tango/lib/compiler/llvmdc/adi.d @@ -378,29 +378,14 @@ extern (C) Array _adSortWchar(wchar[] a) 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; + else if (a1.ptr == a2.ptr) + return 1; // equal -/+ - for (int i = 0; i < a1.length; i++) - { - printf("%4x %4x\n", (cast(short*)p1)[i], (cast(short*)p2)[i]); - } -+/ - - 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 @@ unittest 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 diff --git a/tangotests/arrays2.d b/tangotests/arrays2.d new file mode 100644 index 00000000..dae18d1e --- /dev/null +++ b/tangotests/arrays2.d @@ -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); +} diff --git a/test/calls1.d b/test/calls1.d index 14ec9b67..76446544 100644 --- a/test/calls1.d +++ b/test/calls1.d @@ -1,5 +1,6 @@ module calls1; import tango.core.Vararg; +extern(C) int printf(char*, ...); void main() { {int a = byVal1(3);}