Files
swift-mirror/include/swift/SILOptimizer/Utils/CanonicalizeInstruction.h
Michael Gottesman b6bfea1f39 [sil-optimizer] Get rid of the InstModCallback constructors in favor of onDelete/onCreatedNewInst/etc.
Without this when constructing an InstModCallback it is hard to distinguish
which closure is meant for which operation when passed to the constructor of
InstModCallback (if this was in Swift, we could use argument labels, but we do
not have such things in c++).

This new value type sort of formulation makes it unambiguous which callback is
used for what when constructing one of these.
2021-04-26 23:33:33 -07:00

108 lines
4.2 KiB
C++

//===-- CanonicalizeInstruction.h - canonical SIL peepholes -----*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 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
//
//===----------------------------------------------------------------------===//
///
/// SSA-peephole transformations that yield a more canonical SIL representation.
///
/// Unlike simplifyInstruction, these transformations may effect any
/// instruction, not only single-values, and may arbitrarily generate new SIL
/// instructions.
///
/// Unlike SILCombine, these peepholes must work on 'raw' SIL form and should be
/// limited to those necessary to aid in diagnostics and other mandatory
/// pipelin/e passes. Optimization may only be done to the extent that it
/// neither interferes with diagnostics nor increases compile time.
///
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SILOPTIMIZER_UTILS_CANONICALIZEINSTRUCTION_H
#define SWIFT_SILOPTIMIZER_UTILS_CANONICALIZEINSTRUCTION_H
#include "swift/SIL/BasicBlockUtils.h"
#include "swift/SIL/SILBasicBlock.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
#include "llvm/Support/Debug.h"
namespace swift {
/// Abstract base class. Implements all canonicalization transforms. Extended by
/// passes to be notified of each SIL modification.
struct CanonicalizeInstruction {
// May be overriden by passes.
static constexpr const char *defaultDebugType = "sil-canonicalize";
const char *debugType = defaultDebugType;
DeadEndBlocks &deadEndBlocks;
InstModCallbacks callbacks;
CanonicalizeInstruction(const char *passDebugType,
DeadEndBlocks &deadEndBlocks)
: deadEndBlocks(deadEndBlocks),
callbacks() {
#ifndef NDEBUG
if (llvm::DebugFlag && !llvm::isCurrentDebugType(debugType))
debugType = passDebugType;
#endif
callbacks = InstModCallbacks()
.onDelete([&](SILInstruction *toDelete) {
killInstruction(toDelete);
})
.onCreateNewInst([&](SILInstruction *newInst) {
notifyNewInstruction(newInst);
})
.onSetUseValue([&](Operand *use, SILValue newValue) {
use->set(newValue);
notifyHasNewUsers(newValue);
});
}
virtual ~CanonicalizeInstruction();
const SILFunction *getFunction() const { return deadEndBlocks.getFunction(); }
/// Rewrite this instruction, based on its operands and uses, into a more
/// canonical representation.
///
/// Return an iterator to the next instruction or to the end of the block.
/// The returned iterator will follow any newly added or to-be-deleted
/// instructions, regardless of whether the pass immediately deletes the
/// instructions or simply records them for later deletion.
///
/// To (re)visit new instructions, override notifyNewInstruction().
///
/// To determine if any transformation at all occurred, override
/// notifyNewInstruction(), killInstruction(), and notifyNewUsers().
///
/// Warning: If the \p inst argument is killed and the client immediately
/// erases \p inst, then it may be an invalid pointer upon return.
SILBasicBlock::iterator canonicalize(SILInstruction *inst);
/// Record a newly generated instruction.
virtual void notifyNewInstruction(SILInstruction *inst) = 0;
/// Kill an instruction that no longer has uses, or whose side effect is now
/// represented by a different instruction. The client can defer erasing the
/// instruction but must eventually erase all killed instructions to restore
/// valid SIL.
///
/// This callback should not mutate any other instructions. It may only delete
/// the given argument. It will be called separately for each end-of-scope and
/// debug use before being called on the instruction they use.
virtual void killInstruction(SILInstruction *inst) = 0;
/// Record a SIL value that has acquired new users.
virtual void notifyHasNewUsers(SILValue value) = 0;
};
} // end namespace swift
#endif // SWIFT_SILOPTIMIZER_UTILS_CANONICALIZEINSTRUCTION_H