From 64537a9478505194b3aa2c1440d20a85515d671b Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Sat, 26 Jan 2008 17:13:22 +0100 Subject: [PATCH] [svn r149] fixed: a bunch of D-style variadics problems. fixed: GotoDefaultStatement implemented. fixed: some other minor bugs. --- dmd/statement.c | 2 + dmd/statement.h | 3 ++ gen/arrays.cpp | 1 + gen/functions.cpp | 11 ++++- gen/statements.cpp | 29 ++++++++---- gen/toir.cpp | 77 ++++++++++++++++++++++--------- gen/tollvm.cpp | 16 +++++-- llvmdc.kdevelop | 2 +- llvmdc.kdevelop.filelist | 2 + tango/tango/core/Vararg.d | 27 +++++++++++ tango/tango/stdc/stdarg.d | 16 +++++++ tango/tango/text/convert/Layout.d | 8 +++- 12 files changed, 158 insertions(+), 36 deletions(-) diff --git a/dmd/statement.c b/dmd/statement.c index 5a83ef6c..4d2079ad 100644 --- a/dmd/statement.c +++ b/dmd/statement.c @@ -1955,6 +1955,8 @@ SwitchStatement::SwitchStatement(Loc loc, Expression *c, Statement *b) sdefault = NULL; cases = NULL; hasNoDefault = 0; + // LLVMDC + defaultBB = NULL; } Statement *SwitchStatement::syntaxCopy() diff --git a/dmd/statement.h b/dmd/statement.h index 1a65279e..54ead60a 100644 --- a/dmd/statement.h +++ b/dmd/statement.h @@ -416,6 +416,9 @@ struct SwitchStatement : Statement Statement *inlineScan(InlineScanState *iss); void toIR(IRState *irs); + + // LLVMDC + llvm::BasicBlock* defaultBB; }; struct CaseStatement : Statement diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 25cf67a3..f5846c88 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -446,6 +446,7 @@ void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src) ////////////////////////////////////////////////////////////////////////////////////////// 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 --git a/gen/functions.cpp b/gen/functions.cpp index 7645141d..4c3cbb6b 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -321,7 +321,12 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) 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 @@ void DtoDefineFunc(FuncDeclaration* fd) } 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 --git a/gen/statements.cpp b/gen/statements.cpp index 88048efb..12181834 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -52,13 +52,7 @@ void ReturnStatement::toIR(IRState* p) 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 @@ void ForStatement::toIR(IRState* p) 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 @@ void ForStatement::toIR(IRState* p) 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 @@ void SwitchStatement::toIR(IRState* p) llvm::BasicBlock* defbb = 0; if (!hasNoDefault) { defbb = new llvm::BasicBlock("default", p->topfunc(), oldend); + defaultBB = defbb; } // end (break point) @@ -982,6 +979,22 @@ void GotoStatement::toIR(IRState* p) ////////////////////////////////////////////////////////////////////////////// +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(Statement); //STUBST(LabelStatement); //STUBST(ThrowStatement); STUBST(GotoCaseStatement); -STUBST(GotoDefaultStatement); +//STUBST(GotoDefaultStatement); //STUBST(GotoStatement); //STUBST(UnrolledLoopStatement); //STUBST(OnScopeStatement); diff --git a/gen/toir.cpp b/gen/toir.cpp index c82c4a35..b397452f 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -153,19 +153,25 @@ DValue* VarExp::toElem(IRState* p) 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 @@ DValue* CallExp::toElem(IRState* p) 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 @@ DValue* CallExp::toElem(IRState* p) 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 @@ DValue* CallExp::toElem(IRState* p) 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 @@ DValue* CallExp::toElem(IRState* p) } } } - 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 @@ DValue* IdentityExp::toElem(IRState* p) } 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* CommaExp::toElem(IRState* p) DValue* u = e1->toElem(p); DValue* v = e2->toElem(p); + assert(e2->type == type); return v; } @@ -2991,7 +3022,9 @@ AsmStatement::AsmStatement(Loc loc, Token *tokens) : } Statement *AsmStatement::syntaxCopy() { - assert(0); + /*error("%s: inline asm is not yet implemented", loc.toChars()); + fatal(); + assert(0);*/ return 0; } @@ -3008,7 +3041,9 @@ void AsmStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) int AsmStatement::comeFrom() { - assert(0); + /*error("%s: inline asm is not yet implemented", loc.toChars()); + fatal(); + assert(0);*/ return 0; } diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 48027b24..90203682 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -346,13 +346,16 @@ llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs) 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 @@ void DtoAssign(DValue* lhs, DValue* rhs) } } 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 --git a/llvmdc.kdevelop b/llvmdc.kdevelop index 3968f8d3..6c24e19f 100644 --- a/llvmdc.kdevelop +++ b/llvmdc.kdevelop @@ -601,7 +601,7 @@ - ir + tangotests diff --git a/llvmdc.kdevelop.filelist b/llvmdc.kdevelop.filelist index 002f5b54..eaafe61f 100644 --- a/llvmdc.kdevelop.filelist +++ b/llvmdc.kdevelop.filelist @@ -765,7 +765,9 @@ tangotests/p.d 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 --git a/tango/tango/core/Vararg.d b/tango/tango/core/Vararg.d index 7d9b4d29..bb038340 100644 --- a/tango/tango/core/Vararg.d +++ b/tango/tango/core/Vararg.d @@ -15,6 +15,33 @@ version( GNU ) { 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 --git a/tango/tango/stdc/stdarg.d b/tango/tango/stdc/stdarg.d index 1be6704b..c528644b 100644 --- a/tango/tango/stdc/stdarg.d +++ b/tango/tango/stdc/stdarg.d @@ -13,6 +13,22 @@ version( GNU ) { 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 --git a/tango/tango/text/convert/Layout.d b/tango/tango/text/convert/Layout.d index 5fbf9991..9a8a72b6 100644 --- a/tango/tango/text/convert/Layout.d +++ b/tango/tango/text/convert/Layout.d @@ -44,6 +44,12 @@ version (DigitalMars) 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 @@ class Layout(T) 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) ~ "}"); } /**********************************************************************