mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-04-29 22:50:53 +03:00
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:
parent
1760e261db
commit
12ff7ef803
2 changed files with 22 additions and 2 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue