# HG changeset patch # User Tomas Lindquist Olsen # Date 1223991349 -7200 # Node ID 5a2983f974986860028ba2ebc121b2bdaaa07a96 # Parent 43165a0825355285a35a8b796451956d6ea9b7ad Fixed weird struct problem from downs, see mini/compile_structs1.d Rewrote DtoIndexStruct/Class , the old implementation were way too complex for what we really need now - since the DotVar changes. diff -r 43165a082535 -r 5a2983f97498 gen/classes.cpp --- a/gen/classes.cpp Tue Oct 14 13:21:14 2008 +0200 +++ b/gen/classes.cpp Tue Oct 14 15:35:49 2008 +0200 @@ -1094,75 +1094,34 @@ ////////////////////////////////////////////////////////////////////////////////////////// -LLValue* DtoIndexClass(LLValue* ptr, ClassDeclaration* cd, Type* t, unsigned os, DStructIndexVector& idxs) +LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd) { - Logger::println("checking for offset %u type %s:", os, t->toChars()); + Logger::println("indexing class field %s:", vd->toPrettyChars()); LOG_SCOPE; - if (idxs.empty()) - idxs.push_back(0); + if (Logger::enabled()) + Logger::cout() << "src: " << *src << '\n'; + + // vd must be a field + IrField* field = vd->ir.irField; + assert(field); + + unsigned idx = field->index + 2; // vtbl & monitor + unsigned off = field->indexOffset; const LLType* st = DtoType(cd->type); - if (ptr->getType() != st) { - ptr = gIR->ir->CreateBitCast(ptr, st, "tmp"); - } + src = DtoBitCast(src, st); - const LLType* llt = getPtrToType(DtoType(t)); - unsigned dataoffset = 2; + LLValue* val = DtoGEPi(src, 0,idx); + val = DtoBitCast(val, getPtrToType(DtoType(vd->type))); - IrStruct* irstruct = cd->ir.irStruct; - for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { - VarDeclaration* vd = i->second.var; - assert(vd); - Type* vdtype = vd->type->toBasetype(); - //Logger::println("found %u type %s", vd->offset, vdtype->toChars()); - assert(vd->ir.irField->index >= 0); - if (os == vd->offset && vdtype->toBasetype() == t->toBasetype()) { - Logger::println("found %s %s", vdtype->toChars(), vd->toChars()); - idxs.push_back(vd->ir.irField->index + dataoffset); - //Logger::cout() << "indexing: " << *ptr << '\n'; - ptr = DtoGEPi(ptr, idxs, "tmp"); - if (ptr->getType() != llt) - ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); - //Logger::cout() << "indexing: " << *ptr << '\n'; - if (vd->ir.irField->indexOffset) - ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); - //Logger::cout() << "indexing: " << *ptr << '\n'; - return ptr; - } - else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { - TypeStruct* ts = (TypeStruct*)vdtype; - StructDeclaration* ssd = ts->sym; - idxs.push_back(vd->ir.irField->index + dataoffset); - if (vd->ir.irField->indexOffset) { - Logger::println("has union field offset"); - ptr = DtoGEPi(ptr, idxs, "tmp"); - if (ptr->getType() != llt) - ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); - ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); - DStructIndexVector tmp; - return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); - } - else { - const LLType* sty = getPtrToType(DtoType(vd->type)); - if (ptr->getType() != sty) { - ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp"); - DStructIndexVector tmp; - return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); - } - else { - return DtoIndexStruct(ptr, ssd, t, os-vd->offset, idxs); - } - } - } - } + if (off) + val = DtoGEPi1(val, off); - assert(0); + if (Logger::enabled()) + Logger::cout() << "value: " << *val << '\n'; - size_t llt_sz = getABITypeSize(llt->getContainedType(0)); - assert(os % llt_sz == 0); - ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); - return llvm::GetElementPtrInst::Create(ptr, DtoConstUint(os / llt_sz), "tmp", gIR->scopebb()); + return val; } ////////////////////////////////////////////////////////////////////////////////////////// diff -r 43165a082535 -r 5a2983f97498 gen/classes.h --- a/gen/classes.h Tue Oct 14 13:21:14 2008 +0200 +++ b/gen/classes.h Tue Oct 14 15:35:49 2008 +0200 @@ -37,7 +37,7 @@ DValue* DtoCastInterfaceToObject(DValue* val, Type* to); DValue* DtoDynamicCastInterface(DValue* val, Type* to); -LLValue* DtoIndexClass(LLValue* ptr, ClassDeclaration* cd, Type* t, unsigned os, DStructIndexVector& idxs); +LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* sd, VarDeclaration* vd); LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl); diff -r 43165a082535 -r 5a2983f97498 gen/structs.cpp --- a/gen/structs.cpp Tue Oct 14 13:21:14 2008 +0200 +++ b/gen/structs.cpp Tue Oct 14 15:35:49 2008 +0200 @@ -52,73 +52,31 @@ ////////////////////////////////////////////////////////////////////////////////////////// -LLValue* DtoIndexStruct(LLValue* ptr, StructDeclaration* sd, Type* t, unsigned os, DStructIndexVector& idxs) +LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd) { - Logger::println("checking for offset %u type %s:", os, t->toChars()); + Logger::println("indexing struct field %s:", vd->toPrettyChars()); LOG_SCOPE; - if (idxs.empty()) - idxs.push_back(0); + // vd must be a field + IrField* field = vd->ir.irField; + assert(field); + + unsigned idx = field->index; + unsigned off = field->indexOffset; - const LLType* llt = getPtrToType(DtoType(t)); const LLType* st = getPtrToType(DtoType(sd->type)); + src = DtoBitCast(src, st); + + LLValue* val = DtoGEPi(src, 0,idx); + val = DtoBitCast(val, getPtrToType(DtoType(vd->type))); + + if (off) + val = DtoGEPi1(val, off); if (Logger::enabled()) - { - 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"); - } + Logger::cout() << "value: " << *val << '\n'; - for (unsigned i=0; ifields.dim; ++i) { - VarDeclaration* vd = (VarDeclaration*)sd->fields.data[i]; - Type* vdtype = vd->type->toBasetype(); - //Logger::println("found %u type %s", vd->offset, vdtype->toChars()); - assert(vd->ir.irField->index >= 0); - if (os == vd->offset && vdtype == t) { - idxs.push_back(vd->ir.irField->index); - ptr = DtoGEPi(ptr, idxs, "tmp"); - if (ptr->getType() != llt) - ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); - if (vd->ir.irField->indexOffset) - ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); - return ptr; - } - else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { - TypeStruct* ts = (TypeStruct*)vdtype; - StructDeclaration* ssd = ts->sym; - idxs.push_back(vd->ir.irField->index); - if (vd->ir.irField->indexOffset) { - Logger::println("has union field offset"); - ptr = DtoGEPi(ptr, idxs, "tmp"); - if (ptr->getType() != llt) - ptr = DtoBitCast(ptr, llt); - ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); - DStructIndexVector tmp; - return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); - } - else { - const LLType* sty = getPtrToType(DtoType(vd->type)); - if (ptr->getType() != sty) { - ptr = DtoBitCast(ptr, sty); - DStructIndexVector tmp; - return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); - } - else { - return DtoIndexStruct(ptr, ssd, t, os-vd->offset, idxs); - } - } - } - } - - size_t llt_sz = getTypeStoreSize(llt->getContainedType(0)); - assert(os % llt_sz == 0); - ptr = DtoBitCast(ptr, llt); - return llvm::GetElementPtrInst::Create(ptr, DtoConstUint(os / llt_sz), "tmp", gIR->scopebb()); + return val; } ////////////////////////////////////////////////////////////////////////////////////////// diff -r 43165a082535 -r 5a2983f97498 gen/structs.h --- a/gen/structs.h Tue Oct 14 13:21:14 2008 +0200 +++ b/gen/structs.h Tue Oct 14 15:35:49 2008 +0200 @@ -30,8 +30,8 @@ */ LLValue* DtoStructEquals(TOK op, DValue* lhs, DValue* rhs); -typedef LLSmallVector DStructIndexVector; -LLValue* DtoIndexStruct(LLValue* ptr, StructDeclaration* sd, Type* t, unsigned os, DStructIndexVector& idxs); +// index a struct one level +LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd); struct DUnionField { diff -r 43165a082535 -r 5a2983f97498 gen/toir.cpp --- a/gen/toir.cpp Tue Oct 14 13:21:14 2008 +0200 +++ b/gen/toir.cpp Tue Oct 14 15:35:49 2008 +0200 @@ -500,18 +500,7 @@ Type* e2type = e2->type->toBasetype(); if (e1type != e2type) { - /*if (llvmFieldIndex) { - assert(e1type->ty == Tpointer && e1next && e1next->ty == Tstruct); - Logger::println("add to AddrExp of struct"); - assert(r->isConst()); - llvm::ConstantInt* cofs = llvm::cast(r->isConst()->c); - - TypeStruct* ts = (TypeStruct*)e1next; - DStructIndexVector offsets; - LLValue* v = DtoIndexStruct(l->getRVal(), ts->sym, t->next, cofs->getZExtValue(), offsets); - return new DFieldValue(type, v); - } - else*/ if (e1type->ty == Tpointer) { + if (e1type->ty == Tpointer) { Logger::println("add to pointer"); if (r->isConst()) { llvm::ConstantInt* cofs = llvm::cast(r->isConst()->c); @@ -943,34 +932,21 @@ if (VarDeclaration* vd = var->isVarDeclaration()) { LLValue* arrptr; + // indexing struct pointer if (e1type->ty == Tpointer) { assert(e1type->next->ty == Tstruct); TypeStruct* ts = (TypeStruct*)e1type->next; - Logger::println("Struct member offset:%d", vd->offset); - - LLValue* src = l->getRVal(); - - DStructIndexVector vdoffsets; - arrptr = DtoIndexStruct(src, ts->sym, vd->type, vd->offset, vdoffsets); + arrptr = DtoIndexStruct(l->getRVal(), ts->sym, vd); } - // happens for tuples + // indexing normal struct else if (e1type->ty == Tstruct) { TypeStruct* ts = (TypeStruct*)e1type; - Logger::println("Struct member offset:%d", vd->offset); - - LLValue* src = l->getRVal(); - - DStructIndexVector vdoffsets; - arrptr = DtoIndexStruct(src, ts->sym, vd->type, vd->offset, vdoffsets); + arrptr = DtoIndexStruct(l->getRVal(), ts->sym, vd); } + // indexing class else if (e1type->ty == Tclass) { TypeClass* tc = (TypeClass*)e1type; - Logger::println("Class member offset: %d", vd->offset); - - LLValue* src = l->getRVal(); - - DStructIndexVector vdoffsets; - arrptr = DtoIndexClass(src, tc->sym, vd->type, vd->offset, vdoffsets); + arrptr = DtoIndexClass(l->getRVal(), tc->sym, vd); } else assert(0); @@ -1343,6 +1319,11 @@ if (rv->getType() != lv->getType()) { rv = DtoBitCast(rv, lv->getType()); } + if (Logger::enabled()) + { + Logger::cout() << "lv: " << *lv << '\n'; + Logger::cout() << "rv: " << *rv << '\n'; + } eval = p->ir->CreateICmp(cmpop, lv, rv, "tmp"); } else if (t->iscomplex()) diff -r 43165a082535 -r 5a2983f97498 gen/tollvm.cpp --- a/gen/tollvm.cpp Tue Oct 14 13:21:14 2008 +0200 +++ b/gen/tollvm.cpp Tue Oct 14 15:35:49 2008 +0200 @@ -389,20 +389,6 @@ ////////////////////////////////////////////////////////////////////////////////////////// -LLValue* DtoGEPi(LLValue* ptr, const DStructIndexVector& src, const char* var, llvm::BasicBlock* bb) -{ - size_t n = src.size(); - LLSmallVector dst(n); - - size_t j=0; - for (DStructIndexVector::const_iterator i=src.begin(); i!=src.end(); ++i) - dst[j++] = DtoConstUint(*i); - - return llvm::GetElementPtrInst::Create(ptr, dst.begin(), dst.end(), var?var:"tmp", bb?bb:gIR->scopebb()); -} - -////////////////////////////////////////////////////////////////////////////////////////// - LLValue* DtoGEPi1(LLValue* ptr, unsigned i, const char* var, llvm::BasicBlock* bb) { return llvm::GetElementPtrInst::Create(ptr, DtoConstUint(i), var?var:"tmp", bb?bb:gIR->scopebb()); diff -r 43165a082535 -r 5a2983f97498 gen/tollvm.h --- a/gen/tollvm.h Tue Oct 14 13:21:14 2008 +0200 +++ b/gen/tollvm.h Tue Oct 14 15:35:49 2008 +0200 @@ -48,7 +48,7 @@ // getelementptr helpers LLValue* DtoGEP1(LLValue* ptr, LLValue* i0, const char* var=NULL, llvm::BasicBlock* bb=NULL); LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const char* var=NULL, llvm::BasicBlock* bb=NULL); -LLValue* DtoGEPi(LLValue* ptr, const DStructIndexVector& src, const char* var=NULL, llvm::BasicBlock* bb=NULL); + LLValue* DtoGEPi1(LLValue* ptr, unsigned i0, const char* var=NULL, llvm::BasicBlock* bb=NULL); LLValue* DtoGEPi(LLValue* ptr, unsigned i0, unsigned i1, const char* var=NULL, llvm::BasicBlock* bb=NULL); diff -r 43165a082535 -r 5a2983f97498 tests/mini/compile_structs1.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/compile_structs1.d Tue Oct 14 15:35:49 2008 +0200 @@ -0,0 +1,4 @@ +struct Foo { int a, b, c; union Data { } Data data; } +struct Bar { int a, b; } +struct Baz { int a; union { Foo foo; Bar bar; } } +void test() { Baz baz; if (baz.bar.a) return; }