Files
swift-mirror/include/swift/SILOptimizer/Utils/DebugOptUtils.h
Michael Gottesman 7b55cbc669 [sil-optimizer] Make InstructionDeleter and related APIs to use an InstModCallback instead of a notification callback.
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.
2021-04-26 16:37:43 -07:00

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