mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-07-25 16:45:21 +02:00
[svn r12] fixed accessing aggregate fields of aggregates
removed some useless branches for successive scopes ala {}{}{}
This commit is contained in:
42
gen/toir.c
42
gen/toir.c
@@ -434,15 +434,15 @@ elem* AddExp::toElem(IRState* p)
|
||||
|
||||
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 @@ elem* SymOffExp::toElem(IRState* p)
|
||||
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 @@ elem* DotVarExp::toElem(IRState* p)
|
||||
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 @@ void ScopeStatement::toIR(IRState* p)
|
||||
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);
|
||||
|
||||
20
gen/tollvm.c
20
gen/tollvm.c
@@ -460,7 +460,11 @@ llvm::Constant* LLVM_DtoStructInitializer(StructInitializer* si)
|
||||
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 @@ llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, con
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -37,5 +37,6 @@ llvm::Function* LLVM_DeclareMemCpy32();
|
||||
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"
|
||||
|
||||
24
gen/toobj.c
24
gen/toobj.c
@@ -139,15 +139,27 @@ void Declaration::toObjFile()
|
||||
/* ================================================================== */
|
||||
|
||||
/// 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 @@ static unsigned LLVM_ClassOffsetToIndex(ClassDeclaration* cd, unsigned os, unsig
|
||||
|
||||
/// 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
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
Reference in New Issue
Block a user