Mercurial > projects > ldc
changeset 8:5e69b77a5c51 trunk
[svn r12] fixed accessing aggregate fields of aggregates
removed some useless branches for successive scopes ala {}{}{}
author | lindquist |
---|---|
date | Thu, 27 Sep 2007 06:03:06 +0200 |
parents | 7a155ba88c53 |
children | dafae18f9c08 |
files | dmd/aggregate.h gen/toir.c gen/tollvm.c gen/tollvm.h gen/toobj.c test/classes5.d test/scope1.d test/structs3.d |
diffstat | 8 files changed, 95 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/dmd/aggregate.h Wed Sep 26 19:17:54 2007 +0200 +++ b/dmd/aggregate.h Thu Sep 27 06:03:06 2007 +0200 @@ -18,6 +18,8 @@ #include "root.h" #include "dsymbol.h" +#include <vector> + struct Identifier; struct Type; struct TypeFunction; @@ -97,7 +99,7 @@ llvm::Type* llvmType; llvm::Value* llvmVtbl; llvm::Constant* llvmInitZ; - virtual unsigned offsetToIndex(unsigned os); // converts a DMD field offsets to LLVM struct index + virtual void offsetToIndex(unsigned os, std::vector<unsigned>& result); // converts a DMD field offsets to LLVM struct index vector AggregateDeclaration *isAggregateDeclaration() { return this; } }; @@ -232,7 +234,7 @@ Symbol *vtblsym; - virtual unsigned offsetToIndex(unsigned os); + virtual void offsetToIndex(unsigned os, std::vector<unsigned>& result); ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; } };
--- a/gen/toir.c Wed Sep 26 19:17:54 2007 +0200 +++ b/gen/toir.c Thu Sep 27 06:03:06 2007 +0200 @@ -434,15 +434,15 @@ if (e1->type != e2->type) { if (e1->type->ty == Tpointer && e1->type->next->ty == Tstruct) { - assert(l->field); + //assert(l->field); llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); assert(r->type == elem::CONST); llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->val); TypeStruct* ts = (TypeStruct*)e1->type->next; - llvm::Value* offset = llvm::ConstantInt::get(llvm::Type::Int32Ty, ts->sym->offsetToIndex(cofs->getZExtValue()), false); - - e->mem = LLVM_DtoGEP(l->getValue(), zero, offset, "tmp", p->scopebb()); + std::vector<unsigned> offsets(1,0); + ts->sym->offsetToIndex(cofs->getZExtValue(), offsets); + e->mem = LLVM_DtoGEP(l->getValue(), offsets, "tmp", p->scopebb()); e->type = elem::VAR; e->field = true; } @@ -1126,12 +1126,11 @@ if (vd->type->ty == Tstruct && !(type->ty == Tpointer && type->next == vd->type)) { TypeStruct* vdt = (TypeStruct*)vd->type; e = new elem; - llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - llvm::Value* idx1 = llvm::ConstantInt::get(llvm::Type::Int32Ty, (uint64_t)vdt->sym->offsetToIndex(offset), false); - //const llvm::Type* _typ = llvm::GetElementPtrInst::getIndexedType(LLVM_DtoType(type), idx1); + std::vector<unsigned> dst(1,0); + vdt->sym->offsetToIndex(offset, dst); llvm::Value* ptr = vd->llvmValue; assert(ptr); - e->mem = LLVM_DtoGEP(ptr,idx0,idx1,"tmp",p->scopebb()); + e->mem = LLVM_DtoGEP(ptr,dst,"tmp",p->scopebb()); e->type = elem::VAL; e->field = true; } @@ -1210,26 +1209,24 @@ Logger::print("e1->type=%s\n", e1->type->toChars()); if (VarDeclaration* vd = var->isVarDeclaration()) { - size_t vdoffset = (size_t)-1; + std::vector<unsigned> vdoffsets(1,0); llvm::Value* src = 0; if (e1->type->ty == Tpointer) { assert(e1->type->next->ty == Tstruct); TypeStruct* ts = (TypeStruct*)e1->type->next; - vdoffset = ts->sym->offsetToIndex(vd->offset); - Logger::println("Struct member offset:%d index:%d", vd->offset, vdoffset); + ts->sym->offsetToIndex(vd->offset, vdoffsets); + Logger::println("Struct member offset:%d", vd->offset); src = l->val; } else if (e1->type->ty == Tclass) { TypeClass* tc = (TypeClass*)e1->type; Logger::println("Class member offset: %d", vd->offset); - vdoffset = tc->sym->offsetToIndex(vd->offset); + tc->sym->offsetToIndex(vd->offset, vdoffsets); src = l->getValue(); } - assert(vdoffset != (size_t)-1); + assert(vdoffsets.size() != 1); assert(src != 0); - llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - llvm::Value* offset = llvm::ConstantInt::get(llvm::Type::Int32Ty, vdoffset, false); - llvm::Value* arrptr = LLVM_DtoGEP(src,zero,offset,"tmp",p->scopebb()); + llvm::Value* arrptr = LLVM_DtoGEP(src,vdoffsets,"tmp",p->scopebb()); e->mem = arrptr; Logger::cout() << "mem: " << *e->mem << '\n'; e->type = elem::VAR; @@ -2588,12 +2585,17 @@ llvm::BasicBlock* oldend = gIR->scopeend(); IRScope irs; - irs.begin = new llvm::BasicBlock("scope", gIR->topfunc(), oldend); + // remove useless branches by clearing and reusing the current basicblock + llvm::BasicBlock* bb = gIR->scopebegin(); + if (bb->empty()) { + irs.begin = bb; + } + else { + irs.begin = new llvm::BasicBlock("scope", gIR->topfunc(), oldend); + new llvm::BranchInst(irs.begin, gIR->scopebegin()); + } irs.end = new llvm::BasicBlock("endscope", gIR->topfunc(), oldend); - // pass the previous BB into this - new llvm::BranchInst(irs.begin, gIR->scopebegin()); - gIR->scope() = irs; statement->toIR(p);
--- a/gen/tollvm.c Wed Sep 26 19:17:54 2007 +0200 +++ b/gen/tollvm.c Thu Sep 27 06:03:06 2007 +0200 @@ -460,7 +460,11 @@ VarDeclaration* vd = (VarDeclaration*)si->vars.data[i]; assert(vd); Logger::println("vars[%d] = %s", i, vd->toChars()); - unsigned idx = si->ad->offsetToIndex(vd->offset); + + std::vector<unsigned> idxs; + si->ad->offsetToIndex(vd->offset, idxs); + assert(idxs.size() == 1); + unsigned idx = idxs[0]; llvm::Constant* v = 0; @@ -819,3 +823,17 @@ v[1] = i1; return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb); } + +llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb) +{ + size_t n = src.size(); + std::vector<llvm::Value*> dst(n); + Logger::cout() << "indices:"; + for (size_t i=0; i<n; ++i) + { + Logger::cout() << ' ' << i; + dst[i] = llvm::ConstantInt::get(llvm::Type::Int32Ty, src[i], false); + } + Logger::cout() << '\n'; + return new llvm::GetElementPtrInst(ptr, dst.begin(), dst.end(), var, bb); +}
--- a/gen/tollvm.h Wed Sep 26 19:17:54 2007 +0200 +++ b/gen/tollvm.h Thu Sep 27 06:03:06 2007 +0200 @@ -37,5 +37,6 @@ llvm::Function* LLVM_DeclareMemCpy64(); llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb); +llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb); #include "enums.h"
--- a/gen/toobj.c Wed Sep 26 19:17:54 2007 +0200 +++ b/gen/toobj.c Thu Sep 27 06:03:06 2007 +0200 @@ -139,15 +139,27 @@ /* ================================================================== */ /// Returns the LLVM style index from a DMD style offset -unsigned AggregateDeclaration::offsetToIndex(unsigned os) +void AggregateDeclaration::offsetToIndex(unsigned os, std::vector<unsigned>& result) { + unsigned vos = 0; for (unsigned i=0; i<fields.dim; ++i) { VarDeclaration* vd = (VarDeclaration*)fields.data[i]; - if (os == vd->offset) - return i; + if (vd->type->ty == Tstruct) { + if (vos + vd->type->size() > os) { + TypeStruct* ts = (TypeStruct*)vd->type; + StructDeclaration* sd = ts->sym; + result.push_back(i); + sd->offsetToIndex(os - vos, result); + return; + } + } + else if (os == vd->offset) { + result.push_back(i); + return; + } + vos += vd->offset; } assert(0 && "Offset not found in any aggregate field"); - return 0; } /* ================================================================== */ @@ -175,12 +187,12 @@ /// Returns the LLVM style index from a DMD style offset /// Handles class inheritance -unsigned ClassDeclaration::offsetToIndex(unsigned os) +void ClassDeclaration::offsetToIndex(unsigned os, std::vector<unsigned>& result) { unsigned idx = 0; unsigned r = LLVM_ClassOffsetToIndex(this, os, idx); assert(r != (unsigned)-1 && "Offset not found in any aggregate field"); - return r+1; // vtable is 0 + result.push_back(r+1); // vtable is 0 } /* ================================================================== */
--- a/test/classes5.d Wed Sep 26 19:17:54 2007 +0200 +++ b/test/classes5.d Thu Sep 27 06:03:06 2007 +0200 @@ -13,5 +13,11 @@ void main() { - //C c = new C; + C c = new C; + long* lp = void; + {c.s.l = 64;} + {assert(c.s.l == 64);} + {lp = &c.s.l;} + {assert(*lp == 64);} + printf("classes5 success\n"); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/scope1.d Thu Sep 27 06:03:06 2007 +0200 @@ -0,0 +1,10 @@ +module scope1; + +void main() +{ + printf("1\n"); + { + scope(exit) printf("2\n"); + } + printf("3\n"); +}
--- a/test/structs3.d Wed Sep 26 19:17:54 2007 +0200 +++ b/test/structs3.d Thu Sep 27 06:03:06 2007 +0200 @@ -2,8 +2,8 @@ struct S { - float l; char c; + float f; } struct T @@ -14,4 +14,17 @@ void main() { + T t; + float f = void; + float* fp = void; + {f = t.s.f;} + {t.s.f = 0.0;} + {fp = &t.s.f;} + {*fp = 1.0;} + {assert(t.s.f == 1.0);} + {assert(*(&t.s.f) == 1.0);} + {t.s.c = 'a';} + {assert(t.s.c == 'a');} + {t.l = 64;} + {assert(t.l == 64);} }