Skip to content

Commit 4977850

Browse files
committed
SIL: remove the notifyDeleteHandlers mechanism
It's not needed anymore with delayed instruction deletion. It was used for two purposes: 1. For analysis, which cache instructions, to avoid dangling instruction pointers 2. For passes, which maintain worklists of instructions, to remove a deleted instructions from the worklist. This is now done by checking SILInstruction::isDeleted().
1 parent 772e675 commit 4977850

File tree

15 files changed

+29
-279
lines changed

15 files changed

+29
-279
lines changed

include/swift/SIL/Notifications.h

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -239,27 +239,6 @@ class DeserializationNotificationHandlerSet final
239239
void didDeserialize(ModuleDecl *mod,
240240
SILDefaultWitnessTable *wtable) override;
241241
};
242-
243-
/// A protocol (or interface) for handling value deletion notifications.
244-
///
245-
/// This class is used as a base class for any class that need to accept
246-
/// instruction deletion notification messages. This is used by passes and
247-
/// analysis that need to invalidate data structures that contain pointers.
248-
/// This is similar to LLVM's ValueHandle.
249-
struct DeleteNotificationHandler {
250-
DeleteNotificationHandler() { }
251-
virtual ~DeleteNotificationHandler() {}
252-
253-
/// Handle the invalidation message for the value \p Value.
254-
virtual void handleDeleteNotification(SILNode *value) { }
255-
256-
/// Returns True if the pass, analysis or other entity wants to receive
257-
/// notifications. This callback is called once when the class is being
258-
/// registered, and not once per notification. Entities that implement
259-
/// this callback should always return a constant answer (true/false).
260-
virtual bool needsNotifications() { return false; }
261-
};
262-
263242
} // namespace swift
264243

265244
#endif

