[svn r55] Foreach was always generating code as if the value variable was 'ref'

Other not-so-major improvements
This commit is contained in:
Tomas Lindquist Olsen
2007-10-22 17:25:44 +02:00
parent a9189bd3a9
commit 2c99df8deb
7 changed files with 100 additions and 43 deletions

View File

@@ -445,16 +445,8 @@ void LLVM_DtoCatArrayElement(llvm::Value* arr, Expression* exp)
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;
}
//////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -69,9 +69,8 @@ void ReturnStatement::toIR(IRState* p)
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 @@ void ForeachStatement::toIR(IRState* p)
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 @@ void ForeachStatement::toIR(IRState* p)
// 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);

View File

@@ -499,8 +499,7 @@ elem* AssignExp::toElem(IRState* p)
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 @@ elem* AssignExp::toElem(IRState* p)
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 @@ elem* StructLiteralExp::toElem(IRState* p)
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 @@ elem* NewExp::toElem(IRState* p)
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);
}
}

View File

@@ -435,10 +435,10 @@ llvm::Function* LLVM_DeclareMemCpy64()
//////////////////////////////////////////////////////////////////////////////////////////
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_DtoStructZeroInit(TypeStruct* t, llvm::Value* v)
//////////////////////////////////////////////////////////////////////////////////////////
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* LLVM_DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expr
llvm::Value* allocaInst = 0;
llvm::BasicBlock* entryblock = &gIR->topfunc()->front();
//const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(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 @@ llvm::Value* LLVM_DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expr
}
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 @@ llvm::Value* LLVM_DtoNestedVariable(VarDeclaration* vd)
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);
}
}

View File

@@ -7,8 +7,8 @@ bool LLVM_DtoIsPassedByRef(Type* type);
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_DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expr
llvm::Value* LLVM_DtoNestedVariable(VarDeclaration* vd);
void LLVM_DtoAssign(Type* lhsType, llvm::Value* lhs, llvm::Value* rhs);
#include "enums.h"

24
test/foreach5.d Normal file
View File

@@ -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);
}

15
test/foreach6.d Normal file
View File

@@ -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);
}
}