2020#ifndef SWIFT_SILOPTIMIZER_UTILS_INSTOPTUTILS_H
2121#define SWIFT_SILOPTIMIZER_UTILS_INSTOPTUTILS_H
2222
23- #include " swift/SILOptimizer/Utils/InstModCallbacks.h"
2423#include " swift/SIL/BasicBlockUtils.h"
2524#include " swift/SIL/SILBuilder.h"
2625#include " swift/SIL/SILInstruction.h"
2726#include " swift/SILOptimizer/Analysis/ARCAnalysis.h"
2827#include " swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h"
2928#include " swift/SILOptimizer/Analysis/EpilogueARCAnalysis.h"
3029#include " swift/SILOptimizer/Analysis/SimplifyInstruction.h"
30+ #include " swift/SILOptimizer/Utils/InstModCallbacks.h"
31+ #include " swift/SILOptimizer/Utils/UpdatingInstructionIterator.h"
3132#include " llvm/ADT/SmallPtrSet.h"
3233
3334namespace swift {
@@ -208,8 +209,6 @@ bool tryCheckedCastBrJumpThreading(
208209// / deleter.deleteIfDead(instruction);
209210// / deleter.cleanupDeadInstructions();
210211// /
211- // /
212- // /
213212// / This is designed to be used with a single 'onDelete' callback, which is
214213// / invoked consistently just before deleting each instruction. It's usually
215214// / used to avoid iterator invalidation (see the updatingIterator() factory
@@ -230,37 +229,36 @@ bool tryCheckedCastBrJumpThreading(
230229// / Note that the forceDelete* APIs only invoke notifyWillBeDeletedFunc() when
231230// / an operand's definition will become dead after force-deleting the specified
232231// / instruction. Some clients force-delete related instructions one at a
233- // / time. They may not force-deleted. It's the client's responsiblity to invoke
234- // / notifyWillBeDeletedFunc() on those explicitly deleted instructions if
235- // / needed.
236- // /
232+ // / time. It is the client's responsiblity to invoke notifyWillBeDeletedFunc()
233+ // / on those explicitly deleted instructions if needed.
237234class InstructionDeleter {
238- public:
239- static InstructionDeleter updatingIterator (SILBasicBlock::iterator &iter) {
240- auto onDelete = InstModCallbacks ().onDelete ([&](SILInstruction *deadInst) {
241- if (deadInst->getIterator () == iter)
242- ++iter;
243- deadInst->eraseFromParent ();
244- });
245- return InstructionDeleter (onDelete);
246- }
247-
248- private:
249235 // / A set vector of instructions that are found to be dead. The ordering of
250236 // / instructions in this set is important as when a dead instruction is
251237 // / removed, new instructions will be generated to fix the lifetime of the
252238 // / instruction's operands. This has to be deterministic.
253239 SmallSetVector<SILInstruction *, 8 > deadInstructions;
254240
255- // / Callbacks used when adding/deleting instructions.
256- InstModCallbacks callbacks;
241+ UpdatingInstructionIteratorRegistry iteratorRegistry;
257242
258243public:
259- InstructionDeleter () : deadInstructions(), callbacks() {}
260- InstructionDeleter (InstModCallbacks callbacks)
261- : deadInstructions(), callbacks(callbacks) {}
244+ InstructionDeleter (InstModCallbacks chainedCallbacks = InstModCallbacks())
245+ : deadInstructions(), iteratorRegistry(chainedCallbacks) {}
246+
247+ InstModCallbacks &getCallbacks () { return iteratorRegistry.getCallbacks (); }
248+
249+ UpdatingInstructionIteratorRegistry &getIteratorRegistry () {
250+ return iteratorRegistry;
251+ }
262252
263- InstModCallbacks &getCallbacks () { return callbacks; }
253+ llvm::iterator_range<UpdatingInstructionIterator>
254+ updatingRange (SILBasicBlock *bb) {
255+ return iteratorRegistry.makeIteratorRange (bb);
256+ }
257+
258+ llvm::iterator_range<UpdatingReverseInstructionIterator>
259+ updatingReverseRange (SILBasicBlock *bb) {
260+ return iteratorRegistry.makeReverseIteratorRange (bb);
261+ }
264262
265263 // / If the instruction \p inst is dead, record it so that it can be cleaned
266264 // / up.
0 commit comments