SIL: support vector_base_addr in AccessUtils and WalkUtils

This enables alias analysis and optimizations, like, redundant load elimination, to benefit from it.
This commit is contained in:
Erik Eckstein
2025-05-09 18:20:45 +02:00
parent 0e790fcc5d
commit f6ce61cf43
6 changed files with 104 additions and 1 deletions

View File

@@ -431,7 +431,7 @@ public struct AccessPath : CustomStringConvertible, Hashable {
private func canBeOperandOfIndexAddr(_ value: Value) -> Bool {
switch value {
case is IndexAddrInst, is RefTailAddrInst, is PointerToAddressInst:
case is IndexAddrInst, is RefTailAddrInst, is PointerToAddressInst, is VectorBaseAddrInst:
return true
default:
return false

View File

@@ -509,6 +509,12 @@ extension AddressDefUseWalker {
} else {
return unmatchedPath(address: operand, path: path)
}
case let vba as VectorBaseAddrInst:
if let path = path.popIfMatches(.vectorBase, index: 0) {
return walkDownUses(ofAddress: vba, path: path)
} else {
return unmatchedPath(address: operand, path: path)
}
case is InitEnumDataAddrInst, is UncheckedTakeEnumDataAddrInst:
let ei = instruction as! SingleValueInstruction
if let path = path.popIfMatches(.enumCase, index: (instruction as! EnumInstruction).caseIndex) {
@@ -814,6 +820,8 @@ extension AddressUseDefWalker {
return walkUp(address: sea.struct, path: path.push(.structField, index: sea.fieldIndex))
case let tea as TupleElementAddrInst:
return walkUp(address: tea.tuple, path: path.push(.tupleField, index: tea.fieldIndex))
case let vba as VectorBaseAddrInst:
return walkUp(address: vba.vector, path: path.push(.vectorBase, index: 0))
case let ida as InitEnumDataAddrInst:
return walkUp(address: ida.operand.value, path: path.push(.enumCase, index: ida.caseIndex))
case let uteda as UncheckedTakeEnumDataAddrInst:

View File

@@ -27,6 +27,10 @@ struct Ptr {
var p: Int64
}
struct VectorStruct {
var a: Builtin.FixedArray<100, Int64>
}
class C {}
sil @_getC : $@convention(thin) () -> @owned C
@@ -707,3 +711,20 @@ bb0(%0 : @guaranteed $List):
return %6 : $Int64
}
// CHECK-LABEL: Accesses for vectors
// CHECK: Value: %4 = index_addr %2 : $*Int64, %3 : $Builtin.Int64
// CHECK-NEXT: Scope: base
// CHECK-NEXT: Base: argument - %0 = argument of bb0 : $*VectorStruct
// CHECK-NEXT: Path: "s0.b.i5"
// CHECK-NEXT: no Storage paths
// CHECK-LABEL: End accesses for vectors
sil [ossa] @vectors : $@convention(thin) (@in_guaranteed VectorStruct) -> Int64 {
bb0(%0 : $*VectorStruct):
%1 = struct_element_addr %0, #VectorStruct.a
%2 = vector_base_addr %1
%3 = integer_literal $Builtin.Int64, 5
%4 = index_addr %2, %3
%5 = load [trivial] %4
return %5
}

View File

@@ -99,3 +99,44 @@ bb0(%0 : $*MyStruct, %1 : $Builtin.Word):
%99 = tuple ()
return %99 : $()
}
// CHECK-LABEL: @testVectorBaseAddr
// CHECK: PAIR #18.
// CHECK-NEXT: %2 = vector_base_addr %0 : $*Builtin.FixedArray<10, Int>
// CHECK-NEXT: %3 = index_addr %2 : $*Int, %1 : $Builtin.Word
// CHECK-NEXT: MayAlias
// CHECK: PAIR #21.
// CHECK-NEXT: %2 = vector_base_addr %0 : $*Builtin.FixedArray<10, Int>
// CHECK-NEXT: %6 = index_addr %2 : $*Int, %4 : $Builtin.Word
// CHECK-NEXT: NoAlias
// CHECK: PAIR #22.
// CHECK-NEXT: %2 = vector_base_addr %0 : $*Builtin.FixedArray<10, Int>
// CHECK-NEXT: %7 = index_addr %2 : $*Int, %5 : $Builtin.Word
// CHECK-NEXT: NoAlias
// CHECK: PAIR #27.
// CHECK-NEXT: %3 = index_addr %2 : $*Int, %1 : $Builtin.Word
// CHECK-NEXT: %6 = index_addr %2 : $*Int, %4 : $Builtin.Word
// CHECK-NEXT: MayAlias
// CHECK: PAIR #28.
// CHECK-NEXT: %3 = index_addr %2 : $*Int, %1 : $Builtin.Word
// CHECK-NEXT: %7 = index_addr %2 : $*Int, %5 : $Builtin.Word
// CHECK-NEXT: MayAlias
// CHECK: PAIR #40.
// CHECK-NEXT: %6 = index_addr %2 : $*Int, %4 : $Builtin.Word
// CHECK-NEXT: %7 = index_addr %2 : $*Int, %5 : $Builtin.Word
// CHECK-NEXT: NoAlias
sil @testVectorBaseAddr : $@convention(thin) (@inout Builtin.FixedArray<10, Int>, Builtin.Word) -> () {
bb0(%0 : $*Builtin.FixedArray<10, Int>, %1 : $Builtin.Word):
%2 = vector_base_addr %0
%3 = index_addr %2, %1
%4 = integer_literal $Builtin.Word, 1
%5 = integer_literal $Builtin.Word, 2
%6 = index_addr %2, %4
%7 = index_addr %2, %5
fix_lifetime %2
fix_lifetime %3
fix_lifetime %6
fix_lifetime %7
%99 = tuple ()
return %99 : $()
}

View File

@@ -1510,3 +1510,21 @@ bb0:
dealloc_stack %0 : $*X
return %4 : $Builtin.RawPointer
}
// CHECK-LABEL: Escape information for test_vector_base_addr_escaping:
// CHECK: return[]: %1 = alloc_ref $X
// CHECK: End function test_vector_base_addr_escaping
sil @test_vector_base_addr_escaping : $@convention(thin) () -> @owned X {
bb0:
%0 = alloc_stack $Builtin.FixedArray<10, X>
%1 = alloc_ref $X
%2 = vector_base_addr %0
%3 = integer_literal $Builtin.Int64, 1
%4 = index_addr %2, %3
store %1 to %4
%6 = vector_base_addr %0
%7 = index_addr %6, %3
%8 = load %4
dealloc_stack %0
return %8
}

View File

@@ -1743,3 +1743,18 @@ bb0(%0 : $Int):
dealloc_stack %3
return %6
}
// CHECK-LABEL: sil [ossa] @vector :
// CHECK: return %1
// CHECK-LABEL: } // end sil function 'vector'
sil [ossa] @vector : $@convention(thin) (@inout Builtin.FixedArray<10, Int>, Int, Int) -> Int {
bb0(%0 : $*Builtin.FixedArray<10, Int>, %1 : $Int, %2 : $Int):
%3 = vector_base_addr %0
%4 = integer_literal $Builtin.Word, 1
%5 = index_addr %3, %4
store %1 to [trivial] %5
store %2 to [trivial] %3
%6 = load [trivial] %5
return %6
}