Skip to content

Commit 07eb52a

Browse files
authored
Merge pull request #72636 from Azoy/destroy-array-opt
[IRGen] Optimize Builtin.arrayDestroy when count is 1
2 parents 2f44b0a + 8ea3426 commit 07eb52a

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

lib/IRGen/GenBuiltin.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,17 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
11371137
ptr = IGF.Builder.CreateBitCast(ptr,
11381138
valueTy.second.getStorageType()->getPointerTo());
11391139
Address array = valueTy.second.getAddressForPointer(ptr);
1140+
1141+
// If the count is statically known to be a constant 1, then just call the
1142+
// type's destroy instead of the array variant.
1143+
if (auto ci = dyn_cast<llvm::ConstantInt>(count)) {
1144+
if (ci->isOne()) {
1145+
bool isOutlined = false;
1146+
valueTy.second.destroy(IGF, array, valueTy.first, isOutlined);
1147+
return;
1148+
}
1149+
}
1150+
11401151
valueTy.second.destroyArray(IGF, array, count, valueTy.first);
11411152
return;
11421153
}

stdlib/public/core/UnsafePointer.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,8 +1169,8 @@ extension UnsafeMutablePointer where Pointee: ~Copyable {
11691169
@discardableResult
11701170
public func deinitialize(count: Int) -> UnsafeMutableRawPointer {
11711171
_debugPrecondition(count >= 0, "UnsafeMutablePointer.deinitialize with negative count")
1172-
// TODO: IRGen optimization when `count` value is statically known to be 1,
1173-
// then call `Builtin.destroy(Pointee.self, _rawValue)` instead.
1172+
// Note: When count is statically known to be 1 the compiler will optimize
1173+
// away a call to swift_arrayDestroy into the type's specific destroy.
11741174
Builtin.destroyArray(Pointee.self, _rawValue, count._builtinWordValue)
11751175
return UnsafeMutableRawPointer(self)
11761176
}

test/IRGen/builtins.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,26 @@ func destroyGenArray<T>(_ array: Builtin.RawPointer, count: Builtin.Word, _: T)
456456
Builtin.destroyArray(T.self, array, count)
457457
}
458458

459+
// CHECK-LABEL: define hidden {{.*}}void @"$s8builtins21destroyArraySinglePODyyBpF"(ptr %0)
460+
// CHECK-NOT: call void @swift_arrayDestroy
461+
func destroyArraySinglePOD(_ array: Builtin.RawPointer) {
462+
Builtin.destroyArray(Int.self, array, 1._builtinWordValue)
463+
}
464+
465+
// CHECK-LABEL: define hidden {{.*}}void @"$s8builtins24destroyArraySingleNonPODyyBpF"(ptr %0)
466+
// CHECK-NOT: call void @swift_arrayDestroy
467+
// CHECK: [[TO_DESTROY:%.*]] = load ptr, ptr {{%.*}}
468+
// CHECK: call void @swift_release(ptr [[TO_DESTROY]])
469+
func destroyArraySingleNonPOD(_ array: Builtin.RawPointer) {
470+
Builtin.destroyArray(C.self, array, 1._builtinWordValue)
471+
}
472+
473+
// CHECK-LABEL: define hidden {{.*}}void @"$s8builtins21destroyArraySingleGenyyBp_xmtlF"(ptr %0, ptr %1, ptr %T)
474+
// CHECK-NOT: call void @swift_arrayDestroy
475+
// CHECK: call void {{%.*}}(ptr {{.*}} {{%.*}}, ptr %T)
476+
func destroyArraySingleGen<T>(_ array: Builtin.RawPointer, _: T.Type) {
477+
Builtin.destroyArray(T.self, array, 1._builtinWordValue)
478+
}
459479

460480
// CHECK-LABEL: define hidden {{.*}}void @"$s8builtins12copyPODArray{{[_0-9a-zA-Z]*}}F"(ptr %0, ptr %1, i64 %2)
461481
// check: mul nuw i64 4, %2

0 commit comments

Comments
 (0)