diff --git a/dmd/statement.c b/dmd/statement.c index a21eabae..b3dc416a 100644 --- a/dmd/statement.c +++ b/dmd/statement.c @@ -3464,7 +3464,8 @@ LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement) this->statement = statement; this->tf = NULL; this->lblock = NULL; - this->isReturnLabel = 0; + this->isReturnLabel = 0; + this->llvmBB = NULL; } Statement *LabelStatement::syntaxCopy() diff --git a/dmd/statement.h b/dmd/statement.h index 92dff0ca..2b6ed9ca 100644 --- a/dmd/statement.h +++ b/dmd/statement.h @@ -51,7 +51,8 @@ enum TOK; namespace llvm { - class Value; + class Value; + class BasicBlock; } // Back end @@ -714,7 +715,9 @@ struct LabelStatement : Statement Statement *inlineScan(InlineScanState *iss); - void toIR(IRState *irs); + void toIR(IRState *irs); + + llvm::BasicBlock* llvmBB; }; struct LabelDsymbol : Dsymbol diff --git a/gen/arrays.c b/gen/arrays.c index 32c7afaa..fcbca67f 100644 --- a/gen/arrays.c +++ b/gen/arrays.c @@ -127,65 +127,16 @@ void LLVM_DtoArrayAssign(llvm::Value* dst, llvm::Value* src) 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* l, llvm::Value* r) ////////////////////////////////////////////////////////////////////////////////////////// +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 @@ llvm::Constant* LLVM_DtoConstantSlice(llvm::Constant* dim, llvm::Constant* ptr) } ////////////////////////////////////////////////////////////////////////////////////////// -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 @@ void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, const llvm::Type* t 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 @@ void LLVM_DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz) new llvm::StoreInst(sz,len,gIR->scopebb()); } - - diff --git a/gen/arrays.h b/gen/arrays.h index 43844be3..52bede98 100644 --- a/gen/arrays.h +++ b/gen/arrays.h @@ -9,11 +9,12 @@ llvm::Constant* LLVM_DtoConstantSlice(llvm::Constant* dim, llvm::Constant* ptr); 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 --git a/gen/statements.c b/gen/statements.c index f44bfb40..207eb4d9 100644 --- a/gen/statements.c +++ b/gen/statements.c @@ -695,6 +695,45 @@ void ForeachStatement::toIR(IRState* p) ////////////////////////////////////////////////////////////////////////////// +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(AsmStatement); //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 --git a/gen/toir.c b/gen/toir.c index c74bd8e5..00fb9ce3 100644 --- a/gen/toir.c +++ b/gen/toir.c @@ -1837,21 +1837,11 @@ elem* NewExp::toElem(IRState* p) 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 @@ STUB(AssocArrayLiteralExp); 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 @@ ClassDeclaration::toDebug() 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 @@ void obj_includelib(char*){} AsmStatement::AsmStatement(Loc loc, Token *tokens) : Statement(loc) { + assert(0); } -Statement *AsmStatement::syntaxCopy() { +Statement *AsmStatement::syntaxCopy() +{ + assert(0); return 0; } @@ -2598,14 +2606,15 @@ void AsmStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) int AsmStatement::comeFrom() { + assert(0); return FALSE; } void backend_init() { + // now lazily loaded //LLVM_D_InitRuntime(); - // lazily loaded } void diff --git a/lphobos/std/stdio.d b/lphobos/std/stdio.d index 77243209..bce2f958 100644 --- a/lphobos/std/stdio.d +++ b/lphobos/std/stdio.d @@ -12,7 +12,8 @@ void _writef(T)(T t) { for (int i=1; i= 0f); + assert(arr[1] !<>= 0f); + assert(arr[2] !<>= 0f); + assert(arr[3] !<>= 0f); + assert(arr[4] == 1f); +} + diff --git a/test/goto1.d b/test/goto1.d new file mode 100644 index 00000000..2d66453f --- /dev/null +++ b/test/goto1.d @@ -0,0 +1,11 @@ +module goto1; + +void main() +{ + int i; + goto lbl; + i++; +lbl: + assert(i == 0); +} +