changeset 51:61bc1b4ad3c4 trunk

[svn r55] Foreach was always generating code as if the value variable was 'ref' Other not-so-major improvements
author lindquist
date Mon, 22 Oct 2007 17:25:44 +0200
parents 6fcc08a4d406
children 0c77619e803b
files gen/arrays.c gen/statements.c gen/toir.c gen/tollvm.c gen/tollvm.h test/foreach5.d test/foreach6.d
diffstat 7 files changed, 100 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- 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;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
--- 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);
--- 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);
         }
     }
 
--- 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<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 @@
             }
             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);
+    }
+}
--- 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"
--- /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);
+}
--- /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);
+    }
+}