Files
swift-mirror/include/swift/SIL/SILNodes.def
Arnold Schwaighofer d51053b003 Add convert_escape_to_noescape instruction for converting escaping to noescape functions
@noescape function types will eventually be trivial. A
convert_escape_to_noescape instruction does not take ownership of its
operand. It is a projection to the trivial value carried by the closure
-- both context and implementation function viewed as a trivial value.

A safe SIL program must ensure that the object that the project value is based
on is live beyond the last use of the trivial value. This will be
achieve by means of making the lifetimes dependent.

For example:

  %e = partial_apply [callee_guaranteed] %f(%z) : $@convention(thin) (Builtin.Int64) -> ()
  %n = convert_escape_to_noescape %e : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
  %n2 = mark_dependence %n : $@noescape @callee_guaranteed () -> () on %e : $@callee_guaranteed () -> ()
  %f2 = function_ref @use : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
  apply %f2(%n2) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
  release_value %e : $@callee_guaranteed () -> ()

Note: This is not yet actually used.

Part of:
SR-5441
rdar://36116691
2018-02-06 18:01:23 -08:00

683 lines
32 KiB
C++

//===--- SILNodes.def - Swift SIL Metaprogramming ---------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 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
//
//===----------------------------------------------------------------------===//
//
// This file defines macros used for macro-metaprogramming with SIL nodes.
//
//===----------------------------------------------------------------------===//
/// 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, Parent, TextualName, 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
/// 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 heirarchy 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 heirarchy 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
/// 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
/// 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
/// 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)
VALUE_RANGE(SILArgument, SILPHIArgument, SILFunctionArgument)
ABSTRACT_VALUE(MultipleValueInstructionResult, ValueBase)
MULTIPLE_VALUE_INST_RESULT(BeginApplyResult, MultipleValueInstructionResult)
MULTIPLE_VALUE_INST_RESULT(DestructureStructResult, MultipleValueInstructionResult)
MULTIPLE_VALUE_INST_RESULT(DestructureTupleResult, MultipleValueInstructionResult)
VALUE_RANGE(MultipleValueInstructionResult, BeginApplyResult, DestructureTupleResult)
VALUE(SILUndef, 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(AllocRefInst, alloc_ref,
AllocationInst, None, DoesNotRelease)
SINGLE_VALUE_INST(AllocRefDynamicInst, alloc_ref_dynamic,
AllocationInst, None, DoesNotRelease)
SINGLE_VALUE_INST(AllocValueBufferInst, alloc_value_buffer,
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(GlobalAddrInst, global_addr,
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(ConstStringLiteralInst, const_string_literal,
LiteralInst, None, DoesNotRelease)
SINGLE_VALUE_INST_RANGE(LiteralInst, FunctionRefInst, ConstStringLiteralInst)
// 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
ABSTRACT_SINGLE_VALUE_INST(ConversionInst, SingleValueInstruction)
SINGLE_VALUE_INST(UpcastInst, upcast,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(AddressToPointerInst, address_to_pointer,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(PointerToAddressInst, pointer_to_address,
ConversionInst, None, DoesNotRelease)
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(RefToRawPointerInst, ref_to_raw_pointer,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(RawPointerToRefInst, raw_pointer_to_ref,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(RefToUnownedInst, ref_to_unowned,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(UnownedToRefInst, unowned_to_ref,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(RefToUnmanagedInst, ref_to_unmanaged,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(UnmanagedToRefInst, unmanaged_to_ref,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(ConvertFunctionInst, convert_function,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(ConvertEscapeToNoEscapeInst, convert_escape_to_noescape,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(ThinFunctionToPointerInst, thin_function_to_pointer,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(PointerToThinFunctionInst, pointer_to_thin_function,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(RefToBridgeObjectInst, ref_to_bridge_object,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(BridgeObjectToRefInst, bridge_object_to_ref,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(BridgeObjectToWordInst, bridge_object_to_word,
ConversionInst, None, DoesNotRelease)
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)
SINGLE_VALUE_INST(ObjCMetatypeToObjectInst, objc_metatype_to_object,
ConversionInst, None, DoesNotRelease)
SINGLE_VALUE_INST(ObjCExistentialMetatypeToObjectInst, objc_existential_metatype_to_object,
ConversionInst, None, DoesNotRelease)
// unconditional_checked_cast_value reads the source value and produces
// a new value with a potentially different representation.
SINGLE_VALUE_INST(UnconditionalCheckedCastValueInst, unconditional_checked_cast_value,
ConversionInst, MayRead, MayRelease)
// 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.
SINGLE_VALUE_INST(UnconditionalCheckedCastInst, unconditional_checked_cast,
ConversionInst, MayRead, DoesNotRelease)
SINGLE_VALUE_INST_RANGE(ConversionInst, UpcastInst, UnconditionalCheckedCastInst)
SINGLE_VALUE_INST(ClassifyBridgeObjectInst, classify_bridge_object,
SingleValueInstruction, None, DoesNotRelease)
SINGLE_VALUE_INST(MarkDependenceInst, mark_dependence,
SingleValueInstruction, None, DoesNotRelease)
SINGLE_VALUE_INST(CopyBlockInst, copy_block,
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
SINGLE_VALUE_INST(CopyValueInst, copy_value,
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
SINGLE_VALUE_INST(CopyUnownedValueInst, copy_unowned_value,
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
SINGLE_VALUE_INST(UncheckedOwnershipConversionInst, unchecked_ownership_conversion,
SingleValueInstruction, MayHaveSideEffects, MayRelease)
SINGLE_VALUE_INST(StrongPinInst, strong_pin,
SingleValueInstruction, MayHaveSideEffects, 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(IsUniqueOrPinnedInst, is_unique_or_pinned,
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
// Accessing memory
SINGLE_VALUE_INST(LoadInst, load,
SingleValueInstruction, MayRead, DoesNotRelease)
SINGLE_VALUE_INST(LoadBorrowInst, load_borrow,
SingleValueInstruction, MayRead, DoesNotRelease)
SINGLE_VALUE_INST(BeginBorrowInst, begin_borrow,
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
SINGLE_VALUE_INST(StoreBorrowInst, store_borrow,
SILInstruction, MayWrite, DoesNotRelease)
SINGLE_VALUE_INST(BeginAccessInst, begin_access,
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
SINGLE_VALUE_INST(LoadUnownedInst, load_unowned,
SingleValueInstruction, MayRead, DoesNotRelease)
SINGLE_VALUE_INST(LoadWeakInst, load_weak,
SingleValueInstruction, MayRead, DoesNotRelease)
SINGLE_VALUE_INST(MarkUninitializedInst, mark_uninitialized,
SingleValueInstruction, None, DoesNotRelease)
SINGLE_VALUE_INST(MarkUninitializedBehaviorInst, mark_uninitialized_behavior,
SingleValueInstruction, None, DoesNotRelease)
SINGLE_VALUE_INST(ProjectValueBufferInst, project_value_buffer,
SingleValueInstruction, MayRead, DoesNotRelease)
SINGLE_VALUE_INST(ProjectBoxInst, project_box,
SingleValueInstruction, None, DoesNotRelease)
SINGLE_VALUE_INST(ProjectExistentialBoxInst, project_existential_box,
SingleValueInstruction, None, DoesNotRelease)
// Function Application
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)
// 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)
// Aggregate Types
SINGLE_VALUE_INST(ObjectInst, object,
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(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)
SINGLE_VALUE_INST(SelectValueInst, select_value,
SingleValueInstruction, None, 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)
// Blocks
SINGLE_VALUE_INST(ProjectBlockStorageInst, project_block_storage,
SingleValueInstruction, None, DoesNotRelease)
SINGLE_VALUE_INST(InitBlockStorageHeaderInst, init_block_storage_header,
SingleValueInstruction, None, 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_RANGE(SingleValueInstruction, AllocStackInst, KeyPathInst)
NODE_RANGE(ValueBase, SILPHIArgument, KeyPathInst)
// 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(CheckedCastBranchInst, checked_cast_br,
TermInst, None, DoesNotRelease)
TERMINATOR(CheckedCastAddrBranchInst, checked_cast_addr_br,
TermInst, MayHaveSideEffects, MayRelease)
TERMINATOR(CheckedCastValueBranchInst, checked_cast_value_br,
TermInst, None, DoesNotRelease)
INST_RANGE(TermInst, UnreachableInst, CheckedCastValueBranchInst)
// Deallocation instructions.
ABSTRACT_INST(DeallocationInst, SILInstruction)
NON_VALUE_INST(DeallocStackInst, dealloc_stack,
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(DeallocValueBufferInst, dealloc_value_buffer,
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(StrongRetainUnownedInst, strong_retain_unowned,
RefCountingInst, MayHaveSideEffects,
DoesNotRelease)
NON_VALUE_INST(StrongUnpinInst, strong_unpin,
RefCountingInst, MayHaveSideEffects, DoesNotRelease)
NON_VALUE_INST(UnownedRetainInst, unowned_retain,
RefCountingInst, MayHaveSideEffects, DoesNotRelease)
NON_VALUE_INST(UnownedReleaseInst, unowned_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)
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(SetDeallocatingInst, set_deallocating,
RefCountingInst, MayHaveSideEffects,
DoesNotRelease)
NON_VALUE_INST(AutoreleaseValueInst, autorelease_value,
RefCountingInst, MayHaveSideEffects,
DoesNotRelease)
INST_RANGE(RefCountingInst, StrongRetainInst, AutoreleaseValueInst)
// BindMemory has no physical side effect. Semantically it writes to
// its affected memory region because any reads or writes accessing
// that memory must be dependent on the bind operation.
NON_VALUE_INST(BindMemoryInst, bind_memory,
SILInstruction, MayWrite, DoesNotRelease)
// FIXME: Is MayHaveSideEffects appropriate?
NON_VALUE_INST(FixLifetimeInst, fix_lifetime,
SILInstruction, MayHaveSideEffects, DoesNotRelease)
NON_VALUE_INST(DestroyValueInst, destroy_value,
SILInstruction, MayHaveSideEffects, MayRelease)
NON_VALUE_INST(EndBorrowInst, end_borrow,
SILInstruction, MayHaveSideEffects, DoesNotRelease)
NON_VALUE_INST(EndBorrowArgumentInst, end_borrow_argument,
SILInstruction, MayHaveSideEffects, DoesNotRelease)
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, MayWrite, DoesNotRelease)
NON_VALUE_INST(AssignInst, assign,
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(DebugValueAddrInst, debug_value_addr,
SILInstruction, None, DoesNotRelease)
NON_VALUE_INST(StoreUnownedInst, store_unowned,
SILInstruction, MayWrite, DoesNotRelease)
NON_VALUE_INST(StoreWeakInst, store_weak,
SILInstruction, MayWrite, DoesNotRelease)
NON_VALUE_INST(CopyAddrInst, copy_addr,
SILInstruction, MayHaveSideEffects, MayRelease)
NON_VALUE_INST(DestroyAddrInst, destroy_addr,
SILInstruction, MayHaveSideEffects, MayRelease)
NON_VALUE_INST(EndLifetimeInst, end_lifetime,
SILInstruction, MayHaveSideEffects, MayRelease)
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)
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?
NON_VALUE_INST(CondFailInst, cond_fail,
SILInstruction, MayHaveSideEffects, DoesNotRelease)
NODE_RANGE(NonValueInstruction, UnreachableInst, CondFailInst)
ABSTRACT_INST(MultipleValueInstruction, SILInstruction)
MULTIPLE_VALUE_INST(BeginApplyInst, begin_apply,
SILInstruction, MayHaveSideEffects, MayRelease)
MULTIPLE_VALUE_INST(DestructureStructInst, destructure_struct,
SILInstruction, None, DoesNotRelease)
MULTIPLE_VALUE_INST(DestructureTupleInst, destructure_tuple,
SILInstruction, None, DoesNotRelease)
INST_RANGE(MultipleValueInstruction, BeginApplyInst, DestructureTupleInst)
NODE_RANGE(SILInstruction, AllocStackInst, DestructureTupleInst)
NODE_RANGE(SILNode, SILPHIArgument, DestructureTupleInst)
#undef SINGLE_VALUE_INST_RANGE
#undef INST_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 TERMINATOR
#undef NON_VALUE_INST
#undef MULTIPLE_VALUE_INST_RESULT
#undef MULTIPLE_VALUE_INST
#undef SINGLE_VALUE_INST
#undef FULL_INST
#undef INST
#undef ARGUMENT
#undef VALUE
#undef NODE