From 859177fe3d6ff6575e2b4da570fae578282f18d6 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Fri, 4 Jan 2013 10:19:03 +0100 Subject: [PATCH] Do not unnecessarily call postblit after rvalue array initializers. Fixes DMD testcases 'sdtor' and 'structlit'. --- gen/llvmhelpers.cpp | 10 +++++++--- gen/llvmhelpers.h | 2 +- gen/toir.cpp | 15 +++++++++++++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 16caa7fa..1a2a7725 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -397,7 +397,7 @@ void DtoLeaveMonitor(LLValue* v) // 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()"); LOG_SCOPE; @@ -424,7 +424,9 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op) else if (DtoArrayElementType(t)->equals(stripModifiers(t2))) { 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); } #endif @@ -462,7 +464,9 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op) else if (DtoArrayElementType(t)->equals(stripModifiers(t2))) { 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); } #endif diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 023153b3..c0fbcb66 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -87,7 +87,7 @@ void DtoEnterMonitor(LLValue* v); void DtoLeaveMonitor(LLValue* v); // 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. DValue* DtoNullValue(Type* t); diff --git a/gen/toir.cpp b/gen/toir.cpp index b160ee2e..fa3aa23b 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -623,8 +623,16 @@ DValue* AssignExp::toElem(IRState* p) return r; } - Logger::println("performing normal assignment"); - DtoAssign(loc, l, r, op); + bool canSkipPostblit = false; + 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()) return l; @@ -2983,6 +2991,9 @@ DValue* StructLiteralExp::toElem(IRState* p) // store the initializer there 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 // but not in LLVM; e.g. real/x86_fp80. int implicitPadding =