From a52f0330d091a61e63aac3afae150ac15764ea93 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Wed, 22 Oct 2008 21:50:08 +0200 Subject: [PATCH] Implemented first class delegates. closes #101 --- dmd/statement.c | 35 ++++++++++++++++++++++++++------ gen/functions.cpp | 48 ++++++++++++++++++++++---------------------- gen/llvmhelpers.cpp | 49 +++++++++++++++++++++++++++++---------------- gen/runtime.cpp | 44 +++++++++++----------------------------- gen/tocall.cpp | 27 +++++++++++++++++++------ gen/toir.cpp | 31 ++++++++++++---------------- gen/tollvm.cpp | 40 ++++++++++++++++++------------------ gen/toobj.cpp | 2 +- 8 files changed, 151 insertions(+), 125 deletions(-) diff --git a/dmd/statement.c b/dmd/statement.c index 37a6942f..c48d7b70 100644 --- a/dmd/statement.c +++ b/dmd/statement.c @@ -1517,6 +1517,9 @@ Statement *ForeachStatement::semantic(Scope *sc) Expression *flde; Identifier *id; Type *tret; + TypeDelegate* dgty; + TypeDelegate* dgty2; + TypeDelegate* fldeTy; tret = func->type->nextOf(); @@ -1600,6 +1603,7 @@ Statement *ForeachStatement::semantic(Scope *sc) */ //LDC: Build arguments. static FuncDeclaration *aaApply2_fd = NULL; + static TypeDelegate* aaApply2_dg; if(!aaApply2_fd) { Arguments* args = new Arguments; args->push(new Argument(STCin, Type::tvoid->pointerTo(), NULL, NULL)); @@ -1607,25 +1611,28 @@ Statement *ForeachStatement::semantic(Scope *sc) Arguments* dgargs = new Arguments; dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL)); dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL)); - TypeDelegate* dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); - args->push(new Argument(STCin, dgty, NULL, NULL)); + aaApply2_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); + args->push(new Argument(STCin, aaApply2_dg, NULL, NULL)); aaApply2_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply2"); } static FuncDeclaration *aaApply_fd = NULL; + static TypeDelegate* aaApply_dg; if(!aaApply_fd) { Arguments* args = new Arguments; args->push(new Argument(STCin, Type::tvoid->pointerTo(), NULL, NULL)); args->push(new Argument(STCin, Type::tsize_t, NULL, NULL)); Arguments* dgargs = new Arguments; dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL)); - TypeDelegate* dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); - args->push(new Argument(STCin, dgty, NULL, NULL)); + aaApply_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); + args->push(new Argument(STCin, aaApply_dg, NULL, NULL)); aaApply_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply"); } if (dim == 2) { fdapply = aaApply2_fd; + fldeTy = aaApply2_dg; } else { fdapply = aaApply_fd; + fldeTy = aaApply_dg; } ec = new VarExp(0, fdapply); Expressions *exps = new Expressions(); @@ -1633,7 +1640,15 @@ Statement *ForeachStatement::semantic(Scope *sc) size_t keysize = taa->key->size(); keysize = (keysize + 3) & ~3; exps->push(new IntegerExp(0, keysize, Type::tsize_t)); + + // LDC paint delegate argument to the type runtime expects + if (!fldeTy->equals(flde->type)) + { + flde = new CastExp(loc, flde, flde->type); + flde->type = fldeTy; + } exps->push(flde); + e = new CallExp(loc, ec, exps); e->type = Type::tindex; // don't run semantic() on e } @@ -1674,13 +1689,13 @@ Statement *ForeachStatement::semantic(Scope *sc) Arguments* dgargs = new Arguments; dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL)); dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL)); - TypeDelegate* dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); + dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); args->push(new Argument(STCin, dgty, NULL, NULL)); fdapply = FuncDeclaration::genCfunc(args, Type::tindex, fdname); } else { Arguments* dgargs = new Arguments; dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL)); - TypeDelegate* dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); + dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); args->push(new Argument(STCin, dgty, NULL, NULL)); fdapply = FuncDeclaration::genCfunc(args, Type::tindex, fdname); } @@ -1690,7 +1705,15 @@ Statement *ForeachStatement::semantic(Scope *sc) if (tab->ty == Tsarray) aggr = aggr->castTo(sc, tn->arrayOf()); exps->push(aggr); + + // LDC paint delegate argument to the type runtime expects + if (!dgty->equals(flde->type)) + { + flde = new CastExp(loc, flde, flde->type); + flde->type = dgty; + } exps->push(flde); + e = new CallExp(loc, ec, exps); e->type = Type::tindex; // don't run semantic() on e } diff --git a/gen/functions.cpp b/gen/functions.cpp index 077f07ee..4c201e8c 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -123,15 +123,24 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, co const LLType* at = DtoType(argT); + // handle lazy args + if (arg->storageClass & STClazy) + { + Logger::println("lazy param"); + TypeFunction *ltf = new TypeFunction(NULL, arg->type, 0, LINKd); + TypeDelegate *ltd = new TypeDelegate(ltf); + at = DtoType(ltd); + paramvec.push_back(at); + } // opaque types need special handling - if (llvm::isa(at)) { + else if (llvm::isa(at)) { Logger::println("opaque param"); assert(argT->ty == Tstruct || argT->ty == Tclass); paramvec.push_back(getPtrToType(at)); } - // structs and delegates are passed as a reference, but by value - else if (argT->ty == Tstruct || argT->ty == Tdelegate) { - Logger::println("struct/sarray param"); + // structs are passed as a reference, but by value + else if (argT->ty == Tstruct) { + Logger::println("struct param"); if (!refOrOut) arg->llvmAttrs |= llvm::Attribute::ByVal; paramvec.push_back(getPtrToType(at)); @@ -156,23 +165,6 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, co arg->llvmAttrs |= ea; paramvec.push_back(at); } - - // handle lazy args - if (arg->storageClass & STClazy) - { - if (Logger::enabled()) - Logger::cout() << "for lazy got: " << *paramvec.back() << '\n'; - - TypeFunction *ltf = new TypeFunction(NULL, arg->type, 0, LINKd); - TypeDelegate *ltd = new TypeDelegate(ltf); - at = getPtrToType(DtoType(ltd)); - - if (Logger::enabled()) - Logger::cout() << "lazy updated to: " << *at << '\n'; - - paramvec.back() = at; - // lazy doesn't need byval as the delegate is not visible to the user - } } // construct function type @@ -652,13 +644,14 @@ void DtoDefineFunc(FuncDeclaration* fd) IrLocal* irloc = vd->ir.irLocal; assert(irloc); - bool refoutlazy = vd->storage_class & (STCref | STCout | STClazy); + bool refout = vd->storage_class & (STCref | STCout); + bool lazy = vd->storage_class & STClazy; - if (refoutlazy) + if (refout) { continue; } - else if (DtoIsPassedByRef(vd->type)) + else if (!lazy && DtoIsPassedByRef(vd->type)) { LLValue* vdirval = irloc->value; if (global.params.symdebug && !(isaArgument(vdirval) && !isaArgument(vdirval)->hasByValAttr())) @@ -875,6 +868,13 @@ DValue* DtoArgument(Argument* fnarg, Expression* argexp) else arg = new DImValue(argexp->type, arg->getRVal()); } + // lazy arg + else if (fnarg && (fnarg->storageClass & STClazy)) + { + assert(argexp->type->toBasetype()->ty == Tdelegate); + assert(!arg->isLVal()); + return arg; + } // byval arg, but expr has no storage yet else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isNull())) { diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index a818ac41..f3339166 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -452,15 +452,11 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs) } } else if (t->ty == Tdelegate) { - if (rhs->isNull()) - DtoAggrZeroInit(lhs->getLVal()); - else { - LLValue* l = lhs->getLVal(); - LLValue* r = rhs->getRVal(); - if (Logger::enabled()) - Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; - DtoAggrCopy(l, r); - } + LLValue* l = lhs->getLVal(); + LLValue* r = rhs->getRVal(); + if (Logger::enabled()) + Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; + DtoStore(r, l); } else if (t->ty == Tclass) { assert(t2->ty == Tclass); @@ -694,21 +690,15 @@ DValue* DtoCastFloat(Loc& loc, DValue* val, Type* to) DValue* DtoCastDelegate(Loc& loc, DValue* val, Type* to) { - LLValue* res = 0; - to = to->toBasetype(); - - if (to->ty == Tdelegate) + if (to->toBasetype()->ty == Tdelegate) { - const LLType* toll = getPtrToType(DtoType(to)); - res = DtoBitCast(val->getRVal(), toll); + return DtoPaintType(loc, val, to); } else { error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars()); fatal(); } - - return new DImValue(to, res); } DValue* DtoCast(Loc& loc, DValue* val, Type* to) @@ -773,6 +763,31 @@ DValue* DtoPaintType(Loc& loc, DValue* val, Type* to) return new DImValue(to, DtoAggrPair(len, ptr, "tmp")); } } + else if (from->ty == Tdelegate) + { + Type* dgty = to->toBasetype(); + assert(dgty->ty == Tdelegate); + if (val->isLVal()) + { + LLValue* ptr = val->getLVal(); + assert(isaPointer(ptr)); + ptr = DtoBitCast(ptr, getPtrToType(DtoType(dgty))); + if (Logger::enabled()) + Logger::cout() << "dg ptr: " << *ptr << '\n'; + return new DVarValue(to, ptr); + } + else + { + LLValue* dg = val->getRVal(); + LLValue* context = gIR->ir->CreateExtractValue(dg, 0, ".context"); + LLValue* funcptr = gIR->ir->CreateExtractValue(dg, 1, ".funcptr"); + funcptr = DtoBitCast(funcptr, DtoType(dgty)->getContainedType(1)); + LLValue* aggr = DtoAggrPair(context, funcptr, "tmp"); + if (Logger::enabled()) + Logger::cout() << "dg: " << *aggr << '\n'; + return new DImValue(to, aggr); + } + } else if (from->ty == Tpointer || from->ty == Tclass || from->ty == Taarray) { Type* b = to->toBasetype(); diff --git a/gen/runtime.cpp b/gen/runtime.cpp index 2f0e493e..a32e7ff9 100644 --- a/gen/runtime.cpp +++ b/gen/runtime.cpp @@ -119,11 +119,7 @@ static const LLType* rt_dg1() types.push_back(rt_ptr(LLType::Int8Ty)); types.push_back(rt_ptr(LLType::Int8Ty)); const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::Int32Ty, types, false); - - std::vector t; - t.push_back(rt_ptr(LLType::Int8Ty)); - t.push_back(rt_ptr(fty)); - return rt_ptr(llvm::StructType::get(t)); + return llvm::StructType::get(rt_ptr(LLType::Int8Ty), rt_ptr(fty), 0); } static const LLType* rt_dg2() @@ -133,11 +129,7 @@ static const LLType* rt_dg2() types.push_back(rt_ptr(LLType::Int8Ty)); types.push_back(rt_ptr(LLType::Int8Ty)); const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::Int32Ty, types, false); - - std::vector t; - t.push_back(rt_ptr(LLType::Int8Ty)); - t.push_back(rt_ptr(fty)); - return rt_ptr(llvm::StructType::get(t)); + return llvm::StructType::get(rt_ptr(LLType::Int8Ty), rt_ptr(fty), 0); } static void LLVM_D_BuildRuntimeModule() @@ -365,10 +357,8 @@ static void LLVM_D_BuildRuntimeModule() types.push_back(TY); \ types.push_back(rt_dg1()); \ const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ - llvm::AttrListPtr palist; \ - palist = palist.addAttr(2, llvm::Attribute::ByVal); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setAttributes(palist); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setAttributes(palist); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ } STR_APPLY1(stringTy, "_aApplycw1", "_aApplycd1") STR_APPLY1(wstringTy, "_aApplywc1", "_aApplywd1") @@ -384,10 +374,8 @@ static void LLVM_D_BuildRuntimeModule() types.push_back(TY); \ types.push_back(rt_dg2()); \ const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ - llvm::AttrListPtr palist; \ - palist = palist.addAttr(2, llvm::Attribute::ByVal); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setAttributes(palist); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setAttributes(palist); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ } STR_APPLY2(stringTy, "_aApplycw2", "_aApplycd2") STR_APPLY2(wstringTy, "_aApplywc2", "_aApplywd2") @@ -402,10 +390,8 @@ static void LLVM_D_BuildRuntimeModule() types.push_back(TY); \ types.push_back(rt_dg1()); \ const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ - llvm::AttrListPtr palist; \ - palist = palist.addAttr(2, llvm::Attribute::ByVal); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setAttributes(palist); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setAttributes(palist); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ } STR_APPLY_R1(stringTy, "_aApplyRcw1", "_aApplyRcd1") STR_APPLY_R1(wstringTy, "_aApplyRwc1", "_aApplyRwd1") @@ -420,10 +406,8 @@ static void LLVM_D_BuildRuntimeModule() types.push_back(TY); \ types.push_back(rt_dg2()); \ const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ - llvm::AttrListPtr palist; \ - palist = palist.addAttr(2, llvm::Attribute::ByVal); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setAttributes(palist); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setAttributes(palist); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ } STR_APPLY_R2(stringTy, "_aApplyRcw2", "_aApplyRcd2") STR_APPLY_R2(wstringTy, "_aApplyRwc2", "_aApplyRwd2") @@ -662,9 +646,7 @@ static void LLVM_D_BuildRuntimeModule() types.push_back(sizeTy); types.push_back(rt_dg1()); const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::AttrListPtr palist; - palist = palist.addAttr(3, llvm::Attribute::ByVal); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setAttributes(palist); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } // int _aaApply2(AA aa, size_t keysize, dg2_t dg) @@ -675,9 +657,7 @@ static void LLVM_D_BuildRuntimeModule() types.push_back(sizeTy); types.push_back(rt_dg2()); const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::AttrListPtr palist; - palist = palist.addAttr(3, llvm::Attribute::ByVal); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setAttributes(palist); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } ///////////////////////////////////////////////////////////////////////////////////// diff --git a/gen/tocall.cpp b/gen/tocall.cpp index a1fb34d6..3dfef1bc 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -75,11 +75,18 @@ LLValue* DtoCallableValue(DValue* fn) } else if (type->ty == Tdelegate) { - LLValue* dg = fn->getRVal(); - if (Logger::enabled()) - Logger::cout() << "delegate: " << *dg << '\n'; - LLValue* funcptr = DtoGEPi(dg, 0, 1); - return DtoLoad(funcptr); + if (fn->isLVal()) + { + LLValue* dg = fn->getLVal(); + LLValue* funcptr = DtoGEPi(dg, 0, 1); + return DtoLoad(funcptr); + } + else + { + LLValue* dg = fn->getRVal(); + assert(isaStruct(dg)); + return gIR->ir->CreateExtractValue(dg, 1, ".funcptr"); + } } else { @@ -266,7 +273,15 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* // ... or a delegate context arg else if (delegatecall) { - LLValue* ctxarg = DtoLoad(DtoGEPi(fnval->getRVal(), 0,0)); + LLValue* ctxarg; + if (fnval->isLVal()) + { + ctxarg = DtoLoad(DtoGEPi(fnval->getLVal(), 0,0)); + } + else + { + ctxarg = gIR->ir->CreateExtractValue(fnval->getRVal(), 0, ".ptr"); + } assert(ctxarg->getType() == argiter->get()); ++argiter; args.push_back(ctxarg); diff --git a/gen/toir.cpp b/gen/toir.cpp index 791c8f99..1b3b2e3b 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -110,11 +110,17 @@ DValue* VarExp::toElem(IRState* p) // function parameter else if (vd->isParameter()) { Logger::println("function param"); + Logger::println("type: %s", vd->type->toChars()); FuncDeclaration* fd = vd->toParent2()->isFuncDeclaration(); if (fd && fd != p->func()->decl) { Logger::println("nested parameter"); return DtoNestedVariable(loc, type, vd); } + else if (vd->storage_class & STClazy) { + Logger::println("lazy parameter"); + assert(type->ty == Tdelegate); + return new DVarValue(type, vd->ir.getIrValue()); + } else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa(vd->ir.getIrValue())) { return new DVarValue(type, vd, vd->ir.getIrValue()); } @@ -1833,7 +1839,8 @@ DValue* DelegateExp::toElem(IRState* p) const LLPointerType* int8ptrty = getPtrToType(LLType::Int8Ty); - LLValue* lval = DtoAlloca(DtoType(type), "tmpdelegate"); + assert(type->toBasetype()->ty == Tdelegate); + const LLType* dgty = DtoType(type); DValue* u = e1->toElem(p); LLValue* uval; @@ -1859,11 +1866,7 @@ DValue* DelegateExp::toElem(IRState* p) if (Logger::enabled()) Logger::cout() << "context = " << *uval << '\n'; - LLValue* context = DtoGEPi(lval,0,0); LLValue* castcontext = DtoBitCast(uval, int8ptrty); - DtoStore(castcontext, context); - - LLValue* fptr = DtoGEPi(lval,0,1); Logger::println("func: '%s'", func->toPrettyChars()); @@ -1880,10 +1883,9 @@ DValue* DelegateExp::toElem(IRState* p) castfptr = func->ir.irFunc->func; } - castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0)); - DtoStore(castfptr, fptr); + castfptr = DtoBitCast(castfptr, dgty->getContainedType(1)); - return new DImValue(type, lval); + return new DImValue(type, DtoAggrPair(castcontext, castfptr, ".dg")); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -2098,12 +2100,9 @@ DValue* FuncExp::toElem(IRState* p) DtoForceDefineDsymbol(fd); assert(fd->ir.irFunc->func); - LLValue *lval, *fptr; if(fd->tok == TOKdelegate) { const LLType* dgty = DtoType(type); - lval = DtoAlloca(dgty,"dgstorage"); - LLValue* context = DtoGEPi(lval,0,0); LLValue* cval; IrFunction* irfn = p->func(); if (irfn->nestedVar) @@ -2112,15 +2111,11 @@ DValue* FuncExp::toElem(IRState* p) cval = irfn->nestArg; else cval = getNullPtr(getVoidPtrType()); - cval = DtoBitCast(cval, context->getType()->getContainedType(0)); - DtoStore(cval, context); + cval = DtoBitCast(cval, dgty->getContainedType(0)); - fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb()); + LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, dgty->getContainedType(1)); - LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0)); - DtoStore(castfptr, fptr); - - return new DVarValue(type, lval); + return new DImValue(type, DtoAggrPair(cval, castfptr, ".func")); } else if(fd->tok == TOKfunction) { return new DImValue(type, fd->ir.irFunc->func); diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index d5a4b702..7b6a5bd0 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -25,14 +25,14 @@ bool DtoIsPassedByRef(Type* type) { Type* typ = type->toBasetype(); TY t = typ->ty; - return (t == Tstruct || t == Tdelegate || t == Tsarray); + return (t == Tstruct || t == Tsarray); } bool DtoIsReturnedInArg(Type* type) { Type* typ = type->toBasetype(); TY t = typ->ty; - return (t == Tstruct || t == Tdelegate || t == Tsarray); + return (t == Tstruct || t == Tsarray); } unsigned DtoShouldExtend(Type* type) @@ -221,6 +221,7 @@ const LLType* DtoTypeNotVoid(Type* t) const LLStructType* DtoDelegateType(Type* t) { + assert(t->ty == Tdelegate); const LLType* i8ptr = getVoidPtrType(); const LLType* func = DtoFunctionType(t->next, NULL, i8ptr); const LLType* funcptr = getPtrToType(func); @@ -235,25 +236,22 @@ LLValue* DtoDelegateEquals(TOK op, LLValue* lhs, LLValue* rhs) llvm::Value *b1, *b2; if (rhs == NULL) { - LLValue* l = DtoLoad(DtoGEPi(lhs,0,0)); - LLValue* r = llvm::Constant::getNullValue(l->getType()); - b1 = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ,l,r,"tmp"); - l = DtoLoad(DtoGEPi(lhs,0,1)); - r = llvm::Constant::getNullValue(l->getType()); - b2 = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ,l,r,"tmp"); - } - else - { - LLValue* l = DtoLoad(DtoGEPi(lhs,0,0)); - LLValue* r = DtoLoad(DtoGEPi(rhs,0,0)); - b1 = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ,l,r,"tmp"); - l = DtoLoad(DtoGEPi(lhs,0,1)); - r = DtoLoad(DtoGEPi(rhs,0,1)); - b2 = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ,l,r,"tmp"); + rhs = LLConstant::getNullValue(lhs->getType()); } + + LLValue* l = gIR->ir->CreateExtractValue(lhs, 0); + LLValue* r = gIR->ir->CreateExtractValue(rhs, 0); + b1 = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ,l,r,"tmp"); + + l = gIR->ir->CreateExtractValue(lhs, 1); + r = gIR->ir->CreateExtractValue(rhs, 1); + b2 = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ,l,r,"tmp"); + LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp"); + if (op == TOKnotequal || op == TOKnotidentity) return gIR->ir->CreateNot(b,"tmp"); + return b; } @@ -557,8 +555,8 @@ LLConstant* DtoConstStringPtr(const char* str, const char* section) LLValue* DtoLoad(LLValue* src, const char* name) { - if (Logger::enabled()) - Logger::cout() << "loading " << *src << '\n'; +// if (Logger::enabled()) +// Logger::cout() << "loading " << *src << '\n'; LLValue* ld = gIR->ir->CreateLoad(src, name ? name : "tmp"); //ld->setVolatile(gIR->func()->inVolatile); return ld; @@ -566,8 +564,8 @@ LLValue* DtoLoad(LLValue* src, const char* name) void DtoStore(LLValue* src, LLValue* dst) { - if (Logger::enabled()) - Logger::cout() << "storing " << *src << " into " << *dst << '\n'; +// if (Logger::enabled()) +// Logger::cout() << "storing " << *src << " into " << *dst << '\n'; LLValue* st = gIR->ir->CreateStore(src,dst); //st->setVolatile(gIR->func()->inVolatile); } diff --git a/gen/toobj.cpp b/gen/toobj.cpp index 89a21bef..9acf9c9d 100644 --- a/gen/toobj.cpp +++ b/gen/toobj.cpp @@ -75,7 +75,7 @@ void Module::genobjfile(int multiobj, char** envp) Logger::println("Generating module: %s\n", (md ? md->toChars() : toChars())); LOG_SCOPE; - //printf("codegen: %s\n", srcfile->toChars()); + printf("codegen: %s\n", srcfile->toChars()); // start by deleting the old object file deleteObjFile();