Let special __result variable be an alias for sret

So for functions using sret and featuring an out contract, we save an
additional alloca + memcpy by using the sret pointer as storage.
This commit is contained in:
Martin 2016-07-03 21:26:10 +02:00
parent 1760e261db
commit 12ff7ef803
2 changed files with 22 additions and 2 deletions

View file

@ -884,8 +884,9 @@ void DtoVarDeclaration(VarDeclaration *vd) {
if (isIrLocalCreated(vd)) { if (isIrLocalCreated(vd)) {
// Nothing to do if it has already been allocated. // Nothing to do if it has already been allocated.
} else if (gIR->func()->sretArg && gIR->func()->decl->nrvo_can && } else if (gIR->func()->sretArg && ((gIR->func()->decl->nrvo_can &&
gIR->func()->decl->nrvo_var == vd) { gIR->func()->decl->nrvo_var == vd) ||
vd->isResult())) {
// Named Return Value Optimization (NRVO): // Named Return Value Optimization (NRVO):
// T f() { // T f() {
// T ret; // &ret == hidden pointer // T ret; // &ret == hidden pointer

View file

@ -28,6 +28,23 @@ S returnNRVO()
return r; return r;
} }
// CHECK-LABEL: define{{.*}} @{{.*}}_D18in_place_construct15withOutContractFZS18in_place_construct1S
S withOutContract()
out { assert(__result.a == 0); }
body
{
// make sure NRVO zero-initializes the sret pointee directly
// CHECK: %1 = bitcast %in_place_construct.S* %.sret_arg to i8*
// CHECK: call void @llvm.memset.{{.*}}(i8* %1, i8 0,
const S r;
return r;
// make sure `__result` inside the out contract is just an alias to the sret pointee
// CHECK: %2 = getelementptr inbounds {{.*}}%in_place_construct.S* %.sret_arg, i32 0, i32 0
// CHECK: %3 = load {{.*}}i64* %2
// CHECK: %4 = icmp eq i64 %3, 0
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D18in_place_construct7structsFZv // CHECK-LABEL: define{{.*}} @{{.*}}_D18in_place_construct7structsFZv
void structs() void structs()
{ {
@ -57,6 +74,8 @@ void structs()
// CHECK: call {{.*}}_D18in_place_construct10returnNRVOFZS18in_place_construct1S // CHECK: call {{.*}}_D18in_place_construct10returnNRVOFZS18in_place_construct1S
// CHECK-SAME: %in_place_construct.S* {{.*}} %c // CHECK-SAME: %in_place_construct.S* {{.*}} %c
const c = returnNRVO(); const c = returnNRVO();
withOutContract();
} }
// CHECK-LABEL: define{{.*}} @{{.*}}_D18in_place_construct12staticArraysFZv // CHECK-LABEL: define{{.*}} @{{.*}}_D18in_place_construct12staticArraysFZv