2828#include " swift/SILOptimizer/Analysis/EpilogueARCAnalysis.h"
2929#include " swift/SILOptimizer/Analysis/SimplifyInstruction.h"
3030#include " swift/SILOptimizer/Utils/InstModCallbacks.h"
31- #include " swift/SILOptimizer/Utils/UpdatingInstructionIterator.h"
3231#include " llvm/ADT/SmallPtrSet.h"
3332
3433namespace swift {
@@ -76,6 +75,20 @@ bool hasOnlyEndOfScopeOrEndOfLifetimeUses(SILInstruction *inst);
7675// / Return the number of @inout arguments passed to the given apply site.
7776unsigned getNumInOutArguments (FullApplySite applySite);
7877
78+ // / If \c inst is dead, delete it and recursively eliminate all code that
79+ // / becomes dead because of that. If more than one instruction must
80+ // / be checked/deleted use the \c InstructionDeleter utility.
81+ // /
82+ // / This function will add necessary compensation code to fix the lifetimes of
83+ // / the operands of the deleted instructions.
84+ // /
85+ // / \pre the SIL function containing the instruction is assumed to be
86+ // / consistent, i.e., does not have under or over releases.
87+ // /
88+ // / \p callbacks.onDelete() is invoked to delete each instruction.
89+ void eliminateDeadInstruction (SILInstruction *inst,
90+ InstModCallbacks callbacks = InstModCallbacks());
91+
7992// / For each of the given instructions, if they are dead delete them
8093// / along with their dead operands. Note this utility must be phased out and
8194// / replaced by \c eliminateDeadInstruction and
@@ -85,6 +98,8 @@ unsigned getNumInOutArguments(FullApplySite applySite);
8598// / \param force If Force is set, don't check if the top level instructions
8699// / are considered dead - delete them regardless.
87100// / \param callbacks The inst mod callbacks used to delete instructions.
101+ // /
102+ // / Deprecated: Use InstructionDeleter instead.
88103void recursivelyDeleteTriviallyDeadInstructions (
89104 ArrayRef<SILInstruction *> inst, bool force = false ,
90105 InstModCallbacks callbacks = InstModCallbacks());
@@ -98,6 +113,8 @@ void recursivelyDeleteTriviallyDeadInstructions(
98113// / \param force If Force is set, don't check if the top level instruction is
99114// / considered dead - delete it regardless.
100115// / \param callbacks InstModCallback used to delete instructions.
116+ // /
117+ // / Deprecated: Use InstructionDeleter instead.
101118void recursivelyDeleteTriviallyDeadInstructions (
102119 SILInstruction *inst, bool force = false ,
103120 InstModCallbacks callbacks = InstModCallbacks());
@@ -207,181 +224,6 @@ bool tryCheckedCastBrJumpThreading(
207224 SmallVectorImpl<SILBasicBlock *> &blocksForWorklist,
208225 bool EnableOSSARewriteTerminator);
209226
210- // / A utility for deleting one or more instructions belonging to a function, and
211- // / cleaning up any dead code resulting from deleting those instructions. Use
212- // / this utility instead of \p recursivelyDeleteTriviallyDeadInstruction
213- // / as follows:
214- // / InstructionDeleter deleter;
215- // / deleter.deleteIfDead(instruction);
216- // / deleter.cleanupDeadInstructions();
217- // /
218- // / This is designed to be used with a single 'onDelete' callback, which is
219- // / invoked consistently just before deleting each instruction. It's usually
220- // / used to avoid iterator invalidation (see the updatingIterator() factory
221- // / method). The other InstModCallbacks should generally be handled at a higher
222- // / level, and avoided altogether if possible. The following two are supported
223- // / for flexibility:
224- // /
225- // / callbacks.createdNewInst() is invoked incrementally when it fixes lifetimes
226- // / while deleting a set of instructions, but the SIL may still be invalid
227- // / relative to the new instruction.
228- // /
229- // / callbacks.notifyWillBeDeletedFunc() is invoked when a dead instruction is
230- // / first recognized and was not already passed in by the client. During the
231- // / callback, the to-be-deleted instruction has valid SIL. It's operands and
232- // / uses can be inspected and cached. It will be deleted later during
233- // / cleanupDeadInstructions().
234- // /
235- // / Note that the forceDelete* APIs only invoke notifyWillBeDeletedFunc() when
236- // / an operand's definition will become dead after force-deleting the specified
237- // / instruction. Some clients force-delete related instructions one at a
238- // / time. It is the client's responsiblity to invoke notifyWillBeDeletedFunc()
239- // / on those explicitly deleted instructions if needed.
240- class InstructionDeleter {
241- // / A set vector of instructions that are found to be dead. The ordering of
242- // / instructions in this set is important as when a dead instruction is
243- // / removed, new instructions will be generated to fix the lifetime of the
244- // / instruction's operands. This has to be deterministic.
245- SmallSetVector<SILInstruction *, 8 > deadInstructions;
246-
247- UpdatingInstructionIteratorRegistry iteratorRegistry;
248-
249- public:
250- InstructionDeleter (InstModCallbacks chainedCallbacks = InstModCallbacks())
251- : deadInstructions(), iteratorRegistry(chainedCallbacks) {}
252-
253- UpdatingInstructionIteratorRegistry &getIteratorRegistry () {
254- return iteratorRegistry;
255- }
256-
257- InstModCallbacks &getCallbacks () { return iteratorRegistry.getCallbacks (); }
258-
259- llvm::iterator_range<UpdatingInstructionIterator>
260- updatingRange (SILBasicBlock *bb) {
261- return iteratorRegistry.makeIteratorRange (bb);
262- }
263-
264- llvm::iterator_range<UpdatingReverseInstructionIterator>
265- updatingReverseRange (SILBasicBlock *bb) {
266- return iteratorRegistry.makeReverseIteratorRange (bb);
267- }
268-
269- bool hadCallbackInvocation () const {
270- return const_cast <InstructionDeleter *>(this )
271- ->getCallbacks ()
272- .hadCallbackInvocation ();
273- }
274-
275- // / If the instruction \p inst is dead, record it so that it can be cleaned
276- // / up.
277- // /
278- // / Calls callbacks.notifyWillBeDeleted().
279- bool trackIfDead (SILInstruction *inst);
280-
281- // / Track this instruction as dead even if it has side effects. Used to enable
282- // / the deletion of a bunch of instructions at the same time.
283- // /
284- // / Calls callbacks.notifyWillBeDeleted().
285- void forceTrackAsDead (SILInstruction *inst);
286-
287- // / If the instruction \p inst is dead, delete it immediately along with its
288- // / destroys and scope-ending uses. If any operand definitions will become
289- // / dead after deleting this instruction, track them so they can be deleted
290- // / later during cleanUpDeadInstructions().
291- // /
292- // / Calls callbacks.notifyWillBeDeleted().
293- bool deleteIfDead (SILInstruction *inst);
294-
295- // / Delete the instruction \p inst, ignoring its side effects. If any operand
296- // / definitions will become dead after deleting this instruction, track them
297- // / so they can be deleted later during cleanUpDeadInstructions(). This
298- // / function will add necessary ownership instructions to fix the lifetimes of
299- // / the operands of \p inst to compensate for its deletion.
300- // /
301- // / \pre the function containing \p inst must be using ownership SIL.
302- // / \pre the instruction to be deleted must not have any use other than
303- // / incidental uses.
304- // /
305- // / callbacks.notifyWillBeDeleted will not be called for \p inst but will be
306- // / called for any other instructions that become dead as a result.
307- void forceDeleteAndFixLifetimes (SILInstruction *inst);
308-
309- // / Delete the instruction \p inst and record instructions that may become
310- // / dead because of the removal of \c inst. If in ownership SIL, use the
311- // / \c forceDeleteAndFixLifetimes function instead, unless under special
312- // / circumstances where the client must handle fixing lifetimes of the
313- // / operands of the deleted instructions. This function will not fix the
314- // / lifetimes of the operands of \c inst once it is deleted. This function
315- // / will not clean up dead code resulting from the instruction's removal. To
316- // / do so, invoke the method \c cleanupDeadCode of this instance, once the SIL
317- // / of the contaning function is made consistent.
318- // /
319- // / \pre the instruction to be deleted must not have any use other than
320- // / incidental uses.
321- // /
322- // / callbacks.notifyWillBeDeleted will not be called for \p inst but will be
323- // / called for any other instructions that become dead as a result.
324- void forceDelete (SILInstruction *inst);
325-
326- // / Recursively delete all of the uses of the instruction before deleting the
327- // / instruction itself. Does not fix lifetimes.
328- // /
329- // / callbacks.notifyWillBeDeleted will not be called for \p inst but will
330- // / be called for any other instructions that become dead as a result.
331- void forceDeleteWithUsers (SILInstruction *inst) {
332- deleteWithUses (inst, /* fixLifetimes*/ false , /* forceDeleteUsers*/ true );
333- }
334-
335- // / Clean up dead instructions that are tracked by this instance and all
336- // / instructions that transitively become dead.
337- // /
338- // / \pre the function contaning dead instructions must be consistent (i.e., no
339- // / under or over releases). Note that if \c forceDelete call leaves the
340- // / function body in an inconsistent state, it needs to be made consistent
341- // / before this method is invoked.
342- // /
343- // / callbacks.notifyWillBeDeletedFunc will only be called for instructions
344- // / that become dead during cleanup but were not already tracked.
345- void cleanupDeadInstructions ();
346-
347- // / Recursively visit users of \p inst and delete instructions that are dead
348- // / including \p inst.
349- // /
350- // / callbacks.notifyWillBeDeletedFunc will be called for any dead
351- // / instructions.
352- void recursivelyDeleteUsersIfDead (SILInstruction *inst);
353-
354- // / Recursively visit users of \p inst and force delete them including \p
355- // / inst. Also, destroy the consumed operands of the deleted instructions
356- // / whenever necessary.
357- // /
358- // / callbacks.notifyWillBeDeletedFunc will not be called for \p inst or its
359- // / users but will be called for any other instructions that become dead as a
360- // / result.
361- void recursivelyForceDeleteUsersAndFixLifetimes (SILInstruction *inst);
362-
363- private:
364- void deleteWithUses (SILInstruction *inst, bool fixLifetimes,
365- bool forceDeleteUsers = false );
366- };
367-
368- // / If \c inst is dead, delete it and recursively eliminate all code that
369- // / becomes dead because of that. If more than one instruction must
370- // / be checked/deleted use the \c InstructionDeleter utility.
371- // /
372- // / This function will add necessary compensation code to fix the lifetimes of
373- // / the operands of the deleted instructions.
374- // /
375- // / \pre the SIL function containing the instruction is assumed to be
376- // / consistent, i.e., does not have under or over releases.
377- // /
378- // / \p callbacks is used to delete each instruction. However, the callback
379- // / cannot be used to update instruction iterators since other instructions to
380- // / be deleted remain in the instruction list. If set to nullptr, we use the
381- // / default instruction modification callback structure.
382- void eliminateDeadInstruction (SILInstruction *inst,
383- InstModCallbacks callbacks = InstModCallbacks());
384-
385227// / Get all consumed arguments of a partial_apply.
386228// /
387229// / These are basically all arguments, except inout arguments and arguments
@@ -731,4 +573,4 @@ bool eliminateDeadAllocations(SILFunction &fn);
731573
732574} // end namespace swift
733575
734- #endif
576+ #endif // SWIFT_SILOPTIMIZER_UTILS_INSTOPTUTILS_H
0 commit comments