# HG changeset patch # User lindquist # Date 1201364002 -3600 # Node ID a27941d00351ec0738c7a139e8933d5fff7d3e77 # Parent 336ec4f4bbb3e032db2e1306e109fe5c97936fd7 [svn r149] fixed: a bunch of D-style variadics problems. fixed: GotoDefaultStatement implemented. fixed: some other minor bugs. diff -r 336ec4f4bbb3 -r a27941d00351 dmd/statement.c --- a/dmd/statement.c Fri Jan 25 01:42:36 2008 +0100 +++ b/dmd/statement.c Sat Jan 26 17:13:22 2008 +0100 @@ -1955,6 +1955,8 @@ sdefault = NULL; cases = NULL; hasNoDefault = 0; + // LLVMDC + defaultBB = NULL; } Statement *SwitchStatement::syntaxCopy() diff -r 336ec4f4bbb3 -r a27941d00351 dmd/statement.h --- a/dmd/statement.h Fri Jan 25 01:42:36 2008 +0100 +++ b/dmd/statement.h Sat Jan 26 17:13:22 2008 +0100 @@ -416,6 +416,9 @@ Statement *inlineScan(InlineScanState *iss); void toIR(IRState *irs); + + // LLVMDC + llvm::BasicBlock* defaultBB; }; struct CaseStatement : Statement diff -r 336ec4f4bbb3 -r a27941d00351 gen/arrays.cpp --- a/gen/arrays.cpp Fri Jan 25 01:42:36 2008 +0100 +++ b/gen/arrays.cpp Sat Jan 26 17:13:22 2008 +0100 @@ -446,6 +446,7 @@ ////////////////////////////////////////////////////////////////////////////////////////// void DtoStaticArrayCopy(llvm::Value* dst, llvm::Value* src) { + Logger::cout() << "static array copy: " << *dst << " from " << *src << '\n'; assert(dst->getType() == src->getType()); size_t arrsz = getABITypeSize(dst->getType()->getContainedType(0)); llvm::Value* n = llvm::ConstantInt::get(DtoSize_t(), arrsz, false); diff -r 336ec4f4bbb3 -r a27941d00351 gen/functions.cpp --- a/gen/functions.cpp Fri Jan 25 01:42:36 2008 +0100 +++ b/gen/functions.cpp Sat Jan 26 17:13:22 2008 +0100 @@ -321,7 +321,12 @@ bool declareOnly = false; bool templInst = fdecl->parent && DtoIsTemplateInstance(fdecl->parent); if (!templInst && fdecl->getModule() != gIR->dmodule) + { + Logger::println("not template instance, and not in this module. declare only!"); + Logger::println("current module: %s", gIR->dmodule->ident->toChars()); + Logger::println("func module: %s", fdecl->getModule()->ident->toChars()); declareOnly = true; + } else if (fdecl->llvmInternal == LLVMva_start) declareOnly = true; @@ -548,11 +553,15 @@ } for (std::set::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) { VarDeclaration* vd = *i; + Logger::println("referenced nested variable %s", vd->toChars()); if (!vd->irLocal) vd->irLocal = new IrLocal(vd); vd->irLocal->nestedIndex = j++; if (vd->isParameter()) { - + if (!vd->irLocal->value) { + assert(vd == fd->vthis); + vd->irLocal->value = fd->irFunc->thisVar; + } assert(vd->irLocal->value); nestTypes.push_back(vd->irLocal->value->getType()); } diff -r 336ec4f4bbb3 -r a27941d00351 gen/statements.cpp --- a/gen/statements.cpp Fri Jan 25 01:42:36 2008 +0100 +++ b/gen/statements.cpp Sat Jan 26 17:13:22 2008 +0100 @@ -52,13 +52,7 @@ if (exp) { - Logger::println("return type is: %s", exp->type->toChars()); - - Type* exptype = DtoDType(exp->type); - TY expty = exptype->ty; if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) { - assert(DtoIsPassedByRef(exptype)); - IrFunction* f = p->func(); assert(f->type->llvmRetInPtr); assert(f->decl->irFunc->retArg); @@ -320,6 +314,7 @@ init->toIR(p); // move into the for condition block, ie. start the loop + assert(!gIR->scopereturned()); new llvm::BranchInst(forbb, gIR->scopebb()); p->loopbbs.push_back(IRScope(forincbb,endbb)); @@ -333,7 +328,8 @@ delete cond_e; // conditional branch - llvm::Value* ifbreak = new llvm::BranchInst(forbodybb, endbb, cond_val, forbb); + assert(!gIR->scopereturned()); + new llvm::BranchInst(forbodybb, endbb, cond_val, gIR->scopebb()); // rewrite scope gIR->scope() = IRScope(forbodybb,forincbb); @@ -674,6 +670,7 @@ llvm::BasicBlock* defbb = 0; if (!hasNoDefault) { defbb = new llvm::BasicBlock("default", p->topfunc(), oldend); + defaultBB = defbb; } // end (break point) @@ -982,6 +979,22 @@ ////////////////////////////////////////////////////////////////////////////// +void GotoDefaultStatement::toIR(IRState* p) +{ + Logger::println("GotoDefaultStatement::toIR(): %s", loc.toChars()); + LOG_SCOPE; + + llvm::BasicBlock* oldend = gIR->scopeend(); + llvm::BasicBlock* bb = new llvm::BasicBlock("aftergotodefault", p->topfunc(), oldend); + + assert(!p->scopereturned()); + assert(sw->defaultBB); + new llvm::BranchInst(sw->defaultBB, p->scopebb()); + p->scope() = IRScope(bb,oldend); +} + +////////////////////////////////////////////////////////////////////////////// + void WithStatement::toIR(IRState* p) { Logger::println("WithStatement::toIR(): %s", loc.toChars()); @@ -1085,7 +1098,7 @@ //STUBST(LabelStatement); //STUBST(ThrowStatement); STUBST(GotoCaseStatement); -STUBST(GotoDefaultStatement); +//STUBST(GotoDefaultStatement); //STUBST(GotoStatement); //STUBST(UnrolledLoopStatement); //STUBST(OnScopeStatement); diff -r 336ec4f4bbb3 -r a27941d00351 gen/toir.cpp --- a/gen/toir.cpp Fri Jan 25 01:42:36 2008 +0100 +++ b/gen/toir.cpp Sat Jan 26 17:13:22 2008 +0100 @@ -153,19 +153,25 @@ if (vd->ident == Id::_arguments) { Logger::println("Id::_arguments"); - if (!vd->getIrValue()) + /*if (!vd->getIrValue()) vd->getIrValue() = p->func()->decl->irFunc->_arguments; assert(vd->getIrValue()); - return new DVarValue(vd, vd->getIrValue(), true); + return new DVarValue(vd, vd->getIrValue(), true);*/ + llvm::Value* v = p->func()->decl->irFunc->_arguments; + assert(v); + return new DVarValue(vd, v, true); } // _argptr else if (vd->ident == Id::_argptr) { Logger::println("Id::_argptr"); - if (!vd->getIrValue()) + /*if (!vd->getIrValue()) vd->getIrValue() = p->func()->decl->irFunc->_argptr; assert(vd->getIrValue()); - return new DVarValue(vd, vd->getIrValue(), true); + return new DVarValue(vd, vd->getIrValue(), true);*/ + llvm::Value* v = p->func()->decl->irFunc->_argptr; + assert(v); + return new DVarValue(vd, v, true); } // _dollar else if (vd->ident == Id::dollar) @@ -1048,9 +1054,14 @@ std::vector vtypes; std::vector vtypeinfos; + // number of non variadic args + int begin = tf->parameters->dim; + Logger::println("num non vararg params = %d", begin); + // build struct with argument types - for (int i=0; idim; i++) + for (int i=begin; idim; i++) { + Argument* argu = Argument::getNth(tf->parameters, i); Expression* argexp = (Expression*)arguments->data[i]; vtypes.push_back(DtoType(argexp->type)); } @@ -1059,30 +1070,30 @@ llvm::Value* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint()); // store arguments in the struct - for (int i=0; idim; i++) + for (int i=begin,k=0; idim; i++,k++) { Expression* argexp = (Expression*)arguments->data[i]; if (global.params.llvmAnnotate) DtoAnnotation(argexp->toChars()); - DtoVariadicArgument(argexp, DtoGEPi(mem,0,i,"tmp")); + DtoVariadicArgument(argexp, DtoGEPi(mem,0,k,"tmp")); } // build type info array assert(Type::typeinfo->irStruct->constInit); - const llvm::Type* typeinfotype = getPtrToType(Type::typeinfo->irStruct->constInit->getType()); - Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n'; + const llvm::Type* typeinfotype = DtoType(Type::typeinfo->type); const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements()); llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint()); - for (int i=0; idim; i++) + Logger::cout() << "_arguments storage: " << *typeinfomem << '\n'; + for (int i=begin,k=0; idim; i++,k++) { Expression* argexp = (Expression*)arguments->data[i]; TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration(); DtoForceDeclareDsymbol(tidecl); assert(tidecl->getIrValue()); vtypeinfos.push_back(tidecl->getIrValue()); - llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[i], typeinfotype, "tmp"); - p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,i,"tmp")); + llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[k], typeinfotype, "tmp"); + p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,k,"tmp")); } // put data in d-array @@ -1096,7 +1107,18 @@ j++; llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp"); j++; - llargs.resize(nimplicit+2); + + // pass non variadic args + for (int i=0; iparameters, i); + DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); + llargs[j] = argval->getRVal(); + j++; + } + + // make sure arg vector has the right size + llargs.resize(nimplicit+begin+2); } // normal function else { @@ -1122,20 +1144,23 @@ } } } - Logger::println("%d params passed", n); - for (int i=0; igetReturnType() != llvm::Type::VoidTy) varname = "tmp"; - //Logger::cout() << "Calling: " << *funcval << '\n'; + Logger::cout() << "Calling: " << *funcval << '\n'; // call the function llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb()); @@ -2263,6 +2288,11 @@ } eval = DtoDynArrayIs(op,l,r); } + else if (t1->isfloating()) + { + llvm::FCmpInst::Predicate pred = (op == TOKidentity) ? llvm::FCmpInst::FCMP_OEQ : llvm::FCmpInst::FCMP_ONE; + eval = new llvm::FCmpInst(pred, l, r, "tmp", p->scopebb()); + } else { llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; if (t1->ty == Tpointer && v->isNull() && l->getType() != r->getType()) { @@ -2283,6 +2313,7 @@ DValue* u = e1->toElem(p); DValue* v = e2->toElem(p); + assert(e2->type == type); return v; } @@ -2991,7 +3022,9 @@ } Statement *AsmStatement::syntaxCopy() { - assert(0); + /*error("%s: inline asm is not yet implemented", loc.toChars()); + fatal(); + assert(0);*/ return 0; } @@ -3008,7 +3041,9 @@ int AsmStatement::comeFrom() { - assert(0); + /*error("%s: inline asm is not yet implemented", loc.toChars()); + fatal(); + assert(0);*/ return 0; } diff -r 336ec4f4bbb3 -r a27941d00351 gen/tollvm.cpp --- a/gen/tollvm.cpp Fri Jan 25 01:42:36 2008 +0100 +++ b/gen/tollvm.cpp Sat Jan 26 17:13:22 2008 +0100 @@ -346,13 +346,16 @@ llvm::GlobalValue::LinkageTypes DtoLinkage(PROT prot, uint stc) { + // turns out we can't really make anything internal with the way D works :( + // the things we can need much more info than this can extract. + // TODO : remove this useless function switch(prot) { case PROTprivate: - if (stc & STCextern) + //if (stc & STCextern) return llvm::GlobalValue::ExternalLinkage; - else - return llvm::GlobalValue::InternalLinkage; + //else + // return llvm::GlobalValue::InternalLinkage; case PROTpublic: case PROTpackage: @@ -902,7 +905,12 @@ } } else if (t->ty == Tsarray) { - DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal()); + if (DtoType(lhs->getType()) == DtoType(rhs->getType())) { + DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal()); + } + else { + DtoArrayInit(lhs->getLVal(), rhs->getRVal()); + } } else if (t->ty == Tdelegate) { if (rhs->isNull()) diff -r 336ec4f4bbb3 -r a27941d00351 llvmdc.kdevelop --- a/llvmdc.kdevelop Fri Jan 25 01:42:36 2008 +0100 +++ b/llvmdc.kdevelop Sat Jan 26 17:13:22 2008 +0100 @@ -601,7 +601,7 @@ - ir + tangotests diff -r 336ec4f4bbb3 -r a27941d00351 llvmdc.kdevelop.filelist --- a/llvmdc.kdevelop.filelist Fri Jan 25 01:42:36 2008 +0100 +++ b/llvmdc.kdevelop.filelist Sat Jan 26 17:13:22 2008 +0100 @@ -765,7 +765,9 @@ tangotests/q.d tangotests/r.d tangotests/s.d +tangotests/stdout1.d tangotests/t.d +tangotests/v.d test test/a.d test/aa1.d diff -r 336ec4f4bbb3 -r a27941d00351 tango/tango/core/Vararg.d --- a/tango/tango/core/Vararg.d Fri Jan 25 01:42:36 2008 +0100 +++ b/tango/tango/core/Vararg.d Sat Jan 26 17:13:22 2008 +0100 @@ -15,6 +15,33 @@ { public import std.stdarg; } +else version( LLVMDC ) +{ + /** + * The base vararg list type. + */ + alias void* va_list; + + /** + * This function returns the next argument in the sequence referenced by + * the supplied argument pointer. The argument pointer will be adjusted + * to point to the next arggument in the sequence. + * + * Params: + * vp = The argument pointer. + * + * Returns: + * The next argument in the sequence. The result is undefined if vp + * does not point to a valid argument. + */ + T va_arg(T)(ref va_list vp) + { + size_t size = T.sizeof > size_t.sizeof ? size_t.sizeof : T.sizeof; + va_list vptmp = cast(va_list)((cast(size_t)vp + size - 1) & ~(size - 1)); + vp = vptmp + T.sizeof; + return *cast(T*)vptmp; + } +} else { /** diff -r 336ec4f4bbb3 -r a27941d00351 tango/tango/stdc/stdarg.d --- a/tango/tango/stdc/stdarg.d Fri Jan 25 01:42:36 2008 +0100 +++ b/tango/tango/stdc/stdarg.d Sat Jan 26 17:13:22 2008 +0100 @@ -13,6 +13,22 @@ { public import std.c.stdarg; } +else version( LLVMDC ) +{ + alias void* va_list; + + pragma(LLVM_internal, "va_start") + void va_start(T)(va_list ap, ref T); + + pragma(LLVM_internal, "va_arg") + T va_arg(T)(va_list ap); + + pragma(LLVM_internal, "va_intrinsic", "llvm.va_end") + void va_end(va_list args); + + pragma(LLVM_internal, "va_intrinsic", "llvm.va_copy") + void va_copy(va_list dst, va_list src); +} else { alias void* va_list; diff -r 336ec4f4bbb3 -r a27941d00351 tango/tango/text/convert/Layout.d --- a/tango/tango/text/convert/Layout.d Fri Jan 25 01:42:36 2008 +0100 +++ b/tango/tango/text/convert/Layout.d Sat Jan 26 17:13:22 2008 +0100 @@ -44,6 +44,12 @@ alias void* Arg; alias void* ArgList; } +else version(LLVMDC) + { + private import tango.core.Vararg; + alias void* Arg; + alias va_list ArgList; + } else version (X86_64) { @@ -617,7 +623,7 @@ protected T[] unknown (T[] result, T[] format, TypeInfo type, Arg p) { - return "{unhandled argument type: " ~ fromUtf8 (type.toString, result) ~ "}"; + return cast(T[])("{unhandled argument type: " ~ fromUtf8 (type.toString, result) ~ "}"); } /**********************************************************************