Files
swift-mirror/include/swift/SIL/SILNodes.def
Michael Gottesman e1006c62f9 [move-only] Add copyable_to_moveonlywrapper and moveonlywrapper_to_copyable instructions.
These instructions have the following attributes:

1. copyably_to_moveonlywrapper takes in a 'T' and maps it to a '@moveOnly
T'. This is semantically used when initializing a new moveOnly binding from a
copyable value. It semantically destroys its input @owned value and returns a
brand new independent @owned @moveOnly value. It also is used to convert a
trivial copyable value with type 'Trivial' into an owned non-trivial value of
type '@moveOnly Trivial'. If one thinks of '@moveOnly' as a monad, this is how
one injects a copyable value into the move only space.

2. moveonlywrapper_to_copyable takes in a '@moveOnly T' and produces a new 'T'
value. This is a 'forwarding' instruction where at parse time, we only allow for
one to choose it to be [owned] or [guaranteed].

* moveonlywrapper_to_copyable [owned] is used to signal the end of lifetime of
the '@moveOnly' wrapper. SILGen inserts these when ever a move only value has
its ownership passed to a situation where a copyable value is needed. Since it
is consuming, we know that the no implicit copy checker will ensure that if we
need a copy for it, the program will emit a diagnostic.

* moveonlywrapper_to_copyable [guaranteed] is used to pass a @moveOnly T value
as a copyable guaranteed parameter with type 'T' to a function. In the case of
using no-implicit-copy checking this is always fine since no-implicit-copy is a
local pattern. This would be an error when performing no escape
checking. Importantly, this instruction also is where in the case of an
@moveOnly trivial type, we convert from the non-trivial representation to the
trivial representation.

Some important notes:

1. In a forthcoming commit, I am going to rebase the no implicit copy checker on
top of these instructions. By using '@moveOnly' in the type system, we can
ensure that later in the SIL pipeline, we can have optimizations easily ignore
the code.

2. Be aware of is that due to SILGen only emitting '@moveOnly T' along immediate
accesses to the variable and always converts to a copyable representation when
calling other code, we can simply eliminate from the IR all moveonly-ness from
the IR using a lowering pass (that I am going to upstream). In the evil scheme
we are accomplishing here, we perform lowering of trivial values right after
ownership lowering and before diagnostics to simplify the pipeline.

On another note, I also fixed a few things in SILParsing around getASTType() vs
getRawASTType().
2022-06-09 19:47:31 -07:00

857 lines
40 KiB
C++