include/swift/SIL/SILModule.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -345,10 +345,6 @@ class SILModule {
345345
/// Action to be executed for serializing the SILModule.
346346
ActionCallback SerializeSILAction;
347347

348-
/// A list of clients that need to be notified when an instruction
349-
/// invalidation message is sent.
350-
llvm::SetVector<DeleteNotificationHandler*> NotificationHandlers;
351-
352348
SILModule(llvm::PointerUnion<FileUnit *, ModuleDecl *> context,
353349
Lowering::TypeConverter &TC, const SILOptions &Options);
354350

@@ -424,16 +420,6 @@ class SILModule {
424420
/// Called after an instruction is moved from one function to another.
425421
void notifyMovedInstruction(SILInstruction *inst, SILFunction *fromFunction);
426422

427-
/// Add a delete notification handler \p Handler to the module context.
428-
void registerDeleteNotificationHandler(DeleteNotificationHandler* Handler);
429-
430-
/// Remove the delete notification handler \p Handler from the module context.
431-
void removeDeleteNotificationHandler(DeleteNotificationHandler* Handler);
432-
433-
/// Send the invalidation message that \p V is being deleted to all
434-
/// registered handlers. The order of handlers is deterministic but arbitrary.
435-
void notifyDeleteHandlers(SILNode *node);
436-
437423
/// Set a serialization action.
438424
void setSerializeSILAction(ActionCallback SerializeSILAction);
439425
ActionCallback getSerializeSILAction() const;

include/swift/SILOptimizer/Analysis/Analysis.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct SILAnalysisKind {
3636
};
3737

3838
/// The base class for all SIL-level analysis.
39-
class SILAnalysis : public DeleteNotificationHandler {
39+
class SILAnalysis {
4040
public:
4141
/// This is a list of values that allow passes to communicate to analysis
4242
/// which traits of the code were invalidated. Based on this information

include/swift/SILOptimizer/Analysis/EpilogueARCAnalysis.h

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,6 @@ class EpilogueARCFunctionInfo {
235235
llvm::DenseMap<SILValue, ARCInstructions> EpilogueReleaseInstCache;
236236

237237
public:
238-
void handleDeleteNotification(SILNode *node) {
239-
// Being conservative and clear everything for now.
240-
EpilogueRetainInstCache.clear();
241-
EpilogueReleaseInstCache.clear();
242-
}
243-
244238
/// Constructor.
245239
EpilogueARCFunctionInfo(SILFunction *F, PostOrderAnalysis *PO,
246240
AliasAnalysis *AA, RCIdentityAnalysis *RC)
@@ -288,22 +282,6 @@ class EpilogueARCAnalysis : public FunctionAnalysisBase<EpilogueARCFunctionInfo>
288282
EpilogueARCAnalysis(const EpilogueARCAnalysis &) = delete;
289283
EpilogueARCAnalysis &operator=(const EpilogueARCAnalysis &) = delete;
290284

291-
virtual void handleDeleteNotification(SILNode *node) override {
292-
// If the parent function of this instruction was just turned into an
293-
// external declaration, bail. This happens during SILFunction destruction.
294-
SILFunction *F = node->getFunction();
295-
if (F->isExternalDeclaration()) {
296-
return;
297-
}
298-
299-
// If we do have an analysis, tell it to handle its delete notifications.
300-
if (auto A = maybeGet(F)) {
301-
A.get()->handleDeleteNotification(node);
302-
}
303-
}
304-
305-
virtual bool needsNotifications() override { return true; }
306-
307285
static bool classof(const SILAnalysis *S) {
308286
return S->getKind() == SILAnalysisKind::EpilogueARC;
309287
}

include/swift/SILOptimizer/Analysis/EscapeAnalysis.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -832,11 +832,6 @@ class EscapeAnalysis : public BottomUpIPAnalysis {
832832
/// Propagates the escape states through the graph.
833833
void propagateEscapeStates();
834834

835-
/// Remove a value from the graph. Do not delete the mapped node, but reset
836-
/// mappedValue if it is set to this value, and make sure that the node
837-
/// cannot be looked up with getNode().
838-
void removeFromGraph(ValueBase *V);
839-
840835
enum class Traversal { Follow, Backtrack, Halt };
841836

842837
/// Traverse backward from startNode, following predecessor edges.
@@ -1237,10 +1232,6 @@ class EscapeAnalysis : public BottomUpIPAnalysis {
12371232
/// Notify the analysis about changed witness or vtables.
12381233
virtual void invalidateFunctionTables() override { }
12391234

1240-
virtual void handleDeleteNotification(SILNode *N) override;
1241-
1242-
virtual bool needsNotifications() override { return true; }
1243-
12441235
virtual void verify() const override;
12451236

12461237
virtual void verify(SILFunction *F) const override;

include/swift/SILOptimizer/Analysis/RCIdentityAnalysis.h

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -69,20 +69,6 @@ class RCIdentityFunctionInfo {
6969
/// intermediate array.
7070
void visitRCUses(SILValue V, function_ref<void(Operand *)> Visitor);
7171

72-
void handleDeleteNotification(SILNode *node) {
73-
auto value = dyn_cast<ValueBase>(node);
74-
if (!value)
75-
return;
76-
77-
// Check the cache. If we don't find it, there is nothing to do.
78-
auto Iter = RCCache.find(SILValue(value));
79-
if (Iter == RCCache.end())
80-
return;
81-
82-
// Then erase Iter from the cache.
83-
RCCache.erase(Iter);
84-
}
85-
8672
private:
8773
SILValue getRCIdentityRootInner(SILValue V, unsigned RecursionDepth);
8874
SILValue stripRCIdentityPreservingOps(SILValue V, unsigned RecursionDepth);
@@ -104,18 +90,6 @@ class RCIdentityAnalysis : public FunctionAnalysisBase<RCIdentityFunctionInfo> {
10490
RCIdentityAnalysis(const RCIdentityAnalysis &) = delete;
10591
RCIdentityAnalysis &operator=(const RCIdentityAnalysis &) = delete;
10692

107-
virtual void handleDeleteNotification(SILNode *node) override {
108-
// If the parent function of this instruction was just turned into an
109-
// external declaration, bail. This happens during SILFunction destruction.
110-
SILFunction *F = node->getFunction();
111-
if (F->isExternalDeclaration()) {
112-
return;
113-
}
114-
get(F)->handleDeleteNotification(node);
115-
}
116-
117-
virtual bool needsNotifications() override { return true; }
118-
11993
static bool classof(const SILAnalysis *S) {
12094
return S->getKind() == SILAnalysisKind::RCIdentity;
12195
}

include/swift/SILOptimizer/PassManager/Transforms.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace swift {
2222
class PrettyStackTraceSILFunctionTransform;
2323

2424
/// The base class for all SIL-level transformations.
25-
class SILTransform : public DeleteNotificationHandler {
25+
class SILTransform {
2626
public:
2727
/// The kind of transformation passes we use.
2828
enum class TransformKind {

lib/SIL/IR/SILBasicBlock.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,6 @@ SILFunctionArgument *SILBasicBlock::replaceFunctionArgument(
158158

159159
assert(ArgumentList[i]->use_empty() && "Expected no uses of the old arg!");
160160

161-
// Notify the delete handlers that this argument is being deleted.
162-
M.notifyDeleteHandlers(ArgumentList[i]);
163-
164161
SILFunctionArgument *NewArg = new (M) SILFunctionArgument(Ty, Kind, D);
165162
NewArg->setParent(this);
166163

@@ -184,9 +181,6 @@ SILPhiArgument *SILBasicBlock::replacePhiArgument(unsigned i, SILType Ty,
184181

185182
assert(ArgumentList[i]->use_empty() && "Expected no uses of the old BB arg!");
186183

187-
// Notify the delete handlers that this argument is being deleted.
188-
M.notifyDeleteHandlers(ArgumentList[i]);
189-
190184
SILPhiArgument *NewArg = new (M) SILPhiArgument(Ty, Kind, D);
191185
NewArg->setParent(this);
192186

@@ -246,8 +240,6 @@ SILPhiArgument *SILBasicBlock::insertPhiArgument(unsigned AtArgPos, SILType Ty,
246240
void SILBasicBlock::eraseArgument(int Index) {
247241
assert(getArgument(Index)->use_empty() &&
248242
"Erasing block argument that has uses!");
249-
// Notify the delete handlers that this BB argument is going away.
250-
getModule().notifyDeleteHandlers(getArgument(Index));
251243
ArgumentList.erase(ArgumentList.begin() + Index);
252244
}
253245

lib/SIL/IR/SILModule.cpp

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -808,36 +808,6 @@ void SILModule::notifyMovedInstruction(SILInstruction *inst,
808808
}
809809
}
810810

811-
void SILModule::registerDeleteNotificationHandler(
812-
DeleteNotificationHandler *handler) {
813-
// Ask the handler (that can be an analysis, a pass, or some other data
814-
// structure) if it wants to receive delete notifications.
815-
if (handler->needsNotifications()) {
816-
NotificationHandlers.insert(handler);
817-
}
818-
}
819-
820-
void SILModule::
821-
removeDeleteNotificationHandler(DeleteNotificationHandler* Handler) {
822-
NotificationHandlers.remove(Handler);
823-
}
824-
825-
void SILModule::notifyDeleteHandlers(SILNode *node) {
826-
// Update openedArchetypeDefs.
827-
if (auto *svi = dyn_cast<SingleValueInstruction>(node)) {
828-
if (CanArchetypeType archeTy = svi->getOpenedArchetype()) {
829-
OpenedArchetypeKey key = {archeTy, svi->getFunction()};
830-
assert(openedArchetypeDefs.lookup(key) == svi &&
831-
"archetype def was not registered");
832-
openedArchetypeDefs.erase(key);
833-
}
834-
}
835-
836-
for (auto *Handler : NotificationHandlers) {
837-
Handler->handleDeleteNotification(node);
838-
}
839-
}
840-
841811
// TODO: We should have an "isNoReturn" bit on Swift's BuiltinInfo, but for
842812
// now, let's recognize noreturn intrinsics and builtins specially here.
843813
bool SILModule::isNoReturnBuiltinOrIntrinsic(Identifier Name) {

lib/SILOptimizer/Analysis/EscapeAnalysis.cpp

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,15 +1271,6 @@ bool EscapeAnalysis::ConnectionGraph::forwardTraverseDefer(
12711271
return true;
12721272
}
12731273

1274-
void EscapeAnalysis::ConnectionGraph::removeFromGraph(ValueBase *V) {
1275-
CGNode *node = Values2Nodes.lookup(V);
1276-
if (!node)
1277-
return;
1278-
Values2Nodes.erase(V);
1279-
if (node->mappedValue == V)
1280-
node->mappedValue = nullptr;
1281-
}
1282-
12831274
//===----------------------------------------------------------------------===//
12841275
// Dumping, Viewing and Verification
12851276
//===----------------------------------------------------------------------===//
@@ -2922,21 +2913,6 @@ void EscapeAnalysis::invalidate(SILFunction *F, InvalidationKind K) {
29222913
}
29232914
}
29242915

2925-
void EscapeAnalysis::handleDeleteNotification(SILNode *node) {
2926-
auto value = dyn_cast<ValueBase>(node);
2927-
if (!value) return;
2928-
2929-
if (SILBasicBlock *Parent = node->getParentBlock()) {
2930-
SILFunction *F = Parent->getParent();
2931-
if (FunctionInfo *FInfo = Function2Info.lookup(F)) {
2932-
if (FInfo->isValid()) {
2933-
FInfo->Graph.removeFromGraph(value);
2934-
FInfo->SummaryGraph.removeFromGraph(value);
2935-
}
2936-
}
2937-
}
2938-
}
2939-
29402916
void EscapeAnalysis::verify() const {
29412917
#ifndef NDEBUG
29422918
for (auto Iter : Function2Info) {

lib/SILOptimizer/Mandatory/MandatoryCombine.cpp

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ bool MandatoryCombiner::doOneIteration(SILFunction &function,
296296
// its contents to the worklist and then clear said list in preparation
297297
// for the next iteration.
298298
for (SILInstruction *instruction : createdInstructions) {
299+
if (instruction->isDeleted())
300+
continue;
301+
299302
LLVM_DEBUG(llvm::dbgs() << "MC: add " << *instruction
300303
<< " from tracking list to worklist\n");
301304
worklist.add(instruction);
@@ -400,26 +403,6 @@ class MandatoryCombine final : public SILFunctionTransform {
400403
invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
401404
}
402405
}
403-
404-
protected:
405-
void handleDeleteNotification(SILNode *node) override {
406-
// Remove instructions that were both created and deleted from the list of
407-
// created instructions which will eventually be added to the worklist.
408-
409-
auto *instruction = dyn_cast<SILInstruction>(node);
410-
if (instruction == nullptr) {
411-
return;
412-
}
413-
414-
// Linear searching the tracking list doesn't hurt because usually it only
415-
// contains a few elements.
416-
auto iterator = find(createdInstructions, instruction);
417-
if (createdInstructions.end() != iterator) {
418-
createdInstructions.erase(iterator);
419-
}
420-
}
421-
422-
bool needsNotifications() override { return true; }
423406
};
424407

425408
} // end anonymous namespace

lib/SILOptimizer/Mandatory/MandatoryInlining.cpp

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -417,46 +417,6 @@ static void cleanupCalleeValue(SILValue calleeValue,
417417
namespace {
418418
/// Cleanup dead closures after inlining.
419419
class ClosureCleanup {
420-
using DeadInstSet = SmallBlotSetVector<SILInstruction *, 4>;
421-
422-
/// A helper class to update the set of dead instructions.
423-
///
424-
/// Since this is called by the SILModule callback, the instruction may longer
425-
/// be well-formed. Do not visit its operands. However, it's position in the
426-
/// basic block is still valid.
427-
///
428-
/// FIXME: Using the Module's callback mechanism for this is terrible.
429-
/// Instead, cleanupCalleeValue could be easily rewritten to use its own
430-
/// instruction deletion helper and pass a callback to tryDeleteDeadClosure
431-
/// and recursivelyDeleteTriviallyDeadInstructions.
432-
class DeleteUpdateHandler : public DeleteNotificationHandler {
433-
SILModule &Module;
434-
DeadInstSet &DeadInsts;
435-
436-
public:
437-
DeleteUpdateHandler(SILModule &M, DeadInstSet &DeadInsts)
438-
: Module(M), DeadInsts(DeadInsts) {
439-
Module.registerDeleteNotificationHandler(this);
440-
}
441-
442-
~DeleteUpdateHandler() override {
443-
// Unregister the handler.
444-
Module.removeDeleteNotificationHandler(this);
445-
}
446-
447-
// Handling of instruction removal notifications.
448-
bool needsNotifications() override { return true; }
449-
450-
// Handle notifications about removals of instructions.
451-
void handleDeleteNotification(SILNode *node) override {
452-
auto deletedI = dyn_cast<SILInstruction>(node);
453-
if (!deletedI)
454-
return;
455-
456-
DeadInsts.erase(deletedI);
457-
}
458-
};
459-
460420
SmallBlotSetVector<SILInstruction *, 4> deadFunctionVals;
461421

462422
public:
@@ -500,9 +460,8 @@ class ClosureCleanup {
500460
// set needs to continue to be updated (by this handler) when deleting
501461
// instructions. This assumes that DeadFunctionValSet::erase() is stable.
502462
void cleanupDeadClosures(SILFunction *F) {
503-
DeleteUpdateHandler deleteUpdate(F->getModule(), deadFunctionVals);
504463
for (Optional<SILInstruction *> I : deadFunctionVals) {
505-
if (!I.hasValue())
464+
if (!I.hasValue() || I.getValue()->isDeleted())
506465
continue;
507466

508467
if (auto *SVI = dyn_cast<SingleValueInstruction>(I.getValue()))

0 commit comments

Comments
 (0)