SILGen: use builtin prepareInitialization instead of zeroInitializer when generating a value constructor for an empty non-copyable type

`zeroInitializer` is blocking optimizations. It is not needed because the constructor will initialize the memory anyway.
We only need to tell mandatory passes that this memory should be treated as initialized.
This commit is contained in:
Erik Eckstein
2025-08-01 14:27:14 +02:00
parent adc5d67a9a
commit c1258f5a90
3 changed files with 9 additions and 4 deletions

View File

@@ -738,8 +738,13 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
// move only structs are non-trivial, so we need to handle this here.
if (nominal->getAttrs().hasAttribute<RawLayoutAttr>()) {
// Raw memory is not directly decomposable, but we still want to mark
// it as initialized. Use a zero initializer.
B.createZeroInitAddr(ctor, selfLV.getLValueAddress());
// it as initialized.
auto prepInit = getBuiltinValueDecl(getASTContext(),
getASTContext().getIdentifier("prepareInitialization"));
B.createBuiltin(ctor, prepInit->getBaseIdentifier(),
SILType::getEmptyTupleType(getASTContext()),
SubstitutionMap(),
selfLV.getLValueAddress());
} else if (isa<StructDecl>(nominal)
&& lowering.getLoweredType().isMoveOnly()
&& nominal->getStoredProperties().empty()) {

View File

@@ -20,7 +20,7 @@ struct Lock: ~Copyable {
// CHECK-NEXT: sil{{.*}} @[[INIT:\$.*4LockV.*fC]] :
init() {
// CHECK-NOT: destroy_addr
// CHECK: builtin "zeroInitializer"({{%.*}} : $*Lock)
// CHECK: builtin "prepareInitialization"({{%.*}} : $*Lock)
// CHECK-NOT: destroy_addr
// CHECK: [[F:%.*]] = function_ref @init_lock
// CHECK: apply [[F]](

View File

@@ -20,7 +20,7 @@ public struct Cell<T: ~Copyable>: ~Copyable {
// CHECK-LABEL: sil {{.*}} @$s4CellAAVAARi_zrlEyAByxGxcfC : $@convention(method) <T where T : ~Copyable> (@in T, @thin Cell<T>.Type) -> @out Cell<T> {
// CHECK: bb0({{%.*}} : $*Cell<T>, [[VALUE:%.*]] : $*T, {{%.*}} : $@thin Cell<T>.Type):
// CHECK: {{%.*}} = builtin "zeroInitializer"([[SELF:%.*]] : $*Cell<T>) : $()
// CHECK: {{%.*}} = builtin "prepareInitialization"([[SELF:%.*]] : $*Cell<T>) : $()
// CHECK-NEXT: [[RAW_LAYOUT_ADDR:%.*]] = builtin "addressOfRawLayout"<Cell<T>>([[SELF]] : $*Cell<T>) : $Builtin.RawPointer
// CHECK-NEXT: [[POINTER:%.*]] = struct $UnsafeMutablePointer<T> ([[RAW_LAYOUT_ADDR]] : $Builtin.RawPointer)
// Calling 'UnsafeMutablePointer<T>.initialize(to:)'