# HG changeset patch # User lindquist # Date 1214225322 -7200 # Node ID 895e1b50cf2ab4c65902b95d06e4268807e0cfb1 # Parent 94435b0ab2ddd1227976c0c6f208705b576aad91 [svn r316] Fixed array slice assignments like: int[] arr = ...; arr[] = 42; There was problems with most non basic types... Added an option to premake so we can do: premake --target gnu --no-boehm to disable the Boehm GC. diff -r 94435b0ab2dd -r 895e1b50cf2a gen/arrays.cpp --- a/gen/arrays.cpp Sun Jun 22 21:36:07 2008 +0200 +++ b/gen/arrays.cpp Mon Jun 23 14:48:42 2008 +0200 @@ -111,32 +111,6 @@ ////////////////////////////////////////////////////////////////////////////////////////// -void DtoArrayInit(LLValue* l, LLValue* r) -{ - Logger::println("DtoArrayInit"); - LOG_SCOPE; - - const LLPointerType* ptrty = isaPointer(l->getType()); - const LLType* t = ptrty->getContainedType(0); - const LLArrayType* arrty = isaArray(t); - if (arrty) - { - LLValue* ptr = DtoGEPi(l,0,0); - LLValue* dim = DtoConstSize_t(arrty->getNumElements()); - DtoArrayInit(ptr, dim, r); - } - else if (isaStruct(t)) - { - LLValue* dim = DtoLoad(DtoGEPi(l, 0,0)); - LLValue* ptr = DtoLoad(DtoGEPi(l, 0,1)); - DtoArrayInit(ptr, dim, r); - } - else - assert(0); -} - -////////////////////////////////////////////////////////////////////////////////////////// - typedef const LLType* constLLVMTypeP; static size_t checkRectArrayInit(const LLType* pt, constLLVMTypeP& finalty) @@ -151,40 +125,57 @@ return 0; } -void DtoArrayInit(LLValue* ptr, LLValue* dim, LLValue* val) +void DtoArrayInit(DValue* array, DValue* value) { Logger::println("DtoArrayInit"); LOG_SCOPE; - Logger::cout() << "array: " << *ptr << " dim: " << *dim << " val: " << *val << '\n'; + LLValue* dim = DtoArrayLen(array); + LLValue* ptr = DtoArrayPtr(array); + LLValue* val = value->getRVal(); + + Logger::cout() << "llvm values:\n" << " ptr: " << *ptr << " dim: " << *dim << " val: " << *val << '\n'; + const LLType* pt = ptr->getType()->getContainedType(0); const LLType* t = val->getType(); const LLType* finalTy; + size_t aggrsz = 0; - if (size_t arrsz = checkRectArrayInit(pt, finalTy)) { + Type* valtype = value->getType()->toBasetype(); + + // handle rectangular init + if (size_t arrsz = checkRectArrayInit(pt, finalTy)) + { assert(finalTy == t); LLConstant* c = isaConstant(dim); assert(c); dim = llvm::ConstantExpr::getMul(c, DtoConstSize_t(arrsz)); ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(finalTy), "tmp"); } - else if (isaStruct(t)) { + // handle null aggregate + else if (isaStruct(t)) + { aggrsz = getABITypeSize(t); LLConstant* c = isaConstant(val); - if (c && c->isNullValue()) { - LLValue* nbytes; - if (aggrsz == 1) - nbytes = dim; - else - nbytes = gIR->ir->CreateMul(dim, DtoConstSize_t(aggrsz), "tmp"); - DtoMemSetZero(ptr,nbytes); - return; - } - else { - ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(LLType::Int8Ty), "tmp"); - } + assert(c && c->isNullValue()); + LLValue* nbytes; + if (aggrsz == 1) + nbytes = dim; + else + nbytes = gIR->ir->CreateMul(dim, DtoConstSize_t(aggrsz), "tmp"); + DtoMemSetZero(ptr,nbytes); + return; } - else { + // handle general aggregate case + else if (DtoIsPassedByRef(valtype)) + { + aggrsz = getABITypeSize(pt); + ptr = gIR->ir->CreateBitCast(ptr, getVoidPtrType(), "tmp"); + val = gIR->ir->CreateBitCast(val, getVoidPtrType(), "tmp"); + } + else + { + Logger::cout() << "no special handling" << '\n'; assert(t == pt); } diff -r 94435b0ab2dd -r 895e1b50cf2a gen/arrays.h --- a/gen/arrays.h Sun Jun 22 21:36:07 2008 +0200 +++ b/gen/arrays.h Mon Jun 23 14:48:42 2008 +0200 @@ -14,8 +14,7 @@ void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src); void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src); -void DtoArrayInit(LLValue* l, LLValue* r); -void DtoArrayInit(LLValue* ptr, LLValue* dim, LLValue* val); +void DtoArrayInit(DValue* array, DValue* value); void DtoArrayAssign(LLValue* l, LLValue* r); void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr); void DtoSetArrayToNull(LLValue* v); diff -r 94435b0ab2dd -r 895e1b50cf2a gen/classes.cpp --- a/gen/classes.cpp Sun Jun 22 21:36:07 2008 +0200 +++ b/gen/classes.cpp Mon Jun 23 14:48:42 2008 +0200 @@ -251,6 +251,7 @@ #else iri->vtblTy = isaStruct(itc->ir.vtblType->get()); #endif + assert(iri->vtblTy); // set index iri->index = interIdx++; diff -r 94435b0ab2dd -r 895e1b50cf2a gen/llvmhelpers.cpp --- a/gen/llvmhelpers.cpp Sun Jun 22 21:36:07 2008 +0200 +++ b/gen/llvmhelpers.cpp Mon Jun 23 14:48:42 2008 +0200 @@ -345,7 +345,7 @@ Type* t2 = DtoDType(rhs->getType()); if (t->ty == Tstruct) { - if (t2 != t) { + if (!t->equals(t2)) { // TODO: fix this, use 'rhs' for something DtoAggrZeroInit(lhs->getLVal()); } @@ -359,11 +359,8 @@ if (DSliceValue* s2 = rhs->isSlice()) { DtoArrayCopySlices(s, s2); } - else if (t->next == t2) { - if (s->len) - DtoArrayInit(s->ptr, s->len, rhs->getRVal()); - else - DtoArrayInit(s->ptr, rhs->getRVal()); + else if (t->next->equals(t2)) { + DtoArrayInit(s, rhs); } else { DtoArrayCopyToSlice(s, rhs); @@ -388,7 +385,7 @@ DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal()); } else { - DtoArrayInit(lhs->getLVal(), rhs->getRVal()); + DtoArrayInit(lhs, rhs); } } else if (t->ty == Tdelegate) { diff -r 94435b0ab2dd -r 895e1b50cf2a gen/toir.cpp --- a/gen/toir.cpp Sun Jun 22 21:36:07 2008 +0200 +++ b/gen/toir.cpp Mon Jun 23 14:48:42 2008 +0200 @@ -2702,18 +2702,20 @@ LLValue* mem = 0; bool isinplace = true; + // already has memory (r-value of assignment) + IRExp* topexp = p->topexp(); + if (topexp && topexp->e2 == this && !topexp->v->isSlice()) + { + assert(topexp->e2 == this); + sptr = topexp->v->getLVal(); + } // temporary struct literal - if (!p->topexp() || p->topexp()->e2 != this) + else { sptr = new llvm::AllocaInst(llt,"tmpstructliteral",p->topallocapoint()); isinplace = false; } - // already has memory - else - { - assert(p->topexp()->e2 == this); - sptr = p->topexp()->v->getLVal(); - } + // num elements in literal unsigned n = elements->dim; diff -r 94435b0ab2dd -r 895e1b50cf2a llvmdc.kdevelop.filelist --- a/llvmdc.kdevelop.filelist Sun Jun 22 21:36:07 2008 +0200 +++ b/llvmdc.kdevelop.filelist Mon Jun 23 14:48:42 2008 +0200 @@ -51,7 +51,6 @@ dmd/interpret.c dmd/lexer.c dmd/lexer.h -dmd/link.c dmd/lstring.c dmd/lstring.h dmd/macro.c diff -r 94435b0ab2dd -r 895e1b50cf2a premake.lua --- a/premake.lua Sun Jun 22 21:36:07 2008 +0200 +++ b/premake.lua Mon Jun 23 14:48:42 2008 +0200 @@ -1,11 +1,21 @@ project.name = llvmdc -- options + +-- we always make vtables opaque, it simply kills performance... OPAQUE_VTBLS = 1 + +-- use of boehm gc if OS == "windows" then - USE_BOEHM_GC = 0 + USE_BOEHM_GC = 0 else - USE_BOEHM_GC = 1 + addoption("no-boehm", "Disable use of the Boehm GC") + + if options["no-boehm"] then + USE_BOEHM_GC = 0 + else + USE_BOEHM_GC = 1 + end end -- idgen diff -r 94435b0ab2dd -r 895e1b50cf2a tango/lib/compiler/llvmdc/arrays.d --- a/tango/lib/compiler/llvmdc/arrays.d Sun Jun 22 21:36:07 2008 +0200 +++ b/tango/lib/compiler/llvmdc/arrays.d Mon Jun 23 14:48:42 2008 +0200 @@ -97,13 +97,3 @@ } return (len*elemsz)/newelemsz; } - -// creating args for main -void _d_main_args(uint n, char** args, ref char[][] res) -{ - assert(res.length == n); - foreach(i,v; args[0..n]) - { - res[i] = v[0 .. strlen(v)]; - } -} diff -r 94435b0ab2dd -r 895e1b50cf2a tangotests/arrays4.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tangotests/arrays4.d Mon Jun 23 14:48:42 2008 +0200 @@ -0,0 +1,27 @@ +module tangotests.arrays4; + +struct Str { int a,b; } +void main() { + Str[] arr = new Str[64]; + + auto tmp = Str(1,2); + arr[] = tmp; + assert(arr[0].a == 1); + assert(arr[0].b == 2); + assert(arr[13].a == 1); + assert(arr[13].b == 2); + assert(arr[42].a == 1); + assert(arr[42].b == 2); + assert(arr[63].a == 1); + assert(arr[63].b == 2); + + arr[] = Str(3,4); + assert(arr[0].a == 3); + assert(arr[0].b == 4); + assert(arr[13].a == 3); + assert(arr[13].b == 4); + assert(arr[42].a == 3); + assert(arr[42].b == 4); + assert(arr[63].a == 3); + assert(arr[63].b == 4); +} diff -r 94435b0ab2dd -r 895e1b50cf2a test/vararg4.d --- a/test/vararg4.d Sun Jun 22 21:36:07 2008 +0200 +++ b/test/vararg4.d Mon Jun 23 14:48:42 2008 +0200 @@ -1,5 +1,6 @@ module vararg4; import tango.core.Vararg; +extern(C) int printf(char*, ...); void vafunc(...) { diff -r 94435b0ab2dd -r 895e1b50cf2a test/vararg5.d --- a/test/vararg5.d Sun Jun 22 21:36:07 2008 +0200 +++ b/test/vararg5.d Mon Jun 23 14:48:42 2008 +0200 @@ -1,5 +1,6 @@ module vararg5; import tango.core.Vararg; +extern(C) int printf(char*, ...); void func(...) { char[] str = va_arg!(char[])(_argptr);