diff --git a/SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift b/SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift index 5b49689aae750..21a0c2ce5116e 100644 --- a/SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift +++ b/SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift @@ -56,16 +56,20 @@ struct AliasAnalysis { }, // isObjReleasedFn - { (bridgedCtxt: BridgedPassContext, bridgedObj: BridgedValue, bridgedInst: BridgedInstruction) -> Bool in + { (bridgedCtxt: BridgedPassContext, bridgedObj: BridgedValue, bridgedInst: BridgedInstruction, complexityBudget: Int) -> Bool in let context = FunctionPassContext(_bridged: bridgedCtxt) let inst = bridgedInst.instruction let obj = bridgedObj.value let path = SmallProjectionPath(.anyValueFields) if let apply = inst as? ApplySite { - let effect = getOwnershipEffect(of: apply, for: obj, path: path, context) + // Workaround for quadratic complexity in ARCSequenceOpts. + // We need to use an ever lower budget to not get into noticable compile time troubles. + let budget = complexityBudget / 10 + let effect = getOwnershipEffect(of: apply, for: obj, path: path, complexityBudget: budget, context) return effect.destroy } - return obj.at(path).isEscaping(using: EscapesToInstructionVisitor(target: inst, isAddress: false), context) + return obj.at(path).isEscaping(using: EscapesToInstructionVisitor(target: inst, isAddress: false), + complexityBudget: complexityBudget, context) }, // isAddrVisibleFromObj @@ -159,9 +163,10 @@ private func getMemoryEffect(ofBuiltin builtin: BuiltinInst, for address: Value, } } -private func getOwnershipEffect(of apply: ApplySite, for value: Value, path: SmallProjectionPath, _ context: FunctionPassContext) -> SideEffects.Ownership { +private func getOwnershipEffect(of apply: ApplySite, for value: Value, path: SmallProjectionPath, + complexityBudget: Int, _ context: FunctionPassContext) -> SideEffects.Ownership { let visitor = SideEffectsVisitor(apply: apply, calleeAnalysis: context.calleeAnalysis, isAddress: false) - if let result = value.at(path).visit(using: visitor, context) { + if let result = value.at(path).visit(using: visitor, complexityBudget: complexityBudget, context) { // The resulting effects are the argument effects to which `value` escapes to. return result.ownership } else { diff --git a/SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeUtils.swift b/SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeUtils.swift index 7a0dc42dd11a2..25ac65480b4d5 100644 --- a/SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeUtils.swift +++ b/SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeUtils.swift @@ -99,8 +99,10 @@ extension ProjectedValue { /// it returns the `result` of the `visitor`, if the projected value does not escape. /// Returns nil, if the projected value escapes. /// - func visit(using visitor: V, _ context: some Context) -> V.Result? { - var walker = EscapeWalker(visitor: visitor, context) + func visit(using visitor: V, + complexityBudget: Int = Int.max, + _ context: some Context) -> V.Result? { + var walker = EscapeWalker(visitor: visitor, complexityBudget: complexityBudget, context) if walker.walkUp(addressOrValue: value, path: path.escapePath) == .abortWalk { return nil } diff --git a/include/swift/SILOptimizer/OptimizerBridging.h b/include/swift/SILOptimizer/OptimizerBridging.h index 348d1807d2b4e..36292455b94b5 100644 --- a/include/swift/SILOptimizer/OptimizerBridging.h +++ b/include/swift/SILOptimizer/OptimizerBridging.h @@ -36,7 +36,7 @@ struct BridgedAliasAnalysis { typedef swift::MemoryBehavior (* _Nonnull GetMemEffectFn)( BridgedPassContext context, BridgedValue, BridgedInstruction, SwiftInt); typedef bool (* _Nonnull Escaping2InstFn)( - BridgedPassContext context, BridgedValue, BridgedInstruction); + BridgedPassContext context, BridgedValue, BridgedInstruction, SwiftInt); typedef bool (* _Nonnull Escaping2ValFn)( BridgedPassContext context, BridgedValue, BridgedValue); typedef bool (* _Nonnull Escaping2ValIntFn)( diff --git a/lib/SILOptimizer/Analysis/AliasAnalysis.cpp b/lib/SILOptimizer/Analysis/AliasAnalysis.cpp index cd9bafb4c24f3..a350a69343074 100644 --- a/lib/SILOptimizer/Analysis/AliasAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/AliasAnalysis.cpp @@ -726,7 +726,8 @@ MemoryBehavior AliasAnalysis::getMemoryEffectOnEscapedAddress( bool AliasAnalysis::isObjectReleasedByInst(SILValue obj, SILInstruction *inst) { if (isObjReleasedFunction) { - return isObjReleasedFunction({PM->getSwiftPassInvocation()}, {obj}, {inst->asSILNode()}) != 0; + return isObjReleasedFunction({PM->getSwiftPassInvocation()}, {obj}, {inst->asSILNode()}, + getComplexityBudget(obj)) != 0; } return true; } diff --git a/validation-test/SILOptimizer/large_nested_array.swift b/validation-test/SILOptimizer/large_nested_array.swift new file mode 100644 index 0000000000000..5bd2b197481ff --- /dev/null +++ b/validation-test/SILOptimizer/large_nested_array.swift @@ -0,0 +1,516 @@ + +// The compiler should finish in about 5 seconds. To give some slack, +// specify a timeout of 30 seconds +// If the compiler needs more than 30 seconds, there is probably a real problem. +// So please don't just increase the timeout in case this test fails. + +// RUN: %{python} %S/../../test/Inputs/timeout.py 30 %target-swift-frontend -O -parse-as-library -sil-verify-none -emit-sil %s | %FileCheck %s + +// REQUIRES: swift_stdlib_no_asserts,optimized_stdlib +// REQUIRES: CPU=arm64 || CPU=x86_64 || CPU=aarch64 + +// CHECK: sil @$s18large_nested_array22getTwoDimensionalArraySaySaySiGGyF +public func getTwoDimensionalArray() -> [[Int]] { + return [ + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2], + [0,1,2] + ] +}