Skip to content

Commit b868d53

Browse files
committed
[MoveOnlyAddressChecker] Fix used fields repr.
The address checker records uses in its livenessUses map. Previously, that map mapped from an instruction to a range of fields of the type. But an instruction can use multiple discontiguous fields of a single value. Here, such instructions are properly recorded by fixing the map to store a bit vector for each instruction. rdar://110676577
1 parent 2bfa723 commit b868d53

File tree

5 files changed

+303
-167
lines changed

5 files changed

+303
-167
lines changed

include/swift/SIL/FieldSensitivePrunedLiveness.h

+70-5
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,16 @@ struct TypeTreeLeafTypeRange {
345345
return TypeTreeLeafTypeRange(start, end);
346346
}
347347

348+
/// Whether \p bits contains any of the in-range bits.
349+
bool intersects(SmallBitVector const &bits) const {
350+
for (auto bit : bits.set_bits()) {
351+
if (contains(bit)) {
352+
return true;
353+
}
354+
}
355+
return false;
356+
}
357+
348358
/// Is the given leaf type specified by \p singleLeafElementNumber apart of
349359
/// our \p range of leaf type values in the our larger type.
350360
bool contains(SubElementOffset singleLeafElementNumber) const {
@@ -696,6 +706,14 @@ class FieldSensitivePrunedLiveness {
696706
}
697707
}
698708

