mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
It's not needed anymore, because the "FixedArray" experimental feature is replaced by inline-arrays.
950 lines
46 KiB
C++
950 lines
46 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
|
|
|
|
/// 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)
|
|
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)
|
|
|
|
NODE_RANGE(NonValueInstruction, UnreachableInst, IncrementProfilerCounterInst)
|
|
|
|
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
|