Skip to content

Commit 3146d41

Browse files
authored
Merge pull request #36564 from eeckstein/temprvalueopt-followup
TempRValueOpt: small fixes/improvements for extending access scopes
2 parents c4e4e44 + 9b16a94 commit 3146d41

File tree

7 files changed

+421
-345
lines changed

7 files changed

+421
-345
lines changed

lib/SILOptimizer/Analysis/MemoryBehavior.cpp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -136,37 +136,38 @@ class MemoryBehaviorVisitor
136136
}
137137

138138
MemBehavior visitBeginAccessInst(BeginAccessInst *beginAccess) {
139+
if (!mayAlias(beginAccess->getSource()))
140+
return MemBehavior::None;
141+
142+
// begin_access does not physically read or write memory. But we model it
143+
// as a memory read and/or write to prevent optimizations to move other
144+
// aliased loads/stores across begin_access into the access scope.
139145
switch (beginAccess->getAccessKind()) {
140146
case SILAccessKind::Deinit:
141-
// A [deinit] only directly reads from the object. The fact that it frees
142-
// memory is modeled more precisely by the release operations within the
143-
// deinit scope. Therefore, handle it like a [read] here...
144-
LLVM_FALLTHROUGH;
147+
// For the same reason we treat a ``load [take]`` or a ``destroy_addr``
148+
// as a memory write, we do that for a ``begin_access [deinit]`` as well.
149+
// See SILInstruction::MemoryBehavior.
150+
return MemBehavior::MayReadWrite;
145151
case SILAccessKind::Read:
146-
if (!mayAlias(beginAccess->getSource()))
147-
return MemBehavior::None;
148-
149152
return MemBehavior::MayRead;
150-
151153
case SILAccessKind::Modify:
152154
if (isLetValue()) {
153155
assert(getAccessBase(beginAccess) != getValueAddress()
154156
&& "let modification not allowed");
155157
return MemBehavior::None;
156158
}
157-
// [modify] has a special case for ignoring 'let's, but otherwise is
158-
// identical to an [init]...
159-
LLVM_FALLTHROUGH;
159+
return MemBehavior::MayReadWrite;
160160
case SILAccessKind::Init:
161-
if (!mayAlias(beginAccess->getSource()))
162-
return MemBehavior::None;
163-
164161
return MemBehavior::MayWrite;
165162
}
166163
llvm_unreachable("invalid access kind");
167164
}
168165

169166
MemBehavior visitEndAccessInst(EndAccessInst *endAccess) {
167+
// end_access does not physically read or write memory. But, similar to
168+
// begin_access, we model it as a memory read and/or write to prevent
169+
// optimizations to move other aliased loads/stores across end_access into
170+
// the access scope.
170171
return visitBeginAccessInst(endAccess->getBeginAccess());
171172
}
172173

lib/SILOptimizer/Transforms/TempRValueElimination.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -367,19 +367,27 @@ bool TempRValueOptPass::extendAccessScopes(
367367

368368
for (SILInstruction &inst : make_range(begin, end)) {
369369
if (auto *endAccess = dyn_cast<EndAccessInst>(&inst)) {
370+
// To keep things simple, we can just move a single end_access. Also, we
371+
// cannot move an end_access over a (non-aliasing) end_access.
372+
if (endAccessToMove)
373+
return false;
370374
// Is this the end of an access scope of the copy-source?
371375
if (!aa->isNoAlias(copySrc, endAccess->getSource())) {
372-
// To keep things simple, we can just move a single end_access.
373-
if (endAccessToMove)
374-
return false;
376+
assert(endAccess->getBeginAccess()->getAccessKind() ==
377+
SILAccessKind::Read &&
378+
"a may-write end_access should not be in the copysrc lifetime");
375379
endAccessToMove = endAccess;
376380
}
377381
} else if (endAccessToMove) {
378382
// We cannot move an end_access over a begin_access. This would destroy
379383
// the proper nesting of accesses.
380-
if (isa<BeginAccessInst>(&inst))
384+
if (isa<BeginAccessInst>(&inst) || isa<BeginUnpairedAccessInst>(inst))
381385
return false;
382386
// Don't extend a read-access scope over a (potential) write.
387+
// Note that inst can be a function call containing other access scopes.
388+
// But doing the mayWriteToMemory check, we know that the function can
389+
// only contain read accesses (to the same memory location). So it's fine
390+
// to move endAccessToMove even over such a function call.
383391
if (aa->mayWriteToMemory(&inst, endAccessToMove->getSource()))
384392
return false;
385393
}

lib/SILOptimizer/UtilityPasses/MemBehaviorDumper.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@
2424

2525
using namespace swift;
2626

27-
static llvm::cl::opt<bool> EnableDumpAll(
28-
"enable-mem-behavior-dump-all", llvm::cl::init(false),
29-
llvm::cl::desc("With -mem-behavior-dump, dump all memory access pairs."));
30-
3127
//===----------------------------------------------------------------------===//
3228
// Value Gatherer
3329
//===----------------------------------------------------------------------===//
@@ -58,14 +54,25 @@ class MemBehaviorDumper : public SILModuleTransform {
5854
// To reduce the amount of output, we only dump the memory behavior of
5955
// selected types of instructions.
6056
static bool shouldTestInstruction(SILInstruction *I) {
61-
// Only consider function calls.
62-
if ((EnableDumpAll && I->mayReadOrWriteMemory()) ||
63-
FullApplySite::isa(I) ||
64-
isa<EndApplyInst>(I) ||
65-
isa<AbortApplyInst>(I))
57+
switch (I->getKind()) {
58+
case SILInstructionKind::ApplyInst:
59+
case SILInstructionKind::TryApplyInst:
60+
case SILInstructionKind::EndApplyInst:
61+
case SILInstructionKind::BeginApplyInst:
62+
case SILInstructionKind::AbortApplyInst:
63+
case SILInstructionKind::BeginAccessInst:
64+
case SILInstructionKind::EndAccessInst:
65+
case SILInstructionKind::EndCOWMutationInst:
66+
case SILInstructionKind::CopyValueInst:
67+
case SILInstructionKind::DestroyValueInst:
68+
case SILInstructionKind::EndBorrowInst:
69+
case SILInstructionKind::LoadInst:
70+
case SILInstructionKind::StoreInst:
71+
case SILInstructionKind::CopyAddrInst:
6672
return true;
67-
68-
return false;
73+
default:
74+
return false;
75+
}
6976
}
7077

7178
void run() override {
@@ -88,6 +95,9 @@ class MemBehaviorDumper : public SILModuleTransform {
8895
for (auto &V : Values) {
8996
if (V->getDefiningInstruction() == &I)
9097
continue;
98+
99+
if (!V->getType().isAddress() && !isa<AddressToPointerInst>(V))
100+
continue;
91101

92102
bool Read = AA->mayReadFromMemory(&I, V);
93103
bool Write = AA->mayWriteToMemory(&I, V);

0 commit comments

Comments
 (0)