|
16 | 16 | #include "swift/Basic/FrozenMultiMap.h"
|
17 | 17 | #include "swift/SIL/BasicBlockData.h"
|
18 | 18 | #include "swift/SIL/BasicBlockDatastructures.h"
|
| 19 | +#include "swift/SIL/DynamicCasts.h" |
19 | 20 | #include "swift/SIL/MemAccessUtils.h"
|
20 | 21 | #include "swift/SIL/NodeDatastructures.h"
|
21 | 22 | #include "swift/SIL/OwnershipUtils.h"
|
@@ -50,34 +51,93 @@ static bool SILApplyCrossesIsolation(const SILInstruction *inst) {
|
50 | 51 | return false;
|
51 | 52 | }
|
52 | 53 |
|
53 |
| -static AccessStorage getAccessStorageFromAddr(SILValue value) { |
54 |
| - assert(value->getType().isAddress()); |
55 |
| - auto accessStorage = AccessStorage::compute(value); |
56 |
| - if (accessStorage && accessStorage.getRoot()) { |
57 |
| - if (auto definingInst = accessStorage.getRoot().getDefiningInstruction()) { |
58 |
| - if (isa<InitExistentialAddrInst, CopyValueInst>(definingInst)) |
59 |
| - // look through these because AccessStorage does not |
60 |
| - return getAccessStorageFromAddr(definingInst->getOperand(0)); |
| 54 | +namespace { |
| 55 | + |
| 56 | +struct UseDefChainVisitor |
| 57 | + : public AccessUseDefChainVisitor<UseDefChainVisitor, SILValue> { |
| 58 | + |
| 59 | + SILValue visitAll(SILValue sourceAddr) { |
| 60 | + SILValue result = visit(sourceAddr); |
| 61 | + if (!result) |
| 62 | + return sourceAddr; |
| 63 | + |
| 64 | + while (SILValue nextAddr = visit(result)) |
| 65 | + result = nextAddr; |
| 66 | + |
| 67 | + return result; |
| 68 | + } |
| 69 | + |
| 70 | + SILValue visitBase(SILValue base, AccessStorage::Kind kind) { |
| 71 | + // If we are passed a project_box, we want to return the box itself. The |
| 72 | + // reason for this is that the project_box is considered to be non-aliasing |
| 73 | + // memory. We want to treat it as part of the box which is |
| 74 | + // aliasing... meaning that we need to merge. |
| 75 | + if (kind == AccessStorage::Box) |
| 76 | + return cast<ProjectBoxInst>(base)->getOperand(); |
| 77 | + return SILValue(); |
| 78 | + } |
| 79 | + |
| 80 | + SILValue visitNonAccess(SILValue) { return SILValue(); } |
| 81 | + |
| 82 | + SILValue visitPhi(SILPhiArgument *phi) { |
| 83 | + llvm_unreachable("Should never hit this"); |
| 84 | + } |
| 85 | + |
| 86 | + // Override AccessUseDefChainVisitor to ignore access markers and find the |
| 87 | + // outer access base. |
| 88 | + SILValue visitNestedAccess(BeginAccessInst *access) { |
| 89 | + return visitAll(access->getSource()); |
| 90 | + } |
| 91 | + |
| 92 | + SILValue visitStorageCast(SingleValueInstruction *, Operand *sourceAddr, |
| 93 | + AccessStorageCast castType) { |
| 94 | + return sourceAddr->get(); |
| 95 | + } |
| 96 | + |
| 97 | + SILValue visitAccessProjection(SingleValueInstruction *inst, |
| 98 | + Operand *sourceAddr) { |
| 99 | + // See if this access projection is into a single element value. If so, we |
| 100 | + // do not want to treat this as a merge. |
| 101 | + if (auto p = Projection(inst)) { |
| 102 | + switch (p.getKind()) { |
| 103 | + case ProjectionKind::Upcast: |
| 104 | + case ProjectionKind::RefCast: |
| 105 | + case ProjectionKind::BitwiseCast: |
| 106 | + case ProjectionKind::TailElems: |
| 107 | + case ProjectionKind::Box: |
| 108 | + case ProjectionKind::Class: |
| 109 | + llvm_unreachable("Shouldn't see this here"); |
| 110 | + case ProjectionKind::Index: |
| 111 | + break; |
| 112 | + case ProjectionKind::Enum: |
| 113 | + break; |
| 114 | + case ProjectionKind::Tuple: { |
| 115 | + break; |
| 116 | + } |
| 117 | + case ProjectionKind::Struct: |
| 118 | + break; |
| 119 | + } |
61 | 120 | }
|
| 121 | + |
| 122 | + return sourceAddr->get(); |
62 | 123 | }
|
| 124 | +}; |
63 | 125 |
|
64 |
| - return accessStorage; |
65 |
| -} |
| 126 | +} // namespace |
66 | 127 |
|
67 | 128 | static SILValue getUnderlyingTrackedValue(SILValue value) {
|
68 | 129 | if (!value->getType().isAddress()) {
|
69 | 130 | return getUnderlyingObject(value);
|
70 | 131 | }
|
71 | 132 |
|
72 |
| - if (auto accessStorage = getAccessStorageFromAddr(value)) { |
73 |
| - if (accessStorage.getKind() == AccessRepresentation::Kind::Global) |
74 |
| - // globals don't reduce |
75 |
| - return value; |
76 |
| - assert(accessStorage.getRoot()); |
77 |
| - return accessStorage.getRoot(); |
78 |
| - } |
79 |
| - |
80 |
| - return value; |
| 133 | + UseDefChainVisitor visitor; |
| 134 | + SILValue base = visitor.visitAll(value); |
| 135 | + assert(base); |
| 136 | + if (isa<GlobalAddrInst>(base)) |
| 137 | + return value; |
| 138 | + if (base->getType().isObject()) |
| 139 | + return getUnderlyingObject(base); |
| 140 | + return base; |
81 | 141 | }
|
82 | 142 |
|
83 | 143 | namespace {
|
|
0 commit comments