# HG changeset patch # User Tomas Lindquist Olsen # Date 1221004187 25200 # Node ID fbb1a366cfbcd85b0c94066d39569b3ce8e2932f # Parent c7d7e2282ba3e6bf1f6778c09f0b73ba10394b58 Complex number should now follow the D ABI on x86. They're also treated as first class values now. Big change. diff -r c7d7e2282ba3 -r fbb1a366cfbc dmd/expression.c --- a/dmd/expression.c Mon Sep 08 20:38:55 2008 +0200 +++ b/dmd/expression.c Tue Sep 09 16:49:47 2008 -0700 @@ -7929,7 +7929,6 @@ AddExp::AddExp(Loc loc, Expression *e1, Expression *e2) : BinExp(loc, TOKadd, sizeof(AddExp), e1, e2) { - llvmFieldIndex = false; } Expression *AddExp::semantic(Scope *sc) diff -r c7d7e2282ba3 -r fbb1a366cfbc dmd/expression.h --- a/dmd/expression.h Mon Sep 08 20:38:55 2008 +0200 +++ b/dmd/expression.h Tue Sep 09 16:49:47 2008 -0700 @@ -1173,9 +1173,6 @@ Identifier *opId_r(); elem *toElem(IRState *irs); - - // LLVMDC - bool llvmFieldIndex; }; struct MinExp : BinExp diff -r c7d7e2282ba3 -r fbb1a366cfbc dmd/mtype.c --- a/dmd/mtype.c Mon Sep 08 20:38:55 2008 +0200 +++ b/dmd/mtype.c Tue Sep 09 16:49:47 2008 -0700 @@ -4456,18 +4456,17 @@ // *(&e + offset) accessCheck(e->loc, sc, e, d); + +// LLVMDC we don't want dot exprs turned into pointer arithmetic. it complicates things for no apparent gain +#ifndef IN_LLVM b = new AddrExp(e->loc, e); b->type = e->type->pointerTo(); b = new AddExp(e->loc, b, new IntegerExp(e->loc, v->offset, Type::tint32)); -#if IN_LLVM - // LLVMDC modification - // this is *essential* - ((AddExp*)b)->llvmFieldIndex = true; -#endif b->type = v->type->pointerTo(); e = new PtrExp(e->loc, b); e->type = v->type; return e; +#endif } de = new DotVarExp(e->loc, e, d); diff -r c7d7e2282ba3 -r fbb1a366cfbc gen/aa.cpp --- a/gen/aa.cpp Mon Sep 08 20:38:55 2008 +0200 +++ b/gen/aa.cpp Tue Sep 09 16:49:47 2008 -0700 @@ -23,13 +23,8 @@ pkey = key->getRVal(); } else if (DVarValue* var = key->isVar()) { - if (var->lval) { - pkey = key->getLVal(); - needmem = false; - } - else { - pkey = key->getRVal(); - } + pkey = key->getLVal(); + needmem = false; } else if (key->isConst()) { needmem = true; @@ -37,8 +32,8 @@ } else { LLValue* tmp = DtoAlloca(DtoType(keytype), "aatmpkeystorage"); - DVarValue* var = new DVarValue(keytype, tmp, true); - DtoAssign(loc, var, key); + DVarValue var(keytype, tmp); + DtoAssign(loc, &var, key); return tmp; } @@ -96,7 +91,7 @@ if (ret->getType() != targettype) ret = DtoBitCast(ret, targettype); - return new DVarValue(type, ret, true); + return new DVarValue(type, ret); } ///////////////////////////////////////////////////////////////////////////////////// diff -r c7d7e2282ba3 -r fbb1a366cfbc gen/arrays.cpp --- a/gen/arrays.cpp Mon Sep 08 20:38:55 2008 +0200 +++ b/gen/arrays.cpp Tue Sep 09 16:49:47 2008 -0700 @@ -116,10 +116,10 @@ LLValue* val; // give slices and complex values storage (and thus an address to pass) - if (value->isSlice() || value->isComplex()) + if (value->isSlice()) { val = DtoAlloca(DtoType(value->getType()), ".tmpparam"); - DVarValue lval(value->getType(), val, true); + DVarValue lval(value->getType(), val); DtoAssign(loc, &lval, value); } else @@ -526,7 +526,7 @@ LLValue* ptr = slice->ptr; ptr = llvm::GetElementPtrInst::Create(ptr, idx, "tmp", gIR->scopebb()); - DValue* dptr = new DVarValue(exp->type, ptr, true); + DValue* dptr = new DVarValue(exp->type, ptr); DValue* e = exp->toElem(gIR); @@ -631,7 +631,7 @@ DSliceValue* slice = DtoNewDynArray(type, lenval, false); LLValue* mem = slice->ptr; - DVarValue* memval = new DVarValue(e1->getType(), mem, true); + DVarValue* memval = new DVarValue(e1->getType(), mem); DtoAssign(exp1->loc, memval, e1); src1 = DtoArrayPtr(e2); @@ -662,7 +662,7 @@ DtoMemCpy(mem,src1,bytelen); mem = gIR->ir->CreateGEP(mem,len1,"tmp"); - DVarValue* memval = new DVarValue(e2->getType(), mem, true); + DVarValue* memval = new DVarValue(e2->getType(), mem); DtoAssign(exp1->loc, memval, e2); return slice; diff -r c7d7e2282ba3 -r fbb1a366cfbc gen/complex.cpp --- a/gen/complex.cpp Mon Sep 08 20:38:55 2008 +0200 +++ b/gen/complex.cpp Tue Sep 09 16:49:47 2008 -0700 @@ -8,20 +8,15 @@ #include "gen/llvmhelpers.h" #include "gen/irstate.h" #include "gen/dvalue.h" +#include "gen/logger.h" ////////////////////////////////////////////////////////////////////////////////////////// const llvm::StructType* DtoComplexType(Type* type) { Type* t = type->toBasetype(); - const LLType* base = DtoComplexBaseType(t); - - std::vector types; - types.push_back(base); - types.push_back(base); - - return llvm::StructType::get(types); + return llvm::StructType::get(base, base, NULL); } const LLType* DtoComplexBaseType(Type* t) @@ -47,19 +42,6 @@ ////////////////////////////////////////////////////////////////////////////////////////// -LLConstant* DtoConstComplex(Type* ty, LLConstant* re, LLConstant* im) -{ - assert(0); - const LLType* base = DtoComplexBaseType(ty); - - std::vector inits; - inits.push_back(re); - inits.push_back(im); - - const llvm::VectorType* vt = llvm::VectorType::get(base, 2); - return llvm::ConstantVector::get(vt, inits); -} - LLConstant* DtoConstComplex(Type* _ty, long double re, long double im) { TY ty = _ty->toBasetype()->ty; @@ -108,7 +90,7 @@ { Type* t = val->getType()->toBasetype(); - if (val->isComplex() || t->iscomplex()) { + if (t->iscomplex()) { return DtoCastComplex(loc, val, to); } @@ -127,27 +109,27 @@ baserety = Type::tfloat80; baseimty = Type::timaginary80; } + else { + assert(0); + } + + const LLType* complexTy = DtoType(to); + LLValue* res; if (t->isimaginary()) { - return new DComplexValue(to, LLConstant::getNullValue(DtoType(baserety)), DtoCastFloat(loc, val, baseimty)->getRVal()); + res = DtoAggrPair(complexTy, LLConstant::getNullValue(DtoType(baserety)), DtoCastFloat(loc, val, baseimty)->getRVal()); } - else if (t->isfloating()) { - return new DComplexValue(to, DtoCastFloat(loc, val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty))); + else if (t->isfloating() || t->isintegral()) { + res = DtoAggrPair(complexTy, DtoCastFloat(loc, val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty))); } - else if (t->isintegral()) { - return new DComplexValue(to, DtoCastInt(loc, val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty))); + else { + assert(0); } - assert(0); + return new DImValue(to, res); } ////////////////////////////////////////////////////////////////////////////////////////// -void DtoComplexAssign(LLValue* l, LLValue* r) -{ - DtoStore(DtoLoad(DtoGEPi(r, 0,0, "tmp")), DtoGEPi(l,0,0,"tmp")); - DtoStore(DtoLoad(DtoGEPi(r, 0,1, "tmp")), DtoGEPi(l,0,1,"tmp")); -} - void DtoComplexSet(LLValue* c, LLValue* re, LLValue* im) { DtoStore(re, DtoGEPi(c,0,0,"tmp")); @@ -158,15 +140,10 @@ void DtoGetComplexParts(DValue* c, LLValue*& re, LLValue*& im) { - // get LLValues - if (DComplexValue* cx = c->isComplex()) { - re = cx->re; - im = cx->im; - } - else { - re = DtoLoad(DtoGEPi(c->getRVal(),0,0,"tmp")); - im = DtoLoad(DtoGEPi(c->getRVal(),0,1,"tmp")); - } + LLValue* v = c->getRVal(); + Logger::cout() << "extracting real and imaginary parts from: " << *v << '\n'; + re = gIR->ir->CreateExtractValue(v, 0, ".re_part"); + im = gIR->ir->CreateExtractValue(v, 1, ".im_part"); } DValue* resolveLR(DValue* val, bool getlval) @@ -232,7 +209,8 @@ else // either hasIm(rhstype) or no im at all (then use any) res_im = rhs_im; - return new DComplexValue(type, res_re, res_im); + LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); + return new DImValue(type, res); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -262,7 +240,8 @@ else res_im = lhs_im; - return new DComplexValue(type, res_re, res_im); + LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); + return new DImValue(type, res); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -314,7 +293,8 @@ else res_im = hasRe(lhstype) ? rhs_im : lhs_re; // null! - return new DComplexValue(type, res_re, res_im); + LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); + return new DImValue(type, res); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -390,7 +370,8 @@ res_im = gIR->ir->CreateFDiv(res_im, denom, "res_im"); } - return new DComplexValue(type, res_re, res_im); + LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); + return new DImValue(type, res); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -408,7 +389,8 @@ re = gIR->ir->CreateNeg(a, "tmp"); im = gIR->ir->CreateNeg(b, "tmp"); - return new DComplexValue(type, re, im); + LLValue* res = DtoAggrPair(DtoType(type), re, im); + return new DImValue(type, res); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -462,35 +444,35 @@ re = gIR->ir->CreateFPTrunc(re, toty, "tmp"); im = gIR->ir->CreateFPTrunc(im, toty, "tmp"); } - else if (to->size() > vty->size()) { + else { re = gIR->ir->CreateFPExt(re, toty, "tmp"); im = gIR->ir->CreateFPExt(im, toty, "tmp"); } - else { - return val; + + LLValue* pair = DtoAggrPair(DtoType(_to), re, im); + DValue* rval = new DImValue(_to, pair); + + // if the value we're casting is not a lvalue, the cast value can't be either + if (!val->isLVal()) { + return rval; } - if (val->isComplex()) - return new DComplexValue(_to, re, im); - // unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions. - // so we need to give it storage, or fix the system that handles this stuff (DLRValue) - LLValue* mem = DtoAlloca(DtoType(_to), "castcomplextmp"); - DtoComplexSet(mem, re, im); - return new DLRValue(val, new DImValue(_to, mem)); + // so we need to maintain the storage + return new DLRValue(val, rval); } else if (to->isimaginary()) { - if (val->isComplex()) - return new DImValue(to, val->isComplex()->im); + // FIXME: this loads both values, even when we only need one LLValue* v = val->getRVal(); - DImValue* im = new DImValue(to, DtoLoad(DtoGEPi(v,0,1,"tmp"))); + LLValue* impart = gIR->ir->CreateExtractValue(v, 1, ".im_part"); + DImValue* im = new DImValue(to, impart); return DtoCastFloat(loc, im, to); } else if (to->isfloating()) { - if (val->isComplex()) - return new DImValue(to, val->isComplex()->re); + // FIXME: this loads both values, even when we only need one LLValue* v = val->getRVal(); - DImValue* re = new DImValue(to, DtoLoad(DtoGEPi(v,0,0,"tmp"))); + LLValue* repart = gIR->ir->CreateExtractValue(v, 0, ".re_part"); + DImValue* re = new DImValue(to, repart); return DtoCastFloat(loc, re, to); } else diff -r c7d7e2282ba3 -r fbb1a366cfbc gen/complex.h --- a/gen/complex.h Mon Sep 08 20:38:55 2008 +0200 +++ b/gen/complex.h Tue Sep 09 16:49:47 2008 -0700 @@ -4,7 +4,6 @@ const llvm::StructType* DtoComplexType(Type* t); const LLType* DtoComplexBaseType(Type* t); -LLConstant* DtoConstComplex(Type* t, LLConstant* re, LLConstant* im); LLConstant* DtoConstComplex(Type* t, long double re, long double im); LLConstant* DtoComplexShuffleMask(unsigned a, unsigned b); @@ -13,7 +12,6 @@ LLValue* DtoImagPart(DValue* val); DValue* DtoComplex(Loc& loc, Type* to, DValue* val); -void DtoComplexAssign(LLValue* l, LLValue* r); void DtoComplexSet(LLValue* c, LLValue* re, LLValue* im); void DtoGetComplexParts(DValue* c, LLValue*& re, LLValue*& im); diff -r c7d7e2282ba3 -r fbb1a366cfbc gen/dvalue.cpp --- a/gen/dvalue.cpp Mon Sep 08 20:38:55 2008 +0200 +++ b/gen/dvalue.cpp Tue Sep 09 16:49:47 2008 -0700 @@ -4,60 +4,40 @@ #include "gen/irstate.h" #include "gen/logger.h" #include "gen/dvalue.h" +#include "gen/llvmhelpers.h" #include "declaration.h" ///////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// -DVarValue::DVarValue(Type* t, VarDeclaration* vd, LLValue* llvmValue, bool lvalue) +DVarValue::DVarValue(Type* t, VarDeclaration* vd, LLValue* llvmValue) { var = vd; val = llvmValue; - rval = 0; - lval = lvalue; type = t; } -DVarValue::DVarValue(Type* t, LLValue* lv, LLValue* rv) -{ - var = 0; - val = lv; - rval = rv; - lval = true; - type = t; -} - -DVarValue::DVarValue(Type* t, LLValue* llvmValue, bool lvalue) +DVarValue::DVarValue(Type* t, LLValue* llvmValue) { var = 0; val = llvmValue; - rval = 0; - lval = lvalue; type = t; } LLValue* DVarValue::getLVal() { - assert(val && lval); + assert(val); return val; } LLValue* DVarValue::getRVal() { - assert(rval || val); - if (DtoIsPassedByRef(type)) { - if (rval) return rval; + assert(val); + Type* bt = type->toBasetype(); + if (DtoIsPassedByRef(bt)) return val; - } - else { - if (rval) return rval; - //Logger::cout() << "val: " << *val << '\n'; - if (!isField() && DtoCanLoad(val)) { - return DtoLoad(val); - } - return val; - } + return DtoLoad(val); } ///////////////////////////////////////////////////////////////////////////////////////////////// diff -r c7d7e2282ba3 -r fbb1a366cfbc gen/dvalue.h --- a/gen/dvalue.h Mon Sep 08 20:38:55 2008 +0200 +++ b/gen/dvalue.h Tue Sep 09 16:49:47 2008 -0700 @@ -31,7 +31,6 @@ struct DSliceValue; struct DArrayLenValue; struct DLRValue; -struct DComplexValue; // base class for d-values struct DValue : Object @@ -51,7 +50,6 @@ virtual DSliceValue* isSlice() { return NULL; } virtual DFuncValue* isFunc() { return NULL; } virtual DArrayLenValue* isArrayLen() { return NULL; } - virtual DComplexValue* isComplex() { return NULL; } virtual DLRValue* isLRValue() { return NULL; } protected: @@ -101,14 +99,11 @@ Type* type; VarDeclaration* var; LLValue* val; - LLValue* rval; - bool lval; - DVarValue(Type* t, VarDeclaration* vd, LLValue* llvmValue, bool lvalue); - DVarValue(Type* t, LLValue* lv, LLValue* rv); - DVarValue(Type* t, LLValue* llvmValue, bool lvalue); + DVarValue(Type* t, VarDeclaration* vd, LLValue* llvmValue); + DVarValue(Type* t, LLValue* llvmValue); - virtual bool isLVal() { return val && lval; } + virtual bool isLVal() { return true; } virtual LLValue* getLVal(); virtual LLValue* getRVal(); @@ -119,7 +114,7 @@ // field d-value struct DFieldValue : DVarValue { - DFieldValue(Type* t, LLValue* llvmValue, bool l) : DVarValue(t, llvmValue, l) {} + DFieldValue(Type* t, LLValue* llvmValue) : DVarValue(t, llvmValue) {} virtual DFieldValue* isField() { return this; } }; @@ -173,21 +168,4 @@ virtual DLRValue* isLRValue() { return this; } }; -// complex number immediate d-value (much like slice) -struct DComplexValue : DValue -{ - Type* type; - LLValue* re; - LLValue* im; - - DComplexValue(Type* t, LLValue* r, LLValue* i) { - type = t; - re = r; - im = i; - } - - virtual Type*& getType() { assert(type); return type; } - virtual DComplexValue* isComplex() { return this; } -}; - #endif // LLVMDC_GEN_DVALUE_H diff -r c7d7e2282ba3 -r fbb1a366cfbc gen/functions.cpp --- a/gen/functions.cpp Mon Sep 08 20:38:55 2008 +0200 +++ b/gen/functions.cpp Tue Sep 09 16:49:47 2008 -0700 @@ -122,7 +122,13 @@ bool refOrOut = ((arg->storageClass & STCref) || (arg->storageClass & STCout)); const LLType* at = DtoType(argT); - if (isaStruct(at)) { + + // FIXME: using the llvm type for these is a bad idea... aggregates are first class now and we're starting to use it ... + + if (argT->iscomplex()) { + goto Lbadstuff; + } + else if (isaStruct(at)) { Logger::println("struct param"); paramvec.push_back(getPtrToType(at)); if (!refOrOut) @@ -140,6 +146,7 @@ paramvec.push_back(getPtrToType(at)); } else { +Lbadstuff: if (refOrOut) { Logger::println("by ref param"); at = getPtrToType(at); @@ -866,10 +873,10 @@ arg = new DImValue(argexp->type, arg->getRVal()); } // byval arg, but expr has no storage yet - else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isComplex() || arg->isNull())) + else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isNull())) { LLValue* alloc = DtoAlloca(DtoType(argexp->type), ".tmp_arg"); - DVarValue* vv = new DVarValue(argexp->type, alloc, true); + DVarValue* vv = new DVarValue(argexp->type, alloc); DtoAssign(argexp->loc, vv, arg); arg = vv; } @@ -883,7 +890,7 @@ { Logger::println("DtoVariadicArgument"); LOG_SCOPE; - DVarValue vv(argexp->type, dst, true); + DVarValue vv(argexp->type, dst); DtoAssign(argexp->loc, &vv, argexp->toElem(gIR)); } diff -r c7d7e2282ba3 -r fbb1a366cfbc gen/llvmhelpers.cpp --- a/gen/llvmhelpers.cpp Mon Sep 08 20:38:55 2008 +0200 +++ b/gen/llvmhelpers.cpp Tue Sep 09 16:49:47 2008 -0700 @@ -360,7 +360,7 @@ if (vdparent == irfunc->decl) { LLValue* val = vd->ir.getIrValue(); - return new DVarValue(astype, vd, val, true); + return new DVarValue(astype, vd, val); } // get it from the nested context @@ -381,7 +381,7 @@ val = DtoLoad(val); assert(vd->ir.irLocal->value); val = DtoBitCast(val, vd->ir.irLocal->value->getType(), vd->toChars()); - return new DVarValue(astype, vd, val, true); + return new DVarValue(astype, vd, val); } LLValue* DtoNestedContext(Loc loc, Dsymbol* sym) @@ -486,21 +486,15 @@ DtoStore(r, l); } else if (t->iscomplex()) { - assert(!lhs->isComplex()); - LLValue* dst; if (DLRValue* lr = lhs->isLRValue()) { dst = lr->getLVal(); rhs = DtoCastComplex(loc, rhs, lr->getLType()); } else { - dst = lhs->getRVal(); + dst = lhs->getLVal(); } - - if (DComplexValue* cx = rhs->isComplex()) - DtoComplexSet(dst, cx->re, cx->im); - else - DtoComplexAssign(dst, rhs->getRVal()); + DtoStore(rhs->getRVal(), dst); } else { LLValue* l = lhs->getLVal(); @@ -538,7 +532,8 @@ if (basetype->iscomplex()) { const LLType* basefp = DtoComplexBaseType(basetype); - return new DComplexValue(type, LLConstant::getNullValue(basefp), LLConstant::getNullValue(basefp)); + LLValue* res = DtoAggrPair(DtoType(type), LLConstant::getNullValue(basefp), LLConstant::getNullValue(basefp)); + return new DImValue(type, res); } // integer, floating, pointer and class have no special representation else if (basetype->isintegral() || basetype->isfloating() || basety == Tpointer || basety == Tclass) @@ -790,7 +785,7 @@ gIR->scope() = IRScope(initbb,endinitbb); DValue* ie = DtoInitializer(gvar, init); - DVarValue dst(t, gvar, true); + DVarValue dst(t, gvar); DtoAssign(init->loc, &dst, ie); gIR->ir->CreateStore(DtoConstBool(true), gflag); @@ -1177,7 +1172,7 @@ DValue* ie = DtoInitializer(vd->ir.irLocal->value, vd->init); } - return new DVarValue(vd->type, vd, vd->ir.getIrValue(), true); + return new DVarValue(vd->type, vd, vd->ir.getIrValue()); } // struct declaration else if (StructDeclaration* s = declaration->isStructDeclaration()) diff -r c7d7e2282ba3 -r fbb1a366cfbc gen/statements.cpp --- a/gen/statements.cpp Mon Sep 08 20:38:55 2008 +0200 +++ b/gen/statements.cpp Tue Sep 09 16:49:47 2008 -0700 @@ -62,7 +62,7 @@ if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum); - DValue* rvar = new DVarValue(f->type->next, f->decl->ir.irFunc->retArg, true); + DValue* rvar = new DVarValue(f->type->next, f->decl->ir.irFunc->retArg); DValue* e = exp->toElem(p); @@ -687,7 +687,7 @@ { // give storage llval = DtoAlloca(DtoType(e->type), "tmp"); - DVarValue* vv = new DVarValue(e->type, llval, true); + DVarValue* vv = new DVarValue(e->type, llval); DtoAssign(e->loc, vv, val); } else @@ -1002,9 +1002,9 @@ value->ir.irLocal->value = DtoGEP1(val,loadedKey); if (!value->isRef() && !value->isOut()) { - DValue* dst = new DVarValue(value->type, valvar, true); - DValue* src = new DVarValue(value->type, value->ir.irLocal->value, true); - DtoAssign(loc, dst, src); + DVarValue dst(value->type, valvar); + DVarValue src(value->type, value->ir.irLocal->value); + DtoAssign(loc, &dst, &src); value->ir.irLocal->value = valvar; } @@ -1151,7 +1151,8 @@ DValue* e = exp->toElem(p); assert(!wthis->ir.isSet()); wthis->ir.irLocal = new IrLocal(wthis); - wthis->ir.irLocal->value = e->getRVal(); + wthis->ir.irLocal->value = DtoAlloca(DtoType(wthis->type), wthis->toChars()); + DtoStore(e->getRVal(), wthis->ir.irLocal->value); body->toIR(p); } diff -r c7d7e2282ba3 -r fbb1a366cfbc gen/structs.cpp --- a/gen/structs.cpp Mon Sep 08 20:38:55 2008 +0200 +++ b/gen/structs.cpp Tue Sep 09 16:49:47 2008 -0700 @@ -60,6 +60,10 @@ const LLType* llt = getPtrToType(DtoType(t)); const LLType* st = getPtrToType(DtoType(sd->type)); + + Logger::cout() << "ptr = " << *ptr << '\n'; + Logger::cout() << "st = " << *st << '\n'; + if (ptr->getType() != st) { assert(sd->ir.irStruct->hasUnions); ptr = gIR->ir->CreateBitCast(ptr, st, "tmp"); diff -r c7d7e2282ba3 -r fbb1a366cfbc gen/tocall.cpp --- a/gen/tocall.cpp Mon Sep 08 20:38:55 2008 +0200 +++ b/gen/tocall.cpp Tue Sep 09 16:49:47 2008 -0700 @@ -314,6 +314,8 @@ LLValue* arg = argval->getRVal(); if (fnarg) // can fnarg ever be null in this block? { + Logger::cout() << "arg: " << *arg << '\n'; + Logger::cout() << "expects: " << *callableTy->getParamType(j) << '\n'; if (arg->getType() != callableTy->getParamType(j)) arg = DtoBitCast(arg, callableTy->getParamType(j)); if (fnarg->llvmAttrs) diff -r c7d7e2282ba3 -r fbb1a366cfbc gen/toir.cpp --- a/gen/toir.cpp Mon Sep 08 20:38:55 2008 +0200 +++ b/gen/toir.cpp Tue Sep 09 16:49:47 2008 -0700 @@ -64,14 +64,14 @@ { Logger::println("Id::_arguments"); LLValue* v = p->func()->_arguments; - return new DVarValue(type, vd, v, true); + return new DVarValue(type, vd, v); } // _argptr else if (vd->ident == Id::_argptr && p->func()->_argptr) { Logger::println("Id::_argptr"); LLValue* v = p->func()->_argptr; - return new DVarValue(type, vd, v, true); + return new DVarValue(type, vd, v); } // _dollar else if (vd->ident == Id::dollar) @@ -79,7 +79,7 @@ Logger::println("Id::dollar"); assert(!p->arrays.empty()); LLValue* tmp = DtoArrayLen(p->arrays.back()); - return new DVarValue(type, vd, tmp, false); + return new DImValue(type, tmp); } // typeinfo else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) @@ -88,12 +88,10 @@ DtoForceDeclareDsymbol(tid); assert(tid->ir.getIrValue()); const LLType* vartype = DtoType(type); - LLValue* m; - if (tid->ir.getIrValue()->getType() != getPtrToType(vartype)) - m = p->ir->CreateBitCast(tid->ir.getIrValue(), vartype, "tmp"); - else - m = tid->ir.getIrValue(); - return new DVarValue(type, vd, m, true); + LLValue* m = tid->ir.getIrValue(); + if (m->getType() != getPtrToType(vartype)) + m = p->ir->CreateBitCast(m, vartype, "tmp"); + return new DImValue(type, m); } // classinfo else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration()) @@ -101,7 +99,7 @@ Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars()); DtoForceDeclareDsymbol(cid->cd); assert(cid->cd->ir.irStruct->classInfo); - return new DVarValue(type, vd, cid->cd->ir.irStruct->classInfo, true); + return new DVarValue(type, vd, cid->cd->ir.irStruct->classInfo); } // nested variable else if (vd->nestedref) { @@ -117,7 +115,7 @@ return DtoNestedVariable(loc, type, vd); } else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa(vd->ir.getIrValue())) { - return new DVarValue(type, vd, vd->ir.getIrValue(), true); + return new DVarValue(type, vd, vd->ir.getIrValue()); } else if (llvm::isa(vd->ir.getIrValue())) { return new DImValue(type, vd->ir.getIrValue()); @@ -125,6 +123,7 @@ else assert(0); } else { + Logger::println("a normal variable"); // take care of forward references of global variables if (vd->isDataseg() || (vd->storage_class & STCextern)) { vd->toObjFile(0); // TODO: multiobj @@ -135,7 +134,7 @@ Logger::cout() << "unresolved global had type: " << *DtoType(vd->type) << '\n'; fatal(); } - return new DVarValue(type, vd, vd->ir.getIrValue(), true); + return new DVarValue(type, vd, vd->ir.getIrValue()); } } else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) @@ -158,7 +157,7 @@ assert(ts->sym); DtoForceConstInitDsymbol(ts->sym); assert(ts->sym->ir.irStruct->init); - return new DVarValue(type, ts->sym->ir.irStruct->init, true); + return new DVarValue(type, ts->sym->ir.irStruct->init); } else { @@ -281,6 +280,7 @@ Logger::print("ComplexExp::toElem(): %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; LLConstant* c = toConstElem(p); + LLValue* res; if (c->isNullValue()) { Type* t = type->toBasetype(); @@ -292,10 +292,13 @@ c = DtoConstFP(Type::tfloat80, 0); else assert(0); - return new DComplexValue(type, c, c); + res = DtoAggrPair(DtoType(type), c, c); } - - return new DComplexValue(type, c->getOperand(0), c->getOperand(1)); + else { + res = DtoAggrPair(DtoType(type), c->getOperand(0), c->getOperand(1)); + } + + return new DImValue(type, res); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -360,12 +363,12 @@ LLConstant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false); LLValue* tmpmem = DtoAlloca(DtoType(dtype),"tempstring"); DtoSetArray(tmpmem, clen, arrptr); - return new DVarValue(type, tmpmem, true); + return new DVarValue(type, tmpmem); } else if (dtype->ty == Tsarray) { const LLType* dstType = getPtrToType(LLArrayType::get(ct, len)); LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType); - return new DVarValue(type, emem, true); + return new DVarValue(type, emem); } else if (dtype->ty == Tpointer) { return new DImValue(type, arrptr); @@ -456,7 +459,7 @@ Logger::println("performing array.length assignment"); ArrayLengthExp *ale = (ArrayLengthExp *)e1; DValue* arr = ale->e1->toElem(p); - DVarValue arrval(ale->e1->type, arr->getLVal(), true); + DVarValue arrval(ale->e1->type, arr->getLVal()); DValue* newlen = e2->toElem(p); DSliceValue* slice = DtoResizeDynArray(arrval.getType(), &arrval, newlen); DtoAssign(loc, &arrval, slice); @@ -469,7 +472,7 @@ DValue* r = e2->toElem(p); DtoAssign(loc, l, r); - if (l->isSlice() || l->isComplex()) + if (l->isSlice()) return l; #if 0 @@ -503,7 +506,7 @@ Type* e2type = e2->type->toBasetype(); if (e1type != e2type) { - if (llvmFieldIndex) { + /*if (llvmFieldIndex) { assert(e1type->ty == Tpointer && e1next && e1next->ty == Tstruct); Logger::println("add to AddrExp of struct"); assert(r->isConst()); @@ -512,9 +515,9 @@ TypeStruct* ts = (TypeStruct*)e1next; DStructIndexVector offsets; LLValue* v = DtoIndexStruct(l->getRVal(), ts->sym, t->next, cofs->getZExtValue(), offsets); - return new DFieldValue(type, v, true); + return new DFieldValue(type, v); } - else if (e1type->ty == Tpointer) { + else*/ if (e1type->ty == Tpointer) { Logger::println("add to pointer"); if (r->isConst()) { llvm::ConstantInt* cofs = llvm::cast(r->isConst()->c); @@ -848,7 +851,9 @@ return v; } Logger::println("is nothing special"); - return new DFieldValue(type, v->getLVal(), false); + LLValue* lval = v->getLVal(); + Logger::cout() << "lval: " << *lval << '\n'; + return new DImValue(type, v->getLVal()); } LLConstant* AddrExp::toConstElem(IRState* p) @@ -893,12 +898,18 @@ DValue* a = e1->toElem(p); - // this should be deterministic but right now lvalue casts don't propagate lvalueness !?! + // this is *so* ugly.. I'd really like to figure out some way to avoid this badness... LLValue* lv = a->getRVal(); LLValue* v = lv; - if (DtoCanLoad(v)) + + Type* bt = type->toBasetype(); + + // we can't load function pointers, but they aren't passed by reference either + // FIXME: maybe a MayLoad function isn't a bad idea after all ... + if (!DtoIsPassedByRef(bt) && bt->ty != Tfunction) v = DtoLoad(v); - return new DLRValue(new DVarValue(type, lv, true), new DImValue(type, v)); + + return new DLRValue(new DVarValue(type, lv), new DImValue(type, v)); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -951,7 +962,7 @@ assert(0); //Logger::cout() << "mem: " << *arrptr << '\n'; - return new DVarValue(type, vd, arrptr, true); + return new DVarValue(type, vd, arrptr); } else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) { @@ -1021,7 +1032,7 @@ { LLValue* v = p->func()->thisArg; assert(v); - return new DVarValue(type, v, true); + return new DVarValue(type, v); } // regular this expr else if (VarDeclaration* vd = var->isVarDeclaration()) { @@ -1034,7 +1045,7 @@ Logger::println("normal this exp"); v = p->func()->thisArg; } - return new DVarValue(type, vd, v, true); + return new DVarValue(type, vd, v); } // anything we're not yet handling ? @@ -1082,7 +1093,7 @@ Logger::println("invalid index exp! e1type: %s", e1type->toChars()); assert(0); } - return new DVarValue(type, arrptr, true); + return new DVarValue(type, arrptr); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1479,7 +1490,7 @@ { // allocate LLValue* mem = DtoNew(newtype); - DVarValue tmpvar(newtype, mem, true); + DVarValue tmpvar(newtype, mem); // default initialize Expression* exp = newtype->defaultInit(loc); @@ -1508,7 +1519,7 @@ { LLValue* rval = dval->getRVal(); DtoDeleteMemory(rval); - if (dval->isVar() && dval->isVar()->lval) + if (dval->isVar()) DtoStore(llvm::Constant::getNullValue(rval->getType()), dval->getLVal()); } // class @@ -1531,7 +1542,7 @@ LLValue* rval = dval->getRVal(); DtoDeleteClass(rval); } - if (dval->isVar() && dval->isVar()->lval) { + if (dval->isVar()) { LLValue* lval = dval->getLVal(); DtoStore(llvm::Constant::getNullValue(lval->getType()->getContainedType(0)), lval); } @@ -1957,7 +1968,7 @@ // allocate a temporary for the final result. failed to come up with a better way :/ llvm::BasicBlock* entryblock = &p->topfunc()->front(); LLValue* resval = DtoAlloca(resty,"condtmp"); - DVarValue* dvv = new DVarValue(type, resval, true); + DVarValue* dvv = new DVarValue(type, resval); llvm::BasicBlock* oldend = p->scopeend(); llvm::BasicBlock* condtrue = llvm::BasicBlock::Create("condtrue", gIR->topfunc(), oldend); @@ -2115,10 +2126,10 @@ LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0)); DtoStore(castfptr, fptr); - return new DVarValue(type, lval, true); + return new DVarValue(type, lval); } else if(fd->tok == TOKfunction) { - return new DVarValue(type, fd->ir.irFunc->func, false); + return new DImValue(type, fd->ir.irFunc->func); } assert(0 && "fd->tok must be TOKfunction or TOKdelegate"); @@ -2159,7 +2170,7 @@ LLValue* elemAddr = DtoGEPi(dstMem,0,i,"tmp",p->scopebb()); // emulate assignment - DVarValue* vv = new DVarValue(expr->type, elemAddr, true); + DVarValue* vv = new DVarValue(expr->type, elemAddr); DValue* e = expr->toElem(p); DtoAssign(loc, vv, e); } @@ -2248,7 +2259,7 @@ Logger::cout() << "getting index " << j << " of " << *sptr << '\n'; LLValue* arrptr = DtoGEPi(sptr,0,j); - DValue* darrptr = new DVarValue(vx->type, arrptr, true); + DValue* darrptr = new DVarValue(vx->type, arrptr); DValue* ve = vx->toElem(p); DtoAssign(loc, darrptr, ve); @@ -2324,7 +2335,7 @@ // it should be possible to avoid the temporary in some cases LLValue* tmp = DtoAlloca(aalltype,"aaliteral"); - DValue* aa = new DVarValue(type, tmp, true); + DValue* aa = new DVarValue(type, tmp); DtoStore(LLConstant::getNullValue(aalltype), tmp); const size_t n = keys->dim; diff -r c7d7e2282ba3 -r fbb1a366cfbc gen/tollvm.cpp --- a/gen/tollvm.cpp Mon Sep 08 20:38:55 2008 +0200 +++ b/gen/tollvm.cpp Tue Sep 09 16:49:47 2008 -0700 @@ -25,14 +25,14 @@ { Type* typ = type->toBasetype(); TY t = typ->ty; - return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray || typ->iscomplex()); + return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray); } bool DtoIsReturnedInArg(Type* type) { Type* typ = type->toBasetype(); TY t = typ->ty; - return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray || typ->iscomplex()); + return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray); } unsigned DtoShouldExtend(Type* type) @@ -541,15 +541,6 @@ //st->setVolatile(gIR->func()->inVolatile); } -bool DtoCanLoad(LLValue* ptr) -{ - if (isaPointer(ptr->getType())) { - const LLType* data = ptr->getType()->getContainedType(0); - return data->isFirstClassType() && !(isaStruct(data) || isaArray(data)); - } - return false; -} - ////////////////////////////////////////////////////////////////////////////////////////// LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name) @@ -770,3 +761,12 @@ gIR->module->addTypeName("ModuleReference", st); return st; } + +////////////////////////////////////////////////////////////////////////////////////////// + +LLValue* DtoAggrPair(const LLType* type, LLValue* V1, LLValue* V2, const char* name) +{ + LLValue* res = llvm::UndefValue::get(type); + res = gIR->ir->CreateInsertValue(res, V1, 0, "tmp"); + return gIR->ir->CreateInsertValue(res, V2, 1, name?name:"tmp"); +} diff -r c7d7e2282ba3 -r fbb1a366cfbc gen/tollvm.h --- a/gen/tollvm.h Mon Sep 08 20:38:55 2008 +0200 +++ b/gen/tollvm.h Tue Sep 09 16:49:47 2008 -0700 @@ -60,7 +60,6 @@ LLConstant* DtoConstBool(bool); // llvm wrappers -bool DtoCanLoad(LLValue* ptr); LLValue* DtoLoad(LLValue* src, const char* name=0); void DtoStore(LLValue* src, LLValue* dst); LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name=0); @@ -93,6 +92,9 @@ unsigned char getABITypeAlign(const LLType* t); unsigned char getPrefTypeAlign(const LLType* t); +// pair type helpers +LLValue* DtoAggrPair(const LLType* type, LLValue* V1, LLValue* V2, const char* name = 0); + /** * Generates a call to llvm.memset.i32 (or i64 depending on architecture). * @param dst Destination memory. diff -r c7d7e2282ba3 -r fbb1a366cfbc tests/mini/complex1.d --- a/tests/mini/complex1.d Mon Sep 08 20:38:55 2008 +0200 +++ b/tests/mini/complex1.d Tue Sep 09 16:49:47 2008 -0700 @@ -7,12 +7,8 @@ cfloat cf3 = func(); auto c1 = cf1 + cf2; auto c2 = cf2 - cf3; - { auto c3 = cf1 * cf3; - { auto c4 = cf2 / cf3; - } - } } cfloat func() diff -r c7d7e2282ba3 -r fbb1a366cfbc tests/mini/complex2.d --- a/tests/mini/complex2.d Mon Sep 08 20:38:55 2008 +0200 +++ b/tests/mini/complex2.d Tue Sep 09 16:49:47 2008 -0700 @@ -4,11 +4,7 @@ { cdouble c = 3.0 + 0i; cdouble d = 2.0 + 0i; - { - cdouble c1 = c + 3.0; - cdouble c2 = c - 3.0i; - } - { - cdouble c1 = c / 2.0; - } + cdouble c1 = c + 3.0; + cdouble c2 = c - 3.0i; + cdouble c3 = c / 2.0; } diff -r c7d7e2282ba3 -r fbb1a366cfbc tests/mini/complex3.d --- a/tests/mini/complex3.d Mon Sep 08 20:38:55 2008 +0200 +++ b/tests/mini/complex3.d Tue Sep 09 16:49:47 2008 -0700 @@ -5,5 +5,5 @@ cfloat c1 = 1f + 0i; cfloat c2 = 0f + 0i; c2 += 1f + 0i; - //assert(c1 == c2); + assert(c1 == c2); } diff -r c7d7e2282ba3 -r fbb1a366cfbc tests/mini/complex4.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/complex4.d Tue Sep 09 16:49:47 2008 -0700 @@ -0,0 +1,8 @@ +module complex4; + +void main() +{ + cfloat c = 2f + 3fi; + float r = cast(float)c; + ifloat i = cast(ifloat)c; +} \ No newline at end of file