Skip to content

Commit 96cd8fa

Browse files
authored
Merge pull request #29408 from atrick/fix-escape-bridge
Fix EscapeAnalysis value_to_bridge_object and strong_copy_unowned_value.
2 parents 0dcb78f + ae04531 commit 96cd8fa

File tree

2 files changed

+50
-6
lines changed

2 files changed

+50
-6
lines changed

lib/SILOptimizer/Analysis/EscapeAnalysis.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -2020,12 +2020,9 @@ void EscapeAnalysis::analyzeInstruction(SILInstruction *I,
20202020
ConGraph->getNode(cast<SingleValueInstruction>(I));
20212021
return;
20222022

2023-
#define UNCHECKED_REF_STORAGE(Name, ...) \
2024-
case SILInstructionKind::StrongCopy##Name##ValueInst:
20252023
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
20262024
case SILInstructionKind::Name##RetainInst: \
2027-
case SILInstructionKind::StrongRetain##Name##Inst: \
2028-
case SILInstructionKind::StrongCopy##Name##ValueInst:
2025+
case SILInstructionKind::StrongRetain##Name##Inst:
20292026
#include "swift/AST/ReferenceStorage.def"
20302027
case SILInstructionKind::DeallocStackInst:
20312028
case SILInstructionKind::StrongRetainInst:
@@ -2043,8 +2040,11 @@ void EscapeAnalysis::analyzeInstruction(SILInstruction *I,
20432040
case SILInstructionKind::SetDeallocatingInst:
20442041
case SILInstructionKind::FixLifetimeInst:
20452042
case SILInstructionKind::ClassifyBridgeObjectInst:
2046-
case SILInstructionKind::ValueToBridgeObjectInst:
2047-
// These instructions don't have any effect on escaping.
2043+
// Early bailout: These instructions never produce a pointer value and
2044+
// have no escaping effect on their operands.
2045+
assert(!llvm::any_of(I->getResults(), [this](SILValue result) {
2046+
return isPointer(result);
2047+
}));
20482048
return;
20492049

20502050
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \

test/SILOptimizer/escape_analysis.sil

+44
Original file line numberDiff line numberDiff line change
@@ -1844,3 +1844,47 @@ bb3(%4 : $AnyObject):
18441844
%5 = tuple ()
18451845
return %5 : $()
18461846
}
1847+
1848+
// Test value_to_bridge_object merged with a local reference. A graph node
1849+
// must be created for all values involved, and they must point to an
1850+
// escaping content node.
1851+
// CHECK-LABEL: CG of testValueToBridgeObject
1852+
// CHECK-NEXT: Val [ref] %1 Esc: , Succ: (%5.1)
1853+
// CHECK-NEXT: Val [ref] %5 Esc: , Succ: (%5.1)
1854+
// CHECK-NEXT: Con [int] %5.1 Esc: G, Succ: (%5.2)
1855+
// CHECK-NEXT: Con %5.2 Esc: G, Succ:
1856+
// CHECK-NEXT: Val [ref] %7 Esc: , Succ: (%5.1), %1, %5
1857+
// CHECK-NEXT: Ret [ref] return Esc: , Succ: %7
1858+
// CHECK-LABEL: End
1859+
sil @testValueToBridgeObject : $@convention(thin) (Builtin.Word) -> C {
1860+
bb0(%0 : $Builtin.Word):
1861+
%1 = alloc_ref $C
1862+
cond_br undef, bb1, bb2
1863+
1864+
bb1:
1865+
%derived = ref_to_bridge_object %1 : $C, %0 : $Builtin.Word
1866+
br bb3(%derived : $Builtin.BridgeObject)
1867+
1868+
bb2:
1869+
%5 = value_to_bridge_object %0 : $Builtin.Word
1870+
br bb3(%5 : $Builtin.BridgeObject)
1871+
1872+
bb3(%7 : $Builtin.BridgeObject):
1873+
%result = bridge_object_to_ref %7 : $Builtin.BridgeObject to $C
1874+
return %result : $C
1875+
}
1876+
1877+
// Test strong_copy_unowned_value returned. It must be marked escaping,
1878+
// not simply "returned", because it's reference is formed from a
1879+
// function argument.
1880+
// CHECK-LABEL: CG of testStrongCopyUnowned
1881+
// CHECK-NEXT: Val [ref] %1 Esc: , Succ: (%1.1)
1882+
// CHECK-NEXT: Con [int] %1.1 Esc: G, Succ: (%1.2)
1883+
// CHECK-NEXT: Con %1.2 Esc: G, Succ:
1884+
// CHECK-NEXT: Ret [ref] return Esc: , Succ: %1
1885+
// CHECK-LABEL: End
1886+
sil [ossa] @testStrongCopyUnowned : $@convention(thin) (@guaranteed @sil_unowned Builtin.NativeObject) -> @owned Builtin.NativeObject {
1887+
bb0(%0 : @guaranteed $@sil_unowned Builtin.NativeObject):
1888+
%1 = strong_copy_unowned_value %0 : $@sil_unowned Builtin.NativeObject
1889+
return %1 : $Builtin.NativeObject
1890+
}

0 commit comments

Comments
 (0)