Merge pull request #82798 from eeckstein/fix-let-property-lowering

LetPropertyLowering: remove redundant phis after ssa-update
This commit is contained in:
nate-chandler
2025-07-08 18:07:08 -07:00
committed by GitHub
7 changed files with 59 additions and 1 deletions

View File

@@ -122,6 +122,8 @@ private func insertEndInitInstructions(
use.set(to: ssaUpdater.getValue(atEndOf: use.instruction.parentBlock), context) use.set(to: ssaUpdater.getValue(atEndOf: use.instruction.parentBlock), context)
} }
} }
// This peephole optimization is required to avoid ownership errors.
replacePhisWithIncomingValues(phis: ssaUpdater.insertedPhis, context)
} }
private func constructLetInitRegion( private func constructLetInitRegion(

View File

@@ -50,4 +50,14 @@ struct SSAUpdater<Context: MutatingContext> {
context.notifyInstructionsChanged() context.notifyInstructionsChanged()
return context._bridged.SSAUpdater_getValueInMiddleOfBlock(block.bridged).value return context._bridged.SSAUpdater_getValueInMiddleOfBlock(block.bridged).value
} }
var insertedPhis: [Phi] {
var phis = [Phi]()
let numPhis = context._bridged.SSAUpdater_getNumInsertedPhis()
phis.reserveCapacity(numPhis)
for idx in 0..<numPhis {
phis.append(Phi(context._bridged.SSAUpdater_getInsertedPhi(idx).value)!)
}
return phis
}
} }

View File

@@ -371,6 +371,8 @@ struct BridgedPassContext {
BRIDGED_INLINE void SSAUpdater_addAvailableValue(BridgedBasicBlock block, BridgedValue value) const; BRIDGED_INLINE void SSAUpdater_addAvailableValue(BridgedBasicBlock block, BridgedValue value) const;
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedValue SSAUpdater_getValueAtEndOfBlock(BridgedBasicBlock block) const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedValue SSAUpdater_getValueAtEndOfBlock(BridgedBasicBlock block) const;
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedValue SSAUpdater_getValueInMiddleOfBlock(BridgedBasicBlock block) const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedValue SSAUpdater_getValueInMiddleOfBlock(BridgedBasicBlock block) const;
BRIDGED_INLINE SwiftInt SSAUpdater_getNumInsertedPhis() const;
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedValue SSAUpdater_getInsertedPhi(SwiftInt idx) const;
// Options // Options

View File

@@ -555,6 +555,14 @@ BridgedValue BridgedPassContext::SSAUpdater_getValueInMiddleOfBlock(BridgedBasic
invocation->getSSAUpdater()->getValueInMiddleOfBlock(block.unbridged())}; invocation->getSSAUpdater()->getValueInMiddleOfBlock(block.unbridged())};
} }
SwiftInt BridgedPassContext::SSAUpdater_getNumInsertedPhis() const {
return (SwiftInt)invocation->getInsertedPhisBySSAUpdater().size();
}
BridgedValue BridgedPassContext::SSAUpdater_getInsertedPhi(SwiftInt idx) const {
return {invocation->getInsertedPhisBySSAUpdater()[idx]};
}
bool BridgedPassContext::enableStackProtection() const { bool BridgedPassContext::enableStackProtection() const {
swift::SILModule *mod = invocation->getPassManager()->getModule(); swift::SILModule *mod = invocation->getPassManager()->getModule();
return mod->getOptions().EnableStackProtection; return mod->getOptions().EnableStackProtection;

View File

@@ -75,6 +75,7 @@ class SwiftPassInvocation {
SILModule::SlabList allocatedSlabs; SILModule::SlabList allocatedSlabs;
SILSSAUpdater *ssaUpdater = nullptr; SILSSAUpdater *ssaUpdater = nullptr;
SmallVector<SILPhiArgument *, 4> insertedPhisBySSAUpdater;
SwiftPassInvocation *nestedSwiftPassInvocation = nullptr; SwiftPassInvocation *nestedSwiftPassInvocation = nullptr;
@@ -178,8 +179,9 @@ public:
void initializeSSAUpdater(SILFunction *fn, SILType type, void initializeSSAUpdater(SILFunction *fn, SILType type,
ValueOwnershipKind ownership) { ValueOwnershipKind ownership) {
insertedPhisBySSAUpdater.clear();
if (!ssaUpdater) if (!ssaUpdater)
ssaUpdater = new SILSSAUpdater; ssaUpdater = new SILSSAUpdater(&insertedPhisBySSAUpdater);
ssaUpdater->initialize(fn, type, ownership); ssaUpdater->initialize(fn, type, ownership);
} }
@@ -188,6 +190,8 @@ public:
return ssaUpdater; return ssaUpdater;
} }
ArrayRef<SILPhiArgument *> getInsertedPhisBySSAUpdater() { return insertedPhisBySSAUpdater; }
SwiftPassInvocation *initializeNestedSwiftPassInvocation(SILFunction *newFunction) { SwiftPassInvocation *initializeNestedSwiftPassInvocation(SILFunction *newFunction) {
assert(!nestedSwiftPassInvocation && "Nested Swift pass invocation already initialized"); assert(!nestedSwiftPassInvocation && "Nested Swift pass invocation already initialized");
nestedSwiftPassInvocation = new SwiftPassInvocation(passManager, transform, newFunction); nestedSwiftPassInvocation = new SwiftPassInvocation(passManager, transform, newFunction);

View File

@@ -1562,6 +1562,7 @@ irgen::IRGenModule *SwiftPassInvocation::getIRGenModule() {
} }
void SwiftPassInvocation::endPass() { void SwiftPassInvocation::endPass() {
insertedPhisBySSAUpdater.clear();
assert(allocatedSlabs.empty() && "StackList is leaking slabs"); assert(allocatedSlabs.empty() && "StackList is leaking slabs");
assert(numBlockSetsAllocated == 0 && "Not all BasicBlockSets deallocated"); assert(numBlockSetsAllocated == 0 && "Not all BasicBlockSets deallocated");
assert(numNodeSetsAllocated == 0 && "Not all NodeSets deallocated"); assert(numNodeSetsAllocated == 0 && "Not all NodeSets deallocated");

View File

@@ -311,3 +311,34 @@ bb1(%3a : @reborrow $C):
return %2 : $C return %2 : $C
} }
// CHECK-LABEL: sil [ossa] @test_no_phis :
// CHECK: %3 = end_init_let_ref %2
// CHECK: return %3
// CHECK: } // end sil function 'test_no_phis'
sil [ossa] @test_no_phis : $@convention(thin) (Int, @owned C) -> @owned C {
bb0(%0 : $Int, %1 : @owned $C):
%2 = mark_uninitialized [rootself] %1
%3 = begin_borrow %2
cond_br undef, bb1, bb2
bb1:
br bb7
bb2:
cond_br undef, bb3, bb8
bb3:
cond_br undef, bb4, bb5
bb4:
br bb7
bb5:
br bb6
bb6:
end_borrow %3
return %2
bb7:
br bb6
bb8:
end_borrow %3
destroy_value [dead_end] %2
unreachable
}