Skip to content

Commit 33be23e

Browse files
authored
Merge pull request swiftlang#68316 from eeckstein/fix-arc-sequence-opt-complexity
AliasAnalysis: use a complexity limit for the isObjReleased function
2 parents 0d56677 + f6f9e75 commit 33be23e

File tree

5 files changed

+533
-9
lines changed

5 files changed

+533
-9
lines changed

SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,20 @@ struct AliasAnalysis {
5656
},
5757

5858
// isObjReleasedFn
59-
{ (bridgedCtxt: BridgedPassContext, bridgedObj: BridgedValue, bridgedInst: BridgedInstruction) -> Bool in
59+
{ (bridgedCtxt: BridgedPassContext, bridgedObj: BridgedValue, bridgedInst: BridgedInstruction, complexityBudget: Int) -> Bool in
6060
let context = FunctionPassContext(_bridged: bridgedCtxt)
6161
let inst = bridgedInst.instruction
6262
let obj = bridgedObj.value
6363
let path = SmallProjectionPath(.anyValueFields)
6464
if let apply = inst as? ApplySite {
65-
let effect = getOwnershipEffect(of: apply, for: obj, path: path, context)
65+
// Workaround for quadratic complexity in ARCSequenceOpts.
66+
// We need to use an ever lower budget to not get into noticable compile time troubles.
67+
let budget = complexityBudget / 10
68+
let effect = getOwnershipEffect(of: apply, for: obj, path: path, complexityBudget: budget, context)
6669
return effect.destroy
6770
}
68-
return obj.at(path).isEscaping(using: EscapesToInstructionVisitor(target: inst, isAddress: false), context)
71+
return obj.at(path).isEscaping(using: EscapesToInstructionVisitor(target: inst, isAddress: false),
72+
complexityBudget: complexityBudget, context)
6973
},
7074

7175
// isAddrVisibleFromObj
@@ -159,9 +163,10 @@ private func getMemoryEffect(ofBuiltin builtin: BuiltinInst, for address: Value,
159163
}
160164
}
161165

162-
private func getOwnershipEffect(of apply: ApplySite, for value: Value, path: SmallProjectionPath, _ context: FunctionPassContext) -> SideEffects.Ownership {
166+
private func getOwnershipEffect(of apply: ApplySite, for value: Value, path: SmallProjectionPath,
167+
complexityBudget: Int, _ context: FunctionPassContext) -> SideEffects.Ownership {
163168
let visitor = SideEffectsVisitor(apply: apply, calleeAnalysis: context.calleeAnalysis, isAddress: false)
164-
if let result = value.at(path).visit(using: visitor, context) {
169+
if let result = value.at(path).visit(using: visitor, complexityBudget: complexityBudget, context) {
165170
// The resulting effects are the argument effects to which `value` escapes to.
166171
return result.ownership
167172
} else {

SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeUtils.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,10 @@ extension ProjectedValue {
9999
/// it returns the `result` of the `visitor`, if the projected value does not escape.
100100
/// Returns nil, if the projected value escapes.
101101
///
102-
func visit<V: EscapeVisitorWithResult>(using visitor: V, _ context: some Context) -> V.Result? {
103-
var walker = EscapeWalker(visitor: visitor, context)
102+
func visit<V: EscapeVisitorWithResult>(using visitor: V,
103+
complexityBudget: Int = Int.max,
104+
_ context: some Context) -> V.Result? {
105+
var walker = EscapeWalker(visitor: visitor, complexityBudget: complexityBudget, context)
104106
if walker.walkUp(addressOrValue: value, path: path.escapePath) == .abortWalk {
105107
return nil
106108
}

include/swift/SILOptimizer/OptimizerBridging.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct BridgedAliasAnalysis {
3636
typedef swift::MemoryBehavior (* _Nonnull GetMemEffectFn)(
3737
BridgedPassContext context, BridgedValue, BridgedInstruction, SwiftInt);
3838
typedef bool (* _Nonnull Escaping2InstFn)(
39-
BridgedPassContext context, BridgedValue, BridgedInstruction);
39+
BridgedPassContext context, BridgedValue, BridgedInstruction, SwiftInt);
4040
typedef bool (* _Nonnull Escaping2ValFn)(
4141
BridgedPassContext context, BridgedValue, BridgedValue);
4242
typedef bool (* _Nonnull Escaping2ValIntFn)(

lib/SILOptimizer/Analysis/AliasAnalysis.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,8 @@ MemoryBehavior AliasAnalysis::getMemoryEffectOnEscapedAddress(
726726

727727
bool AliasAnalysis::isObjectReleasedByInst(SILValue obj, SILInstruction *inst) {
728728
if (isObjReleasedFunction) {
729-
return isObjReleasedFunction({PM->getSwiftPassInvocation()}, {obj}, {inst->asSILNode()}) != 0;
729+
return isObjReleasedFunction({PM->getSwiftPassInvocation()}, {obj}, {inst->asSILNode()},
730+
getComplexityBudget(obj)) != 0;
730731
}
731732
return true;
732733
}

0 commit comments

Comments
 (0)