diff --git a/gen/arrays.cpp b/gen/arrays.cpp index e0a1970f..bfd23b50 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -111,32 +111,6 @@ void DtoArrayAssign(LLValue* dst, LLValue* src) ////////////////////////////////////////////////////////////////////////////////////////// -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 @@ static size_t checkRectArrayInit(const LLType* pt, constLLVMTypeP& finalty) 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 --git a/gen/arrays.h b/gen/arrays.h index fda7c6b2..c5e82fa4 100644 --- a/gen/arrays.h +++ b/gen/arrays.h @@ -14,8 +14,7 @@ LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c); 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 --git a/gen/classes.cpp b/gen/classes.cpp index 4deda3cf..cd5f99b8 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -251,6 +251,7 @@ void DtoResolveClass(ClassDeclaration* cd) #else iri->vtblTy = isaStruct(itc->ir.vtblType->get()); #endif + assert(iri->vtblTy); // set index iri->index = interIdx++; diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index b994c255..cf0bf0fd 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -345,7 +345,7 @@ void DtoAssign(DValue* lhs, DValue* rhs) 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 @@ void DtoAssign(DValue* lhs, DValue* rhs) 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 @@ void DtoAssign(DValue* lhs, DValue* rhs) DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal()); } else { - DtoArrayInit(lhs->getLVal(), rhs->getRVal()); + DtoArrayInit(lhs, rhs); } } else if (t->ty == Tdelegate) { diff --git a/gen/toir.cpp b/gen/toir.cpp index 2ff59d36..bb153783 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -2702,18 +2702,20 @@ DValue* StructLiteralExp::toElem(IRState* p) 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 --git a/llvmdc.kdevelop.filelist b/llvmdc.kdevelop.filelist index 72dcdc82..8cf0303d 100644 --- a/llvmdc.kdevelop.filelist +++ b/llvmdc.kdevelop.filelist @@ -51,7 +51,6 @@ dmd/inline.c dmd/interpret.c dmd/lexer.c dmd/lexer.h -dmd/link.c dmd/lstring.c dmd/lstring.h dmd/macro.c diff --git a/premake.lua b/premake.lua index a0ea5ae5..4062d489 100644 --- a/premake.lua +++ b/premake.lua @@ -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 --git a/tango/lib/compiler/llvmdc/arrays.d b/tango/lib/compiler/llvmdc/arrays.d index 178f302f..198b60bd 100644 --- a/tango/lib/compiler/llvmdc/arrays.d +++ b/tango/lib/compiler/llvmdc/arrays.d @@ -97,13 +97,3 @@ size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz) } 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 --git a/tangotests/arrays4.d b/tangotests/arrays4.d new file mode 100644 index 00000000..a171bf13 --- /dev/null +++ b/tangotests/arrays4.d @@ -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 --git a/test/vararg4.d b/test/vararg4.d index 6c3210c2..952cc758 100644 --- a/test/vararg4.d +++ b/test/vararg4.d @@ -1,5 +1,6 @@ module vararg4; import tango.core.Vararg; +extern(C) int printf(char*, ...); void vafunc(...) { diff --git a/test/vararg5.d b/test/vararg5.d index 9f74e34b..f6d817b3 100644 --- a/test/vararg5.d +++ b/test/vararg5.d @@ -1,5 +1,6 @@ module vararg5; import tango.core.Vararg; +extern(C) int printf(char*, ...); void func(...) { char[] str = va_arg!(char[])(_argptr);