changeset 37:77cdca8c210f trunk

[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer. initial label/goto support.
author lindquist
date Wed, 10 Oct 2007 03:38:24 +0200
parents c0967c4b2a74
children 27b2f40bdb58
files dmd/statement.c dmd/statement.h gen/arrays.c gen/arrays.h gen/statements.c gen/toir.c lphobos/std/stdio.d test/arrays4.d test/arrays5.d test/goto1.d
diffstat 10 files changed, 206 insertions(+), 113 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/statement.c	Tue Oct 09 07:51:13 2007 +0200
+++ b/dmd/statement.c	Wed Oct 10 03:38:24 2007 +0200
@@ -3464,7 +3464,8 @@
     this->statement = statement;
     this->tf = NULL;
     this->lblock = NULL;
-    this->isReturnLabel = 0;
+    this->isReturnLabel = 0;
+    this->llvmBB = NULL;
 }
 
 Statement *LabelStatement::syntaxCopy()
--- a/dmd/statement.h	Tue Oct 09 07:51:13 2007 +0200
+++ b/dmd/statement.h	Wed Oct 10 03:38:24 2007 +0200
@@ -51,7 +51,8 @@
 
 namespace llvm
 {
-    class Value;
+    class Value;
+    class BasicBlock;
 }
 
 // Back end
@@ -714,7 +715,9 @@
 
     Statement *inlineScan(InlineScanState *iss);
 
-    void toIR(IRState *irs);
+    void toIR(IRState *irs);
+    
+    llvm::BasicBlock* llvmBB;
 };
 
 struct LabelDsymbol : Dsymbol
--- a/gen/arrays.c	Tue Oct 09 07:51:13 2007 +0200
+++ b/gen/arrays.c	Wed Oct 10 03:38:24 2007 +0200
@@ -127,65 +127,16 @@
 void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r)
 {
     const llvm::PointerType* ptrty = llvm::cast<llvm::PointerType>(l->getType());
-    if (llvm::isa<llvm::ArrayType>(ptrty->getContainedType(0)))
+    const llvm::Type* t = ptrty->getContainedType(0);
+    const llvm::ArrayType* arrty = llvm::cast_or_null<llvm::ArrayType>(t);
+    if (arrty)
     {
-        const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(ptrty->getContainedType(0));
-        llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
-
-        std::vector<llvm::Value*> args;
-        args.resize(3);
-        args[0] = LLVM_DtoGEP(l,zero,zero,"tmp",gIR->scopebb());
-        args[1] = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false);
-        args[2] = r;
-        
-        const char* funcname = NULL;
-        
-        if (llvm::isa<llvm::PointerType>(arrty->getElementType())) {
-            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());
-        }
-        else if (r->getType() == llvm::Type::Int1Ty) {
-            funcname = "_d_array_init_i1";
-        }
-        else if (r->getType() == llvm::Type::Int8Ty) {
-            funcname = "_d_array_init_i8";
-        }
-        else if (r->getType() == llvm::Type::Int16Ty) {
-            funcname = "_d_array_init_i16";
-        }
-        else if (r->getType() == llvm::Type::Int32Ty) {
-            funcname = "_d_array_init_i32";
-        }
-        else if (r->getType() == llvm::Type::Int64Ty) {
-            funcname = "_d_array_init_i64";
-        }
-        else if (r->getType() == llvm::Type::FloatTy) {
-            funcname = "_d_array_init_float";
-        }
-        else if (r->getType() == llvm::Type::DoubleTy) {
-            funcname = "_d_array_init_double";
-        }
-        else {
-            assert(0);
-        }
-        
-        Logger::cout() << *args[0] << '|' << *args[2] << '\n';
-        
-        llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
-        assert(fn);
-        llvm::CallInst* call = new llvm::CallInst(fn, args.begin(), args.end(), "", gIR->scopebb());
-        call->setCallingConv(llvm::CallingConv::C);
-        
-        Logger::println("array init call ok");
+        llvm::Value* ptr = LLVM_DtoGEPi(l,0,0,"tmp",gIR->scopebb());
+        llvm::Value* dim = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false);
+        llvm::Value* val = r;
+        LLVM_DtoArrayInit(ptr, dim, val);
     }
-    else if (llvm::isa<llvm::StructType>(ptrty->getContainedType(0)))
+    else if (llvm::isa<llvm::StructType>(t))
     {
         assert(0 && "Only static arrays support initialisers atm");
     }
