//===--- SILNodes.def - Swift SIL Metaprogramming ---------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2022 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 // //===----------------------------------------------------------------------===// /// /// \file /// /// This file defines macros used for macro-metaprogramming with SIL nodes. It /// supports changing how macros expand by #defining an auxillary variable /// before including SILNodes.def as summarized in the chart below: /// /// | #define | Operation | /// |--------------------+-----------------------------------------------------| /// | N/A | Visit single value insts as insts | /// | VALUE | Visit single value insts as values | /// | ABSTRACT_VALUE | Visit abstract single value insts as values | /// | DYNAMICCAST_INST | Visit dynamic casts as dynamic casts. | /// /// We describe the triggering variables below: /// /// 1. VALUE(ID, PARENT). /// /// If defined will cause SingleValueInsts to passed to VALUE(ID, PARENT) /// instead of to FULL_INST. /// /// 2. ABSTRACT_VALUE(ID, PARENT). /// /// If defined this will cause ABSTRACT_SINGLE_VALUE_INST to expand to /// ABSTRACT_VALUE INSTEAD OF ABSTRACT_INST. /// /// 3. DYNAMICCAST_INST(ID, PARENT) /// /// If defined this will cause: /// /// * DYNAMICCAST_SINGLE_VALUE_INST /// * DYNAMICCAST_TERMINATOR /// * DYNAMICCAST_NON_VALUE_INST /// /// To expand to DYNAMICCAST_INST(ID, PARENT) instead of delegating to /// SINGLE_VALUE_INST, TERMINATOR, or NON_VALUE_INST /// //===----------------------------------------------------------------------===// /// NODE(ID, PARENT) /// /// A concrete subclass of SILNode. ID is the name of the class as well /// as a member of SILNodeKind. PARENT is the name of its abstract /// superclass. #ifndef NODE #define NODE(ID, PARENT) #endif /// SINGLE_VALUE_INST(ID, TEXTUALNAME, PARENT, MEMBEHAVIOR, MAYRELEASE) /// /// A concrete subclass of SingleValueInstruction, which inherits from /// both ValueBase and SILInstruction. ID is a member of both ValueKind /// and SILInstructionKind. #ifndef SINGLE_VALUE_INST #ifdef VALUE #define SINGLE_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \ VALUE(ID, PARENT) #else #define SINGLE_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \ FULL_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) #endif #endif /// DYNAMICCAST_SINGLE_VALUE_INST(ID, TEXTUALNAME, PARENT, MEMBEHAVIOR, MAYRELEASE) /// /// A SINGLE_VALUE_INST that is a cast instruction. ID is a member of /// SILDynamicCastKind. #ifndef DYNAMICCAST_SINGLE_VALUE_INST #ifdef DYNAMICCAST_INST #define DYNAMICCAST_SINGLE_VALUE_INST(ID, TEXTUALNAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \ DYNAMICCAST_INST(ID, TEXTUALNAME) #else #define DYNAMICCAST_SINGLE_VALUE_INST(ID, TEXTUALNAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \ SINGLE_VALUE_INST(ID, TEXTUALNAME, PARENT, MEMBEHAVIOR, MAYRELEASE) #endif #endif /// MULTIPLE_VALUE_INST(Id, TextualName, Parent, MemBehavior, MayRelease) /// /// A concrete subclass of MultipleValueInstruction. ID is a member of /// SILInstructionKind. The Node's class name is ID and the name of the base /// class in the hierarchy is PARENT. #ifndef MULTIPLE_VALUE_INST #define MULTIPLE_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \ FULL_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) #endif /// MULTIPLE_VALUE_INST_RESULT(ID, PARENT) /// /// A concrete subclass of MultipleValueInstructionResult. ID is a member of /// ValueKind. The Node's class name is ID and the name of the base class in /// the hierarchy is PARENT. #ifndef MULTIPLE_VALUE_INST_RESULT #define MULTIPLE_VALUE_INST_RESULT(ID, PARENT) VALUE(ID, PARENT) #endif /// VALUE(ID, PARENT) /// /// A concrete subclass of ValueBase. ID is a member of ValueKind. /// ID is a member of ValueKind. The node's class name is /// Id, and the name of its base class (in the SILValue hierarchy) is Parent. #ifndef VALUE #define VALUE(ID, PARENT) NODE(ID, PARENT) #endif /// ARGUMENT(ID, PARENT) /// /// A concrete subclass of SILArgument, which is a subclass of ValueBase. #ifndef ARGUMENT #define ARGUMENT(ID, PARENT) VALUE(ID, PARENT) #endif /// INST(ID, PARENT) /// /// A concrete subclass of SILInstruction. ID is a member of /// SILInstructionKind. #ifndef INST #define INST(ID, PARENT) NODE(ID, PARENT) #endif /// FULL_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) /// /// A macro which includes a bunch of secondary information about /// an instruction. In addition to the information from INST: /// /// NAME is the name of the instruction in SIL assembly. /// The argument will be a bare identifier, not a string literal. /// /// MEMBEHAVIOR is an enum value that reflects the memory behavior of the /// instruction. It is only used in the implementation of /// SILInstruction::getMemoryBehavior(). Memory behavior is relative, so /// whenever possible, clients should instead use /// AliasAnalysis::computeMemoryBehavior(SILInstruction, SILValue) which only /// defaults to SILInstruction::getMemoryBehavior() when AliasAnalysis cannot /// disambiguate the instruction's effects from the value of interest. /// /// MAYRELEASE indicates whether the execution of the /// instruction may result in memory being released. #ifndef FULL_INST #define FULL_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) INST(ID, PARENT) #endif /// NON_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) /// /// ID is a SILInstructionKind and the name of a subclass of SILInstruction /// that does not inherit from ValueBase. #ifndef NON_VALUE_INST #define NON_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \ FULL_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) #endif #ifndef DYNAMICCAST_NON_VALUE_INST #ifdef DYNAMICCAST_INST #define DYNAMICCAST_NON_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \ DYNAMICCAST_INST(ID, NAME) #else #define DYNAMICCAST_NON_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \ NON_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) #endif #endif /// TERMINATOR(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) /// /// ID is a member of TerminatorKind and the name of a subclass of TermInst. #ifndef TERMINATOR #define TERMINATOR(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \ NON_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) #endif /// DYNAMICCAST_TERMINATOR(ID, TEXTUAL_NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) /// /// A terminator that casts its inputs. ID is a member of SILDynamicCastKind. #ifndef DYNAMICCAST_TERMINATOR #ifdef DYNAMICCAST_INST #define DYNAMICCAST_TERMINATOR(ID, TEXTUAL_NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \ DYNAMICCAST_INST(ID, TEXTUAL_NAME) #else #define DYNAMICCAST_TERMINATOR(ID, TEXTUAL_NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \ TERMINATOR(ID, TEXTUAL_NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) #endif #endif /// ABSTRACT_NODE(ID, PARENT) /// /// An abstract class in the SILNode hierarchy. It does not have an /// enumerator in SILNodeKind and is never the most-derived type of a /// node. ID is the name of the class. /// /// PARENT is the name of its abstract superclass in the node /// hierarchy, which will be either a subject of an ABSTRACT_NODE /// entry or SILNode. SingleValueInstruction considers its superclass /// to be SILInstruction for the purposes of the node hierarchy. #ifndef ABSTRACT_NODE #define ABSTRACT_NODE(ID, PARENT) #endif // Handle SingleValueInstruction. #ifdef ABSTRACT_VALUE #define ABSTRACT_VALUE_AND_INST(ID, VALUE_PARENT, INST_PARENT) \ ABSTRACT_VALUE(ID, VALUE_PARENT) #else #define ABSTRACT_VALUE_AND_INST(ID, VALUE_PARENT, INST_PARENT) \ ABSTRACT_INST(ID, INST_PARENT) #endif /// ABSTRACT_SINGLE_VALUE_INST(ID, PARENT) /// /// An abstract subclass of SingleValueInstruction, which is therefore /// in both the ValueBase and SILInstruction hierarchies. #ifndef ABSTRACT_SINGLE_VALUE_INST #ifdef ABSTRACT_VALUE #define ABSTRACT_SINGLE_VALUE_INST(ID, PARENT) ABSTRACT_VALUE(ID, PARENT) #else #define ABSTRACT_SINGLE_VALUE_INST(ID, PARENT) ABSTRACT_INST(ID, PARENT) #endif #endif /// ABSTRACT_VALUE(ID, PARENT) /// /// An abstract class in the ValueBase hierarchy. It does not have an /// enumerator in ValueKind and is never the most-derived type of a /// node. ID is the name of the class. /// /// PARENT is the name of its abstract superclass in the ValueBase /// hierarchy, which be either a subject of an ABSTRACT_VALUE /// entry or ValueBase. #ifndef ABSTRACT_VALUE #define ABSTRACT_VALUE(ID, PARENT) ABSTRACT_NODE(ID, PARENT) #endif /// ABSTRACT_INST(ID, PARENT) /// /// An abstract class in the SILInstruction hierarchy. It does not /// enumerator in SILInstructionKind and is never the most-derived type /// of a node. ID is the name of the class. /// /// PARENT is the name of its abstract superclass in the SILInstruction /// hierarchy, which be either a subject of an ABSTRACT_INST /// entry or SILInstruction. #ifndef ABSTRACT_INST #define ABSTRACT_INST(ID, PARENT) ABSTRACT_NODE(ID, PARENT) #endif /// NODE_RANGE(ID, PARENT) /// /// The enumerator range of an abstract class in the SILNode hierarchy. /// This will always appear right after the last member of the class. #ifndef NODE_RANGE #define NODE_RANGE(ID, FIRST, LAST) #endif #ifndef SINGLE_VALUE_INST_RANGE #ifdef VALUE_RANGE #define SINGLE_VALUE_INST_RANGE(ID, FIRST, LAST) VALUE_RANGE(ID, FIRST, LAST) #else #define SINGLE_VALUE_INST_RANGE(ID, FIRST, LAST) INST_RANGE(ID, FIRST, LAST) #endif #endif /// VALUE_RANGE(ID, PARENT) /// /// The enumerator range of an abstract class in the ValueBase hierarchy. #ifndef VALUE_RANGE #define VALUE_RANGE(ID, FIRST, LAST) NODE_RANGE(ID, FIRST, LAST) #endif /// ARGUMENT_RANGE(ID, FIRST, LAST) /// /// The enumerator range of an abstract class in the SILArgument /// hierarchy. #ifndef ARGUMENT_RANGE #define ARGUMENT_RANGE(ID, FIRST, LAST) VALUE_RANGE(ID, FIRST, LAST) #endif /// INST_RANGE(ID, PARENT) /// /// The enumerator range of an abstract class in the SILInstruction /// hierarchy. #ifndef INST_RANGE #define INST_RANGE(ID, FIRST, LAST) NODE_RANGE(ID, FIRST, LAST) #endif ABSTRACT_NODE(ValueBase, SILNode) ABSTRACT_VALUE(SILArgument, ValueBase) ARGUMENT(SILPhiArgument, SILArgument) ARGUMENT(SILFunctionArgument, SILArgument) ARGUMENT_RANGE(SILArgument, SILPhiArgument, SILFunctionArgument) VALUE(MultipleValueInstructionResult, ValueBase) VALUE(SILUndef, ValueBase) /// Used internally in e.g. the SIL parser and deserializer. /// A PlaceholderValue must not appear in valid SIL. VALUE(PlaceholderValue, ValueBase) ABSTRACT_NODE(SILInstruction, SILNode) ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction) // Allocation instructions. ABSTRACT_SINGLE_VALUE_INST(AllocationInst, SingleValueInstruction) SINGLE_VALUE_INST(AllocStackInst, alloc_stack, AllocationInst, None, DoesNotRelease) SINGLE_VALUE_INST(AllocPackInst, alloc_pack, AllocationInst, None, DoesNotRelease) SINGLE_VALUE_INST(AllocPackMetadataInst, alloc_pack_metadata, AllocationInst, None, DoesNotRelease) SINGLE_VALUE_INST(AllocRefInst, alloc_ref, AllocationInst, None, DoesNotRelease) SINGLE_VALUE_INST(AllocRefDynamicInst, alloc_ref_dynamic, AllocationInst, None, DoesNotRelease) SINGLE_VALUE_INST(AllocBoxInst, alloc_box, AllocationInst, None, DoesNotRelease) SINGLE_VALUE_INST(AllocExistentialBoxInst, alloc_existential_box, AllocationInst, MayWrite, DoesNotRelease) SINGLE_VALUE_INST_RANGE(AllocationInst, AllocStackInst, AllocExistentialBoxInst) ABSTRACT_SINGLE_VALUE_INST(IndexingInst, SingleValueInstruction) SINGLE_VALUE_INST(IndexAddrInst, index_addr, IndexingInst, None, DoesNotRelease) SINGLE_VALUE_INST(TailAddrInst, tail_addr, IndexingInst, None, DoesNotRelease) SINGLE_VALUE_INST(IndexRawPointerInst, index_raw_pointer, IndexingInst, None, DoesNotRelease) SINGLE_VALUE_INST_RANGE(IndexingInst, IndexAddrInst, IndexRawPointerInst) // Literals ABSTRACT_SINGLE_VALUE_INST(LiteralInst, SingleValueInstruction) SINGLE_VALUE_INST(FunctionRefInst, function_ref, LiteralInst, None, DoesNotRelease) SINGLE_VALUE_INST(DynamicFunctionRefInst, dynamic_function_ref, LiteralInst, None, DoesNotRelease) SINGLE_VALUE_INST(PreviousDynamicFunctionRefInst, prev_dynamic_function_ref, LiteralInst, None, DoesNotRelease) SINGLE_VALUE_INST(GlobalAddrInst, global_addr, LiteralInst, None, DoesNotRelease) SINGLE_VALUE_INST(BaseAddrForOffsetInst, base_addr_for_offset, LiteralInst, None, DoesNotRelease) SINGLE_VALUE_INST(GlobalValueInst, global_value, LiteralInst, None, DoesNotRelease) SINGLE_VALUE_INST(IntegerLiteralInst, integer_literal, LiteralInst, None, DoesNotRelease) SINGLE_VALUE_INST(FloatLiteralInst, float_literal, LiteralInst, None, DoesNotRelease) SINGLE_VALUE_INST(StringLiteralInst, string_literal, LiteralInst, None, DoesNotRelease) SINGLE_VALUE_INST(HasSymbolInst, has_symbol, LiteralInst, MayRead, DoesNotRelease) SINGLE_VALUE_INST_RANGE(LiteralInst, FunctionRefInst, HasSymbolInst) // Dynamic Dispatch ABSTRACT_SINGLE_VALUE_INST(MethodInst, SingleValueInstruction) SINGLE_VALUE_INST(ClassMethodInst, class_method, MethodInst, None, DoesNotRelease) SINGLE_VALUE_INST(SuperMethodInst, super_method, MethodInst, None, DoesNotRelease) SINGLE_VALUE_INST(ObjCMethodInst, objc_method, MethodInst, None, DoesNotRelease) SINGLE_VALUE_INST(ObjCSuperMethodInst, objc_super_method, MethodInst, None, DoesNotRelease) SINGLE_VALUE_INST(WitnessMethodInst, witness_method, MethodInst, None, DoesNotRelease) SINGLE_VALUE_INST_RANGE(MethodInst, ClassMethodInst, WitnessMethodInst) // Conversions SINGLE_VALUE_INST(UpcastInst, upcast, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(AddressToPointerInst, address_to_pointer, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(PointerToAddressInst, pointer_to_address, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(UncheckedRefCastInst, unchecked_ref_cast, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(UncheckedAddrCastInst, unchecked_addr_cast, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(UncheckedTrivialBitCastInst, unchecked_trivial_bit_cast, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(UncheckedBitwiseCastInst, unchecked_bitwise_cast, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(UncheckedValueCastInst, unchecked_value_cast, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(RefToRawPointerInst, ref_to_raw_pointer, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(RawPointerToRefInst, raw_pointer_to_ref, SingleValueInstruction, None, DoesNotRelease) #define LOADABLE_REF_STORAGE(Name, name, ...) \ SINGLE_VALUE_INST(RefTo##Name##Inst, ref_to_##name, \ SingleValueInstruction, None, DoesNotRelease) \ SINGLE_VALUE_INST(Name##ToRefInst, name##_to_ref, \ SingleValueInstruction, None, DoesNotRelease) #include "swift/AST/ReferenceStorage.def" SINGLE_VALUE_INST(ConvertFunctionInst, convert_function, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(ThunkInst, thunk, SingleValueInstruction, MayHaveSideEffects, MayRelease) SINGLE_VALUE_INST(ConvertEscapeToNoEscapeInst, convert_escape_to_noescape, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(RefToBridgeObjectInst, ref_to_bridge_object, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(BridgeObjectToRefInst, bridge_object_to_ref, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(BridgeObjectToWordInst, bridge_object_to_word, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(ThinToThickFunctionInst, thin_to_thick_function, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(ThickToObjCMetatypeInst, thick_to_objc_metatype, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(ObjCToThickMetatypeInst, objc_to_thick_metatype, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(ObjCMetatypeToObjectInst, objc_metatype_to_object, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(ObjCExistentialMetatypeToObjectInst, objc_existential_metatype_to_object, SingleValueInstruction, None, DoesNotRelease) // unconditional_checked_cast_inst is only MayRead to prevent a subsequent // release of the cast's source from being hoisted above the cast: // retain X // Y = unconditional_checked_cast_inst X // _ = Y // release X // This release cannot be reordered with the cast. // // With Semantic SIL, this pattern of unbalanced retain/release // should never happen. Since unconditional_checked_cast is a // scalar cast that doesn't affect the value's representation, its // side effect can then be modeled as None. DYNAMICCAST_SINGLE_VALUE_INST(UnconditionalCheckedCastInst, unconditional_checked_cast, SingleValueInstruction, MayRead, DoesNotRelease) SINGLE_VALUE_INST(ClassifyBridgeObjectInst, classify_bridge_object, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(ValueToBridgeObjectInst, value_to_bridge_object, SingleValueInstruction, None, DoesNotRelease) // MarkDependenceAddrInst has read effects for the base operand. See // getMemoryBehavior() SINGLE_VALUE_INST(MarkDependenceInst, mark_dependence, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(CopyBlockInst, copy_block, SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) SINGLE_VALUE_INST(CopyBlockWithoutEscapingInst, copy_block_without_escaping, SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) // A copy_value's retain semantics are fully encapsulated in OSSA // invariants. It has no side effects relative to other OSSA values. SINGLE_VALUE_INST(CopyValueInst, copy_value, SingleValueInstruction, None, DoesNotRelease) // A copy_value instruction that was explicitly asked for by the user. Left // alone by OSSA optimizations. SINGLE_VALUE_INST(ExplicitCopyValueInst, explicit_copy_value, SingleValueInstruction, None, DoesNotRelease) // Produce a @sil_unowned value from the specified value of reference type. SINGLE_VALUE_INST(UnownedCopyValueInst, unowned_copy_value, SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) SINGLE_VALUE_INST(WeakCopyValueInst, weak_copy_value, SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) #define REF_STORAGE(Name, name, ...) \ SINGLE_VALUE_INST(StrongCopy##Name##ValueInst, strong_copy_##name##_value, \ SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) #include "swift/AST/ReferenceStorage.def" SINGLE_VALUE_INST(UncheckedOwnershipConversionInst, unchecked_ownership_conversion, SingleValueInstruction, None, MayRelease) // A move_value is an OSSA only instruction. Its result does not have any side // effects relative to other OSSA values like copy_value. SINGLE_VALUE_INST(MoveValueInst, move_value, SingleValueInstruction, None, DoesNotRelease) // A drop_deinit has no user-level side effects. It does, however, change the // information about the owenership of its operand, and therefore cannot be // arbitrarily deleted. It effectively wraps the type of the operand so that // the resulting value is an equivalent type without a user-defined deinit. // // TODO: Add an OwnershipEffect type of side effect for instructions like // drop_deinit to indicate their ownership effects. SINGLE_VALUE_INST(DropDeinitInst, drop_deinit, SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) // A canary value inserted by a SIL generating frontend to signal to the move // checker to check a specific value. Valid only in Raw SIL. The relevant // checkers should remove the mark_unresolved_non_copyable_value instruction after successfully // running the relevant diagnostic. SINGLE_VALUE_INST(MarkUnresolvedNonCopyableValueInst, mark_unresolved_non_copyable_value, SingleValueInstruction, None, DoesNotRelease) // A canary value inserted by a SIL generating frontend to signal to the // reference binding transform to check/transform a specific value. Valid // only in Raw SIL. The relevant checkers should remove the instruction after // successfully running the relevant diagnostic. SINGLE_VALUE_INST(MarkUnresolvedReferenceBindingInst, mark_unresolved_reference_binding, SingleValueInstruction, None, DoesNotRelease) // Convert a $T to $@moveOnly T. This is the method that one uses to convert a // trivial value to a non-trivial move only value. Ownership is fixed at construction by // frontend to express specific semantics: guaranteed for guaranteed function arguments // and owned for assignment/owned function arguments. SINGLE_VALUE_INST(CopyableToMoveOnlyWrapperValueInst, copyable_to_moveonlywrapper, SingleValueInstruction, None, DoesNotRelease) // Convert a $@moveOnly T object to $T. Ownership is fixed at construction by // frontend to express specific semantics: guaranteed for function arguments // and owned for assignment/return values. SINGLE_VALUE_INST(MoveOnlyWrapperToCopyableValueInst, moveonlywrapper_to_copyable, SingleValueInstruction, None, DoesNotRelease) // Convert a ${ @moveOnly T } to $T. This is a forwarding instruction that // acts similarly to an object cast, unlike MoveOnlyWrapperToCopyableValue. SINGLE_VALUE_INST(MoveOnlyWrapperToCopyableBoxInst, moveonlywrapper_to_copyable_box, SingleValueInstruction, None, DoesNotRelease) // Convert a $*@moveOnly T to $*T. Acts just as a cast. SINGLE_VALUE_INST(MoveOnlyWrapperToCopyableAddrInst, moveonlywrapper_to_copyable_addr, SingleValueInstruction, None, DoesNotRelease) // Convert a $*T to $*@moveOnly T. Acts just as a cast. SINGLE_VALUE_INST(CopyableToMoveOnlyWrapperAddrInst, copyable_to_moveonlywrapper_addr, SingleValueInstruction, None, DoesNotRelease) // IsUnique does not actually write to memory but should be modeled // as such. Its operand is a pointer to an object reference. The // optimizer should not assume that the same object is pointed to after // the isUnique instruction. It appears to write a new object reference. SINGLE_VALUE_INST(IsUniqueInst, is_unique, SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) SINGLE_VALUE_INST(EndCOWMutationInst, end_cow_mutation, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(DestroyNotEscapedClosureInst, destroy_not_escaped_closure, SingleValueInstruction, MayHaveSideEffects, MayRelease) // Accessing memory SINGLE_VALUE_INST(LoadInst, load, SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) SINGLE_VALUE_INST(LoadBorrowInst, load_borrow, SingleValueInstruction, MayRead, DoesNotRelease) SINGLE_VALUE_INST(BeginBorrowInst, begin_borrow, SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) SINGLE_VALUE_INST(BorrowedFromInst, borrowed, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(StoreBorrowInst, store_borrow, SILInstruction, MayWrite, DoesNotRelease) // begin_access may trap. Trapping is unordered with respect to memory access, // and with respect to other traps, but it is still conservatively considered // a side effect. SINGLE_VALUE_INST(BeginAccessInst, begin_access, SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) #define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \ SINGLE_VALUE_INST(Load##Name##Inst, load_##name, \ SingleValueInstruction, MayRead, DoesNotRelease) #include "swift/AST/ReferenceStorage.def" SINGLE_VALUE_INST(MarkUninitializedInst, mark_uninitialized, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(ProjectBoxInst, project_box, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(ProjectExistentialBoxInst, project_existential_box, SingleValueInstruction, None, DoesNotRelease) // Functions SINGLE_VALUE_INST(ApplyInst, apply, SingleValueInstruction, MayHaveSideEffects, MayRelease) SINGLE_VALUE_INST(BuiltinInst, builtin, SingleValueInstruction, MayHaveSideEffects, MayRelease) SINGLE_VALUE_INST(PartialApplyInst, partial_apply, SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) SINGLE_VALUE_INST(EndApplyInst, end_apply, SILInstruction, MayHaveSideEffects, MayRelease) SINGLE_VALUE_INST(FunctionExtractIsolationInst, function_extract_isolation, SingleValueInstruction, None, DoesNotRelease) // Metatypes SINGLE_VALUE_INST(MetatypeInst, metatype, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(ValueMetatypeInst, value_metatype, SingleValueInstruction, MayRead, DoesNotRelease) SINGLE_VALUE_INST(ExistentialMetatypeInst, existential_metatype, SingleValueInstruction, MayRead, DoesNotRelease) SINGLE_VALUE_INST(ObjCProtocolInst, objc_protocol, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(TypeValueInst, type_value, SingleValueInstruction, None, DoesNotRelease) // Aggregate Types SINGLE_VALUE_INST(ObjectInst, object, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(VectorInst, vector, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(TupleInst, tuple, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(TupleExtractInst, tuple_extract, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(TupleElementAddrInst, tuple_element_addr, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(TuplePackElementAddrInst, tuple_pack_element_addr, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(TuplePackExtractInst, tuple_pack_extract, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(PackElementGetInst, pack_element_get, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(StructInst, struct, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(StructExtractInst, struct_extract, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(StructElementAddrInst, struct_element_addr, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(RefElementAddrInst, ref_element_addr, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(RefTailAddrInst, ref_tail_addr, SingleValueInstruction, None, DoesNotRelease) // Enums SINGLE_VALUE_INST(EnumInst, enum, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(UncheckedEnumDataInst, unchecked_enum_data, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(InitEnumDataAddrInst, init_enum_data_addr, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(UncheckedTakeEnumDataAddrInst, unchecked_take_enum_data_addr, SingleValueInstruction, MayWrite, DoesNotRelease) SINGLE_VALUE_INST(SelectEnumInst, select_enum, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(SelectEnumAddrInst, select_enum_addr, SingleValueInstruction, MayRead, DoesNotRelease) // Protocol and Protocol Composition Types SINGLE_VALUE_INST(InitExistentialAddrInst, init_existential_addr, SingleValueInstruction, MayWrite, DoesNotRelease) SINGLE_VALUE_INST(InitExistentialValueInst, init_existential_value, SingleValueInstruction, MayWrite, DoesNotRelease) SINGLE_VALUE_INST(OpenExistentialAddrInst, open_existential_addr, SingleValueInstruction, MayRead, DoesNotRelease) SINGLE_VALUE_INST(InitExistentialRefInst, init_existential_ref, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(OpenExistentialRefInst, open_existential_ref, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(InitExistentialMetatypeInst, init_existential_metatype, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(OpenExistentialMetatypeInst, open_existential_metatype, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(OpenExistentialBoxInst, open_existential_box, SingleValueInstruction, MayRead, DoesNotRelease) SINGLE_VALUE_INST(OpenExistentialValueInst, open_existential_value, SingleValueInstruction, MayRead, DoesNotRelease) SINGLE_VALUE_INST(OpenExistentialBoxValueInst, open_existential_box_value, SingleValueInstruction, MayRead, DoesNotRelease) // Variadic generics SINGLE_VALUE_INST(OpenPackElementInst, open_pack_element, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(PackLengthInst, pack_length, SingleValueInstruction, None, DoesNotRelease) // Variadic pack indexing ABSTRACT_SINGLE_VALUE_INST(AnyPackIndexInst, SingleValueInstruction) SINGLE_VALUE_INST(DynamicPackIndexInst, dynamic_pack_index, AnyPackIndexInst, None, DoesNotRelease) SINGLE_VALUE_INST(PackPackIndexInst, pack_pack_index, AnyPackIndexInst, None, DoesNotRelease) SINGLE_VALUE_INST(ScalarPackIndexInst, scalar_pack_index, AnyPackIndexInst, None, DoesNotRelease) SINGLE_VALUE_INST_RANGE(AnyPackIndexInst, DynamicPackIndexInst, ScalarPackIndexInst) // Blocks SINGLE_VALUE_INST(ProjectBlockStorageInst, project_block_storage, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(InitBlockStorageHeaderInst, init_block_storage_header, SingleValueInstruction, None, DoesNotRelease) // Differentiable programming SINGLE_VALUE_INST(DifferentiableFunctionInst, differentiable_function, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(LinearFunctionInst, linear_function, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(DifferentiableFunctionExtractInst, differentiable_function_extract, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(LinearFunctionExtractInst, linear_function_extract, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(DifferentiabilityWitnessFunctionInst, differentiability_witness_function, SingleValueInstruction, None, DoesNotRelease) // Async // TODO: The side effects declarations on this instruction could likely // be tightened, though we want to be careful that passes that try to do // code motion or eliminate this instruction don't do so without awareness of // its structural requirements. ABSTRACT_SINGLE_VALUE_INST(GetAsyncContinuationInstBase, SingleValueInstruction) SINGLE_VALUE_INST(GetAsyncContinuationInst, get_async_continuation, GetAsyncContinuationInstBase, MayHaveSideEffects, MayRelease) SINGLE_VALUE_INST(GetAsyncContinuationAddrInst, get_async_continuation_addr, GetAsyncContinuationInstBase, MayHaveSideEffects, MayRelease) SINGLE_VALUE_INST_RANGE(GetAsyncContinuationInstBase, GetAsyncContinuationInst, GetAsyncContinuationAddrInst) SINGLE_VALUE_INST(ExtractExecutorInst, extract_executor, SingleValueInstruction, MayRead, DoesNotRelease) // Key paths // TODO: The only "side effect" is potentially retaining the returned key path // object; is there a more specific effect? SINGLE_VALUE_INST(KeyPathInst, keypath, SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) SINGLE_VALUE_INST(BeginDeallocRefInst, begin_dealloc_ref, SingleValueInstruction, None, DoesNotRelease) SINGLE_VALUE_INST(EndInitLetRefInst, end_init_let_ref, SingleValueInstruction, None, DoesNotRelease) // BindMemory and RebindMemory have no physical side effect. Semantically they // access their affected memory region because any reads or writes accessing // that memory must be dependent on the bind operation. SINGLE_VALUE_INST(BindMemoryInst, bind_memory, SILInstruction, MayReadWrite, DoesNotRelease) SINGLE_VALUE_INST(RebindMemoryInst, rebind_memory, SILInstruction, MayReadWrite, DoesNotRelease) SINGLE_VALUE_INST_RANGE(SingleValueInstruction, AllocStackInst, RebindMemoryInst) NODE_RANGE(ValueBase, SILPhiArgument, RebindMemoryInst) // Terminators ABSTRACT_INST(TermInst, SILInstruction) TERMINATOR(UnreachableInst, unreachable, TermInst, None, DoesNotRelease) TERMINATOR(ReturnInst, return, TermInst, None, DoesNotRelease) TERMINATOR(ThrowInst, throw, TermInst, None, DoesNotRelease) TERMINATOR(ThrowAddrInst, throw_addr, TermInst, None, DoesNotRelease) TERMINATOR(YieldInst, yield, TermInst, MayHaveSideEffects, MayRelease) TERMINATOR(UnwindInst, unwind, TermInst, None, DoesNotRelease) TERMINATOR(TryApplyInst, try_apply, TermInst, MayHaveSideEffects, MayRelease) TERMINATOR(BranchInst, br, TermInst, None, DoesNotRelease) TERMINATOR(CondBranchInst, cond_br, TermInst, None, DoesNotRelease) TERMINATOR(SwitchValueInst, switch_value, TermInst, None, DoesNotRelease) TERMINATOR(SwitchEnumInst, switch_enum, TermInst, None, DoesNotRelease) TERMINATOR(SwitchEnumAddrInst, switch_enum_addr, TermInst, MayRead, DoesNotRelease) TERMINATOR(DynamicMethodBranchInst, dynamic_method_br, TermInst, None, DoesNotRelease) TERMINATOR(AwaitAsyncContinuationInst, await_async_continuation, TermInst, MayHaveSideEffects, MayRelease) DYNAMICCAST_TERMINATOR(CheckedCastBranchInst, checked_cast_br, TermInst, None, DoesNotRelease) DYNAMICCAST_TERMINATOR(CheckedCastAddrBranchInst, checked_cast_addr_br, TermInst, MayHaveSideEffects, MayRelease) INST_RANGE(TermInst, UnreachableInst, CheckedCastAddrBranchInst) // Deallocation instructions. ABSTRACT_INST(DeallocationInst, SILInstruction) NON_VALUE_INST(DeallocStackInst, dealloc_stack, DeallocationInst, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(DeallocPackInst, dealloc_pack, DeallocationInst, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(DeallocPackMetadataInst, dealloc_pack_metadata, DeallocationInst, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(DeallocStackRefInst, dealloc_stack_ref, DeallocationInst, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(DeallocRefInst, dealloc_ref, DeallocationInst, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(DeallocPartialRefInst, dealloc_partial_ref, DeallocationInst, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(DeallocBoxInst, dealloc_box, DeallocationInst, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(DeallocExistentialBoxInst, dealloc_existential_box, DeallocationInst, MayHaveSideEffects, DoesNotRelease) INST_RANGE(DeallocationInst, DeallocStackInst, DeallocExistentialBoxInst) // Reference Counting ABSTRACT_INST(RefCountingInst, SILInstruction) NON_VALUE_INST(StrongRetainInst, strong_retain, RefCountingInst, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(StrongReleaseInst, strong_release, RefCountingInst, MayHaveSideEffects, MayRelease) NON_VALUE_INST(UnmanagedRetainValueInst, unmanaged_retain_value, RefCountingInst, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(UnmanagedReleaseValueInst, unmanaged_release_value, RefCountingInst, MayHaveSideEffects, MayRelease) NON_VALUE_INST(UnmanagedAutoreleaseValueInst, unmanaged_autorelease_value, RefCountingInst, MayHaveSideEffects, DoesNotRelease) #define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \ NON_VALUE_INST(StrongRetain##Name##Inst, strong_retain_##name, \ RefCountingInst, MayHaveSideEffects, DoesNotRelease) \ NON_VALUE_INST(Name##RetainInst, name##_retain, \ RefCountingInst, MayHaveSideEffects, DoesNotRelease) \ NON_VALUE_INST(Name##ReleaseInst, name##_release, \ RefCountingInst, MayHaveSideEffects, MayRelease) #include "swift/AST/ReferenceStorage.def" NON_VALUE_INST(RetainValueInst, retain_value, RefCountingInst, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(RetainValueAddrInst, retain_value_addr, RefCountingInst, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(ReleaseValueInst, release_value, RefCountingInst, MayHaveSideEffects, MayRelease) NON_VALUE_INST(ReleaseValueAddrInst, release_value_addr, RefCountingInst, MayHaveSideEffects, MayRelease) NON_VALUE_INST(AutoreleaseValueInst, autorelease_value, RefCountingInst, MayHaveSideEffects, DoesNotRelease) INST_RANGE(RefCountingInst, StrongRetainInst, AutoreleaseValueInst) // FIXME: Is MayHaveSideEffects appropriate? NON_VALUE_INST(FixLifetimeInst, fix_lifetime, SILInstruction, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(HopToExecutorInst, hop_to_executor, SILInstruction, MayHaveSideEffects, MayRelease) NON_VALUE_INST(DestroyValueInst, destroy_value, SILInstruction, MayHaveSideEffects, MayRelease) NON_VALUE_INST(EndBorrowInst, end_borrow, SILInstruction, MayHaveSideEffects, DoesNotRelease) // end_access is considered to have side effects because it modifies runtime // state outside of the memory modified by the access that is visible to // Swift. This "side effect" only needs to creates a dependency on begin_access // instructions. NON_VALUE_INST(EndAccessInst, end_access, SILInstruction, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(BeginUnpairedAccessInst, begin_unpaired_access, SILInstruction, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(EndUnpairedAccessInst, end_unpaired_access, SILInstruction, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(StoreInst, store, SILInstruction, MayHaveSideEffects, MayRelease) NON_VALUE_INST(AssignInst, assign, SILInstruction, MayWrite, DoesNotRelease) NON_VALUE_INST(AssignByWrapperInst, assign_by_wrapper, SILInstruction, MayWrite, DoesNotRelease) NON_VALUE_INST(AssignOrInitInst, assign_or_init, SILInstruction, MayWrite, DoesNotRelease) NON_VALUE_INST(MarkFunctionEscapeInst, mark_function_escape, SILInstruction, None, DoesNotRelease) NON_VALUE_INST(DebugValueInst, debug_value, SILInstruction, None, DoesNotRelease) NON_VALUE_INST(DebugStepInst, debug_step, SILInstruction, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(SpecifyTestInst, specify_test, SILInstruction, None, DoesNotRelease) #define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \ NON_VALUE_INST(Store##Name##Inst, store_##name, \ SILInstruction, MayWrite, DoesNotRelease) #include "swift/AST/ReferenceStorage.def" NON_VALUE_INST(CopyAddrInst, copy_addr, SILInstruction, MayHaveSideEffects, MayRelease) NON_VALUE_INST(ExplicitCopyAddrInst, explicit_copy_addr, SILInstruction, MayHaveSideEffects, MayRelease) NON_VALUE_INST(TupleAddrConstructorInst, tuple_addr_constructor, SILInstruction, MayHaveSideEffects, MayRelease) NON_VALUE_INST(DestroyAddrInst, destroy_addr, SILInstruction, MayHaveSideEffects, MayRelease) NON_VALUE_INST(EndLifetimeInst, end_lifetime, SILInstruction, MayHaveSideEffects, MayRelease) NON_VALUE_INST(ExtendLifetimeInst, extend_lifetime, SILInstruction, None, DoesNotRelease) NON_VALUE_INST(InjectEnumAddrInst, inject_enum_addr, SILInstruction, MayWrite, DoesNotRelease) NON_VALUE_INST(DeinitExistentialAddrInst, deinit_existential_addr, SILInstruction, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(DeinitExistentialValueInst, deinit_existential_value, SILInstruction, MayHaveSideEffects, DoesNotRelease) DYNAMICCAST_NON_VALUE_INST( UnconditionalCheckedCastAddrInst, unconditional_checked_cast_addr, SILInstruction, MayHaveSideEffects, MayRelease) NON_VALUE_INST(UncheckedRefCastAddrInst, unchecked_ref_cast_addr, SILInstruction, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(AllocGlobalInst, alloc_global, SILInstruction, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(AbortApplyInst, abort_apply, SILInstruction, MayHaveSideEffects, MayRelease) NON_VALUE_INST(PackElementSetInst, pack_element_set, SILInstruction, MayHaveSideEffects, DoesNotRelease) // Runtime failure // FIXME: Special MemBehavior for runtime failure? NON_VALUE_INST(CondFailInst, cond_fail, SILInstruction, MayHaveSideEffects, DoesNotRelease) // A move_addr is a Raw SIL only instruction that is equivalent to a copy_addr // [init]. It is lowered during the diagnostic passes to a copy_addr [init] if // the move checker found uses that prevented us from converting this to a // move or if we do not find such uses, a copy_addr [init] [take]. NON_VALUE_INST(MarkUnresolvedMoveAddrInst, mark_unresolved_move_addr, SILInstruction, None, DoesNotRelease) NON_VALUE_INST(MergeIsolationRegionInst, merge_isolation_region, SILInstruction, None, DoesNotRelease) NON_VALUE_INST(IgnoredUseInst, ignored_use, SILInstruction, None, DoesNotRelease) NON_VALUE_INST(IncrementProfilerCounterInst, increment_profiler_counter, SILInstruction, MayReadWrite, DoesNotRelease) // MarkDependenceAddrInst has read effects for the base operand. See // getMemoryBehavior(). NON_VALUE_INST(MarkDependenceAddrInst, mark_dependence_addr, SILInstruction, MayReadWrite, DoesNotRelease) NON_VALUE_INST(EndCOWMutationAddrInst, end_cow_mutation_addr, SILInstruction, MayHaveSideEffects, DoesNotRelease) NODE_RANGE(NonValueInstruction, UnreachableInst, EndCOWMutationAddrInst) ABSTRACT_INST(MultipleValueInstruction, SILInstruction) MULTIPLE_VALUE_INST(BeginApplyInst, begin_apply, MultipleValueInstruction, MayHaveSideEffects, MayRelease) // begin_cow_mutation is defined to have side effects, because it has // dependencies with instructions which retain the buffer operand. This prevents // optimizations from moving begin_cow_mutation instructions across such retain // instructions. MULTIPLE_VALUE_INST(BeginCOWMutationInst, begin_cow_mutation, MultipleValueInstruction, MayHaveSideEffects, DoesNotRelease) MULTIPLE_VALUE_INST(DestructureStructInst, destructure_struct, MultipleValueInstruction, None, DoesNotRelease) MULTIPLE_VALUE_INST(DestructureTupleInst, destructure_tuple, MultipleValueInstruction, None, DoesNotRelease) INST_RANGE(MultipleValueInstruction, BeginApplyInst, DestructureTupleInst) NODE_RANGE(NonSingleValueInstruction, UnreachableInst, DestructureTupleInst) NODE_RANGE(SILInstruction, AllocStackInst, DestructureTupleInst) NODE_RANGE(SILNode, SILPhiArgument, DestructureTupleInst) #undef SINGLE_VALUE_INST_RANGE #undef INST_RANGE #undef ARGUMENT_RANGE #undef VALUE_RANGE #undef NODE_RANGE #undef ABSTRACT_SINGLE_VALUE_INST #undef ABSTRACT_INST #undef ABSTRACT_VALUE #undef ABSTRACT_NODE #undef ABSTRACT_VALUE_AND_INST #undef DYNAMICCAST_TERMINATOR #undef TERMINATOR #undef NON_VALUE_INST #undef DYNAMICCAST_NON_VALUE_INST #undef MULTIPLE_VALUE_INST_RESULT #undef MULTIPLE_VALUE_INST #undef DYNAMICCAST_SINGLE_VALUE_INST #undef DYNAMICCAST_INST #undef SINGLE_VALUE_INST #undef FULL_INST #undef INST #undef ARGUMENT #undef VALUE #undef NODE