Skip to content

Commit 2935090

Browse files
committed
Convert TransitiveAddressWalker to use CRTP instead of virtual functions.
1 parent 308a6fe commit 2935090

File tree

6 files changed

+36
-29
lines changed

6 files changed

+36
-29
lines changed

include/swift/SIL/AddressWalker.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,16 @@ namespace swift {
3737
/// Validated by the SIL verifier as always being able to visit all addresses
3838
/// derived from alloc_stack, ref_element_addr, project_box, ref_tail_addr and
3939
/// all other address roots.
40+
template <typename Impl>
4041
class TransitiveAddressWalker {
4142
/// Whether we could tell if this address use didn't escape, did have a
4243
/// pointer escape, or unknown if we failed to understand something.
4344
AddressUseKind result = AddressUseKind::NonEscaping;
4445

4546
unsigned didInvalidate = false;
4647

47-
public:
48-
virtual ~TransitiveAddressWalker() {}
48+
Impl &asImpl() { return *reinterpret_cast<Impl *>(this); }
49+
const Impl &asImpl() const { return *reinterpret_cast<const Impl *>(this); }
4950

5051
protected:
5152
/// Customization point for visiting uses. Returns true if we should continue
@@ -54,9 +55,11 @@ class TransitiveAddressWalker {
5455
/// NOTE: Do not call this directly from within
5556
/// findTransitiveUsesForAddress. Please call callVisitUse. This is intended
5657
/// just for subclasses to override.
57-
virtual bool visitUse(Operand *use) { return true; }
58+
bool visitUse(Operand *use) { return true; }
5859

59-
virtual void onError(Operand *use) {}
60+
/// Customization point for visiting operands that we were unable to
61+
/// understand. These cause us to return AddressUseKind::Unknown.
62+
void onError(Operand *use) {}
6063

6164
void meet(AddressUseKind other) {
6265
assert(!didInvalidate);
@@ -67,15 +70,17 @@ class TransitiveAddressWalker {
6770
/// Shim that actually calls visitUse and changes early exit.
6871
void callVisitUse(Operand *use) {
6972
assert(!didInvalidate);
70-
if (!visitUse(use))
73+
if (!asImpl().visitUse(use))
7174
result = AddressUseKind::Unknown;
7275
}
7376

7477
public:
7578
AddressUseKind walk(SILValue address) &&;
7679
};
7780

78-
inline AddressUseKind TransitiveAddressWalker::walk(SILValue projectedAddress) && {
81+
template <typename Impl>
82+
inline AddressUseKind
83+
TransitiveAddressWalker<Impl>::walk(SILValue projectedAddress) && {
7984
assert(!didInvalidate);
8085

8186
// When we exit, set the result to be invalidated so we can't use this again.
@@ -269,7 +274,7 @@ inline AddressUseKind TransitiveAddressWalker::walk(SILValue projectedAddress) &
269274

270275
// We were unable to recognize this user, so set AddressUseKind to unknown
271276
// and call onError with the specific user that caused the problem.
272-
onError(op);
277+
asImpl().onError(op);
273278
return AddressUseKind::Unknown;
274279
}
275280

include/swift/SIL/OwnershipUtils.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -736,15 +736,16 @@ inline AddressUseKind findTransitiveUsesForAddress(
736736
// guaranteed uses to determine if a load_borrow is an escape in OSSA. This
737737
// is OSSA specific behavior and we should probably create a different API
738738
// for that. But for now, this lets this APIs users stay the same.
739-
struct BasicTransitiveAddressVisitor final : TransitiveAddressWalker {
739+
struct BasicTransitiveAddressVisitor
740+
: TransitiveAddressWalker<BasicTransitiveAddressVisitor> {
740741
SmallVectorImpl<Operand *> *foundUses;
741742
std::function<void(Operand *)> *onErrorFunc;
742743

743744
BasicTransitiveAddressVisitor(SmallVectorImpl<Operand *> *foundUses,
744745
std::function<void(Operand *)> *onErrorFunc)
745746
: foundUses(foundUses), onErrorFunc(onErrorFunc) {}
746747

747-
bool visitUse(Operand *use) override {
748+
bool visitUse(Operand *use) {
748749
if (!foundUses)
749750
return true;
750751

@@ -771,7 +772,7 @@ inline AddressUseKind findTransitiveUsesForAddress(
771772
return true;
772773
}
773774

774-
void onError(Operand *use) override {
775+
void onError(Operand *use) {
775776
if (onErrorFunc)
776777
(*onErrorFunc)(use);
777778
}

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -732,9 +732,9 @@ struct ImmutableAddressUseVerifier {
732732
};
733733

734734
static void checkAddressWalkerCanVisitAllTransitiveUses(SILValue address) {
735-
struct Visitor final : TransitiveAddressWalker {
736-
bool visitUse(Operand *use) override { return true; }
737-
void onError(Operand *use) override {}
735+
struct Visitor : TransitiveAddressWalker<Visitor> {
736+
bool visitUse(Operand *use) { return true; }
737+
void onError(Operand *use) {}
738738
};
739739

740740
Visitor visitor;

lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -826,9 +826,9 @@ static SILValue tryRewriteToPartialApplyStack(
826826

827827
bool origIsUnusedDuringClosureLifetime = true;
828828

829-
class OrigUnusedDuringClosureLifetimeWalker final
830-
: public TransitiveAddressWalker
831-
{
829+
class OrigUnusedDuringClosureLifetimeWalker
830+
: public TransitiveAddressWalker<
831+
OrigUnusedDuringClosureLifetimeWalker> {
832832
SSAPrunedLiveness &closureLiveness;
833833
bool &origIsUnusedDuringClosureLifetime;
834834
public:
@@ -837,8 +837,8 @@ static SILValue tryRewriteToPartialApplyStack(
837837
: closureLiveness(closureLiveness),
838838
origIsUnusedDuringClosureLifetime(origIsUnusedDuringClosureLifetime)
839839
{}
840-
841-
virtual bool visitUse(Operand *origUse) override {
840+
841+
bool visitUse(Operand *origUse) {
842842
LLVM_DEBUG(llvm::dbgs() << "looking at use\n";
843843
origUse->getUser()->printInContext(llvm::dbgs());
844844
llvm::dbgs() << "\n");
@@ -857,7 +857,7 @@ static SILValue tryRewriteToPartialApplyStack(
857857
return true;
858858
}
859859
};
860-
860+
861861
OrigUnusedDuringClosureLifetimeWalker origUseWalker(closureLiveness,
862862
origIsUnusedDuringClosureLifetime);
863863
auto walkResult = std::move(origUseWalker).walk(orig);

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,14 +1469,14 @@ struct CopiedLoadBorrowEliminationState {
14691469
/// An early transform that we run to convert any load_borrow that are copied
14701470
/// directly or that have any subelement that is copied to a load [copy]. This
14711471
/// lets the rest of the optimization handle these as appropriate.
1472-
struct CopiedLoadBorrowEliminationVisitor final
1473-
: public TransitiveAddressWalker {
1472+
struct CopiedLoadBorrowEliminationVisitor
1473+
: public TransitiveAddressWalker<CopiedLoadBorrowEliminationVisitor> {
14741474
CopiedLoadBorrowEliminationState &state;
14751475

14761476
CopiedLoadBorrowEliminationVisitor(CopiedLoadBorrowEliminationState &state)
14771477
: state(state) {}
14781478

1479-
bool visitUse(Operand *op) override {
1479+
bool visitUse(Operand *op) {
14801480
LLVM_DEBUG(llvm::dbgs() << "CopiedLBElim visiting ";
14811481
llvm::dbgs() << " User: " << *op->getUser());
14821482
auto *lbi = dyn_cast<LoadBorrowInst>(op->getUser());
@@ -1857,7 +1857,7 @@ void PartialReinitChecker::performPartialReinitChecking(
18571857
namespace {
18581858

18591859
/// Visit all of the uses of value in preparation for running our algorithm.
1860-
struct GatherUsesVisitor final : public TransitiveAddressWalker {
1860+
struct GatherUsesVisitor : public TransitiveAddressWalker<GatherUsesVisitor> {
18611861
MoveOnlyAddressCheckerPImpl &moveChecker;
18621862
UseState &useState;
18631863
MarkMustCheckInst *markedValue;
@@ -1873,7 +1873,7 @@ struct GatherUsesVisitor final : public TransitiveAddressWalker {
18731873
: moveChecker(moveChecker), useState(useState), markedValue(markedValue),
18741874
diagnosticEmitter(diagnosticEmitter) {}
18751875

1876-
bool visitUse(Operand *op) override;
1876+
bool visitUse(Operand *op);
18771877
void reset(MarkMustCheckInst *address) { useState.address = address; }
18781878
void clear() { useState.clear(); }
18791879

lib/SILOptimizer/Mandatory/MoveOnlyUtils.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,8 @@ struct SimpleTemporaryAllocStackElimState {
391391
}
392392
};
393393

394-
struct SimpleTemporaryAllocStackElimVisitor final
395-
: public TransitiveAddressWalker {
394+
struct SimpleTemporaryAllocStackElimVisitor
395+
: public TransitiveAddressWalker<SimpleTemporaryAllocStackElimVisitor> {
396396
SimpleTemporaryAllocStackElimState &state;
397397
CopyAddrInst *caiToVisit;
398398
CopyAddrInst *&nextCAI;
@@ -416,7 +416,7 @@ struct SimpleTemporaryAllocStackElimVisitor final
416416
return true;
417417
}
418418

419-
bool visitUse(Operand *op) override {
419+
bool visitUse(Operand *op) {
420420
LLVM_DEBUG(llvm::dbgs() << "SimpleTemporaryAllocStackElimVisitor visiting: "
421421
<< *op->getUser());
422422

@@ -555,12 +555,13 @@ bool siloptimizer::eliminateTemporaryAllocationsFromLet(
555555
return false;
556556

557557
StackList<CopyAddrInst *> copiesToVisit(markedInst->getFunction());
558-
struct FindCopyAddrWalker final : public TransitiveAddressWalker {
558+
struct FindCopyAddrWalker
559+
: public TransitiveAddressWalker<FindCopyAddrWalker> {
559560
StackList<CopyAddrInst *> &copiesToVisit;
560561
FindCopyAddrWalker(StackList<CopyAddrInst *> &copiesToVisit)
561562
: TransitiveAddressWalker(), copiesToVisit(copiesToVisit) {}
562563

563-
bool visitUse(Operand *op) override {
564+
bool visitUse(Operand *op) {
564565
auto *cai = dyn_cast<CopyAddrInst>(op->getUser());
565566
// We want copy_addr that are not a take of src and are an init of their
566567
// dest.

0 commit comments

Comments
 (0)