# HG changeset patch # User lindquist # Date 1191980304 -7200 # Node ID 77cdca8c210f3250f7ae29ec3fac98e1a51e658b # Parent c0967c4b2a7473e73705847c7933b927f1619dae [svn r41] new'd dynamic arrays are now initialized with the element type's default initializer. initial label/goto support. diff -r c0967c4b2a74 -r 77cdca8c210f dmd/statement.c --- 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() diff -r c0967c4b2a74 -r 77cdca8c210f dmd/statement.h --- 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 diff -r c0967c4b2a74 -r 77cdca8c210f gen/arrays.c --- 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(l->getType()); - if (llvm::isa(ptrty->getContainedType(0))) + const llvm::Type* t = ptrty->getContainedType(0); + const llvm::ArrayType* arrty = llvm::cast_or_null(t); + if (arrty) { - const llvm::ArrayType* arrty = llvm::cast(ptrty->getContainedType(0)); - llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - - std::vector 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(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(ptrty->getContainedType(0))) + else if (llvm::isa(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 args(3,NULL); + args[0] = ptr; + args[1] = dim; + args[2] = val; + + const char* funcname = NULL; + + if (llvm::isa(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()); } - - diff -r c0967c4b2a74 -r 77cdca8c210f gen/arrays.h --- 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 diff -r c0967c4b2a74 -r 77cdca8c210f gen/statements.c --- 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); diff -r c0967c4b2a74 -r 77cdca8c210f gen/toir.c --- 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 *TypeSArray::toCParamtype() +{ + assert(0); + return 0; +} -type * -TypeDArray::toCtype() +type * TypeDArray::toCtype() { + assert(0); return 0; } -type * -TypeAArray::toCtype() +type * TypeAArray::toCtype() { + assert(0); return 0; } -type * -TypePointer::toCtype() +type * TypePointer::toCtype() { + assert(0); return 0; } -type * -TypeDelegate::toCtype() +type * TypeDelegate::toCtype() { + assert(0); return 0; } -type * -TypeClass::toCtype() +type * TypeClass::toCtype() { + assert(0); return 0; } -void -ClassDeclaration::toDebug() +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 diff -r c0967c4b2a74 -r 77cdca8c210f lphobos/std/stdio.d --- 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= 0f); + assert(arr[1] !<>= 0f); + assert(arr[2] !<>= 0f); + assert(arr[3] !<>= 0f); + assert(arr[4] == 1f); +} + diff -r c0967c4b2a74 -r 77cdca8c210f test/goto1.d --- /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); +} +