Skip to content

Commit 1752b48

Browse files
authored
Merge pull request #71997 from Azoy/fix-zero-init-escape
[EscapeAnalysis] Handle atomic instructions in escape analysis
2 parents 698ae7b + 254e4f0 commit 1752b48

File tree

3 files changed

+170
-0
lines changed

3 files changed

+170
-0
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeUtils.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,41 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
420420
return .continueWalk
421421
}
422422
return isEscaping
423+
424+
case .AtomicLoad:
425+
// Treat atomic loads as regular loads and just walk down their uses.
426+
if !followLoads(at: path) {
427+
return .continueWalk
428+
}
429+
430+
// Even when analyzing atomics, a loaded trivial value can be ignored.
431+
if hasRelevantType(bi, at: path.projectionPath) {
432+
return .continueWalk
433+
}
434+
435+
return walkDownUses(ofValue: bi, path: path.with(knownType: nil))
436+
437+
case .AtomicStore, .AtomicRMW:
438+
// If we shouldn't follow the store, then we can keep walking.
439+
if !path.followStores {
440+
return .continueWalk
441+
}
442+
443+
// Be conservative and just say the store is escaping.
444+
return isEscaping
445+
446+
case .CmpXChg:
447+
// If we have to follow loads or stores of a cmpxchg, then just bail.
448+
if followLoads(at: path) || path.followStores {
449+
return isEscaping
450+
}
451+
452+
return .continueWalk
453+
454+
case .Fence:
455+
// Fences do not affect escape analysis.
456+
return .continueWalk
457+
423458
default:
424459
return isEscaping
425460
}

test/SILOptimizer/mem-behavior.sil

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,131 @@ bb0:
11001100
return %4 : $()
11011101
}
11021102

