mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-28 01:23:14 +01:00
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:
@@ -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: ");
|
||||
|
||||
Reference in New Issue
Block a user