Skip to content

Commit dd02c75

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 dd02c75

File tree

5 files changed

+312
-168
lines changed

5 files changed

+312
-168
lines changed

include/swift/SIL/FieldSensitivePrunedLiveness.h

Lines changed: 74 additions & 5 deletions
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,14 @@ 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.insert({user, InterestingUser(getNumSubElements())}).first;
890+
}
891+
return *&iter->second;
892+
}
893+
865894
/// If \p user has had uses recored, return a pointer to the InterestingUser
866895
/// where they've been recorded.
867896
InterestingUser const *getInterestingUser(SILInstruction *user) const {
@@ -918,11 +947,12 @@ class FieldSensitivePrunedLiveness {
918947
/// argument must be copied.
919948
void addInterestingUser(SILInstruction *user, TypeTreeLeafTypeRange range,
920949
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);
950+
getOrCreateInterestingUser(user).addUses(range, lifetimeEnding);
951+
}
952+
953+
void addInterestingUser(SILInstruction *user, SmallBitVector const &bits,
954+
bool lifetimeEnding) {
955+
getOrCreateInterestingUser(user).addUses(bits, lifetimeEnding);
926956
}
927957
};
928958

@@ -1036,6 +1066,11 @@ class FieldSensitivePrunedLiveRange : public FieldSensitivePrunedLiveness {
10361066
void updateForUse(SILInstruction *user, TypeTreeLeafTypeRange span,
10371067
bool lifetimeEnding);
10381068

1069+
/// Customize updateForUse for FieldSensitivePrunedLiveness such that we check
1070+
/// that we consider defs as stopping liveness from being propagated up.
1071+
void updateForUse(SILInstruction *user, SmallBitVector const &bits,
1072+
bool lifetimeEnding);
1073+
10391074
/// Compute the boundary from the blocks discovered during liveness analysis.
10401075
///
10411076
/// Precondition: \p liveness.getDiscoveredBlocks() is a valid list of all
@@ -1107,6 +1142,16 @@ class FieldSensitiveSSAPrunedLiveRange
11071142
return inst == defInst.first && defInst.second->contains(bit);
11081143
}
11091144

1145+
bool isDef(SILInstruction *inst, SmallBitVector const &bits) const {
1146+
if (inst != defInst.first)
1147+
return false;
1148+
for (auto bit : bits.set_bits()) {
1149+
if (!defInst.second->contains(bit))
1150+
return false;
1151+
}
1152+
return true;
1153+
}
1154+
11101155
bool isDef(SILInstruction *inst, TypeTreeLeafTypeRange span) const {
11111156
return inst == defInst.first &&
11121157
defInst.second->setIntersection(span).has_value();
@@ -1217,6 +1262,30 @@ class FieldSensitiveMultiDefPrunedLiveRange
12171262
*iter, [&](TypeTreeLeafTypeRange span) { return span.contains(bit); });
12181263
}
12191264

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

lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp

Lines changed: 46 additions & 0 deletions
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,42 @@ 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(llvm::dbgs()
844+
<< "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(
855+
llvm::dbgs()
856+
<< " Marking inst as interesting user and returning!\n");
857+
addInterestingUser(user, bits, lifetimeEnding);
858+
return;
859+
}
860+
}
861+
862+
// Otherwise, just delegate to our parent class's update for use. This will
863+
// update liveness for our predecessor blocks and add this instruction as an
864+
// interesting user.
865+
PRUNED_LIVENESS_LOG(llvm::dbgs()
866+
<< "No defs found! Delegating to "
867+
"FieldSensitivePrunedLiveness::updateForUse.\n");
868+
FieldSensitivePrunedLiveness::updateForUse(user, bits, lifetimeEnding);
869+
}
870+
825871
//===----------------------------------------------------------------------===//
826872
// MARK: Boundary Computation Utilities
827873
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)