1103+
// CHECK-LABEL: @test_builtin_zeroInitializer_atomicload
1104+
// CHECK: PAIR #0.
1105+
// CHECK-NEXT: %2 = builtin "zeroInitializer"<C>(%1 : $*C)
1106+
// CHECK-NEXT: %0 = alloc_stack
1107+
// CHECK-NEXT: r=0,w=0
1108+
// CHECK: PAIR #1.
1109+
// CHECK-NEXT: %2 = builtin "zeroInitializer"<C>(%1 : $*C)
1110+
// CHECK-NEXT: %1 = alloc_stack
1111+
// CHECK-NEXT: r=0,w=1
1112+
sil @test_builtin_zeroInitializer_atomicload : $@convention(thin) () -> Builtin.Int64 {
1113+
bb0:
1114+
%0 = alloc_stack $C
1115+
%1 = alloc_stack $C
1116+
%2 = builtin "zeroInitializer"<C>(%1 : $*C) : $()
1117+
%3 = apply undef<C>(%1) : $@convention(thin) <C> () -> @out C
1118+
copy_addr [take] %1 to [init] %0 : $*C
1119+
dealloc_stack %1 : $*C
1120+
%4 = address_to_pointer %0 : $*C to $Builtin.RawPointer
1121+
%5 = builtin "atomicload_monotonic_Int64"(%4 : $Builtin.RawPointer) : $Builtin.Int64
1122+
destroy_addr %0 : $*C
1123+
dealloc_stack %0 : $*C
1124+
return %5 : $Builtin.Int64
1125+
}
1126+
1127+
// CHECK-LABEL: @test_builtin_zeroInitializer_atomicstore
1128+
// CHECK: PAIR #0.
1129+
// CHECK-NEXT: %2 = builtin "zeroInitializer"<C>(%1 : $*C)
1130+
// CHECK-NEXT: %0 = alloc_stack
1131+
// CHECK-NEXT: r=0,w=0
1132+
// CHECK: PAIR #1.
1133+
// CHECK-NEXT: %2 = builtin "zeroInitializer"<C>(%1 : $*C)
1134+
// CHECK-NEXT: %1 = alloc_stack
1135+
// CHECK-NEXT: r=0,w=1
1136+
sil @test_builtin_zeroInitializer_atomicstore : $@convention(thin) () -> () {
1137+
bb0:
1138+
%0 = alloc_stack $C
1139+
%1 = alloc_stack $C
1140+
%2 = builtin "zeroInitializer"<C>(%1 : $*C) : $()
1141+
%3 = apply undef<C>(%1) : $@convention(thin) <C> () -> @out C
1142+
copy_addr [take] %1 to [init] %0 : $*C
1143+
dealloc_stack %1 : $*C
1144+
%4 = address_to_pointer %0 : $*C to $Builtin.RawPointer
1145+
%5 = integer_literal $Builtin.Int64, 1
1146+
%6 = builtin "atomicstore_monotonic_Int64"(%4 : $Builtin.RawPointer, %5 : $Builtin.Int64) : $()
1147+
destroy_addr %0 : $*C
1148+
dealloc_stack %0 : $*C
1149+
%7 = tuple ()
1150+
return %7 : $()
1151+
}
1152+
1153+
// CHECK-LABEL: @test_builtin_zeroInitializer_atomicrmw
1154+
// CHECK: PAIR #0.
1155+
// CHECK-NEXT: %2 = builtin "zeroInitializer"<C>(%1 : $*C)
1156+
// CHECK-NEXT: %0 = alloc_stack
1157+
// CHECK-NEXT: r=0,w=0
1158+
// CHECK: PAIR #1.
1159+
// CHECK-NEXT: %2 = builtin "zeroInitializer"<C>(%1 : $*C)
1160+
// CHECK-NEXT: %1 = alloc_stack
1161+
// CHECK-NEXT: r=0,w=1
1162+
sil @test_builtin_zeroInitializer_atomicrmw : $@convention(thin) () -> (Builtin.Int64, Builtin.Int64) {
1163+
bb0:
1164+
%0 = alloc_stack $C
1165+
%1 = alloc_stack $C
1166+
%2 = builtin "zeroInitializer"<C>(%1 : $*C) : $()
1167+
%3 = apply undef<C>(%1) : $@convention(thin) <C> () -> @out C
1168+
copy_addr [take] %1 to [init] %0 : $*C
1169+
dealloc_stack %1 : $*C
1170+
%4 = address_to_pointer %0 : $*C to $Builtin.RawPointer
1171+
%5 = integer_literal $Builtin.Int64, 1
1172+
%6 = builtin "atomicrmw_xchg_monotonic_Int64"(%4 : $Builtin.RawPointer, %5 : $Builtin.Int64) : $Builtin.Int64
1173+
%7 = builtin "atomicrmw_add_monotonic_Int64"(%4 : $Builtin.RawPointer, %5 : $Builtin.Int64) : $Builtin.Int64
1174+
destroy_addr %0 : $*C
1175+
dealloc_stack %0 : $*C
1176+
%8 = tuple (%6 : $Builtin.Int64, %7 : $Builtin.Int64)
1177+
return %8 : $(Builtin.Int64, Builtin.Int64)
1178+
}
1179+
1180+
// CHECK-LABEL: @test_builtin_zeroInitializer_cmpxchg
1181+
// CHECK: PAIR #0.
1182+
// CHECK-NEXT: %2 = builtin "zeroInitializer"<C>(%1 : $*C)
1183+
// CHECK-NEXT: %0 = alloc_stack
1184+
// CHECK-NEXT: r=0,w=0
1185+
// CHECK: PAIR #1.
1186+
// CHECK-NEXT: %2 = builtin "zeroInitializer"<C>(%1 : $*C)
1187+
// CHECK-NEXT: %1 = alloc_stack
1188+
// CHECK-NEXT: r=0,w=1
1189+
sil @test_builtin_zeroInitializer_cmpxchg : $@convention(thin) () -> (Builtin.Int64, Builtin.Int1) {
1190+
bb0:
1191+
%0 = alloc_stack $C
1192+
%1 = alloc_stack $C
1193+
%2 = builtin "zeroInitializer"<C>(%1 : $*C) : $()
1194+
%3 = apply undef<C>(%1) : $@convention(thin) <C> () -> @out C
1195+
copy_addr [take] %1 to [init] %0 : $*C
1196+
dealloc_stack %1 : $*C
1197+
%4 = address_to_pointer %0 : $*C to $Builtin.RawPointer
1198+
%5 = integer_literal $Builtin.Int64, 1
1199+
%6 = builtin "cmpxchg_monotonic_monotonic_Int64"(%4 : $Builtin.RawPointer, %5 : $Builtin.Int64) : $(Builtin.Int64, Builtin.Int1)
1200+
destroy_addr %0 : $*C
1201+
dealloc_stack %0 : $*C
1202+
return %6 : $(Builtin.Int64, Builtin.Int1)
1203+
}
1204+
1205+
// CHECK-LABEL: @test_builtin_zeroInitializer_fence
1206+
// CHECK: PAIR #0.
1207+
// CHECK-NEXT: %2 = builtin "zeroInitializer"<C>(%1 : $*C)
1208+
// CHECK-NEXT: %0 = alloc_stack
1209+
// CHECK-NEXT: r=0,w=0
1210+
// CHECK: PAIR #1.
1211+
// CHECK-NEXT: %2 = builtin "zeroInitializer"<C>(%1 : $*C)
1212+
// CHECK-NEXT: %1 = alloc_stack
1213+
// CHECK-NEXT: r=0,w=1
1214+
sil @test_builtin_zeroInitializer_fence : $@convention(thin) () -> () {
1215+
bb0:
1216+
%0 = alloc_stack $C
1217+
%1 = alloc_stack $C
1218+
%2 = builtin "zeroInitializer"<C>(%1 : $*C) : $()
1219+
%3 = apply undef<C>(%1) : $@convention(thin) <C> () -> @out C
1220+
copy_addr [take] %1 to [init] %0 : $*C
1221+
dealloc_stack %1 : $*C
1222+
%5 = builtin "fence_release"() : $()
1223+
destroy_addr %0 : $*C
1224+
dealloc_stack %0 : $*C
1225+
return %5 : $()
1226+
}
1227+
11031228
// CHECK-LABEL: @test_stored_pointer
11041229
// CHECK: PAIR #3.
11051230
// CHECK-NEXT: %5 = apply %4(%2) : $@convention(thin) (@in Builtin.RawPointer) -> ()

