Skip to content

Commit cc0aa2f

Browse files
committed
Add an AccessPath abstraction and formalize memory access
Things that have come up recently but are somewhat blocked on this: - Moving AccessMarkerElimination down in the pipeline - SemanticARCOpts correctness and improvements - AliasAnalysis improvements - LICM performance regressions - RLE/DSE improvements Begin to formalize the model for valid memory access in SIL. Ignoring ownership, every access is a def-use chain in three parts: object root -> formal access base -> memory operation address AccessPath abstracts over this path and standardizes the identity of a memory access throughout the optimizer. This abstraction is the basis for a new AccessPathVerification. With that verification, we now have all the properties we need for the type of analysis requires for exclusivity enforcement, but now generalized for any memory analysis. This is suitable for an extremely lightweight analysis with no side data structures. We currently have a massive amount of ad-hoc memory analysis throughout SIL, which is incredibly unmaintainable, bug-prone, and not performance-robust. We can begin taking advantage of this verifably complete model to solve that problem. The properties this gives us are: Access analysis must be complete over memory operations: every memory operation needs a recognizable valid access. An access can be unidentified only to the extent that it is rooted in some non-address type and we can prove that it is at least *not* part of an access to a nominal class or global property. Pointer provenance is also required for future IRGen-level bitfield optimizations. Access analysis must be complete over address users: for an identified object root all memory accesses including subobjects must be discoverable. Access analysis must be symmetric: use-def and def-use analysis must be consistent. AccessPath is merely a wrapper around the existing accessed-storage utilities and IndexTrieNode. Existing passes already very succesfully use this approach, but in an ad-hoc way. With a general utility we can: - update passes to use this approach to identify memory access, reducing the space and time complexity of those algorithms. - implement an inexpensive on-the-fly, debug mode address lifetime analysis - implement a lightweight debug mode alias analysis - ultimately improve the power, efficiency, and maintainability of full alias analysis - make our type-based alias analysis sensistive to the access path
1 parent 92a1816 commit cc0aa2f

File tree

10 files changed

+1742
-410
lines changed

10 files changed

+1742
-410
lines changed

include/swift/SIL/MemAccessUtils.h

Lines changed: 578 additions & 206 deletions
Large diffs are not rendered by default.

include/swift/SIL/PatternMatch.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,16 @@ using BuiltinApplyTy = typename Apply_match<BuiltinValueKind, Tys...>::Ty;
668668
// Define matchers for most of builtin instructions.
669669
#include "swift/AST/Builtins.def"
670670

671+
#undef BUILTIN_UNARY_OP_MATCH_WITH_ARG_MATCHER
672+
#undef BUILTIN_BINARY_OP_MATCH_WITH_ARG_MATCHER
673+
#undef BUILTIN_VARARGS_OP_MATCH_WITH_ARG_MATCHER
674+
#undef BUILTIN_CAST_OPERATION
675+
#undef BUILTIN_CAST_OR_BITCAST_OPERATION
676+
#undef BUILTIN_BINARY_OPERATION_ALL
677+
#undef BUILTIN_BINARY_PREDICATE
678+
#undef BUILTIN_MISC_OPERATION
679+
#undef BUILTIN
680+
671681
//===
672682
// Convenience compound builtin instructions matchers that succeed
673683
// if any of the sub-matchers succeed.

include/swift/SILOptimizer/Analysis/ValueTracking.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ bool pointsToLocalObject(SILValue V);
3939
/// Returns true if \p V is a uniquely identified address or reference. Two
4040
/// uniquely identified pointers with distinct roots cannot alias. However, a
4141
/// uniquely identified pointer may alias with unidentified pointers. For
42-
/// example, the uniquely identified pointer may escape to a call that returns an
43-
/// alias of that pointer.
42+
/// example, the uniquely identified pointer may escape to a call that returns
43+
/// an alias of that pointer.
4444
///
4545
/// It may be any of:
4646
///
@@ -53,14 +53,17 @@ bool pointsToLocalObject(SILValue V);
5353
///
5454
/// - an address projection based on an exclusive argument with no levels of
5555
/// indirection (e.g. ref_element_addr, project_box, etc.).
56+
///
57+
/// TODO: Fold this into the AccessedStorage API. pointsToLocalObject should be
58+
/// performed by AccessedStorage::isUniquelyIdentified.
5659
inline bool isUniquelyIdentified(SILValue V) {
5760
SILValue objectRef = V;
5861
if (V->getType().isAddress()) {
5962
auto storage = findAccessedStorage(V);
6063
if (!storage)
6164
return false;
6265

63-
if (storage.isUniquelyIdentifiedAfterEnforcement())
66+
if (storage.isUniquelyIdentified())
6467
return true;
6568

6669
if (!storage.isObjectAccess())

lib/IRGen/IRGenSIL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4125,7 +4125,7 @@ void IRGenSILFunction::visitRefTailAddrInst(RefTailAddrInst *i) {
41254125
}
41264126

41274127
static bool isInvariantAddress(SILValue v) {
4128-
SILValue accessedAddress = getAccessedAddress(v);
4128+
SILValue accessedAddress = getAccessAddress(v);
41294129
if (auto *ptrRoot = dyn_cast<PointerToAddressInst>(accessedAddress)) {
41304130
return ptrRoot->isInvariant();
41314131
}

0 commit comments

Comments
 (0)