Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,11 @@ private func getRemovableAllocStackDestination(
// %x = load %allocStack // looks like a load, but is a `load [take]`
// strong_release %x
// ```
guard copy.parentFunction.hasOwnership || allocStack.isDestroyedOnAllPaths(context) else {
guard copy.parentFunction.hasOwnership ||
allocStack.isDestroyedOnAllPaths(context) ||
// We can easily remove a dead alloc_stack
allocStack.uses.ignore(user: copy).ignore(usersOfType: DeallocStackInst.self).isEmpty
else {
return nil
}

Expand All @@ -177,6 +181,10 @@ private func hoistDestroy(of allocStack: AllocStackInst, after lastUse: Instruct
case let li as LoadInst where li.loadOwnership == .take:
assert(li.address == allocStack, "load must be not take a projected address")
return
case let apply as ApplyInst where apply.consumes(address: allocStack):
if allocStack.uses.contains(where: { $0.instruction == apply && apply.convention(of: $0)!.isGuaranteed }) {
return
}
default:
break
}
Expand Down Expand Up @@ -266,6 +274,14 @@ private extension AllocStackInst {
}
}

private extension ApplySite {
func consumes(address: Value) -> Bool {
argumentOperands.contains { argOp in
argOp.value == address && convention(of: argOp)!.isConsumed
}
}
}

/// Tries to move an `end_access` down to extend the access scope over all uses of the `alloc_stack`.
/// For example:
/// ```
Expand Down Expand Up @@ -531,13 +547,21 @@ private struct UseCollector : AddressDefUseWalker {
uses.insert(copyFromStack)
return .continueWalk

case is DebugValueInst:
return .continueWalk

default:
return .abortWalk
}
}

private mutating func visitApply(address: Operand, apply: ApplySite) -> WalkResult {
if !apply.convention(of: address)!.isGuaranteed {
let argConvention = apply.convention(of: address)!
guard argConvention.isGuaranteed ||
// Only accept consuming-in arguments if it consumes the whole `alloc_stack`. A consume from
// a projection would destroy only a part of the `alloc_stack` and we don't handle this.
(argConvention == .indirectIn && (copy.isTakeOfSource && address.value == copy.destinationAddress))
else {
return .abortWalk
}
uses.insert(apply)
Expand Down
2 changes: 0 additions & 2 deletions include/swift/SILOptimizer/PassManager/Passes.def
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,6 @@ LEGACY_PASS(ConstantEvaluatorTester, "test-constant-evaluator",
"Test constant evaluator")
LEGACY_PASS(ConstantEvaluableSubsetChecker, "test-constant-evaluable-subset",
"Test Swift code snippets expected to be constant evaluable")
LEGACY_PASS(CopyForwarding, "copy-forwarding",
"Copy Forwarding to Remove Redundant Copies")
LEGACY_PASS(CopyPropagation, "copy-propagation",
"Copy propagation to Remove Redundant SSA Copies, pruning debug info")
LEGACY_PASS(MandatoryCopyPropagation, "mandatory-copy-propagation",
Expand Down
4 changes: 3 additions & 1 deletion lib/SIL/Utils/InstructionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -841,7 +841,9 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType)
return RuntimeEffect::MetaData | RuntimeEffect::Releasing;
if (!ca->isTakeOfSrc())
return RuntimeEffect::MetaData | RuntimeEffect::RefCounting;
return RuntimeEffect::MetaData;
if (ca->getSrc()->getType().hasArchetype())
return RuntimeEffect::MetaData;
return RuntimeEffect::NoEffect;
}
case SILInstructionKind::TupleAddrConstructorInst: {
auto *ca = cast<TupleAddrConstructorInst>(inst);
Expand Down
6 changes: 0 additions & 6 deletions lib/SILOptimizer/PassManager/PassPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,12 +459,6 @@ void addFunctionPasses(SILPassPipelinePlan &P,
P.addDestroyAddrHoisting();
}

// Propagate copies through stack locations. Should run after
// box-to-stack promotion since it is limited to propagating through
// stack locations. Should run before aggregate lowering since that
// splits up copy_addr.
P.addCopyForwarding();

// This DCE pass is the only DCE on ownership SIL. It can cleanup OSSA related
// dead code, e.g. left behind by the ObjCBridgingOptimization.
P.addDCE();
Expand Down
1 change: 0 additions & 1 deletion lib/SILOptimizer/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ target_sources(swiftSILOptimizer PRIVATE
COWOpts.cpp
CSE.cpp
ConditionForwarding.cpp
CopyForwarding.cpp
CopyPropagation.cpp
DeadCodeElimination.cpp
DeadObjectElimination.cpp
Expand Down
Loading