mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
I recently have been running into the issue that many of these APIs perform the deletion operation themselves and notify the caller it is going to delete instead of allowing the caller to specify how the instruction is deleted. This causes interesting semantic issues (see the loop in deleteInstruction I simplified) and breaks composition since many parts of the optimizer use InstModCallbacks for this purpose. To fix this, I added a notify will be deleted construct to InstModCallback. In a similar way to the rest of it, if the notify is not set, we do not call any code implying that we should have good predictable performance in loops since we will always skip the function call. I also changed InstModCallback::deleteInst() to notify before deleting so we have a default safe behavior. All previous use sites of this API do not care about being notified and the only new use sites of this API are in InstructionDeleter that perform special notification behavior (it notifies for certain sets of instructions it is going to delete before it deletes any of them). To work around this, I added a bool to deleteInst to control this behavior and defaulted to notifying. This should ensure that all other use sites still compose correctly.
86 lines
2.8 KiB
C++
86 lines
2.8 KiB
C++
//===--- DebugOptUtils.h --------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// Debug Info related utilities that rely on code in SILOptimizer/ and thus can
|
|
/// not be in include/swift/SIL/DebugUtils.h.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_SILOPTIMIZER_DEBUGOPTUTILS_H
|
|
#define SWIFT_SILOPTIMIZER_DEBUGOPTUTILS_H
|
|
|
|
#include "swift/SIL/DebugUtils.h"
|
|
#include "swift/SIL/SILValue.h"
|
|
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
|
|
|
|
namespace swift {
|
|
|
|
/// Deletes all of the debug instructions that use \p value.
|
|
inline void deleteAllDebugUses(SILValue value, InstModCallbacks &callbacks) {
|
|
for (auto ui = value->use_begin(), ue = value->use_end(); ui != ue;) {
|
|
auto *inst = ui->getUser();
|
|
++ui;
|
|
if (inst->isDebugInstruction()) {
|
|
callbacks.deleteInst(inst);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Deletes all of the debug uses of any result of \p inst.
|
|
inline void deleteAllDebugUses(SILInstruction *inst,
|
|
InstModCallbacks &callbacks) {
|
|
for (SILValue v : inst->getResults()) {
|
|
deleteAllDebugUses(v, callbacks);
|
|
}
|
|
}
|
|
|
|
/// Erases the instruction \p I from it's parent block and deletes it, including
|
|
/// all debug instructions which use \p I.
|
|
/// Precondition: The instruction may only have debug instructions as uses.
|
|
/// If the iterator \p InstIter references any deleted instruction, it is
|
|
/// incremented.
|
|
///
|
|
/// \p callbacks InstModCallback to use.
|
|
///
|
|
/// Returns an iterator to the next non-deleted instruction after \p I.
|
|
inline SILBasicBlock::iterator
|
|
eraseFromParentWithDebugInsts(SILInstruction *inst,
|
|
InstModCallbacks callbacks = InstModCallbacks()) {
|
|
auto nextII = std::next(inst->getIterator());
|
|
|
|
auto results = inst->getResults();
|
|
bool foundAny;
|
|
do {
|
|
foundAny = false;
|
|
for (auto result : results) {
|
|
while (!result->use_empty()) {
|
|
foundAny = true;
|
|
auto *user = result->use_begin()->getUser();
|
|
assert(user->isDebugInstruction());
|
|
if (nextII == user->getIterator())
|
|
++nextII;
|
|
callbacks.deleteInst(user);
|
|
}
|
|
}
|
|
} while (foundAny);
|
|
|
|
// Just matching what eraseFromParentWithDebugInsts is today.
|
|
if (nextII == inst->getIterator())
|
|
++nextII;
|
|
callbacks.deleteInst(inst, false /*do not notify*/);
|
|
return nextII;
|
|
}
|
|
|
|
} // namespace swift
|
|
|
|
#endif
|