Skip to content

Commit d557688

Browse files
authored
Merge pull request #36310 from eeckstein/memory-lifetime
Support all relevant address-instructions in MemoryLocations and the MemoryLifetimeVerifier
2 parents fe667da + 9f1ccde commit d557688

16 files changed

+504
-143
lines changed

include/swift/SIL/MemoryLifetime.h

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -189,18 +189,16 @@ class MemoryLocations {
189189
/// small. They can be handled separately with handleSingleBlockLocations().
190190
llvm::SmallVector<SingleValueInstruction *, 16> singleBlockLocations;
191191

192-
/// A Cache for single-payload enums.
193-
llvm::DenseMap<SILType, EnumElementDecl *> singlePayloadEnums;
194-
195192
/// The bit-set of locations for which numNonTrivialFieldsNotCovered is > 0.
196193
Bits nonTrivialLocations;
197194

198-
/// If true, support init_enum_data_addr and unchecked_take_enum_data_addr
199-
bool handleEnumDataProjections;
195+
/// If true, support init_enum_data_addr, unchecked_take_enum_data_addr,
196+
/// init_existential_addr and open_existential_addr.
197+
bool handleNonTrivialProjections;
200198

201199
public:
202-
MemoryLocations(bool handleEnumDataProjections) :
203-
handleEnumDataProjections(handleEnumDataProjections) {}
200+
MemoryLocations(bool handleNonTrivialProjections) :
201+
handleNonTrivialProjections(handleNonTrivialProjections) {}
204202

205203
MemoryLocations(const MemoryLocations &) = delete;
206204
MemoryLocations &operator=(const MemoryLocations &) = delete;
@@ -236,17 +234,31 @@ class MemoryLocations {
236234

237235
/// Sets the location bits os \p addr in \p bits, if \p addr is associated
238236
/// with a location.
239-
void setBits(Bits &bits, SILValue addr) {
237+
void setBits(Bits &bits, SILValue addr) const {
240238
if (auto *loc = getLocation(addr))
241239
bits |= loc->subLocations;
242240
}
243241

244242
/// Clears the location bits os \p addr in \p bits, if \p addr is associated
245243
/// with a location.
246-
void clearBits(Bits &bits, SILValue addr) {
244+
void clearBits(Bits &bits, SILValue addr) const {
247245
if (auto *loc = getLocation(addr))
248246
bits.reset(loc->subLocations);
249247
}
248+
249+
void genBits(Bits &genSet, Bits &killSet, SILValue addr) const {
250+
if (auto *loc = getLocation(addr)) {
251+
killSet.reset(loc->subLocations);
252+
genSet |= loc->subLocations;
253+
}
254+
}
255+
256+
void killBits(Bits &genSet, Bits &killSet, SILValue addr) const {
257+
if (auto *loc = getLocation(addr)) {
258+
killSet |= loc->subLocations;
259+
genSet.reset(loc->subLocations);
260+
}
261+
}
250262

251263
/// Analyzes all locations in a function.
252264
///
@@ -283,15 +295,6 @@ class MemoryLocations {
283295
// (locationIdx, fieldNr) -> subLocationIdx
284296
using SubLocationMap = llvm::DenseMap<std::pair<unsigned, unsigned>, unsigned>;
285297

286-
/// Returns the payload case of a single-payload enum.
287-
///
288-
/// Returns null if \p enumTy is not a single-payload enum.
289-
/// We are currently only handling enum data projections for single-payload
290-
/// enums, because it's much simpler to represent them with Locations. We
291-
/// could also support multi-payload enums, but that gets complicated. Most
292-
/// importantly, we can handle Swift.Optional.
293-
EnumElementDecl *getSinglePayloadEnumCase(SILType enumTy);
294-
295298
/// Helper function called by analyzeLocation to check all uses of the
296299
/// location recursively.
297300
///
@@ -368,17 +371,11 @@ class MemoryDataflow {
368371
// Utility functions for setting and clearing gen- and kill-bits.
369372

370373
void genBits(SILValue addr, const MemoryLocations &locs) {
371-
if (auto *loc = locs.getLocation(addr)) {
372-
killSet.reset(loc->subLocations);
373-
genSet |= loc->subLocations;
374-
}
374+
locs.genBits(genSet, killSet, addr);
375375
}
376376

377377
void killBits(SILValue addr, const MemoryLocations &locs) {
378-
if (auto *loc = locs.getLocation(addr)) {
379-
genSet.reset(loc->subLocations);
380-
killSet |= loc->subLocations;
381-
}
378+
locs.killBits(genSet, killSet, addr);
382379
}
383380

384381
bool exitReachable() const {

include/swift/SIL/SILInstruction.h

Lines changed: 23 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,19 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
10091009
node->getKind() <= SILNodeKind::Last_##ID; \
10101010
}
10111011

1012+
/// Abstract base class which defines the source and destination operand numbers
1013+
/// for copy-like instructions, like store, assign, copy_addr and cast
1014+
/// instructions.
1015+
class CopyLikeInstruction {
1016+
public:
1017+
enum {
1018+
/// The source operand index.
1019+
Src,
1020+
/// The destination operand index.
1021+
Dest
1022+
};
1023+
};
1024+
10121025
/// Abstract base class used for isa checks on instructions to determine if they
10131026
/// forward ownership and to verify that the set of ownership instructions and
10141027
/// the ownership utilities stay in sync via assertions.
@@ -3823,7 +3836,8 @@ static_assert(2 == SILNode::NumStoreOwnershipQualifierBits, "Size mismatch");
38233836
/// StoreInst - Represents a store from a memory location.
38243837
class StoreInst
38253838
: public InstructionBase<SILInstructionKind::StoreInst,
3826-
NonValueInstruction> {
3839+
NonValueInstruction>,
3840+
public CopyLikeInstruction {
38273841
friend SILBuilder;
38283842

38293843
private:
@@ -3833,13 +3847,6 @@ class StoreInst
38333847
StoreOwnershipQualifier Qualifier);
38343848

38353849
public:
3836-
enum {
3837-
/// the value being stored
3838-
Src,
3839-
/// the lvalue being stored to
3840-
Dest
3841-
};
3842-
38433850
SILValue getSrc() const { return Operands[Src].get(); }
38443851
SILValue getDest() const { return Operands[Dest].get(); }
38453852

@@ -3915,17 +3922,10 @@ inline auto BeginBorrowInst::getEndBorrows() const -> EndBorrowRange {
39153922
/// address. Must be paired with an end_borrow in its use-def list.
39163923
class StoreBorrowInst
39173924
: public InstructionBase<SILInstructionKind::StoreBorrowInst,
3918-
SingleValueInstruction> {
3925+
SingleValueInstruction>,
3926+
public CopyLikeInstruction {
39193927
friend class SILBuilder;
39203928

3921-
public:
3922-
enum {
3923-
/// The source of the value being borrowed.
3924-
Src,
3925-
/// The destination of the borrowed value.
3926-
Dest
3927-
};
3928-
39293929
private:
39303930
FixedOperandList<2> Operands;
39313931
StoreBorrowInst(SILDebugLocation DebugLoc, SILValue Src, SILValue Dest);
@@ -4326,7 +4326,8 @@ static_assert(2 == SILNode::NumAssignOwnershipQualifierBits, "Size mismatch");
43264326

43274327
template <SILInstructionKind Kind, int NumOps>
43284328
class AssignInstBase
4329-
: public InstructionBase<Kind, NonValueInstruction> {
4329+
: public InstructionBase<Kind, NonValueInstruction>,
4330+
public CopyLikeInstruction {
43304331

43314332
protected:
43324333
FixedOperandList<NumOps> Operands;
@@ -4337,13 +4338,6 @@ class AssignInstBase
43374338
Operands(this, std::forward<T>(args)...) { }
43384339

43394340
public:
4340-
enum {
4341-
/// the value being stored
4342-
Src,
4343-
/// the lvalue being stored to
4344-
Dest
4345-
};
4346-
43474341
SILValue getSrc() const { return Operands[Src].get(); }
43484342
SILValue getDest() const { return Operands[Dest].get(); }
43494343

@@ -4663,18 +4657,10 @@ class Store##Name##Inst \
46634657
/// but a copy instruction must be used for address-only types.
46644658
class CopyAddrInst
46654659
: public InstructionBase<SILInstructionKind::CopyAddrInst,
4666-
NonValueInstruction> {
4660+
NonValueInstruction>,
4661+
public CopyLikeInstruction {
46674662
friend SILBuilder;
46684663

4669-
public:
4670-
enum {
4671-
/// The lvalue being loaded from.
4672-
Src,
4673-
4674-
/// The lvalue being stored to.
4675-
Dest
4676-
};
4677-
46784664
private:
46794665
FixedOperandList<2> Operands;
46804666

@@ -8657,7 +8643,8 @@ template<SILInstructionKind Kind,
86578643
typename Base>
86588644
class AddrCastInstBase
86598645
: public InstructionBaseWithTrailingOperands<Kind, Derived,
8660-
TypesForAddrCasts<Base>> {
8646+
TypesForAddrCasts<Base>>,
8647+
public CopyLikeInstruction {
86618648
protected:
86628649
friend InstructionBaseWithTrailingOperands<Kind, Derived, Operand>;
86638650

@@ -8688,13 +8675,6 @@ class AddrCastInstBase
86888675
return this->getAllOperands().slice(2);
86898676
}
86908677

8691-
enum {
8692-
/// the value being stored
8693-
Src,
8694-
/// the lvalue being stored to
8695-
Dest
8696-
};
8697-
86988678
SILValue getSrc() const { return this->getAllOperands()[Src].get(); }
86998679
SILValue getDest() const { return this->getAllOperands()[Dest].get(); }
87008680

0 commit comments

Comments
 (0)