Rewrite StructLiteralExp::toElem to store individual fields instead of

generating a constant to fill the entire struct with a single `store`.
This is much more efficient at compile time (fixing #320) and vastly reduces
the size of the emitted code. Since LLVM no longer needs to keep the data for
all fields in "registers" until the store happens, it should also be more
efficient at run time in cases where the fields aren't assigned with constants.

There's also some code clean-up by removing duplicated logic.
This commit is contained in:
Frits van Bommel 2009-06-06 20:16:13 +02:00
parent b4f8bd6e52
commit 1958e17734
3 changed files with 33 additions and 138 deletions

View file

@ -1226,78 +1226,6 @@ LLConstant* DtoConstExpInit(Loc loc, Type* type, Expression* exp)
//////////////////////////////////////////////////////////////////////////////////////////
static LLValue* expand_value_to_sarray(Type *base, Expression* exp)
{
Logger::println("building type %s from expression (%s) of type %s", base->toChars(), exp->toChars(), exp->type->toChars());
const LLType* dstTy = DtoType(base);
if (Logger::enabled())
Logger::cout() << "final llvm type requested: " << *dstTy << '\n';
// get initial value
LLValue* val = exp->toElem(gIR)->getRVal();
if (DtoIsPassedByRef(exp->type))
val = DtoLoad(val);
Type* expbase = exp->type->toBasetype();
Logger::println("expbase: %s", expbase->toChars());
Type* t = base->toBasetype();
LLSmallVector<size_t, 4> dims;
while(1)
{
Logger::println("t: %s", t->toChars());
if (t->equals(expbase))
break;
assert(t->ty == Tsarray);
TypeSArray* tsa = (TypeSArray*)t;
dims.push_back(tsa->dim->toInteger());
assert(t->nextOf());
t = t->nextOf()->toBasetype();
}
size_t i = dims.size();
assert(i);
std::vector<LLValue*> inits;
while (i--)
{
// start with undefined array
const LLArrayType* arrty = LLArrayType::get(val->getType(), dims[i]);
LLValue* tmp = llvm::UndefValue::get(arrty);
for (size_t j = 0; j < dims[i]; j++)
{
tmp = gIR->ir->CreateInsertValue(tmp, val, j);
}
val = tmp;
}
return val;
}
LLValue* DtoExprValue(Type* type, Expression* e)
{
Type* t1 = e->type->toBasetype();
Type* t2 = type->toBasetype();
// expand static arrays
if (t2->ty == Tsarray && !t1->equals(t2))
{
return expand_value_to_sarray(t2, e);
}
// or not
else
{
DValue* dv = e->toElem(gIR);
LLValue* v = dv->getRVal();
if (DtoIsPassedByRef(e->type))
v = DtoLoad(v);
return v;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void DtoAnnotation(const char* str)
{
std::string s("CODE: ");