1
1
# SIL utilities for modeling memory access
2
2
3
- The ` AccessBase ` , ` AccessedStorage ` and ` AccessPath ` types formalize
3
+ The ` AccessBase ` , ` AccessStorage ` and ` AccessPath ` types formalize
4
4
memory access in SIL. Given an address-typed SIL value, it is possible
5
5
to reliably identify the storage location of the accessed
6
- memory. ` AccessedStorage ` identifies an accessed storage
6
+ memory. ` AccessStorage ` identifies an accessed storage
7
7
location. ` AccessPath ` contains both a storage location and the
8
8
"access path" within that memory object. The relevant API details are
9
9
documented in MemAccessUtils.h
@@ -30,17 +30,17 @@ address is immutable for the duration of its access scope
30
30
31
31
## Access path def-use relationship
32
32
33
- Computing ` AccessedStorage ` and ` AccessPath ` for any given SIL address
33
+ Computing ` AccessStorage ` and ` AccessPath ` for any given SIL address
34
34
involves a use-def traversal to determine the origin of the
35
35
address. It may traverse operations on values of type address,
36
36
Builtin.RawPointer, box, and reference. The logic that
37
37
formalizes which SIL operations may be involved in the def-use chain
38
38
is encapsulated with the ` AccessUseDefChainVisitor ` . The traversal can
39
39
be customized by implementing this visitor. Customization is not
40
- expected to change the meaning of AccessedStorage or
40
+ expected to change the meaning of AccessStorage or
41
41
AccessPath. Rather, it is intended for additional pass-specific
42
42
book-keeping or for higher-level convenience APIs that operate on the
43
- use-def chain bypassing AccessedStorage completely.
43
+ use-def chain bypassing AccessStorage completely.
44
44
45
45
Access def-use chains are divided by four points: the object "root", the
46
46
access "base", the outer-most "access" scope, and the "address" of a
@@ -114,13 +114,13 @@ bb3(%a : $A):
114
114
115
115
Each object property and its tail storage is considered a separate
116
116
formal access base. The reference root is only one component of an
117
- ` AccessedStorage ` location. AccessedStorage also identifies the class
117
+ ` AccessStorage ` location. AccessStorage also identifies the class
118
118
property being accessed within that object.
119
119
120
120
A reference root may be borrowed, so the use-def path from the base to
121
121
the root may cross a borrow scope. This means that uses of one base
122
122
may not be replaced with a different base even if it has the same
123
- AccessedStorage because they may not be contained within the same
123
+ AccessStorage because they may not be contained within the same
124
124
borrow scope. However, this is the only part of the access path that
125
125
may be borrowed. Address uses with the same base can be substituted
126
126
without checking the borrow scope.
@@ -132,7 +132,7 @@ produced by an instruction that directly identifies the kind of
132
132
storage being accessed without further use-def traversal. Common
133
133
access bases are ` alloc_stack ` , ` global_addr ` ,
134
134
` ref_element_addr ` , ` project_box ` , and function arguments (see
135
- ` AccessedStorage ::Kind` ).
135
+ ` AccessStorage ::Kind` ).
136
136
137
137
The access base is the same as the "root" SILValue for all storage
138
138
kinds except global and reference storage. Reference storage includes
@@ -155,7 +155,7 @@ and the memory operation cannot cross an access scope.
155
155
Typically, the base is the address-type source operand of a
156
156
` begin_access ` . However, the path from the access base to the
157
157
` begin_access ` may include * storage casts* (see
158
- ` isAccessedStorageCast ` ). It may involve address an pointer
158
+ ` isAccessStorageCast ` ). It may involve address an pointer
159
159
types, and may traverse phis. For some kinds of storage, the base may
160
160
itself even be a non-address pointer. For phis that cannot be uniquely
161
161
resolved, the base may even be a box type.
@@ -186,14 +186,14 @@ allows for a class of storage optimizations, such as bitfields, in
186
186
which address storage is always uniquely determined. Currently, if a
187
187
(non-address) phi on the access path from ` base ` to ` access ` does not
188
188
have a common base, then it is considered an invalid access (the
189
- AccessedStorage object is not valid). SIL verification ensures that a
190
- formal access always has valid AccessedStorage (WIP). In other words,
189
+ AccessStorage object is not valid). SIL verification ensures that a
190
+ formal access always has valid AccessStorage (WIP). In other words,
191
191
the source of a ` begin_access ` marker must be a single, non-phi
192
192
base. In the future, for further simplicity, we may also disallow
193
193
pointer phis unless they have a common base.
194
194
195
195
Not all SIL memory access is part of a formal access, but the
196
- ` AccessedStorage ` and ` AccessPath ` abstractions are universally
196
+ ` AccessStorage ` and ` AccessPath ` abstractions are universally
197
197
applicable. Non-formal access still has an access base, even though
198
198
the use-def search does not begin at a ` begin_access ` marker. For
199
199
non-formal access, SIL verification is not as strict. An invalid
@@ -264,7 +264,7 @@ end_access %outerAccess : $*Int
264
264
265
265
For most purposes, the inner access scopes are irrelevant. When we ask
266
266
for the "accessed storage" for ` %innerAccess ` , we get an
267
- ` AccessedStorage ` value of "Stack" kind with base `%var =
267
+ ` AccessStorage ` value of "Stack" kind with base `%var =
268
268
alloc_stack`. If instead of finding the original accessed storage, we
269
269
want to identify the enclosing formal access scope, we need to use a
270
270
different API that supports the special ` Nested ` storage kind. This is
@@ -371,9 +371,9 @@ bb3(%p3 : $Builtin.RawPointer):
371
371
load %field : $*Int64
372
372
```
373
373
374
- ## AccessedStorage
374
+ ## AccessStorage
375
375
376
- ` AccessedStorage ` identifies an accessed storage location, be it a
376
+ ` AccessStorage ` identifies an accessed storage location, be it a
377
377
box, stack location, class property, global variable, or argument. It
378
378
is implemented as a value object that requires no compile-time memory
379
379
allocation and can be used as the hash key for that location. Extra
@@ -383,9 +383,9 @@ accessed and information about the location's uniqueness or whether it
383
383
is distinct from other storage.
384
384
385
385
Two __ uniquely identified__ storage locations may only alias if their
386
- AccessedStorage objects are identical.
386
+ AccessStorage objects are identical.
387
387
388
- ` AccessedStorage ` records the "root" SILValue of the access. The root is
388
+ ` AccessStorage ` records the "root" SILValue of the access. The root is
389
389
the same as the access base for all storage kinds except global and
390
390
class storage. For class properties, the storage root is the reference
391
391
root of the object, not the base of the property. Multiple
@@ -396,11 +396,11 @@ instructions may reference the same variable. To find all global uses,
396
396
the client must independently find all global variable references
397
397
within the function. Clients that need to know which SILValue base was
398
398
discovered during use-def traversal in all cases can make use of
399
- ` AccessedStorageWithBase ` or ` AccessPathWithBase ` .
399
+ ` AccessStorageWithBase ` or ` AccessPathWithBase ` .
400
400
401
401
### AccessPath
402
402
403
- ` AccessPath ` extends ` AccessedStorage ` to include the path components
403
+ ` AccessPath ` extends ` AccessStorage ` to include the path components
404
404
that determine the address of a subobject within the access base. The
405
405
access path is a string of index offsets and subobject projection
406
406
indices.
0 commit comments