Skip to content

Commit 983d955

Browse files
committed
AccessUtils: do a simple type-based alias analysis in AccessBase.isDistinct
If the operand types (which are classes) of `ref_element_addr` or `ref_tail_addr` differ, then we know those can't be the same objects.
1 parent cf99536 commit 983d955

File tree

2 files changed

+53
-3
lines changed

2 files changed

+53
-3
lines changed

SwiftCompilerSources/Sources/SIL/Utilities/AccessUtils.swift

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,15 @@ public enum AccessBase : CustomStringConvertible, Hashable {
237237
}
238238
}
239239

240+
func hasDifferentType(_ lhs: Value, _ rhs: Value) -> Bool {
241+
return lhs.type != rhs.type &&
242+
// If the types have unbound generic arguments then we don't know
243+
// the possible range of the type. A type such as $Array<Int> may
244+
// alias $Array<T>. Right now we are conservative and we assume
245+
// that $UnsafeMutablePointer<T> and $Int may alias.
246+
!lhs.type.hasArchetype && !rhs.type.hasArchetype
247+
}
248+
240249
func argIsDistinct(_ arg: FunctionArgument, from other: AccessBase) -> Bool {
241250
if arg.convention.isExclusiveIndirect {
242251
// Exclusive indirect arguments cannot alias with an address for which we know that it
@@ -252,16 +261,19 @@ public enum AccessBase : CustomStringConvertible, Hashable {
252261
// First handle all pairs of the same kind (except `yield` and `pointer`).
253262
case (.box(let pb), .box(let otherPb)):
254263
return pb.fieldIndex != otherPb.fieldIndex ||
255-
isDifferentAllocation(pb.box.referenceRoot, otherPb.box.referenceRoot)
264+
isDifferentAllocation(pb.box.referenceRoot, otherPb.box.referenceRoot) ||
265+
hasDifferentType(pb.box, otherPb.box)
256266
case (.stack(let asi), .stack(let otherAsi)):
257267
return asi != otherAsi
258268
case (.global(let global), .global(let otherGlobal)):
259269
return global != otherGlobal
260270
case (.class(let rea), .class(let otherRea)):
261271
return rea.fieldIndex != otherRea.fieldIndex ||
262-
isDifferentAllocation(rea.instance, otherRea.instance)
272+
isDifferentAllocation(rea.instance, otherRea.instance) ||
273+
hasDifferentType(rea.instance, otherRea.instance)
263274
case (.tail(let rta), .tail(let otherRta)):
264-
return isDifferentAllocation(rta.instance, otherRta.instance)
275+
return isDifferentAllocation(rta.instance, otherRta.instance) ||
276+
hasDifferentType(rta.instance, otherRta.instance)
265277
case (.argument(let arg), .argument(let otherArg)):
266278
return (arg.convention.isExclusiveIndirect || otherArg.convention.isExclusiveIndirect) && arg != otherArg
267279

test/SILOptimizer/basic-aa.sil

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,3 +646,41 @@ bb0:
646646
return %99 : $()
647647
}
648648

649+
class GenericClass<T> {
650+
var x : T
651+
}
652+
653+
// CHECK-LABEL: @test_generic_class
654+
// CHECK: PAIR #10.
655+
// CHECK-NEXT: %2 = ref_element_addr %0 : $GenericClass<T>, #GenericClass.x
656+
// CHECK-NEXT: %3 = ref_element_addr %1 : $GenericClass<Int>, #GenericClass.x
657+
// CHECK-NEXT: MayAlias
658+
sil [ossa] @test_generic_class : $@convention(thin) <T> (@guaranteed GenericClass<T>, @guaranteed GenericClass<Int>) -> () {
659+
bb0(%0 : @guaranteed $GenericClass<T>, %1 : @guaranteed $GenericClass<Int>):
660+
%2 = ref_element_addr %0 : $GenericClass<T>, #GenericClass.x
661+
%3 = ref_element_addr %1 : $GenericClass<Int>, #GenericClass.x
662+
663+
fix_lifetime %2 : $*T
664+
fix_lifetime %3 : $*Int
665+
666+
%9999 = tuple()
667+
return %9999 : $()
668+
}
669+
670+
// CHECK-LABEL: @test_bound_generic_class
671+
// CHECK: PAIR #10.
672+
// CHECK-NEXT: %2 = ref_element_addr %0 : $GenericClass<Int32>, #GenericClass.x
673+
// CHECK-NEXT: %3 = ref_element_addr %1 : $GenericClass<Int>, #GenericClass.x
674+
// CHECK-NEXT: NoAlias
675+
sil [ossa] @test_bound_generic_class : $@convention(thin) (@guaranteed GenericClass<Int32>, @guaranteed GenericClass<Int>) -> () {
676+
bb0(%0 : @guaranteed $GenericClass<Int32>, %1 : @guaranteed $GenericClass<Int>):
677+
%2 = ref_element_addr %0 : $GenericClass<Int32>, #GenericClass.x
678+
%3 = ref_element_addr %1 : $GenericClass<Int>, #GenericClass.x
679+
680+
fix_lifetime %2 : $*Int32
681+
fix_lifetime %3 : $*Int
682+
683+
%9999 = tuple()
684+
return %9999 : $()
685+
}
686+

0 commit comments

Comments
 (0)