Handle mark_dependence in ArrayElementPropagation

This commit is contained in:
Meghana Gupta
2023-10-25 02:07:06 -07:00
parent 08cd370117
commit 473905b6b2
5 changed files with 75 additions and 29 deletions

View File

@@ -841,7 +841,8 @@ bool swift::ArraySemanticsCall::mapInitializationStores(
return false;
// Match initialization stores into ElementBuffer. E.g.
// %83 = struct_extract %element_buffer : $UnsafeMutablePointer<Int>
// %82 = struct_extract %element_buffer : $UnsafeMutablePointer<Int>
// %83 = mark_dependence %82 : $Builtin.RawPointer on ArrayVal
// %84 = pointer_to_address %83 : $Builtin.RawPointer to strict $*Int
// store %85 to %84 : $*Int
// %87 = integer_literal $Builtin.Word, 1
@@ -850,12 +851,27 @@ bool swift::ArraySemanticsCall::mapInitializationStores(
// If this an ArrayUninitializedIntrinsic then the ElementBuffer is a
// builtin.RawPointer. Otherwise, it is an UnsafeMutablePointer, which would
// be struct-extracted to obtain a builtin.RawPointer.
SILValue UnsafeMutablePointerExtract =
(getKind() == ArrayCallKind::kArrayUninitialized)
? dyn_cast_or_null<StructExtractInst>(
getSingleNonDebugUser(ElementBuffer))
: ElementBuffer;
// be struct-extracted to obtain a builtin.RawPointer. In this case
// mark_dependence can be an operand of the struct_extract or its user.
SILValue UnsafeMutablePointerExtract;
if (getKind() == ArrayCallKind::kArrayUninitializedIntrinsic) {
UnsafeMutablePointerExtract = dyn_cast_or_null<MarkDependenceInst>(
getSingleNonDebugUser(ElementBuffer));
} else {
auto user = getSingleNonDebugUser(ElementBuffer);
// Match mark_dependence (struct_extract or
// struct_extract (mark_dependence
if (auto *MDI = dyn_cast_or_null<MarkDependenceInst>(user)) {
UnsafeMutablePointerExtract =
dyn_cast_or_null<StructExtractInst>(getSingleNonDebugUser(MDI));
} else {
if (auto *SEI = dyn_cast_or_null<StructExtractInst>(user)) {
UnsafeMutablePointerExtract =
dyn_cast_or_null<MarkDependenceInst>(getSingleNonDebugUser(SEI));
}
}
}
if (!UnsafeMutablePointerExtract)
return false;

View File

@@ -122,6 +122,9 @@ bool ArrayAllocation::replacementsAreValid() {
/// Recursively look at all uses of this definition. Abort if the array value
/// could escape or be changed. Collect all uses that are calls to array.count.
bool ArrayAllocation::recursivelyCollectUses(ValueBase *Def) {
LLVM_DEBUG(llvm::dbgs() << "Collecting uses of:");
LLVM_DEBUG(Def->dump());
for (auto *Opd : Def->getUses()) {
auto *User = Opd->getUser();
// Ignore reference counting and debug instructions.
@@ -181,17 +184,28 @@ bool ArrayAllocation::analyze(ApplyInst *Alloc) {
if (!Uninitialized)
return false;
ArrayValue = Uninitialized.getArrayValue();
if (!ArrayValue)
return false;
LLVM_DEBUG(llvm::dbgs() << "Found array allocation: ");
LLVM_DEBUG(Alloc->dump());
// Figure out all stores to the array.
if (!mapInitializationStores(Uninitialized))
ArrayValue = Uninitialized.getArrayValue();
if (!ArrayValue) {
LLVM_DEBUG(llvm::dbgs() << "Did not find array value\n");
return false;
}
LLVM_DEBUG(llvm::dbgs() << "ArrayValue: ");
LLVM_DEBUG(ArrayValue->dump());
// Figure out all stores to the array.
if (!mapInitializationStores(Uninitialized)) {
LLVM_DEBUG(llvm::dbgs() << "Could not map initializing stores\n");
return false;
}
// Check if the array value was stored or has escaped.
if (!recursivelyCollectUses(ArrayValue))
if (!recursivelyCollectUses(ArrayValue)) {
LLVM_DEBUG(llvm::dbgs() << "Array value stored or escaped\n");
return false;
}
return true;
}
@@ -328,6 +342,8 @@ public:
auto &Fn = *getFunction();
bool Changed = false;
LLVM_DEBUG(llvm::dbgs() << "ArrayElementPropagation looking at function: "
<< Fn.getName() << "\n");
for (auto &BB : Fn) {
for (auto &Inst : BB) {
if (auto *Apply = dyn_cast<ApplyInst>(&Inst)) {

View File

@@ -70,7 +70,8 @@ sil @propagate_with_get_element_returning_direct_result : $@convention(thin) ()
%5 = function_ref @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
%6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
%7 = tuple_extract %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>), 0
%8 = tuple_extract %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>), 1
%8a = tuple_extract %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>), 1
%8 = mark_dependence %8a : $UnsafeMutablePointer<MyInt> on %7 : $MyArray<MyInt>
debug_value %7 : $MyArray<MyInt>
debug_value %8 : $UnsafeMutablePointer<MyInt>
%9 = struct_extract %8 : $UnsafeMutablePointer<MyInt>, #UnsafeMutablePointer._rawValue
@@ -144,7 +145,8 @@ sil @repeated_initialization : $@convention(thin) () -> () {
%5 = function_ref @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
%6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
%7 = tuple_extract %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>), 0
%8 = tuple_extract %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>), 1
%8a = tuple_extract %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>), 1
%8 = mark_dependence %8a : $UnsafeMutablePointer<MyInt> on %7 : $MyArray<MyInt>
%9 = struct_extract %8 : $UnsafeMutablePointer<MyInt>, #UnsafeMutablePointer._rawValue
%10 = pointer_to_address %9 : $Builtin.RawPointer to [strict] $*MyInt
%11 = integer_literal $Builtin.Int64, 0
@@ -193,7 +195,8 @@ sil @unknown_use : $@convention(thin) () -> () {
%5 = function_ref @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
%6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
%7 = tuple_extract %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>), 0
%8 = tuple_extract %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>), 1
%8a = tuple_extract %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>), 1
%8 = mark_dependence %8a : $UnsafeMutablePointer<MyInt> on %7 : $MyArray<MyInt>
%9 = struct_extract %8 : $UnsafeMutablePointer<MyInt>, #UnsafeMutablePointer._rawValue
%10 = pointer_to_address %9 : $Builtin.RawPointer to [strict] $*MyInt
%11 = integer_literal $Builtin.Int64, 0
@@ -240,7 +243,8 @@ sil @append_contentsOf_int : $@convention(thin) () -> () {
%5 = function_ref @arrayAdoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin Array<MyInt>.Type) -> @owned (Array<MyInt>, UnsafeMutablePointer<MyInt>)
%6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin Array<MyInt>.Type) -> @owned (Array<MyInt>, UnsafeMutablePointer<MyInt>)
%7 = tuple_extract %6 : $(Array<MyInt>, UnsafeMutablePointer<MyInt>), 0
%8 = tuple_extract %6 : $(Array<MyInt>, UnsafeMutablePointer<MyInt>), 1
%8a = tuple_extract %6 : $(Array<MyInt>, UnsafeMutablePointer<MyInt>), 1
%8 = mark_dependence %8a : $UnsafeMutablePointer<MyInt> on %7 : $Array<MyInt>
%9 = struct_extract %8 : $UnsafeMutablePointer<MyInt>, #UnsafeMutablePointer._rawValue
%10 = pointer_to_address %9 : $Builtin.RawPointer to [strict] $*MyInt
%11 = integer_literal $Builtin.Int64, 27
@@ -289,7 +293,8 @@ bb0(%0 : $*Array<Hello>, %1 : $Hello):
%9 = function_ref @adoptStorageHello : $@convention(method) (@owned _ContiguousArrayStorage<Hello>, MyInt, @thin Array<Hello>.Type) -> (@owned Array<Hello>, UnsafeMutablePointer<Hello>)
%10 = apply %9(%7, %6, %8) : $@convention(method) (@owned _ContiguousArrayStorage<Hello>, MyInt, @thin Array<Hello>.Type) -> (@owned Array<Hello>, UnsafeMutablePointer<Hello>)
%11 = tuple_extract %10 : $(Array<Hello>, UnsafeMutablePointer<Hello>), 0
%12 = tuple_extract %10 : $(Array<Hello>, UnsafeMutablePointer<Hello>), 1
%12a = tuple_extract %10 : $(Array<Hello>, UnsafeMutablePointer<Hello>), 1
%12 = mark_dependence %12a : $UnsafeMutablePointer<Hello> on %7 : $_ContiguousArrayStorage<Hello>
%13 = struct_extract %12 : $UnsafeMutablePointer<Hello>, #UnsafeMutablePointer._rawValue
%22 = pointer_to_address %13 : $Builtin.RawPointer to [strict] $*Hello
strong_retain %1 : $Hello