test/SILOptimizer/templvalueopt.sil

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,16 @@ bb0(%ret_addr : $*T):
264264
apply undef<T>(%temporary) : $@convention(thin) <T> () -> @out T
265265
copy_addr [take] %temporary to [init] %ret_addr : $*T
266266
dealloc_stack %temporary : $*T
267+
268+
// Ensure that the following builtin instructions don't interfere with
269+
// temp l value from getting rid of the temporary.
270+
%empty = builtin "fence_release"() : $()
271+
%ptr = address_to_pointer %ret_addr : $*T to $Builtin.RawPointer
272+
%load = builtin "atomicload_monotonic_Int64"(%ptr : $Builtin.RawPointer) : $Builtin.Int64
273+
%onetwoeight = integer_literal $Builtin.Int64, 128
274+
%empty2 = builtin "atomicstore_monotonic_Int64"(%ptr : $Builtin.RawPointer, %onetwoeight : $Builtin.Int64) : $()
275+
%add = builtin "atomicrmw_add_monotonic_Int64"(%ptr : $Builtin.RawPointer, %onetwoeight : $Builtin.Int64) : $Builtin.Int64
276+
%cmpxchg = builtin "cmpxchg_monotonic_monotonic_Int64"(%ptr : $Builtin.RawPointer, %onetwoeight : $Builtin.Int64, %onetwoeight : $Builtin.Int64) : $(Builtin.Int64, Builtin.Int1)
267277
%15 = tuple ()
268278
return %15 : $()
269279
}

0 commit comments

Comments
 (0)