# HG changeset patch # User lindquist # Date 1193306953 -7200 # Node ID b688ad419f8cdec315ec2dd202b2a2f0becdb3b0 # Parent 2c39b5292cf3f3c4b989bf8e02ecf86adf0a5157 [svn r68] Added support for multi-dimensional static arrays. Several bugfixes to array support. diff -r 2c39b5292cf3 -r b688ad419f8c gen/arrays.c --- a/gen/arrays.c Thu Oct 25 10:05:21 2007 +0200 +++ b/gen/arrays.c Thu Oct 25 12:09:13 2007 +0200 @@ -143,24 +143,53 @@ ////////////////////////////////////////////////////////////////////////////////////////// +typedef const llvm::Type* constLLVMTypeP; + +static size_t checkRectArrayInit(const llvm::Type* pt, constLLVMTypeP& finalty) +{ + if (llvm::isa(pt)) { + size_t n = checkRectArrayInit(pt->getContainedType(0), finalty); + size_t ne = llvm::cast(pt)->getNumElements(); + if (n) return n * ne; + return ne; + } + finalty = pt; + return 0; +} + void LLVM_DtoArrayInit(llvm::Value* ptr, llvm::Value* dim, llvm::Value* val) { - const llvm::Type* t = ptr->getType()->getContainedType(0); + const llvm::Type* pt = ptr->getType()->getContainedType(0); + const llvm::Type* t = val->getType(); + const llvm::Type* finalTy; + if (size_t arrsz = checkRectArrayInit(pt, finalTy)) { + assert(finalTy == t); + llvm::Constant* c = llvm::cast_or_null(dim); + assert(c); + dim = llvm::ConstantExpr::getMul(c, LLVM_DtoConstSize_t(arrsz)); + ptr = gIR->ir->CreateBitCast(ptr, llvm::PointerType::get(finalTy), "tmp"); + } + else if (llvm::isa(t)) { + assert(0); + } + else { + assert(t == pt); + } std::vector args; args.push_back(ptr); args.push_back(dim); args.push_back(val); - + const char* funcname = NULL; - + if (llvm::isa(t)) { funcname = "_d_array_init_pointer"; - + const llvm::Type* dstty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty)); if (args[0]->getType() != dstty) args[0] = new llvm::BitCastInst(args[0],dstty,"tmp",gIR->scopebb()); - + const llvm::Type* valty = llvm::PointerType::get(llvm::Type::Int8Ty); if (args[2]->getType() != valty) args[2] = new llvm::BitCastInst(args[2],valty,"tmp",gIR->scopebb()); @@ -187,6 +216,7 @@ funcname = "_d_array_init_double"; } else { + Logger::cout() << *ptr->getType() << " = " << *val->getType() << '\n'; assert(0); } @@ -607,3 +637,21 @@ llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp"); return b; } + +////////////////////////////////////////////////////////////////////////////////////////// +llvm::Constant* LLVM_DtoConstantStaticArray(const llvm::Type* t, llvm::Constant* c) +{ + assert(llvm::isa(t)); + const llvm::ArrayType* at = llvm::cast(t); + + if (llvm::isa(at->getElementType())) + { + c = LLVM_DtoConstantStaticArray(at->getElementType(), c); + } + else { + assert(at->getElementType() == c->getType()); + } + std::vector initvals; + initvals.resize(at->getNumElements(), c); + return llvm::ConstantArray::get(at, initvals); +} diff -r 2c39b5292cf3 -r b688ad419f8c gen/arrays.h --- a/gen/arrays.h Thu Oct 25 10:05:21 2007 +0200 +++ b/gen/arrays.h Thu Oct 25 12:09:13 2007 +0200 @@ -6,6 +6,7 @@ llvm::Constant* LLVM_DtoConstArrayInitializer(ArrayInitializer* si); llvm::Constant* LLVM_DtoConstantSlice(llvm::Constant* dim, llvm::Constant* ptr); +llvm::Constant* LLVM_DtoConstantStaticArray(const llvm::Type* t, llvm::Constant* c); void LLVM_DtoArrayCopy(elem* dst, elem* src); void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r); diff -r 2c39b5292cf3 -r b688ad419f8c gen/toir.c --- a/gen/toir.c Thu Oct 25 10:05:21 2007 +0200 +++ b/gen/toir.c Thu Oct 25 12:09:13 2007 +0200 @@ -1458,32 +1458,41 @@ vdt->sym->offsetToIndex(t->next, offset, dst); llvm::Value* ptr = llvalue; assert(ptr); - e->mem = LLVM_DtoGEP(ptr,dst,"tmp",p->scopebb()); + e->mem = LLVM_DtoGEP(ptr,dst,"tmp"); e->type = elem::VAL; e->field = true; } else if (vdtype->ty == Tsarray) { - /*e = new elem; - llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - e->val = new llvm::GetElementPtrInst(vd->llvmValue,idx0,idx0,"tmp",p->scopebb());*/ e = new elem; - llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - //llvm::Value* idx1 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); - e->mem = LLVM_DtoGEP(llvalue,idx0,idx0,"tmp",p->scopebb()); + assert(llvalue); e->arg = llvalue; e->type = elem::VAL; + + const llvm::Type* llt = LLVM_DtoType(t); + llvm::Value* off = 0; + if (offset != 0) { + Logger::println("offset = %d\n", offset); + } + if (llvalue->getType() != llt) { + e->mem = p->ir->CreateBitCast(llvalue, llt, "tmp"); + if (offset != 0) + e->mem = LLVM_DtoGEPi(e->mem, offset, "tmp"); + } + else { + assert(offset == 0); + e->mem = LLVM_DtoGEPi(llvalue,0,0,"tmp"); + } } else if (offset == 0) { e = new elem; + e->type = elem::VAL; assert(llvalue); e->mem = llvalue; + const llvm::Type* llt = LLVM_DtoType(t); if (llvalue->getType() != llt) { - Logger::cout() << "llt is:" << *llt << '\n'; - //const llvm::PointerType* vpty = llvm::PointerType::get(llvm::Type::Int8Ty); e->mem = p->ir->CreateBitCast(e->mem, llt, "tmp"); } - e->type = elem::VAL; } else { assert(0); @@ -2009,6 +2018,7 @@ if (t->isintegral() || t->ty == Tpointer) { + Logger::println("integral or pointer"); llvm::ICmpInst::Predicate cmpop; switch(op) { @@ -2025,6 +2035,7 @@ } else if (t->isfloating()) { + Logger::println("floating"); llvm::FCmpInst::Predicate cmpop; switch(op) { @@ -2041,14 +2052,17 @@ } else if (t->ty == Tsarray) { + Logger::println("static array"); e->val = LLVM_DtoStaticArrayCompare(op,l->mem,r->mem); } else if (t->ty == Tarray) { + Logger::println("dynamic array"); e->val = LLVM_DtoDynArrayCompare(op,l->mem,r->mem); } else if (t->ty == Tdelegate) { + Logger::println("delegate"); e->val = LLVM_DtoCompareDelegate(op,l->mem,r->mem); } else diff -r 2c39b5292cf3 -r b688ad419f8c gen/toobj.c --- a/gen/toobj.c Thu Oct 25 10:05:21 2007 +0200 +++ b/gen/toobj.c Thu Oct 25 12:09:13 2007 +0200 @@ -35,6 +35,7 @@ #include "gen/elem.h" #include "gen/logger.h" #include "gen/tollvm.h" +#include "gen/arrays.h" ////////////////////////////////////////////////////////////////////////////////////////// @@ -546,15 +547,7 @@ // array single value init else if (llvm::isa(_type)) { - const llvm::ArrayType* at = llvm::cast(_type); - if (at->getElementType() == _init->getType()) { - std::vector initvals; - initvals.resize(at->getNumElements(), _init); - _init = llvm::ConstantArray::get(at, initvals); - } - else { - assert(0); - } + _init = LLVM_DtoConstantStaticArray(_type, _init); } else { Logger::cout() << "Unexpected initializer type: " << *_type << '\n'; @@ -562,6 +555,7 @@ } } + Logger::cout() << "final init = " << *_init << '\n'; gvar->setInitializer(_init); } diff -r 2c39b5292cf3 -r b688ad419f8c lphobos/internal/arrays.d --- a/lphobos/internal/arrays.d Thu Oct 25 10:05:21 2007 +0200 +++ b/lphobos/internal/arrays.d Thu Oct 25 12:09:13 2007 +0200 @@ -1,7 +1,16 @@ module internal.arrays; +private import llvm.intrinsic; + extern(C): +int memcmp(void*,void*,size_t); + +version(LLVM64) +alias llvm_memcpy_i64 llvm_memcpy; +else +alias llvm_memcpy_i32 llvm_memcpy; + // per-element array init routines void _d_array_init_i1(bool* a, size_t n, bool v) @@ -68,8 +77,17 @@ *p++ = v; } +void _d_array_init(void* a, size_t na, void* v, size_t nv) +{ + auto p = a; + auto end = a + na*nv; + while (p !is end) { + llvm_memcpy(p,v,nv,0); + p += nv; + } +} + // array comparison routines -int memcmp(void*,void*,size_t); bool _d_static_array_eq(void* lhs, void* rhs, size_t bytesize) { diff -r 2c39b5292cf3 -r b688ad419f8c test/multiarr1.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/multiarr1.d Thu Oct 25 12:09:13 2007 +0200 @@ -0,0 +1,10 @@ +module multiarr1; + +void main() +{ + int[16][16] a; + a[10][13] = 42; + assert(a[0][0] == 0); + assert(a[10][13] == 42); + {assert(*((cast(int*)a)+10*16+13) == 42);} +} diff -r 2c39b5292cf3 -r b688ad419f8c test/multiarr2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/multiarr2.d Thu Oct 25 12:09:13 2007 +0200 @@ -0,0 +1,7 @@ +module multiarr2; + +void main() +{ + static float[1][2][3] arr; + assert(arr[2][1][0] !<>= float.nan); +} diff -r 2c39b5292cf3 -r b688ad419f8c test/multiarr3.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/multiarr3.d Thu Oct 25 12:09:13 2007 +0200 @@ -0,0 +1,10 @@ +module multiarr3; + +void main() +{ + static int[2][2] arr = [[1,2],[3,4]]; + assert(arr[0][0] == 1); + assert(arr[0][1] == 2); + assert(arr[1][0] == 3); + assert(arr[1][1] == 4); +} diff -r 2c39b5292cf3 -r b688ad419f8c test/multiarr4.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/multiarr4.d Thu Oct 25 12:09:13 2007 +0200 @@ -0,0 +1,13 @@ +module multiarr4; + +void main() +{ + char[][] a; + a.length = 2; + a[0] = "hello"; + a[1] = "world"; + foreach(v;a) + { + printf("%.*s\n", v.length, v.ptr); + } +}