|
10 | 10 | //
|
11 | 11 | //===----------------------------------------------------------------------===//
|
12 | 12 | ///
|
| 13 | +/// Pass order dependencies: |
| 14 | +/// |
| 15 | +/// - Will benefit from running after AccessEnforcementSelection. |
| 16 | +/// |
| 17 | +/// - Should run immediately before the AccessEnforcementWMO to share |
| 18 | +/// AccessedStorageAnalysis results. |
| 19 | +/// |
13 | 20 | /// This pass optimizes access enforcement as follows:
|
14 | 21 | ///
|
15 |
| -/// Access marker folding: Find begin/end access scopes that are uninterrupted |
16 |
| -/// by a potential conflicting access. Flag those as [nontracking] access. |
| 22 | +/// **Access marker folding**: Find begin/end access scopes that are |
| 23 | +/// uninterrupted by a potential conflicting access. Flag those as [nontracking] |
| 24 | +/// access. |
17 | 25 | ///
|
18 | 26 | /// Folding must prove that no dynamic conflicts occur inside of an access
|
19 | 27 | /// scope. That is, a scope has no "nested inner conflicts". The access itself
|
|
39 | 47 | /// any path to an access' end of scope has a potentially conflicting access,
|
40 | 48 | /// then that access is marked as a nested conflict.
|
41 | 49 | ///
|
42 |
| -/// Pass order dependencies: |
43 |
| -/// - Will benefit from running after AccessEnforcementSelection. |
| 50 | +/// **Local access marker removal** |
| 51 | +/// |
| 52 | +/// When none of the local accesses on local storage (box/stack) have nested |
| 53 | +/// conflicts, then all the locall accesses may be removed. This is somwhat rare |
| 54 | +/// because static diagnostics already promote the obvious cases to static |
| 55 | +/// checks. However, there are two reasons that dynamic local markers may be |
| 56 | +/// removed: (1) inlining may cause closure access to become local access (2) |
| 57 | +/// local storage may truly escape, but none of the the local access scopes |
| 58 | +/// cross a call site. |
44 | 59 | ///
|
45 | 60 | /// TODO: Perform another run of AccessEnforcementSelection immediately before
|
46 | 61 | /// this pass. Currently, that pass only works well when run before
|
@@ -558,9 +573,23 @@ foldNonNestedAccesses(AccessConflictAnalysis::AccessMap &accessMap) {
|
558 | 573 | return changed;
|
559 | 574 | }
|
560 | 575 |
|
| 576 | +/// Perform local access marker elimination. |
| 577 | +/// |
561 | 578 | /// Eliminate accesses to uniquely identified local storage for which no
|
562 | 579 | /// accesses can have nested conflicts. This is only valid if the function's
|
563 |
| -/// local storage cannot be potentially modified by unidentified access. |
| 580 | +/// local storage cannot be potentially modified by unidentified access: |
| 581 | +/// |
| 582 | +/// - Arguments cannot alias with local storage, so accessing an argument has no |
| 583 | +/// effect on analysis of the current function. When a callee accesses an |
| 584 | +/// argument, AccessedStorageAnalysis will either map the accessed storage to |
| 585 | +/// a value in the caller's function, or mark it as unidentified. |
| 586 | +/// |
| 587 | +/// - Stack or Box local storage could potentially be accessed via Unidentified |
| 588 | +/// access. (Some Unidentified accesses are for initialization or for |
| 589 | +/// temporary storage instead, but those should never have Dynamic |
| 590 | +/// enforcement). These accesses can only be eliminated when there is no |
| 591 | +/// Unidentified access within the function without the [no_nested_conflict] |
| 592 | +/// flag. |
564 | 593 | ///
|
565 | 594 | /// This simply invalidates the AccessMap result rather than erasing individual
|
566 | 595 | /// entries.
|
|
0 commit comments