mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
[svn r55] Foreach was always generating code as if the value variable was 'ref'
Other not-so-major improvements
This commit is contained in:
12
gen/arrays.c
12
gen/arrays.c
@@ -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;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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);
|
||||
|
||||
23
gen/toir.c
23
gen/toir.c
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
44
gen/tollvm.c
44
gen/tollvm.c
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
24
test/foreach5.d
Normal 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
15
test/foreach6.d
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user