View File

@@ -68,7 +68,8 @@ sil [ossa] @propagate_with_get_element_returning_direct_result : $@convention(th
%4 = metatype $@thin MyArray<MyInt>.Type
%5 = function_ref @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
%6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
(%7, %8) = destructure_tuple %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
(%7, %8a) = destructure_tuple %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
%8 = mark_dependence %8a : $UnsafeMutablePointer<MyInt> on %7 : $MyArray<MyInt>
debug_value %7 : $MyArray<MyInt>
debug_value %8 : $UnsafeMutablePointer<MyInt>
%9 = struct_extract %8 : $UnsafeMutablePointer<MyInt>, #UnsafeMutablePointer._rawValue
@@ -138,7 +139,8 @@ sil [ossa] @repeated_initialization : $@convention(thin) () -> () {
%4 = metatype $@thin MyArray<MyInt>.Type
%5 = function_ref @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
%6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
(%7, %8) = destructure_tuple %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
(%7, %8a) = destructure_tuple %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
%8 = mark_dependence %8a : $UnsafeMutablePointer<MyInt> on %7 : $MyArray<MyInt>
%9 = struct_extract %8 : $UnsafeMutablePointer<MyInt>, #UnsafeMutablePointer._rawValue
%10 = pointer_to_address %9 : $Builtin.RawPointer to [strict] $*MyInt
%11 = integer_literal $Builtin.Int64, 0
@@ -185,7 +187,8 @@ sil [ossa] @unknown_use : $@convention(thin) () -> () {
%4 = metatype $@thin MyArray<MyInt>.Type
%5 = function_ref @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
%6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
(%7, %8) = destructure_tuple %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
(%7, %8a) = destructure_tuple %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
%8 = mark_dependence %8a : $UnsafeMutablePointer<MyInt> on %7 : $MyArray<MyInt>
%9 = struct_extract %8 : $UnsafeMutablePointer<MyInt>, #UnsafeMutablePointer._rawValue
%10 = pointer_to_address %9 : $Builtin.RawPointer to [strict] $*MyInt
%11 = integer_literal $Builtin.Int64, 0
@@ -233,7 +236,8 @@ sil [ossa] @append_contentsOf_int : $@convention(thin) () -> () {
%4 = metatype $@thin Array<MyInt>.Type
%5 = function_ref @arrayAdoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin Array<MyInt>.Type) -> @owned (Array<MyInt>, UnsafeMutablePointer<MyInt>)
%6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin Array<MyInt>.Type) -> @owned (Array<MyInt>, UnsafeMutablePointer<MyInt>)
(%7, %8) = destructure_tuple %6 : $(Array<MyInt>, UnsafeMutablePointer<MyInt>)
(%7, %8a) = destructure_tuple %6 : $(Array<MyInt>, UnsafeMutablePointer<MyInt>)
%8 = mark_dependence %8a : $UnsafeMutablePointer<MyInt> on %7 : $Array<MyInt>
%9 = struct_extract %8 : $UnsafeMutablePointer<MyInt>, #UnsafeMutablePointer._rawValue
%10 = pointer_to_address %9 : $Builtin.RawPointer to [strict] $*MyInt
%11 = integer_literal $Builtin.Int64, 27
@@ -257,7 +261,7 @@ sil [ossa] @append_contentsOf_int : $@convention(thin) () -> () {
// CHECK-LABEL: sil [ossa] @negative_index
// CHECK: store %{{[0-9]+}} to [trivial]
// CHECK: [[GETF:%.*]] = function_ref @getElement : $@convention(method) (MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray<MyInt>) -> MyInt
// CHECK: apply [[GETF]](%15, %17, %19, %7) : $@convention(method) (MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray<MyInt>) -> MyInt
// CHECK: apply [[GETF]](%16, %18, %20, %7) : $@convention(method) (MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray<MyInt>) -> MyInt
// CHECK-LABEL: // end sil function 'negative_index'
sil [ossa] @negative_index : $@convention(thin) () -> () {
bb0:
@@ -268,7 +272,8 @@ bb0:
%4 = metatype $@thin MyArray<MyInt>.Type
%5 = function_ref @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
%6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
(%7, %8) = destructure_tuple %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
(%7, %8a) = destructure_tuple %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
%8 = mark_dependence %8a : $UnsafeMutablePointer<MyInt> on %7 : $MyArray<MyInt>
%9 = struct_extract %8 : $UnsafeMutablePointer<MyInt>, #UnsafeMutablePointer._rawValue
%10 = pointer_to_address %9 : $Builtin.RawPointer to [strict] $*MyInt
%11 = integer_literal $Builtin.Int64, 0

View File

@@ -68,7 +68,8 @@ bb0(%arg0 : @owned $MyKlass, %arg1 : @owned $MyKlass, %arg2 : @owned $MyKlass):
%4 = metatype $@thin MyArray<MyKlass>.Type
%5 = function_ref @adoptStorage : $@convention(thin) (@owned _ContiguousArrayStorage<MyKlass>, MyInt, @thin MyArray<MyKlass>.Type) -> @owned (MyArray<MyKlass>, UnsafeMutablePointer<MyKlass>)
%6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned _ContiguousArrayStorage<MyKlass>, MyInt, @thin MyArray<MyKlass>.Type) -> @owned (MyArray<MyKlass>, UnsafeMutablePointer<MyKlass>)
(%7, %8) = destructure_tuple %6 : $(MyArray<MyKlass>, UnsafeMutablePointer<MyKlass>)
(%7, %8a) = destructure_tuple %6 : $(MyArray<MyKlass>, UnsafeMutablePointer<MyKlass>)
%8 = mark_dependence %8a : $UnsafeMutablePointer<MyKlass> on %7 : $MyArray<MyKlass>
debug_value %7 : $MyArray<MyKlass>
debug_value %8 : $UnsafeMutablePointer<MyKlass>
%9 = struct_extract %8 : $UnsafeMutablePointer<MyKlass>, #UnsafeMutablePointer._rawValue
@@ -143,7 +144,8 @@ bb0(%arg0 : @owned $MyKlass, %arg1 : @owned $MyKlass, %arg2 : @owned $MyKlass):
%4 = metatype $@thin MyArray<MyKlass>.Type
%5 = function_ref @adoptStorage : $@convention(thin) (@owned _ContiguousArrayStorage<MyKlass>, MyInt, @thin MyArray<MyKlass>.Type) -> @owned (MyArray<MyKlass>, UnsafeMutablePointer<MyKlass>)
%6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned _ContiguousArrayStorage<MyKlass>, MyInt, @thin MyArray<MyKlass>.Type) -> @owned (MyArray<MyKlass>, UnsafeMutablePointer<MyKlass>)
(%7, %8) = destructure_tuple %6 : $(MyArray<MyKlass>, UnsafeMutablePointer<MyKlass>)
(%7, %8a) = destructure_tuple %6 : $(MyArray<MyKlass>, UnsafeMutablePointer<MyKlass>)
%8 = mark_dependence %8a : $UnsafeMutablePointer<MyKlass> on %7 : $MyArray<MyKlass>
debug_value %7 : $MyArray<MyKlass>
debug_value %8 : $UnsafeMutablePointer<MyKlass>
%9 = struct_extract %8 : $UnsafeMutablePointer<MyKlass>, #UnsafeMutablePointer._rawValue
@@ -213,7 +215,8 @@ bb0(%arg0 : @owned $MyKlass):
%4 = metatype $@thin MyArray<MyKlass>.Type
%5 = function_ref @adoptStorage : $@convention(thin) (@owned _ContiguousArrayStorage<MyKlass>, MyInt, @thin MyArray<MyKlass>.Type) -> @owned (MyArray<MyKlass>, UnsafeMutablePointer<MyKlass>)
%6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned _ContiguousArrayStorage<MyKlass>, MyInt, @thin MyArray<MyKlass>.Type) -> @owned (MyArray<MyKlass>, UnsafeMutablePointer<MyKlass>)
(%7, %8) = destructure_tuple %6 : $(MyArray<MyKlass>, UnsafeMutablePointer<MyKlass>)
(%7, %8a) = destructure_tuple %6 : $(MyArray<MyKlass>, UnsafeMutablePointer<MyKlass>)
%8 = mark_dependence %8a : $UnsafeMutablePointer<MyKlass> on %7 : $MyArray<MyKlass>
debug_value %7 : $MyArray<MyKlass>
debug_value %8 : $UnsafeMutablePointer<MyKlass>
%9 = struct_extract %8 : $UnsafeMutablePointer<MyKlass>, #UnsafeMutablePointer._rawValue
@@ -272,7 +275,8 @@ bb0(%0 : $*Array<MyKlass>, %1 : @owned $MyKlass):
%8 = metatype $@thin Array<MyKlass>.Type
%9 = function_ref @adoptStorageMyKlass : $@convention(method) (@owned _ContiguousArrayStorage<MyKlass>, MyInt, @thin Array<MyKlass>.Type) -> (@owned Array<MyKlass>, UnsafeMutablePointer<MyKlass>)
%10 = apply %9(%7, %6, %8) : $@convention(method) (@owned _ContiguousArrayStorage<MyKlass>, MyInt, @thin Array<MyKlass>.Type) -> (@owned Array<MyKlass>, UnsafeMutablePointer<MyKlass>)
(%11, %12) = destructure_tuple %10 : $(Array<MyKlass>, UnsafeMutablePointer<MyKlass>)
(%11, %12a) = destructure_tuple %10 : $(Array<MyKlass>, UnsafeMutablePointer<MyKlass>)
%12 = mark_dependence %12a : $UnsafeMutablePointer<MyKlass> on %11 : $Array<MyKlass>
%13 = struct_extract %12 : $UnsafeMutablePointer<MyKlass>, #UnsafeMutablePointer._rawValue
%22 = pointer_to_address %13 : $Builtin.RawPointer to [strict] $*MyKlass
%copy1 = copy_value %1 : $MyKlass