@@ -195,6 +146,61 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
+void LLVM_DtoArrayInit(llvm::Value* ptr, llvm::Value* dim, llvm::Value* val)
+{
+    const llvm::Type* t = ptr->getType()->getContainedType(0);
+
+    std::vector<llvm::Value*> args(3,NULL);
+    args[0] = ptr;
+    args[1] = dim;
+    args[2] = val;
+    
+    const char* funcname = NULL;
+    
+    if (llvm::isa<llvm::PointerType>(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());
+    }
+    else if (t == llvm::Type::Int1Ty) {
+        funcname = "_d_array_init_i1";
+    }
+    else if (t == llvm::Type::Int8Ty) {
+        funcname = "_d_array_init_i8";
+    }
+    else if (t == llvm::Type::Int16Ty) {
+        funcname = "_d_array_init_i16";
+    }
+    else if (t == llvm::Type::Int32Ty) {
+        funcname = "_d_array_init_i32";
+    }
+    else if (t == llvm::Type::Int64Ty) {
+        funcname = "_d_array_init_i64";
+    }
+    else if (t == llvm::Type::FloatTy) {
+        funcname = "_d_array_init_float";
+    }
+    else if (t == llvm::Type::DoubleTy) {
+        funcname = "_d_array_init_double";
+    }
+    else {
+        assert(0);
+    }
+
+    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
+    assert(fn);
+    llvm::CallInst* call = new llvm::CallInst(fn, args.begin(), args.end(), "", gIR->scopebb());
+    call->setCallingConv(llvm::CallingConv::C);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
 void LLVM_DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr)
 {
     Logger::cout() << "LLVM_DtoSetArray(" << *arr << ", " << *dim << ", " << *ptr << ")\n";
@@ -369,8 +375,9 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
-void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, const llvm::Type* ty)
+void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit)
 {
+    const llvm::Type* ty = LLVM_DtoType(dty);
     size_t sz = gTargetData->getTypeSize(ty);
     llvm::ConstantInt* n = llvm::ConstantInt::get(LLVM_DtoSize_t(), sz, false);
     llvm::Value* bytesize = llvm::BinaryOperator::createMul(n,dim,"tmp",gIR->scopebb());
@@ -378,6 +385,12 @@
     llvm::Value* nullptr = llvm::ConstantPointerNull::get(llvm::PointerType::get(ty));
 
     llvm::Value* newptr = LLVM_DtoRealloc(nullptr, bytesize);
+    
+    if (doinit) {
+        elem* e = dty->defaultInit()->toElem(gIR);
+        LLVM_DtoArrayInit(newptr,dim,e->getValue());
+        delete e;
+    }
 
     llvm::Value* lenptr = LLVM_DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
     new llvm::StoreInst(dim,lenptr,gIR->scopebb());
@@ -402,5 +415,3 @@
     new llvm::StoreInst(sz,len,gIR->scopebb());
 }
 
-
-
--- a/gen/arrays.h	Tue Oct 09 07:51:13 2007 +0200
+++ b/gen/arrays.h	Wed Oct 10 03:38:24 2007 +0200
@@ -9,11 +9,12 @@
 
 void LLVM_DtoArrayCopy(elem* dst, elem* src);
 void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r);
+void LLVM_DtoArrayInit(llvm::Value* ptr, llvm::Value* dim, llvm::Value* val);
 void LLVM_DtoArrayAssign(llvm::Value* l, llvm::Value* r);
 void LLVM_DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr);
 void LLVM_DtoNullArray(llvm::Value* v);
 
-void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, const llvm::Type* ty);
+void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit=true);
 void LLVM_DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz);
 
 #endif // LLVMC_GEN_ARRAYS_H
