Skip to content

Commit e0fdce1

Browse files
committed
[region-isolation] Convert TransferringOperand to be a bump allocated ptr type from a pointer type.
I need to start tracking the dynamic IsolationRegionInfo for the transferring operand so I can ignore uses that are part of the same IsolationRegionInfo. IsolationRegionInfo doesn't fit into a pointer, so just to keep things the same, I am going to just allocate it. This is an initial staging commit that tests out the bump ptr allocating without expanding the type yet.
1 parent 42991a5 commit e0fdce1

File tree

3 files changed

+75
-57
lines changed

3 files changed

+75
-57
lines changed

include/swift/Basic/ImmutablePointerSet.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,55 @@ class ImmutablePointerSetFactory {
250250
return NewNode;
251251
}
252252

253+
template <typename U, typename... Args>
254+
struct IsTrivialTypedPointerAndHasProfile {
255+
constexpr static bool hasProfile =
256+
std::is_same_v<decltype(std::remove_pointer<U>::type::Profile(
257+
std::declval<Args>()...)),
258+
void>;
259+
constexpr static bool value =
260+
hasProfile && std::is_trivial_v<U> && std::is_pointer_v<U>;
261+
};
262+
263+
/// Emplace a new value with \p args if we do not yet have one. We allocate
264+
/// the object with our bump ptr allocator, so we require that the type be
265+
/// trivial.
266+
template <typename... Args>
267+
typename std::enable_if_t<IsTrivialTypedPointerAndHasProfile<
268+
T, llvm::FoldingSetNodeID &, Args...>::value,
269+
PtrSet> *
270+
emplace(Args... args) {
271+
llvm::FoldingSetNodeID ID;
272+
using NoPointerTy = typename std::remove_pointer<T>::type;
273+
NoPointerTy::Profile(ID, std::forward<Args>(args)...);
274+
275+
void *InsertPt;
276+
if (auto *PSet = Set.FindNodeOrInsertPos(ID, InsertPt)) {
277+
return PSet;
278+
}
279+
280+
size_t NumElts = 1;
281+
size_t MemSize = sizeof(PtrSet) + sizeof(NoPointerTy);
282+
283+
// Allocate the memory.
284+
auto *Mem =
285+
reinterpret_cast<PtrSet *>(Allocator.Allocate(MemSize, AllocAlignment));
286+
287+
// Copy in the pointers into the tail allocated memory. We do not need to do
288+
// any sorting/uniquing ourselves since we assume that our users perform
289+
// this task for us.
290+
llvm::MutableArrayRef<NoPointerTy *> DataMem(
291+
reinterpret_cast<NoPointerTy **>(&Mem[1]), NumElts);
292+
NoPointerTy *type =
293+
new (Allocator) NoPointerTy(std::forward<Args>(args)...);
294+
DataMem[0] = type;
295+
296+
// Allocate the new node and insert it into the Set.
297+
auto *NewNode = new (Mem) PtrSet(this, DataMem);
298+
Set.InsertNode(NewNode, InsertPt);
299+
return NewNode;
300+
}
301+
253302
PtrSet *get(T value) {
254303
llvm::FoldingSetNodeID ID;
255304
ID.AddPointer(PtrTraits::getAsVoidPointer(value));

include/swift/SILOptimizer/Utils/PartitionUtils.h

Lines changed: 20 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -134,51 +134,20 @@ struct TransferringOperand {
134134
<< "User: " << *getUser();
135135
}
136136

137-
SWIFT_DEBUG_DUMP { print(llvm::dbgs()); }
138-
};
139-
140-
} // namespace swift
141-
142-
namespace llvm {
143-
144-
template <>
145-
struct PointerLikeTypeTraits<swift::TransferringOperand> {
146-
using TransferringOperand = swift::TransferringOperand;
147-
148-
static inline void *getAsVoidPointer(TransferringOperand ptr) {
149-
return PointerLikeTypeTraits<
150-
TransferringOperand::ValueType>::getAsVoidPointer(ptr.value);
151-
}
152-
static inline TransferringOperand getFromVoidPointer(void *ptr) {
153-
return {PointerLikeTypeTraits<
154-
TransferringOperand::ValueType>::getFromVoidPointer(ptr)};
137+
static void Profile(llvm::FoldingSetNodeID &id, Operand *op,
138+
bool isClosureCaptured) {
139+
id.AddPointer(op);
140+
id.AddBoolean(isClosureCaptured);
155141
}
156142

157-
static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<
158-
TransferringOperand::ValueType>::NumLowBitsAvailable;
159-
};
160-
161-
template <>
162-
struct DenseMapInfo<swift::TransferringOperand> {
163-
using TransferringOperand = swift::TransferringOperand;
164-
using ParentInfo = DenseMapInfo<TransferringOperand::ValueType>;
165-
166-
static TransferringOperand getEmptyKey() {
167-
return TransferringOperand(ParentInfo::getEmptyKey());
168-
}
169-
static TransferringOperand getTombstoneKey() {
170-
return TransferringOperand(ParentInfo::getTombstoneKey());
143+
void Profile(llvm::FoldingSetNodeID &id) const {
144+
Profile(id, getOperand(), isClosureCaptured());
171145
}
172146

173-
static unsigned getHashValue(TransferringOperand operand) {
174-
return ParentInfo::getHashValue(operand.value);
175-
}
176-
static bool isEqual(TransferringOperand LHS, TransferringOperand RHS) {
177-
return ParentInfo::isEqual(LHS.value, RHS.value);
178-
}
147+
SWIFT_DEBUG_DUMP { print(llvm::dbgs()); }
179148
};
180149

181-
} // namespace llvm
150+
} // namespace swift
182151

183152
namespace swift {
184153

@@ -371,9 +340,9 @@ class Partition {
371340

372341
using Element = PartitionPrimitives::Element;
373342
using Region = PartitionPrimitives::Region;
374-
using TransferringOperandSet = ImmutablePointerSet<TransferringOperand>;
343+
using TransferringOperandSet = ImmutablePointerSet<TransferringOperand *>;
375344
using TransferringOperandSetFactory =
376-
ImmutablePointerSetFactory<TransferringOperand>;
345+
ImmutablePointerSetFactory<TransferringOperand *>;
377346

378347
private:
379348
/// A map from a region number to a instruction that consumes it.
@@ -721,8 +690,8 @@ class Partition {
721690
bool isClosureCaptured = false;
722691
if (isTransferred) {
723692
isClosureCaptured = llvm::any_of(
724-
iter->getSecond()->range(), [](const TransferringOperand &operand) {
725-
return operand.isClosureCaptured();
693+
iter->getSecond()->range(), [](const TransferringOperand *operand) {
694+
return operand->isClosureCaptured();
726695
});
727696
}
728697

@@ -765,8 +734,8 @@ class Partition {
765734
bool isClosureCaptured = false;
766735
if (isTransferred) {
767736
isClosureCaptured = llvm::any_of(
768-
iter->getSecond()->range(), [](const TransferringOperand &operand) {
769-
return operand.isClosureCaptured();
737+
iter->getSecond()->range(), [](const TransferringOperand *operand) {
738+
return operand->isClosureCaptured();
770739
});
771740
}
772741

@@ -795,7 +764,7 @@ class Partition {
795764
if (isTransferred) {
796765
for (auto op : iter->getSecond()->data()) {
797766
os << " ";
798-
op.print(os);
767+
op->print(os);
799768
}
800769
} else {
801770
os << "None.\n";
@@ -1208,7 +1177,7 @@ struct PartitionOpEvaluator {
12081177

12091178
/// Call handleLocalUseAfterTransfer on our CRTP subclass.
12101179
void handleLocalUseAfterTransfer(const PartitionOp &op, Element elt,
1211-
TransferringOperand transferringOp) const {
1180+
TransferringOperand *transferringOp) const {
12121181
return asImpl().handleLocalUseAfterTransfer(op, elt, transferringOp);
12131182
}
12141183

@@ -1326,9 +1295,9 @@ struct PartitionOpEvaluator {
13261295
}
13271296

13281297
// Mark op.getOpArgs()[0] as transferred.
1329-
p.markTransferred(
1330-
op.getOpArgs()[0],
1331-
ptrSetFactory.get({op.getSourceOp(), isClosureCapturedElt}));
1298+
auto *ptrSet =
1299+
ptrSetFactory.emplace(op.getSourceOp(), isClosureCapturedElt);
1300+
p.markTransferred(op.getOpArgs()[0], ptrSet);
13321301
return;
13331302
}
13341303
case PartitionOpKind::UndoTransfer: {
@@ -1419,7 +1388,7 @@ struct PartitionOpEvaluatorBaseImpl : PartitionOpEvaluator<Subclass> {
14191388
/// region. Can be used to get the immediate value transferred or the
14201389
/// transferring instruction.
14211390
void handleLocalUseAfterTransfer(const PartitionOp &op, Element elt,
1422-
TransferringOperand transferringOp) const {}
1391+
TransferringOperand *transferringOp) const {}
14231392

14241393
/// This is called if we detect a never transferred element that was passed to
14251394
/// a transfer instruction.

lib/SILOptimizer/Mandatory/TransferNonSendable.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,7 @@ struct DiagnosticEvaluator final
12351235

12361236
void handleLocalUseAfterTransfer(const PartitionOp &partitionOp,
12371237
TrackableValueID transferredVal,
1238-
TransferringOperand transferringOp) const {
1238+
TransferringOperand *transferringOp) const {
12391239
// Ignore this if we have a gep like instruction that is returning a
12401240
// sendable type and transferringOp was not set with closure
12411241
// capture.
@@ -1244,7 +1244,7 @@ struct DiagnosticEvaluator final
12441244
if (isa<TupleElementAddrInst, StructElementAddrInst>(svi) &&
12451245
!regionanalysisimpl::isNonSendableType(svi->getType(),
12461246
svi->getFunction())) {
1247-
bool isCapture = transferringOp.isClosureCaptured();
1247+
bool isCapture = transferringOp->isClosureCaptured();
12481248
if (!isCapture) {
12491249
return;
12501250
}
@@ -1254,14 +1254,14 @@ struct DiagnosticEvaluator final
12541254
auto rep = info->getValueMap().getRepresentative(transferredVal);
12551255
LLVM_DEBUG(llvm::dbgs()
12561256
<< " Emitting Use After Transfer Error!\n"
1257-
<< " Transferring Inst: " << *transferringOp.getUser()
1257+
<< " Transferring Inst: " << *transferringOp->getUser()
12581258
<< " Transferring Op Value: "
1259-
<< transferringOp.getOperand()->get()
1259+
<< transferringOp->getOperand()->get()
12601260
<< " Require Inst: " << *partitionOp.getSourceInst()
12611261
<< " ID: %%" << transferredVal << "\n"
12621262
<< " Rep: " << *rep << " Transferring Op Num: "
1263-
<< transferringOp.getOperand()->getOperandNumber() << '\n');
1264-
transferOpToRequireInstMultiMap.insert(transferringOp.getOperand(),
1263+
<< transferringOp->getOperand()->getOperandNumber() << '\n');
1264+
transferOpToRequireInstMultiMap.insert(transferringOp->getOperand(),
12651265
partitionOp.getSourceInst());
12661266
}
12671267

0 commit comments

Comments
 (0)