# HG changeset patch # User lindquist # Date 1193066744 -7200 # Node ID 61bc1b4ad3c4baa244993a2019afd579a1908471 # Parent 6fcc08a4d406e90e55c3ba60d75e4a79c870a1eb [svn r55] Foreach was always generating code as if the value variable was 'ref' Other not-so-major improvements diff -r 6fcc08a4d406 -r 61bc1b4ad3c4 gen/arrays.c --- a/gen/arrays.c Mon Oct 22 15:40:56 2007 +0200 +++ b/gen/arrays.c Mon Oct 22 17:25:44 2007 +0200 @@ -445,16 +445,8 @@ elem* e = exp->toElem(gIR); Type* et = LLVM_DtoDType(exp->type); - - if (et->ty == Tstruct) { - TypeStruct* ts = (TypeStruct*)et; - LLVM_DtoStructCopy(ts,ptr,e->getValue()); - } - else { - llvm::Value* val = e->getValue(); - Logger::cout() << "ptr = '" << *ptr << "' element = '" << *val << "'\n"; - new llvm::StoreInst(val, ptr, gIR->scopebb()); - } + LLVM_DtoAssign(et, ptr, e->getValue()); + delete e; } ////////////////////////////////////////////////////////////////////////////////////////// diff -r 6fcc08a4d406 -r 61bc1b4ad3c4 gen/statements.c --- a/gen/statements.c Mon Oct 22 15:40:56 2007 +0200 +++ b/gen/statements.c Mon Oct 22 17:25:44 2007 +0200 @@ -69,9 +69,8 @@ if (expty == Tstruct) { if (!e->inplace) { - TypeStruct* ts = (TypeStruct*)exptype; assert(e->mem); - LLVM_DtoStructCopy(ts,f->llvmRetArg,e->mem); + LLVM_DtoStructCopy(f->llvmRetArg,e->mem); } } else if (expty == Tdelegate) { @@ -649,7 +648,7 @@ if (key) key->llvmValue = keyvar; const llvm::Type* valtype = LLVM_DtoType(value->type); - llvm::Value* valvar = new llvm::AllocaInst(keytype, "foreachval", p->topallocapoint()); + llvm::Value* valvar = !value->isRef() ? new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint()) : NULL; Type* aggrtype = LLVM_DtoDType(aggr->type); if (aggrtype->ty == Tsarray) @@ -708,10 +707,20 @@ // get value for this iteration llvm::Constant* zero = llvm::ConstantInt::get(keytype,0,false); + llvm::Value* loadedKey = p->ir->CreateLoad(keyvar,"tmp"); if (aggrtype->ty == Tsarray) - value->llvmValue = LLVM_DtoGEP(val,zero,new llvm::LoadInst(keyvar,"tmp",p->scopebb()),"tmp",p->scopebb()); + value->llvmValue = LLVM_DtoGEP(val,zero,loadedKey,"tmp"); else if (aggrtype->ty == Tarray) - value->llvmValue = new llvm::GetElementPtrInst(val,new llvm::LoadInst(keyvar,"tmp",p->scopebb()),"tmp",p->scopebb()); + value->llvmValue = new llvm::GetElementPtrInst(val,loadedKey,"tmp",p->scopebb()); + + if (!value->isRef()) { + elem* e = new elem; + e->mem = value->llvmValue; + e->type = elem::VAR; + LLVM_DtoAssign(LLVM_DtoDType(value->type), valvar, e->getValue()); + delete e; + value->llvmValue = valvar; + } // body p->scope() = IRScope(p->scopebb(),endbb); diff -r 6fcc08a4d406 -r 61bc1b4ad3c4 gen/toir.c --- a/gen/toir.c Mon Oct 22 15:40:56 2007 +0200 +++ b/gen/toir.c Mon Oct 22 17:25:44 2007 +0200 @@ -499,8 +499,7 @@ if (e2ty == Tstruct) { // struct literals do the assignment themselvs (in place) if (!r->inplace) { - TypeStruct* ts = (TypeStruct*)e2type; - LLVM_DtoStructCopy(ts,l->mem,r->getValue()); + LLVM_DtoStructCopy(l->mem,r->getValue()); } else { e->inplace = true; @@ -510,8 +509,7 @@ else if (e2type->isintegral()){ IntegerExp* iexp = (IntegerExp*)e2; assert(iexp->value == 0 && "Only integral struct initializer allowed is zero"); - TypeStruct* st = (TypeStruct*)e1type; - LLVM_DtoStructZeroInit(st, l->mem); + LLVM_DtoStructZeroInit(l->mem); } // :x else @@ -1550,18 +1548,7 @@ Logger::cout() << *val << " | " << *arrptr << '\n'; Type* vxtype = LLVM_DtoDType(vx->type); - if (vxtype->ty == Tstruct) { - TypeStruct* ts = (TypeStruct*)vxtype; - LLVM_DtoStructCopy(ts,arrptr,val); - } - else if (vxtype->ty == Tarray) { - LLVM_DtoArrayAssign(arrptr,val); - } - else if (vxtype->ty == Tsarray) { - LLVM_DtoStaticArrayCopy(arrptr,val); - } - else - new llvm::StoreInst(val, arrptr, p->scopebb()); + LLVM_DtoAssign(vxtype, arrptr, val); } delete ve; } @@ -2058,10 +2045,10 @@ else if (ntype->ty == Tstruct) { TypeStruct* ts = (TypeStruct*)ntype; if (ts->isZeroInit()) { - LLVM_DtoStructZeroInit(ts,e->mem); + LLVM_DtoStructZeroInit(e->mem); } else { - LLVM_DtoStructCopy(ts,e->mem,ts->llvmInit); + LLVM_DtoStructCopy(e->mem,ts->llvmInit); } } diff -r 6fcc08a4d406 -r 61bc1b4ad3c4 gen/tollvm.c --- a/gen/tollvm.c Mon Oct 22 15:40:56 2007 +0200 +++ b/gen/tollvm.c Mon Oct 22 17:25:44 2007 +0200 @@ -435,10 +435,10 @@ ////////////////////////////////////////////////////////////////////////////////////////// -llvm::Value* LLVM_DtoStructZeroInit(TypeStruct* t, llvm::Value* v) +llvm::Value* LLVM_DtoStructZeroInit(llvm::Value* v) { assert(gIR); - uint64_t n = gTargetData->getTypeSize(t->llvmType); + uint64_t n = gTargetData->getTypeSize(v->getType()->getContainedType(0)); //llvm::Type* sarrty = llvm::PointerType::get(llvm::ArrayType::get(llvm::Type::Int8Ty, n)); llvm::Type* sarrty = llvm::PointerType::get(llvm::Type::Int8Ty); @@ -459,12 +459,12 @@ ////////////////////////////////////////////////////////////////////////////////////////// -llvm::Value* LLVM_DtoStructCopy(TypeStruct* t, llvm::Value* dst, llvm::Value* src) +llvm::Value* LLVM_DtoStructCopy(llvm::Value* dst, llvm::Value* src) { assert(dst->getType() == src->getType()); assert(gIR); - uint64_t n = gTargetData->getTypeSize(t->llvmType); + uint64_t n = gTargetData->getTypeSize(dst->getType()->getContainedType(0)); //llvm::Type* sarrty = llvm::PointerType::get(llvm::ArrayType::get(llvm::Type::Int8Ty, n)); llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); @@ -1110,11 +1110,11 @@ llvm::Value* allocaInst = 0; llvm::BasicBlock* entryblock = &gIR->topfunc()->front(); //const llvm::PointerType* pty = llvm::cast(arg->mem->getType()); - const llvm::PointerType* pty = llvm::PointerType::get(LLVM_DtoType(argexp->type)); + const llvm::Type* realtypell = LLVM_DtoType(realtype); + const llvm::PointerType* pty = llvm::PointerType::get(realtypell); if (argty == Tstruct) { allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->topallocapoint()); - TypeStruct* ts = (TypeStruct*)LLVM_DtoDType(argexp->type); - LLVM_DtoStructCopy(ts,allocaInst,arg->mem); + LLVM_DtoStructCopy(allocaInst,arg->mem); } else if (argty == Tdelegate) { allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->topallocapoint()); @@ -1122,7 +1122,7 @@ } else if (argty == Tarray) { if (arg->type == elem::SLICE) { - allocaInst = new llvm::AllocaInst(LLVM_DtoType(argexp->type), "tmpparam", gIR->topallocapoint()); + allocaInst = new llvm::AllocaInst(realtypell, "tmpparam", gIR->topallocapoint()); LLVM_DtoSetArray(allocaInst, arg->arg, arg->mem); } else { @@ -1209,3 +1209,31 @@ assert(0 && "nested var not found"); return NULL; } + +////////////////////////////////////////////////////////////////////////////////////////// + +void LLVM_DtoAssign(Type* t, llvm::Value* lhs, llvm::Value* rhs) +{ + Logger::cout() << "assignment:" << '\n' << *lhs << *rhs << '\n'; + + if (t->ty == Tstruct) { + assert(lhs->getType() == rhs->getType()); + LLVM_DtoStructCopy(lhs,rhs); + } + else if (t->ty == Tarray) { + assert(lhs->getType() == rhs->getType()); + LLVM_DtoArrayAssign(lhs,rhs); + } + else if (t->ty == Tsarray) { + assert(lhs->getType() == rhs->getType()); + LLVM_DtoStaticArrayCopy(lhs,rhs); + } + else if (t->ty == Tdelegate) { + assert(lhs->getType() == rhs->getType()); + LLVM_DtoDelegateCopy(lhs,rhs); + } + else { + assert(lhs->getType()->getContainedType(0) == rhs->getType()); + gIR->ir->CreateStore(rhs, lhs); + } +} diff -r 6fcc08a4d406 -r 61bc1b4ad3c4 gen/tollvm.h --- a/gen/tollvm.h Mon Oct 22 15:40:56 2007 +0200 +++ b/gen/tollvm.h Mon Oct 22 17:25:44 2007 +0200 @@ -7,8 +7,8 @@ Type* LLVM_DtoDType(Type* t); const llvm::Type* LLVM_DtoStructType(Type* t); -llvm::Value* LLVM_DtoStructZeroInit(TypeStruct* t, llvm::Value* v); -llvm::Value* LLVM_DtoStructCopy(TypeStruct* t, llvm::Value* dst, llvm::Value* src); +llvm::Value* LLVM_DtoStructZeroInit(llvm::Value* v); +llvm::Value* LLVM_DtoStructCopy(llvm::Value* dst, llvm::Value* src); llvm::Constant* LLVM_DtoConstStructInitializer(StructInitializer* si); const llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thisparam = 0); @@ -56,4 +56,6 @@ llvm::Value* LLVM_DtoNestedVariable(VarDeclaration* vd); +void LLVM_DtoAssign(Type* lhsType, llvm::Value* lhs, llvm::Value* rhs); + #include "enums.h" diff -r 6fcc08a4d406 -r 61bc1b4ad3c4 test/foreach5.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/foreach5.d Mon Oct 22 17:25:44 2007 +0200 @@ -0,0 +1,24 @@ +module foreach5; + +void main() +{ + int[3] arr = [1,2,3]; + + foreach(v;arr) { + v++; + } + + printf("%d\n", arr[0]); + assert(arr[0] == 1); + assert(arr[1] == 2); + assert(arr[2] == 3); + + foreach(ref v;arr) { + v++; + } + + printf("%d\n", arr[0]); + assert(arr[0] == 2); + assert(arr[1] == 3); + assert(arr[2] == 4); +} diff -r 6fcc08a4d406 -r 61bc1b4ad3c4 test/foreach6.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/foreach6.d Mon Oct 22 17:25:44 2007 +0200 @@ -0,0 +1,15 @@ +module foreach6; + +struct S +{ + long l; + float f; +} + +void main() +{ + S[4] arr; + foreach(i,v;arr) { + v = S(i,i*2.5); + } +}