709+
/// Record that the instruction uses the bits in \p bits.
710+
void addUses(SmallBitVector const &bits, bool lifetimeEnding) {
711+
liveBits |= bits;
712+
if (lifetimeEnding) {
713+
consumingBits |= bits;
714+
}
715+
}
716+
699717
/// Populates the provided vector with contiguous ranges of bits which are
700718
/// users of the same sort.
701719
void getContiguousRanges(
@@ -838,6 +856,9 @@ class FieldSensitivePrunedLiveness {
838856
void updateForUse(SILInstruction *user, TypeTreeLeafTypeRange span,
839857
bool lifetimeEnding);
840858

859+
void updateForUse(SILInstruction *user, SmallBitVector const &bits,
860+
bool lifetimeEnding);
861+
841862
void getBlockLiveness(SILBasicBlock *bb, TypeTreeLeafTypeRange span,
842863
SmallVectorImpl<FieldSensitivePrunedLiveBlocks::IsLive>
843864
&resultingFoundLiveness) const {
@@ -862,6 +883,16 @@ class FieldSensitivePrunedLiveness {
862883
SmallBitVector &liveOutBits,
863884
SmallBitVector &deadBits) const;
864885

886+
InterestingUser &getOrCreateInterestingUser(SILInstruction *user) {
887+
auto iter = users.find(user);
888+
if (iter == users.end()) {
889+
iter = users
890+
.insert({user, InterestingUser(getNumSubElements())})
891+
.first;
892+
}
893+
return *&iter->second;
894+
}
895+
865896
/// If \p user has had uses recored, return a pointer to the InterestingUser
866897
/// where they've been recorded.
867898
InterestingUser const *getInterestingUser(SILInstruction *user) const {
@@ -918,11 +949,12 @@ class FieldSensitivePrunedLiveness {
918949
/// argument must be copied.
919950
void addInterestingUser(SILInstruction *user, TypeTreeLeafTypeRange range,
920951
bool lifetimeEnding) {
921-
auto iter = users.find(user);
922-
if (iter == users.end()) {
923-
iter = users.insert({user, InterestingUser(getNumSubElements())}).first;
924-
}
925-
iter->second.addUses(range, lifetimeEnding);
952+
getOrCreateInterestingUser(user).addUses(range, lifetimeEnding);
953+
}
954+
955+
void addInterestingUser(SILInstruction *user, SmallBitVector const &bits,
956+
bool lifetimeEnding) {
957+
getOrCreateInterestingUser(user).addUses(bits, lifetimeEnding);
926958
}
927959
};
928960

@@ -1036,6 +1068,11 @@ class FieldSensitivePrunedLiveRange : public FieldSensitivePrunedLiveness {
10361068
void updateForUse(SILInstruction *user, TypeTreeLeafTypeRange span,
10371069
bool lifetimeEnding);
10381070

1071+
/// Customize updateForUse for FieldSensitivePrunedLiveness such that we check
1072+
/// that we consider defs as stopping liveness from being propagated up.
1073+
void updateForUse(SILInstruction *user, SmallBitVector const &bits,
1074+
bool lifetimeEnding);
1075+
10391076
/// Compute the boundary from the blocks discovered during liveness analysis.
10401077
///
10411078
/// Precondition: \p liveness.getDiscoveredBlocks() is a valid list of all
@@ -1107,6 +1144,10 @@ class FieldSensitiveSSAPrunedLiveRange
11071144
return inst == defInst.first && defInst.second->contains(bit);
11081145
}
11091146

1147+
bool isDef(SILInstruction *inst, SmallBitVector const &bits) const {
1148+
return inst == defInst.first && llvm::all_of(bits.set_bits(), [&](auto bit){ return defInst.second->contains(bit); });
1149+
}
1150+
11101151
bool isDef(SILInstruction *inst, TypeTreeLeafTypeRange span) const {
11111152
return inst == defInst.first &&
11121153
defInst.second->setIntersection(span).has_value();
@@ -1217,6 +1258,30 @@ class FieldSensitiveMultiDefPrunedLiveRange
12171258
*iter, [&](TypeTreeLeafTypeRange span) { return span.contains(bit); });
12181259
}
12191260

1261+
bool isDef(SILValue value, SmallBitVector const &bits) const {
1262+
assert(isInitialized());
1263+
auto iter = defs.find(cast<SILNode>(value));
1264+
if (!iter)
1265+
return false;
1266+
SmallBitVector allBits(bits.size());
1267+
for (auto range : *iter) {
1268+
range.setBits(allBits);
1269+
}
1270+
return (bits & allBits) == bits;
1271+
}
1272+
1273+
bool isDef(SILInstruction *inst, SmallBitVector const &bits) const {
1274+
assert(isInitialized());
1275+
auto iter = defs.find(cast<SILNode>(inst));
1276+
if (!iter)
1277+
return false;
1278+
SmallBitVector allBits(bits.size());
1279+
for (auto range : *iter) {
1280+
range.setBits(allBits);
1281+
}
1282+
return (bits & allBits) == bits;
1283+
}
1284+
12201285
bool isDef(SILInstruction *inst, TypeTreeLeafTypeRange span) const {
12211286
assert(isInitialized());
12221287
auto iter = defs.find(cast<SILNode>(inst));

lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp

+44
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,16 @@ void FieldSensitivePrunedLiveness::updateForUse(SILInstruction *user,
609609
addInterestingUser(user, range, lifetimeEnding);
610610
}
611611

612+
void FieldSensitivePrunedLiveness::updateForUse(SILInstruction *user,
613+
SmallBitVector const &bits,
614+
bool lifetimeEnding) {
615+
for (auto bit : bits.set_bits()) {
616+
liveBlocks.updateForUse(user, bit);
617+
}
618+
619+
addInterestingUser(user, bits, lifetimeEnding);
620+
}
621+
612622
//===----------------------------------------------------------------------===//
613623
// MARK: FieldSensitivePrunedLiveRange
614624
//===----------------------------------------------------------------------===//
@@ -822,6 +832,40 @@ void FieldSensitivePrunedLiveRange<LivenessWithDefs>::updateForUse(
822832
FieldSensitivePrunedLiveness::updateForUse(user, range, lifetimeEnding);
823833
}
824834

835+
template <typename LivenessWithDefs>
836+
void FieldSensitivePrunedLiveRange<LivenessWithDefs>::updateForUse(
837+
SILInstruction *user, SmallBitVector const &bits, bool lifetimeEnding) {
838+
PRUNED_LIVENESS_LOG(
839+
llvm::dbgs()
840+
<< "Begin FieldSensitivePrunedLiveRange<LivenessWithDefs>::updateForUse "
841+
"for: "
842+
<< *user);
843+
PRUNED_LIVENESS_LOG(
844+
llvm::dbgs() << "Looking for def instruction earlier in the block!\n");
845+
846+
auto *parentBlock = user->getParent();
847+
for (auto ii = std::next(user->getReverseIterator()),
848+
ie = parentBlock->rend();
849+
ii != ie; ++ii) {
850+
// If we find the def, just mark this instruction as being an interesting
851+
// instruction.
852+
if (asImpl().isDef(&*ii, bits)) {
853+
PRUNED_LIVENESS_LOG(llvm::dbgs() << " Found def: " << *ii);
854+
PRUNED_LIVENESS_LOG(llvm::dbgs()
855+
<< " Marking inst as interesting user and returning!\n");
856+
addInterestingUser(user, bits, lifetimeEnding);
857+
return;
858+
}
859+
}
860+
861+
// Otherwise, just delegate to our parent class's update for use. This will
862+
// update liveness for our predecessor blocks and add this instruction as an
863+
// interesting user.
864+
PRUNED_LIVENESS_LOG(llvm::dbgs() << "No defs found! Delegating to "
865+
"FieldSensitivePrunedLiveness::updateForUse.\n");
866+
FieldSensitivePrunedLiveness::updateForUse(user, bits, lifetimeEnding);
867+
}
868+
825869
//===----------------------------------------------------------------------===//
826870
// MARK: Boundary Computation Utilities
827871
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)