| //===-- 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/SILBasicBlock.h" |
| #include "swift/SIL/SILInstruction.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; |
| |
| CanonicalizeInstruction(const char *passDebugType) { |
| #ifndef NDEBUG |
| if (llvm::DebugFlag && !llvm::isCurrentDebugType(debugType)) |
| debugType = passDebugType; |
| #endif |
| } |
| |
| virtual ~CanonicalizeInstruction(); |
| |
| /// 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 |