Skip to content

Commit 20edeb6

Browse files
committed
Swift Optimizer: add Onone simplification of unchecked_enum_data instructions
1 parent 4cf6269 commit 20edeb6

File tree

3 files changed

+113
-1
lines changed

3 files changed

+113
-1
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ swift_compiler_sources(Optimizer
1313
SimplifyBuiltin.swift
1414
SimplifyCondBranch.swift
1515
SimplifyGlobalValue.swift
16-
SimplifyStrongRetainRelease.swift)
16+
SimplifyStrongRetainRelease.swift
17+
SimplifyUncheckedEnumData.swift)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===--- SimplifyUncheckedEnumData.swift ----------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SIL
14+
15+
extension UncheckedEnumDataInst : OnoneSimplifyable {
16+
func simplify(_ context: SimplifyContext) {
17+
guard let enumInst = operand as? EnumInst else {
18+
return
19+
}
20+
if caseIndex != enumInst.caseIndex {
21+
return
22+
}
23+
context.tryReplaceRedundantInstructionPair(first: enumInst, second: self, with: enumInst.operand)
24+
}
25+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -onone-simplification -simplify-instruction=unchecked_enum_data | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ONONE
2+
// RUN: %target-sil-opt -enable-sil-verify-all %s -simplification -simplify-instruction=unchecked_enum_data | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-O
3+
4+
// REQUIRES: swift_in_compiler
5+
6+
import Swift
7+
import Builtin
8+
9+
enum E {
10+
case A(String)
11+
case B(String)
12+
}
13+
14+
// CHECK-LABEL: sil @forward_enum_data
15+
// CHECK: return %0
16+
// CHECK: } // end sil function 'forward_enum_data'
17+
sil @forward_enum_data : $@convention(thin) (@owned String) -> @owned String {
18+
bb0(%0 : $String):
19+
%1 = enum $E, #E.B!enumelt, %0 : $String
20+
%2 = unchecked_enum_data %1 : $E, #E.B!enumelt
21+
return %2 : $String
22+
}
23+
24+
// CHECK-LABEL: sil @wrong_case
25+
// CHECK: %1 = enum
26+
// CHECK: %2 = unchecked_enum_data %1
27+
// CHECK: return %2
28+
// CHECK: } // end sil function 'wrong_case'
29+
sil @wrong_case : $@convention(thin) (@owned String) -> @owned String {
30+
bb0(%0 : $String):
31+
%1 = enum $E, #E.B!enumelt, %0 : $String
32+
// Strictly speaking this is illegal SIL.
33+
%2 = unchecked_enum_data %1 : $E, #E.A!enumelt
34+
return %2 : $String
35+
}
36+
37+
// CHECK-LABEL: sil [ossa] @forward_borrowed_enum_data
38+
// CHECK: %1 = copy_value %0
39+
// CHECK: return %1
40+
// CHECK: } // end sil function 'forward_borrowed_enum_data'
41+
sil [ossa] @forward_borrowed_enum_data : $@convention(thin) (@guaranteed String) -> @owned String {
42+
bb0(%0 : @guaranteed $String):
43+
%1 = enum $E, #E.B!enumelt, %0 : $String
44+
%2 = unchecked_enum_data %1 : $E, #E.B!enumelt
45+
%3 = copy_value %2 : $String
46+
return %3 : $String
47+
}
48+
49+
// CHECK-LABEL: sil [ossa] @forward_owned_enum_data :
50+
// CHECK: return %0
51+
// CHECK: } // end sil function 'forward_owned_enum_data'
52+
sil [ossa] @forward_owned_enum_data : $@convention(thin) (@owned String) -> @owned String {
53+
bb0(%0 : @owned $String):
54+
%1 = enum $E, #E.B!enumelt, %0 : $String
55+
%2 = unchecked_enum_data %1 : $E, #E.B!enumelt
56+
return %2 : $String
57+
}
58+
59+
// CHECK-LABEL: sil [ossa] @dont_forward_owned_enum_data_with_uses :
60+
// CHECK %1 = enum
61+
// CHECK %4 = unchecked_enum_data %1
62+
// CHECK return %4
63+
// CHECK: } // end sil function 'dont_forward_owned_enum_data_with_uses'
64+
sil [ossa] @dont_forward_owned_enum_data_with_uses : $@convention(thin) (@owned String) -> @owned String {
65+
bb0(%0 : @owned $String):
66+
%1 = enum $E, #E.B!enumelt, %0 : $String
67+
%2 = begin_borrow %1 : $E
68+
end_borrow %2 : $E
69+
%4 = unchecked_enum_data %1 : $E, #E.B!enumelt
70+
return %4 : $String
71+
}
72+
73+
// CHECK-LABEL: sil [ossa] @forward_owned_enum_data_with_debug_use
74+
// CHECK-ONONE: %1 = enum
75+
// CHECK-ONONE: %3 = unchecked_enum_data %1
76+
// CHECK-ONONE: return %3
77+
// CHECK-O: return %0
78+
// CHECK: } // end sil function 'forward_owned_enum_data_with_debug_use'
79+
sil [ossa] @forward_owned_enum_data_with_debug_use : $@convention(thin) (@owned String) -> @owned String {
80+
bb0(%0 : @owned $String):
81+
%1 = enum $E, #E.B!enumelt, %0 : $String
82+
debug_value %1 : $E, let, name "e"
83+
%3 = unchecked_enum_data %1 : $E, #E.B!enumelt
84+
return %3 : $String
85+
}
86+

0 commit comments

Comments
 (0)