--- a/gen/statements.c	Tue Oct 09 07:51:13 2007 +0200
+++ b/gen/statements.c	Wed Oct 10 03:38:24 2007 +0200
@@ -695,6 +695,45 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
+void LabelStatement::toIR(IRState* p)
+{
+    Logger::println("LabelStatement::toIR(): %s", toChars());
+    LOG_SCOPE;
+
+    assert(tf == NULL);
+    assert(!isReturnLabel);
+
+    llvm::BasicBlock* oldend = gIR->scopeend();
+    if (llvmBB)
+        llvmBB->moveBefore(oldend);
+    else
+        llvmBB = new llvm::BasicBlock("label", p->topfunc(), oldend);
+
+    new llvm::BranchInst(llvmBB, p->scopebb());
+    p->scope() = IRScope(llvmBB,oldend);
+    statement->toIR(p);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void GotoStatement::toIR(IRState* p)
+{
+    Logger::println("GotoStatement::toIR(): %s", toChars());
+    LOG_SCOPE;
+
+    assert(tf == NULL);
+
+    llvm::BasicBlock* oldend = gIR->scopeend();
+    llvm::BasicBlock* bb = new llvm::BasicBlock("aftergoto", p->topfunc(), oldend);
+
+    if (label->statement->llvmBB == NULL)
+        label->statement->llvmBB = new llvm::BasicBlock("label", p->topfunc());
+    new llvm::BranchInst(label->statement->llvmBB, p->scopebb());
+    p->scope() = IRScope(bb,oldend);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
 //////////////////////////////////////////////////////////////////////////////
 
 #define STUBST(x) void x::toIR(IRState * p) {error("Statement type "#x" not implemented: %s", toChars());fatal();}
@@ -720,10 +759,10 @@
 //STUBST(TryCatchStatement);
 //STUBST(TryFinallyStatement);
 STUBST(VolatileStatement);
-STUBST(LabelStatement);
+//STUBST(LabelStatement);
 //STUBST(ThrowStatement);
 STUBST(GotoCaseStatement);
 STUBST(GotoDefaultStatement);
-STUBST(GotoStatement);
+//STUBST(GotoStatement);
 //STUBST(UnrolledLoopStatement);
 //STUBST(OnScopeStatement);
--- a/gen/toir.c	Tue Oct 09 07:51:13 2007 +0200
+++ b/gen/toir.c	Wed Oct 10 03:38:24 2007 +0200
@@ -1837,21 +1837,11 @@
             e->mem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb());
         }
         else if (newtype->ty == Tarray) {
-            t = LLVM_DtoType(newtype->next);
             assert(arguments);
             if (arguments->dim == 1) {
                 elem* sz = ((Expression*)arguments->data[0])->toElem(p);
                 llvm::Value* dimval = sz->getValue();
-                /*llvm::Value* usedimval = dimval;
-                if (dimval->getType() != llvm::Type::Int32Ty)
-                    usedimval = new llvm::TruncInst(dimval, llvm::Type::Int32Ty,"tmp",p->scopebb());*/
-
-                //e->mem = LLVM_DtoRealloc(0,t);
-                //new llvm::MallocInst(t,usedimval,"tmp",p->scopebb());
-
-                //LLVM_DtoSetArray(p->toplval(), dimval, e->mem);
-
-                LLVM_DtoNewDynArray(p->toplval(), dimval, t);
+                LLVM_DtoNewDynArray(p->toplval(), dimval, newtype->next);
                 delete sz;
             }
             else {
@@ -2433,112 +2423,127 @@
 
 unsigned Type::totym() { return 0; }
 
-type *
-Type::toCtype() {
+type * Type::toCtype()
+{
+    assert(0);
     return 0;
 }
 
 type * Type::toCParamtype()
 {
+    assert(0);
     return 0;
 }
 Symbol * Type::toSymbol()
 {
+    assert(0);
     return 0;
 }
 
 type *
 TypeTypedef::toCtype()
 {
+    assert(0);
     return 0;
 }
 
 type *
 TypeTypedef::toCParamtype()
 {
+    assert(0);
     return 0;
 }
 
 void
 TypedefDeclaration::toDebug()
 {
+    assert(0);
 }
 
 
 type *
 TypeEnum::toCtype()
 {
+    assert(0);
     return 0;
 }
 
 type *
 TypeStruct::toCtype()
 {
+    assert(0);
     return 0;
 }
 
 void
 StructDeclaration::toDebug()
 {
+    assert(0);
 }
 
 Symbol * TypeClass::toSymbol()
 {
+    assert(0);
     return 0;
 }
 
 unsigned TypeFunction::totym()
 {
+    assert(0);
     return 0;
 }
 
-type *
-TypeFunction::toCtype()
+type * TypeFunction::toCtype()
 {
+    assert(0);
     return 0;
 }
 
-type *
-TypeSArray::toCtype()
+type * TypeSArray::toCtype()
 {
+    assert(0);
     return 0;
 }
 
-type *TypeSArray::toCParamtype() { return 0; }
-
-type *
-TypeDArray::toCtype()
+type *TypeSArray::toCParamtype()
 {
+    assert(0);
     return 0;
 }
 
-type *
-TypeAArray::toCtype()
+type * TypeDArray::toCtype()
 {
+    assert(0);
     return 0;
 }
 
-type *
-TypePointer::toCtype()
+type * TypeAArray::toCtype()
 {
+    assert(0);
     return 0;
 }
 
-type *
-TypeDelegate::toCtype()
+type * TypePointer::toCtype()
 {
+    assert(0);
     return 0;
 }
 
-type *
-TypeClass::toCtype()
+type * TypeDelegate::toCtype()
 {
+    assert(0);
     return 0;
 }
 
-void
-ClassDeclaration::toDebug()
+type * TypeClass::toCtype()
 {
+    assert(0);
+    return 0;
+}
+
+void ClassDeclaration::toDebug()
+{
+    assert(0);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -2546,32 +2551,32 @@
 void
 EnumDeclaration::toDebug()
 {
-
+    assert(0);
 }
 
-int
-Dsymbol::cvMember(unsigned char*)
+int Dsymbol::cvMember(unsigned char*)
 {
+    assert(0);
     return 0;
 }
-int
-EnumDeclaration::cvMember(unsigned char*)
+int EnumDeclaration::cvMember(unsigned char*)
 {
+    assert(0);
     return 0;
 }
-int
-FuncDeclaration::cvMember(unsigned char*)
+int FuncDeclaration::cvMember(unsigned char*)
 {
+    assert(0);
     return 0;
 }
-int
-VarDeclaration::cvMember(unsigned char*)
+int VarDeclaration::cvMember(unsigned char*)
 {
+    assert(0);
     return 0;
 }
-int
-TypedefDeclaration::cvMember(unsigned char*)
+int TypedefDeclaration::cvMember(unsigned char*)
 {
+    assert(0);
     return 0;
 }
 
@@ -2580,8 +2585,11 @@
 AsmStatement::AsmStatement(Loc loc, Token *tokens) :
     Statement(loc)
 {
+    assert(0);
 }
-Statement *AsmStatement::syntaxCopy() {
+Statement *AsmStatement::syntaxCopy()
+{
+    assert(0);
     return 0;
 }
 
@@ -2598,14 +2606,15 @@
 
 int AsmStatement::comeFrom()
 {
+    assert(0);
     return FALSE;
 }
 
 void
 backend_init()
 {
+    // now lazily loaded
     //LLVM_D_InitRuntime();
-    // lazily loaded
 }
 
 void
--- a/lphobos/std/stdio.d	Tue Oct 09 07:51:13 2007 +0200
+++ b/lphobos/std/stdio.d	Wed Oct 10 03:38:24 2007 +0200
@@ -12,7 +12,8 @@
     for (int i=1; i<t.length; ++i) { _writef(','); _writef(t[i]); }
     _writef(']');
   } else
-  static if(is(T==int)) printf("%i", t); else
+  static if(is(T: int)) printf("%i", t); else
+  static if(is(T: real)) printf("%f", t); else
   static assert(false, "Cannot print "~T.stringof);
 }
 
@@ -20,5 +21,6 @@
   foreach (v; t) _writef(v);
 }
 void writefln(T...)(T t) {
-  writef(t, "\n"[]);
+  writef(t, "\n");
 }
+
--- a/test/arrays4.d	Tue Oct 09 07:51:13 2007 +0200
+++ b/test/arrays4.d	Wed Oct 10 03:38:24 2007 +0200
@@ -3,5 +3,7 @@
 void main()
 {
     auto arr = new int[4];
-    {auto arrcat = arr ~ arr;}
+    auto arrcat = arr ~ arr;
+    assert(arrcat.length == arr.length * 2);
 }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/arrays5.d	Wed Oct 10 03:38:24 2007 +0200
@@ -0,0 +1,14 @@
+module arrays5;
+//import std.stdio;
+void main()
+{
+    auto arr = new float[5];
+    arr[4] = 1f;
+    //writefln(arr);
+    assert(arr[0] !<>= 0f);
+    assert(arr[1] !<>= 0f);
+    assert(arr[2] !<>= 0f);
+    assert(arr[3] !<>= 0f);
+    assert(arr[4] == 1f);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/goto1.d	Wed Oct 10 03:38:24 2007 +0200
@@ -0,0 +1,11 @@
+module goto1;
+
+void main()
+{
+    int i;
+    goto lbl;
+    i++;
+lbl:
+    assert(i == 0);
+}
+