Skip to content

Cleanup and document SIL memory behavior APIs. #67188

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 1 commit into from
Jul 11, 2023
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
9 changes: 7 additions & 2 deletions include/swift/SIL/SILNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,13 @@
/// NAME is the name of the instruction in SIL assembly.
/// The argument will be a bare identifier, not a string literal.
///
/// MEMBEHAVIOR is an enum value that reflects the memory behavior of
/// the instruction.
/// MEMBEHAVIOR is an enum value that reflects the memory behavior of the
/// instruction. It is only used in the implementation of
/// SILInstruction::getMemoryBehavior(). Memory behavior is relative, so
/// whenever possible, clients should instead use
/// AliasAnalysis::computeMemoryBehavior(SILInstruction, SILValue) which only
/// defaults to SILInstruction::getMemoryBehavior() when AliasAnalysis cannot
/// disambiguate the instruction's effects from the value of interest.
///
/// MAYRELEASE indicates whether the execution of the
/// instruction may result in memory being released.
Expand Down
51 changes: 41 additions & 10 deletions include/swift/SILOptimizer/Analysis/AliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ namespace swift {

/// This class is a simple wrapper around an alias analysis cache. This is
/// needed since we do not have an "analysis" infrastructure.
///
/// This wrapper sits above the SwiftCompilerSource implementation of
/// AliasAnalysis. The implementation calls into AliasAnalysis.swift via
/// BridgedAliasAnalysis whenever the result may depend on escape analysis.
class AliasAnalysis {
public:

Expand Down Expand Up @@ -159,14 +163,24 @@ class AliasAnalysis {
return alias(V1, V2, TBAAType1, TBAAType2) == AliasResult::MayAlias;
}

/// Use the alias analysis to determine the memory behavior of Inst with
/// respect to V.
/// Compute the effects of Inst's memory behavior on the memory pointed to by
/// the value V.
///
/// This is the top-level API for memory behavior.
///
/// 1. MemoryBehaviorVisitor overrides select instruction types. Types that
/// have no override default to SILInstruction::getMemoryBehavior(), which is
/// not specific to the memory pointed to by V.
///
/// 2. For instruction types overridden by MemoryBehaviorVisitor, this uses
/// alias analysis to disambiguate the Inst's memory effects from the memory
/// pointed to by value V. 'mayAlias' is used for memory operations and
/// 'getMemoryEffectOnEscapedAddress' is used for calls and releases.
///
/// 3. For calls, alias analysis uses callee analysis to retrieve function
/// side effects which provides the memory behavior of each argument.
MemoryBehavior computeMemoryBehavior(SILInstruction *Inst, SILValue V);

/// Use the alias analysis to determine the memory behavior of Inst with
/// respect to V.
MemoryBehavior computeMemoryBehaviorInner(SILInstruction *Inst, SILValue V);

/// Returns true if \p Inst may read from memory at address \p V.
///
/// For details see MemoryBehavior::MayRead.
Expand Down Expand Up @@ -203,20 +217,37 @@ class AliasAnalysis {
/// Returns true if \p Ptr may be released by the builtin \p BI.
bool canBuiltinDecrementRefCount(BuiltinInst *BI, SILValue Ptr);

/// Returns true if the address(es of) `addr` can escape to `toInst`.
MemoryBehavior getMemoryBehaviorOfInst(SILValue addr, SILInstruction *toInst);
int getEstimatedFunctionSize(SILValue valueInFunction);

/// Returns true if the object(s of) `obj` can escape to `toInst`.
///
/// Special entry point into BridgedAliasAnalysis (escape analysis) for use in
/// ARC analysis.
bool isObjectReleasedByInst(SILValue obj, SILInstruction *toInst);

/// Is the `addr` within all reachable objects/addresses, when start walking
/// from `obj`?
///
/// Special entry point into BridgedAliasAnalysis (escape analysis) for use in
/// ARC analysis.
bool isAddrVisibleFromObject(SILValue addr, SILValue obj);

/// MARK: implementation helpers for MemBehaviorVisitor.

/// If the address(es of) `addr` can escape to `toInst` (based on escape
/// analysis), return the memory effect of `toInst` on the escaped memory.
///
/// This should not be called directly; it is an implementation helper for
/// querying escape analysis.
MemoryBehavior getMemoryEffectOnEscapedAddress(SILValue addr, SILInstruction *toInst);

protected:
/// Use the alias analysis to determine the memory behavior of Inst with
/// respect to V.
MemoryBehavior computeMemoryBehaviorInner(SILInstruction *Inst, SILValue V);

/// Returns true if `lhs` can reference the same field as `rhs`.
bool canReferenceSameField(SILValue lhs, SILValue rhs);

int getEstimatedFunctionSize(SILValue valueInFunction);
};


Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/Analysis/AliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ void BridgedAliasAnalysis::registerAnalysis(GetMemEffectFn getMemEffectsFn,
canReferenceSameFieldFunction = canReferenceSameFieldFn;
}

MemoryBehavior AliasAnalysis::getMemoryBehaviorOfInst(
MemoryBehavior AliasAnalysis::getMemoryEffectOnEscapedAddress(
SILValue addr, SILInstruction *toInst) {
if (getMemEffectsFunction) {
return (MemoryBehavior)getMemEffectsFunction({PM->getSwiftPassInvocation()}, {addr},
Expand Down
20 changes: 10 additions & 10 deletions lib/SILOptimizer/Analysis/MemoryBehavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,50 +317,50 @@ MemBehavior MemoryBehaviorVisitor::visitMarkUnresolvedMoveAddrInst(
MemBehavior MemoryBehaviorVisitor::visitBuiltinInst(BuiltinInst *BI) {
MemBehavior mb = BI->getMemoryBehavior();
if (mb != MemBehavior::None) {
return AA->getMemoryBehaviorOfInst(V, BI);
return AA->getMemoryEffectOnEscapedAddress(V, BI);
}
return MemBehavior::None;
}

MemBehavior MemoryBehaviorVisitor::visitTryApplyInst(TryApplyInst *AI) {
return AA->getMemoryBehaviorOfInst(V, AI);
return AA->getMemoryEffectOnEscapedAddress(V, AI);
}

MemBehavior MemoryBehaviorVisitor::visitApplyInst(ApplyInst *AI) {
return AA->getMemoryBehaviorOfInst(V, AI);
return AA->getMemoryEffectOnEscapedAddress(V, AI);
}

MemBehavior MemoryBehaviorVisitor::visitBeginApplyInst(BeginApplyInst *AI) {
return AA->getMemoryBehaviorOfInst(V, AI);
return AA->getMemoryEffectOnEscapedAddress(V, AI);
}

MemBehavior MemoryBehaviorVisitor::visitEndApplyInst(EndApplyInst *EAI) {
return AA->getMemoryBehaviorOfInst(V, EAI->getBeginApply());
return AA->getMemoryEffectOnEscapedAddress(V, EAI->getBeginApply());
}

MemBehavior MemoryBehaviorVisitor::visitAbortApplyInst(AbortApplyInst *AAI) {
return AA->getMemoryBehaviorOfInst(V, AAI->getBeginApply());
return AA->getMemoryEffectOnEscapedAddress(V, AAI->getBeginApply());
}

MemBehavior
MemoryBehaviorVisitor::visitStrongReleaseInst(StrongReleaseInst *SI) {
return AA->getMemoryBehaviorOfInst(V, SI);
return AA->getMemoryEffectOnEscapedAddress(V, SI);
}

#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
MemBehavior \
MemoryBehaviorVisitor::visit##Name##ReleaseInst(Name##ReleaseInst *SI) { \
return AA->getMemoryBehaviorOfInst(V, SI); \
return AA->getMemoryEffectOnEscapedAddress(V, SI); \
}
#include "swift/AST/ReferenceStorage.def"

MemBehavior MemoryBehaviorVisitor::visitReleaseValueInst(ReleaseValueInst *SI) {
return AA->getMemoryBehaviorOfInst(V, SI);
return AA->getMemoryEffectOnEscapedAddress(V, SI);
}

MemBehavior
MemoryBehaviorVisitor::visitDestroyValueInst(DestroyValueInst *DVI) {
return AA->getMemoryBehaviorOfInst(V, DVI);
return AA->getMemoryEffectOnEscapedAddress(V, DVI);
}

MemBehavior MemoryBehaviorVisitor::visitSetDeallocatingInst(SetDeallocatingInst *SDI) {
Expand Down