mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-08 11:56:12 +03: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:
parent
b4f8bd6e52
commit
1958e17734
3 changed files with 33 additions and 138 deletions
|
@ -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: ");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue