Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1100,9 +1100,6 @@ extension Type {
/// False if expanding a type is invalid. For example, expanding a
/// struct-with-deinit drops the deinit.
func shouldExpand(_ context: some Context) -> Bool {
if !context.options.useAggressiveReg2MemForCodeSize {
return true
}
return context.bridgedPassContext.shouldExpand(self.bridged)
}
}
Expand Down
7 changes: 7 additions & 0 deletions lib/DriverTool/sil_opt_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,11 @@ struct SILOptOptions {
"enable-address-dependencies",
llvm::cl::desc("Enable enforcement of lifetime dependencies on addressable values."));

llvm::cl::opt<bool> DisaleAggressiveReg2Mem = llvm::cl::opt<bool>(
"disable-aggressive-reg2mem",
llvm::cl::desc("Disable aggressive reg2mem optimizations."),
llvm::cl::init(false));

llvm::cl::opt<bool> EnableCalleeAllocatedCoroAbi = llvm::cl::opt<bool>(
"enable-callee-allocated-coro-abi",
llvm::cl::desc("Override per-platform settings and use yield_once_2."),
Expand Down Expand Up @@ -921,6 +926,8 @@ int sil_opt_main(ArrayRef<const char *> argv, void *MainAddr) {
options.EnablePackMetadataStackPromotion;

SILOpts.EnableAddressDependencies = options.EnableAddressDependencies;
if (options.DisaleAggressiveReg2Mem)
SILOpts.UseAggressiveReg2MemForCodeSize = false;
if (options.EnableCalleeAllocatedCoroAbi)
SILOpts.CoroutineAccessorsUseYieldOnce2 = true;
if (options.DisableCalleeAllocatedCoroAbi)
Expand Down
8 changes: 8 additions & 0 deletions lib/SIL/Utils/InstructionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1486,10 +1486,18 @@ bool swift::shouldExpand(SILModule &module, SILType ty) {
if (nominalTy->getValueTypeDestructor())
return false;
}

// At this point we know it's valid to expand the type, next decide if we
// "should" expand it.

if (EnableExpandAll) {
return true;
}

if (!module.getOptions().UseAggressiveReg2MemForCodeSize) {
return true;
}

unsigned numFields = module.Types.countNumberOfFields(ty, expansion);
return (numFields <= 6);
}
3 changes: 3 additions & 0 deletions test/IRGen/moveonly_value_functions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
// RUN: | \
// RUN: %IRGenFileCheck %s

// FIXME: This test currently requires aggressive reg2mem to be enabled
// UNSUPPORTED: CPU=wasm32

@_silgen_name("external_symbol")
func external_symbol()

Expand Down
44 changes: 44 additions & 0 deletions test/SILOptimizer/redundant_load_elim_struct_deinit.sil
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// RUN: %target-sil-opt -module-name Swift -sil-print-types -enforce-exclusivity=none -enable-sil-verify-all %s -redundant-load-elimination | %FileCheck %s
// RUN: %target-sil-opt -module-name Swift -sil-print-types -enforce-exclusivity=none -enable-sil-verify-all %s -redundant-load-elimination -disable-aggressive-reg2mem | %FileCheck %s

// REQUIRES: swift_in_compiler

import Builtin

@_marker protocol Copyable {}

final class C1 {}

struct S1 {}

struct StructWithDeinit : ~Copyable {
// stored class-instance to ensure this struct has a non-trivial
var f1: C1
var f2: S1
deinit
}

// CHECK-LABEL: sil [ossa] @test : $@convention(thin) (@owned StructWithDeinit, @owned S1) -> ()
// CHECK: %[[STACK:.*]] = alloc_stack $StructWithDeinit
// CHECK: load [take] %[[STACK]] : $*StructWithDeinit
// CHECK: } // end sil function 'test'
sil [ossa] @test : $@convention(thin) (@owned StructWithDeinit, @owned S1) -> () {
bb0(%0 : @owned $StructWithDeinit, %1 : $S1):
%2 = alloc_stack $StructWithDeinit
store %0 to [init] %2
// partial store into f2
%3 = struct_element_addr %2, #StructWithDeinit.f2
store %1 to [trivial] %3

// redundant load of the whole struct
%4 = load [take] %2
destroy_value %4

dealloc_stack %2
%5 = tuple ()
return %5
}

sil @s1_deinit : $@convention(method) (@owned StructWithDeinit) -> ()
sil_moveonlydeinit StructWithDeinit { @s1_deinit }