Cleanup and document SIL memory behavior APIs.

This is code that I am fairly familiar with but it still took a day of
investigation to figure out how it is supposed to be used now in the
presence of bridging.

This primarily involved ruling out the possibity that the mid-level
Swift APIs could at some point call into the lower-level C++ APIs.

The biggest problem was that AliasAnalysis::getMemoryBehaviorOfInst()
was declared as a public interface, and it's name indicates that it
computes the memory behavior. But it is just a wrapper around a Swift
API and never actually calls into any of the C++ logic that is
responsible for computing memory behavior!
This commit is contained in:
Andrew Trick
2023-07-07 20:54:31 -07:00
parent b426c1507d
commit 5bae8551ff
4 changed files with 59 additions and 23 deletions

View File

@@ -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:
@@ -159,14 +163,24 @@ public:
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.
@@ -203,20 +217,37 @@ public:
/// 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);
};