//===--- 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
#ifndef BRIDGED_SINGLE_VALUE_INST
#define BRIDGED_SINGLE_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \
SINGLE_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE)
#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) \
BRIDGED_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.
///
/// 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 BRIDGED_NON_VALUE_INST
#define BRIDGED_NON_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \
NON_VALUE_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) \
BRIDGED_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) \
BRIDGED_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)
BRIDGED_SINGLE_VALUE_INST(AllocStackInst, alloc_stack,
AllocationInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(AllocRefInst, alloc_ref,
AllocationInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(AllocRefDynamicInst, alloc_ref_dynamic,
AllocationInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(AllocBoxInst, alloc_box,
AllocationInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(AllocExistentialBoxInst, alloc_existential_box,
AllocationInst, MayWrite, DoesNotRelease)
SINGLE_VALUE_INST_RANGE(AllocationInst, AllocStackInst, AllocExistentialBoxInst)
ABSTRACT_SINGLE_VALUE_INST(IndexingInst, SingleValueInstruction)
BRIDGED_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)
BRIDGED_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)
BRIDGED_SINGLE_VALUE_INST(GlobalAddrInst, global_addr,
LiteralInst, None, DoesNotRelease)
SINGLE_VALUE_INST(BaseAddrForOffsetInst, base_addr_for_offset,
LiteralInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(GlobalValueInst, global_value,
LiteralInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(IntegerLiteralInst, integer_literal,
LiteralInst, None, DoesNotRelease)
SINGLE_VALUE_INST(FloatLiteralInst, float_literal,
LiteralInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(StringLiteralInst, string_literal,
LiteralInst, None, DoesNotRelease)
SINGLE_VALUE_INST_RANGE(LiteralInst, FunctionRefInst, StringLiteralInst)
// Dynamic Dispatch
ABSTRACT_SINGLE_VALUE_INST(MethodInst, SingleValueInstruction)
BRIDGED_SINGLE_VALUE_INST(ClassMethodInst, class_method,
MethodInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(SuperMethodInst, super_method,
MethodInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(ObjCMethodInst, objc_method,
MethodInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(ObjCSuperMethodInst, objc_super_method,
MethodInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(WitnessMethodInst, witness_method,
MethodInst, None, DoesNotRelease)
SINGLE_VALUE_INST_RANGE(MethodInst, ClassMethodInst, WitnessMethodInst)
// Conversions
ABSTRACT_SINGLE_VALUE_INST(ConversionInst, SingleValueInstruction)
BRIDGED_SINGLE_VALUE_INST(UpcastInst, upcast,
ConversionInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(AddressToPointerInst, address_to_pointer,
ConversionInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(PointerToAddressInst, pointer_to_address,
ConversionInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(UncheckedRefCastInst, unchecked_ref_cast,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(UncheckedAddrCastInst, unchecked_addr_cast,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(UncheckedTrivialBitCastInst, unchecked_trivial_bit_cast,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(UncheckedBitwiseCastInst, unchecked_bitwise_cast,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(UncheckedValueCastInst, unchecked_value_cast,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(RefToRawPointerInst, ref_to_raw_pointer,
ConversionInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(RawPointerToRefInst, raw_pointer_to_ref,
ConversionInst, None, DoesNotRelease)
#define LOADABLE_REF_STORAGE(Name, name, ...) \
SINGLE_VALUE_INST(RefTo##Name##Inst, ref_to_##name, \
ConversionInst, None, DoesNotRelease) \
SINGLE_VALUE_INST(Name##ToRefInst, name##_to_ref, \
ConversionInst, None, DoesNotRelease)
#include "swift/AST/ReferenceStorage.def"
BRIDGED_SINGLE_VALUE_INST(ConvertFunctionInst, convert_function,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(ConvertEscapeToNoEscapeInst, convert_escape_to_noescape,
ConversionInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(RefToBridgeObjectInst, ref_to_bridge_object,
ConversionInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(BridgeObjectToRefInst, bridge_object_to_ref,
ConversionInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(BridgeObjectToWordInst, bridge_object_to_word,
ConversionInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(ThinToThickFunctionInst, thin_to_thick_function,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(ThickToObjCMetatypeInst, thick_to_objc_metatype,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(ObjCToThickMetatypeInst, objc_to_thick_metatype,
ConversionInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(ObjCMetatypeToObjectInst, objc_metatype_to_object,
ConversionInst, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(ObjCExistentialMetatypeToObjectInst, objc_existential_metatype_to_object,
ConversionInst, 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,
ConversionInst, MayRead, DoesNotRelease)
SINGLE_VALUE_INST_RANGE(ConversionInst, UpcastInst, UnconditionalCheckedCastInst)
BRIDGED_SINGLE_VALUE_INST(ClassifyBridgeObjectInst, classify_bridge_object,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(ValueToBridgeObjectInst, value_to_bridge_object,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_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.
BRIDGED_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)
#define UNCHECKED_REF_STORAGE(Name, name, ...) \
SINGLE_VALUE_INST(StrongCopy##Name##ValueInst, strong_copy_##name##_value, \
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_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 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_must_check instruction after successfully
// running the relevant diagnostic.
SINGLE_VALUE_INST(MarkMustCheckInst, mark_must_check,
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.
SINGLE_VALUE_INST(CopyableToMoveOnlyWrapperValueInst, copyable_to_moveonlywrapper,
SingleValueInstruction, None, DoesNotRelease)
// Convert a $@moveOnly T 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)
// 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)
// 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)
BRIDGED_SINGLE_VALUE_INST(EndCOWMutationInst, end_cow_mutation,
SingleValueInstruction, None, DoesNotRelease)
SINGLE_VALUE_INST(IsEscapingClosureInst, is_escaping_closure,
SingleValueInstruction, MayRead, DoesNotRelease)
// Accessing memory
BRIDGED_SINGLE_VALUE_INST(LoadInst, load,
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(LoadBorrowInst, load_borrow,
SingleValueInstruction, MayRead, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(BeginBorrowInst, begin_borrow,
SingleValueInstruction, MayHaveSideEffects, 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.
BRIDGED_SINGLE_VALUE_INST(BeginAccessInst, begin_access,
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
#define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
BRIDGED_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)
BRIDGED_SINGLE_VALUE_INST(ProjectBoxInst, project_box,
SingleValueInstruction, None, DoesNotRelease)
SINGLE_VALUE_INST(ProjectExistentialBoxInst, project_existential_box,
SingleValueInstruction, None, DoesNotRelease)
// Function Application
BRIDGED_SINGLE_VALUE_INST(ApplyInst, apply,
SingleValueInstruction, MayHaveSideEffects, MayRelease)
BRIDGED_SINGLE_VALUE_INST(BuiltinInst, builtin,
SingleValueInstruction, MayHaveSideEffects, MayRelease)
BRIDGED_SINGLE_VALUE_INST(PartialApplyInst, partial_apply,
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
// Metatypes
SINGLE_VALUE_INST(MetatypeInst, metatype,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(ValueMetatypeInst, value_metatype,
SingleValueInstruction, MayRead, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(ExistentialMetatypeInst, existential_metatype,
SingleValueInstruction, MayRead, DoesNotRelease)
SINGLE_VALUE_INST(ObjCProtocolInst, objc_protocol,
SingleValueInstruction, None, DoesNotRelease)
// Aggregate Types
SINGLE_VALUE_INST(ObjectInst, object,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(TupleInst, tuple,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(TupleExtractInst, tuple_extract,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(TupleElementAddrInst, tuple_element_addr,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(StructInst, struct,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(StructExtractInst, struct_extract,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(StructElementAddrInst, struct_element_addr,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(RefElementAddrInst, ref_element_addr,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(RefTailAddrInst, ref_tail_addr,
SingleValueInstruction, None, DoesNotRelease)
// Enums
BRIDGED_SINGLE_VALUE_INST(EnumInst, enum,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(UncheckedEnumDataInst, unchecked_enum_data,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(InitEnumDataAddrInst, init_enum_data_addr,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_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)
SINGLE_VALUE_INST(SelectValueInst, select_value,
SingleValueInstruction, None, DoesNotRelease)
// Protocol and Protocol Composition Types
BRIDGED_SINGLE_VALUE_INST(InitExistentialAddrInst, init_existential_addr,
SingleValueInstruction, MayWrite, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(InitExistentialValueInst, init_existential_value,
SingleValueInstruction, MayWrite, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(OpenExistentialAddrInst, open_existential_addr,
SingleValueInstruction, MayRead, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(InitExistentialRefInst, init_existential_ref,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(OpenExistentialRefInst, open_existential_ref,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(InitExistentialMetatypeInst, init_existential_metatype,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(OpenExistentialMetatypeInst, open_existential_metatype,
SingleValueInstruction, None, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(OpenExistentialBoxInst, open_existential_box,
SingleValueInstruction, MayRead, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(OpenExistentialValueInst, open_existential_value,
SingleValueInstruction, MayRead, DoesNotRelease)
BRIDGED_SINGLE_VALUE_INST(OpenExistentialBoxValueInst, open_existential_box_value,
SingleValueInstruction, MayRead, DoesNotRelease)
// 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)
// BindMemory and RebindMemory have no physical side effect. Semantically they
// write to 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, MayWrite, DoesNotRelease)
SINGLE_VALUE_INST(RebindMemoryInst, rebind_memory,
SILInstruction, MayWrite, 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(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)
BRIDGED_NON_VALUE_INST(DeallocStackInst, dealloc_stack,
DeallocationInst, MayHaveSideEffects, DoesNotRelease)
BRIDGED_NON_VALUE_INST(DeallocStackRefInst, dealloc_stack_ref,
DeallocationInst, MayHaveSideEffects, DoesNotRelease)
BRIDGED_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)
BRIDGED_NON_VALUE_INST(StrongRetainInst, strong_retain,
RefCountingInst, MayHaveSideEffects, DoesNotRelease)
BRIDGED_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"
BRIDGED_NON_VALUE_INST(RetainValueInst, retain_value,
RefCountingInst, MayHaveSideEffects, DoesNotRelease)
NON_VALUE_INST(RetainValueAddrInst, retain_value_addr,
RefCountingInst, MayHaveSideEffects, DoesNotRelease)
BRIDGED_NON_VALUE_INST(ReleaseValueInst, release_value,
RefCountingInst, MayHaveSideEffects, MayRelease)
NON_VALUE_INST(ReleaseValueAddrInst, release_value_addr,
RefCountingInst, MayHaveSideEffects, MayRelease)
BRIDGED_NON_VALUE_INST(SetDeallocatingInst, set_deallocating,
RefCountingInst, MayHaveSideEffects,
DoesNotRelease)
NON_VALUE_INST(AutoreleaseValueInst, autorelease_value,
RefCountingInst, MayHaveSideEffects,
DoesNotRelease)
INST_RANGE(RefCountingInst, StrongRetainInst, AutoreleaseValueInst)
// FIXME: Is MayHaveSideEffects appropriate?
BRIDGED_NON_VALUE_INST(FixLifetimeInst, fix_lifetime,
SILInstruction, MayHaveSideEffects, DoesNotRelease)
NON_VALUE_INST(HopToExecutorInst, hop_to_executor,
SILInstruction, MayHaveSideEffects, DoesNotRelease)
BRIDGED_NON_VALUE_INST(DestroyValueInst, destroy_value,
SILInstruction, MayHaveSideEffects, MayRelease)
BRIDGED_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.
BRIDGED_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)
BRIDGED_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(MarkFunctionEscapeInst, mark_function_escape,
SILInstruction, None, DoesNotRelease)
BRIDGED_NON_VALUE_INST(DebugValueInst, debug_value,
SILInstruction, None, DoesNotRelease)
#define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
BRIDGED_NON_VALUE_INST(Store##Name##Inst, store_##name, \
SILInstruction, MayWrite, DoesNotRelease)
#include "swift/AST/ReferenceStorage.def"
BRIDGED_NON_VALUE_INST(CopyAddrInst, copy_addr,
SILInstruction, MayHaveSideEffects, MayRelease)
BRIDGED_NON_VALUE_INST(DestroyAddrInst, destroy_addr,
SILInstruction, MayHaveSideEffects, MayRelease)
NON_VALUE_INST(EndLifetimeInst, end_lifetime,
SILInstruction, MayHaveSideEffects, MayRelease)
BRIDGED_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(EndApplyInst, end_apply,
SILInstruction, MayHaveSideEffects, MayRelease)
NON_VALUE_INST(AbortApplyInst, abort_apply,
SILInstruction, MayHaveSideEffects, MayRelease)
// Runtime failure
// FIXME: Special MemBehavior for runtime failure?
BRIDGED_NON_VALUE_INST(CondFailInst, cond_fail,
SILInstruction, MayHaveSideEffects, DoesNotRelease)
NODE_RANGE(NonValueInstruction, UnreachableInst, CondFailInst)
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 BRIDGED_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 BRIDGED_SINGLE_VALUE_INST
#undef FULL_INST
#undef INST
#undef ARGUMENT
#undef VALUE
#undef NODE