Skip to content

AliasAnalysis: use a complexity limit for the isObjReleased function #68316

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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 @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<V: EscapeVisitorWithResult>(using visitor: V, _ context: some Context) -> V.Result? {
var walker = EscapeWalker(visitor: visitor, context)
func visit<V: EscapeVisitorWithResult>(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
}
Expand Down
2 changes: 1 addition & 1 deletion include/swift/SILOptimizer/OptimizerBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)(
Expand Down
3 changes: 2 additions & 1 deletion lib/SILOptimizer/Analysis/AliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Loading