Do not unnecessarily call postblit after rvalue array initializers.

Fixes DMD testcases 'sdtor' and 'structlit'.
This commit is contained in:
David Nadlinger 2013-01-04 10:19:03 +01:00
parent bcd8f26b26
commit 859177fe3d
3 changed files with 21 additions and 6 deletions

View file

@ -397,7 +397,7 @@ void DtoLeaveMonitor(LLValue* v)
// is this a good approach at all ? // is this a good approach at all ?
void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op) void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op, bool canSkipPostblit)
{ {
Logger::println("DtoAssign()"); Logger::println("DtoAssign()");
LOG_SCOPE; LOG_SCOPE;
@ -424,7 +424,9 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op)
else if (DtoArrayElementType(t)->equals(stripModifiers(t2))) { else if (DtoArrayElementType(t)->equals(stripModifiers(t2))) {
DtoArrayInit(loc, s, rhs, op); DtoArrayInit(loc, s, rhs, op);
} }
else if (op != -1 && op != TOKblit && arrayNeedsPostblit(t)) { else if (op != -1 && op != TOKblit && !canSkipPostblit &&
arrayNeedsPostblit(t)
) {
DtoArrayAssign(s, rhs, op); DtoArrayAssign(s, rhs, op);
} }
#endif #endif
@ -462,7 +464,9 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op)
else if (DtoArrayElementType(t)->equals(stripModifiers(t2))) { else if (DtoArrayElementType(t)->equals(stripModifiers(t2))) {
DtoArrayInit(loc, lhs, rhs, op); DtoArrayInit(loc, lhs, rhs, op);
} }
else if (op != -1 && op != TOKblit && arrayNeedsPostblit(t)) { else if (op != -1 && op != TOKblit && !canSkipPostblit &&
arrayNeedsPostblit(t)
) {
DtoArrayAssign(lhs, rhs, op); DtoArrayAssign(lhs, rhs, op);
} }
#endif #endif

View file

@ -87,7 +87,7 @@ void DtoEnterMonitor(LLValue* v);
void DtoLeaveMonitor(LLValue* v); void DtoLeaveMonitor(LLValue* v);
// basic operations // basic operations
void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op = -1); void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op = -1, bool canSkipPostblit = false);
/// Create a null DValue. /// Create a null DValue.
DValue* DtoNullValue(Type* t); DValue* DtoNullValue(Type* t);

View file

@ -623,8 +623,16 @@ DValue* AssignExp::toElem(IRState* p)
return r; return r;
} }
Logger::println("performing normal assignment"); bool canSkipPostblit = false;
DtoAssign(loc, l, r, op); if (!(e2->op == TOKslice && ((UnaExp *)e2)->e1->isLvalue()) &&
!(e2->op == TOKcast && ((UnaExp *)e2)->e1->isLvalue()) &&
(e2->op == TOKslice || !e2->isLvalue()))
{
canSkipPostblit = true;
}
Logger::println("performing normal assignment (canSkipPostblit = %d)", canSkipPostblit);
DtoAssign(loc, l, r, op, canSkipPostblit);
if (l->isSlice()) if (l->isSlice())
return l; return l;
@ -2983,6 +2991,9 @@ DValue* StructLiteralExp::toElem(IRState* p)
// store the initializer there // store the initializer there
DtoAssign(loc, &field, val, TOKconstruct); DtoAssign(loc, &field, val, TOKconstruct);
if (expr)
callPostblit(loc, expr, field.getLVal());
// Also zero out padding bytes counted as being part of the type in DMD // Also zero out padding bytes counted as being part of the type in DMD
// but not in LLVM; e.g. real/x86_fp80. // but not in LLVM; e.g. real/x86_fp80.
int implicitPadding = int implicitPadding =