mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This instruction can be used to disable ownership verification on it's result and will be allowed only in raw SIL. Sometimes SILGen can produce invalid ownership SSA, that cannot be resolved until mandatory passes run. We have a few ways to piecewise disable verification. With unchecked_ownership instruction we can provide a uniform way to disable ownership verification for a value.
965 lines
46 KiB
C++
965 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)
|
|
SINGLE_VALUE_INST(ImplicitActorToOpaqueIsolationCastInst, implicitactor_to_opaqueisolation_cast,
|
|
SingleValueInstruction, None, DoesNotRelease)
|
|
// unconditional_checked_cast_inst is only MayRead to prevent a subsequent
|
|
// release of the cast's source from being hoisted above the cast:
|
|
// retain X
|
|
// Y = unconditional_checked_cast_inst X
|
|
// _ = Y
|
|
// release X // This release cannot be reordered with the cast.
|
|
//
|
|
// With Semantic SIL, this pattern of unbalanced retain/release
|
|
// should never happen. Since unconditional_checked_cast is a
|
|
// scalar cast that doesn't affect the value's representation, its
|
|
// side effect can then be modeled as None.
|
|
DYNAMICCAST_SINGLE_VALUE_INST(UnconditionalCheckedCastInst, unconditional_checked_cast,
|
|
SingleValueInstruction, MayRead, DoesNotRelease)
|
|
|
|
SINGLE_VALUE_INST(ClassifyBridgeObjectInst, classify_bridge_object,
|
|
SingleValueInstruction, None, DoesNotRelease)
|
|
SINGLE_VALUE_INST(ValueToBridgeObjectInst, value_to_bridge_object,
|
|
SingleValueInstruction, None, DoesNotRelease)
|
|
// MarkDependenceAddrInst has read effects for the base operand. See
|
|
// getMemoryBehavior()
|
|
SINGLE_VALUE_INST(MarkDependenceInst, mark_dependence,
|
|
SingleValueInstruction, None, DoesNotRelease)
|
|
SINGLE_VALUE_INST(CopyBlockInst, copy_block,
|
|
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
|
|
SINGLE_VALUE_INST(CopyBlockWithoutEscapingInst, copy_block_without_escaping,
|
|
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
|
|
// A copy_value's retain semantics are fully encapsulated in OSSA
|
|
// invariants. It has no side effects relative to other OSSA values.
|
|
SINGLE_VALUE_INST(CopyValueInst, copy_value,
|
|
SingleValueInstruction, None, DoesNotRelease)
|
|
// A copy_value instruction that was explicitly asked for by the user. Left
|
|
// alone by OSSA optimizations.
|
|
SINGLE_VALUE_INST(ExplicitCopyValueInst, explicit_copy_value,
|
|
SingleValueInstruction, None, DoesNotRelease)
|
|
// Produce a @sil_unowned value from the specified value of reference type.
|
|
SINGLE_VALUE_INST(UnownedCopyValueInst, unowned_copy_value,
|
|
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
|
|
SINGLE_VALUE_INST(WeakCopyValueInst, weak_copy_value,
|
|
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
|
|
#define REF_STORAGE(Name, name, ...) \
|
|
SINGLE_VALUE_INST(StrongCopy##Name##ValueInst, strong_copy_##name##_value, \
|
|
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
|
|
#include "swift/AST/ReferenceStorage.def"
|
|
SINGLE_VALUE_INST(UncheckedOwnershipConversionInst, unchecked_ownership_conversion,
|
|
SingleValueInstruction, None, DoesNotRelease)
|
|
|
|
// 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)
|
|
SINGLE_VALUE_INST(UncheckedOwnershipInst, unchecked_ownership,
|
|
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(VectorBaseAddrInst, vector_base_addr,
|
|
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(ReturnBorrowInst, return_borrow,
|
|
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(AssignOrInitInst, assign_or_init,
|
|
SILInstruction, MayWrite, DoesNotRelease)
|
|
NON_VALUE_INST(MarkFunctionEscapeInst, mark_function_escape,
|
|
SILInstruction, None, DoesNotRelease)
|
|
NON_VALUE_INST(DebugValueInst, debug_value,
|
|
SILInstruction, None, DoesNotRelease)
|
|
NON_VALUE_INST(DebugStepInst, debug_step,
|
|
SILInstruction, MayHaveSideEffects, DoesNotRelease)
|
|
NON_VALUE_INST(SpecifyTestInst, specify_test,
|
|
SILInstruction, None, DoesNotRelease)
|
|
#define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
|
|
NON_VALUE_INST(Store##Name##Inst, store_##name, \
|
|
SILInstruction, MayWrite, DoesNotRelease)
|
|
#include "swift/AST/ReferenceStorage.def"
|
|
NON_VALUE_INST(CopyAddrInst, copy_addr,
|
|
SILInstruction, MayHaveSideEffects, MayRelease)
|
|
NON_VALUE_INST(ExplicitCopyAddrInst, explicit_copy_addr,
|
|
SILInstruction, MayHaveSideEffects, MayRelease)
|
|
NON_VALUE_INST(TupleAddrConstructorInst, tuple_addr_constructor,
|
|
SILInstruction, MayHaveSideEffects, MayRelease)
|
|
NON_VALUE_INST(DestroyAddrInst, destroy_addr,
|
|
SILInstruction, MayHaveSideEffects, MayRelease)
|
|
NON_VALUE_INST(EndLifetimeInst, end_lifetime,
|
|
SILInstruction, MayHaveSideEffects, MayRelease)
|
|
NON_VALUE_INST(ExtendLifetimeInst, extend_lifetime,
|
|
SILInstruction, None, DoesNotRelease)
|
|
NON_VALUE_INST(InjectEnumAddrInst, inject_enum_addr,
|
|
SILInstruction, MayWrite, DoesNotRelease)
|
|
NON_VALUE_INST(DeinitExistentialAddrInst, deinit_existential_addr,
|
|
SILInstruction, MayHaveSideEffects, DoesNotRelease)
|
|
NON_VALUE_INST(DeinitExistentialValueInst, deinit_existential_value,
|
|
SILInstruction, MayHaveSideEffects, DoesNotRelease)
|
|
DYNAMICCAST_NON_VALUE_INST(
|
|
UnconditionalCheckedCastAddrInst, unconditional_checked_cast_addr,
|
|
SILInstruction, MayHaveSideEffects, MayRelease)
|
|
NON_VALUE_INST(UncheckedRefCastAddrInst, unchecked_ref_cast_addr,
|
|
SILInstruction, MayHaveSideEffects, DoesNotRelease)
|
|
NON_VALUE_INST(AllocGlobalInst, alloc_global,
|
|
SILInstruction, MayHaveSideEffects, DoesNotRelease)
|
|
NON_VALUE_INST(AbortApplyInst, abort_apply,
|
|
SILInstruction, MayHaveSideEffects, MayRelease)
|
|
NON_VALUE_INST(PackElementSetInst, pack_element_set,
|
|
SILInstruction, MayHaveSideEffects, DoesNotRelease)
|
|
|
|
// Runtime failure
|
|
// FIXME: Special MemBehavior for runtime failure?
|
|
NON_VALUE_INST(CondFailInst, cond_fail,
|
|
SILInstruction, MayHaveSideEffects, DoesNotRelease)
|
|
|
|
// A move_addr is a Raw SIL only instruction that is equivalent to a copy_addr
|
|
// [init]. It is lowered during the diagnostic passes to a copy_addr [init] if
|
|
// the move checker found uses that prevented us from converting this to a
|
|
// move or if we do not find such uses, a copy_addr [init] [take].
|
|
NON_VALUE_INST(MarkUnresolvedMoveAddrInst, mark_unresolved_move_addr,
|
|
SILInstruction, None, DoesNotRelease)
|
|
|
|
NON_VALUE_INST(MergeIsolationRegionInst, merge_isolation_region,
|
|
SILInstruction, None, DoesNotRelease)
|
|
|
|
NON_VALUE_INST(IgnoredUseInst, ignored_use,
|
|
SILInstruction, None, DoesNotRelease)
|
|
|
|
NON_VALUE_INST(IncrementProfilerCounterInst, increment_profiler_counter,
|
|
SILInstruction, MayReadWrite, DoesNotRelease)
|
|
|
|
// MarkDependenceAddrInst has read effects for the base operand. See
|
|
// getMemoryBehavior().
|
|
NON_VALUE_INST(MarkDependenceAddrInst, mark_dependence_addr,
|
|
SILInstruction, MayReadWrite, DoesNotRelease)
|
|
|
|
NON_VALUE_INST(EndCOWMutationAddrInst, end_cow_mutation_addr,
|
|
SILInstruction, MayHaveSideEffects, DoesNotRelease)
|
|
NODE_RANGE(NonValueInstruction, UnreachableInst, EndCOWMutationAddrInst)
|
|
|
|
ABSTRACT_INST(MultipleValueInstruction, SILInstruction)
|
|
MULTIPLE_VALUE_INST(BeginApplyInst, begin_apply,
|
|
MultipleValueInstruction, MayHaveSideEffects, MayRelease)
|
|
|
|
// begin_cow_mutation is defined to have side effects, because it has
|
|
// dependencies with instructions which retain the buffer operand. This prevents
|
|
// optimizations from moving begin_cow_mutation instructions across such retain
|
|
// instructions.
|
|
MULTIPLE_VALUE_INST(BeginCOWMutationInst, begin_cow_mutation,
|
|
MultipleValueInstruction, MayHaveSideEffects, DoesNotRelease)
|
|
MULTIPLE_VALUE_INST(DestructureStructInst, destructure_struct,
|
|
MultipleValueInstruction, None, DoesNotRelease)
|
|
MULTIPLE_VALUE_INST(DestructureTupleInst, destructure_tuple,
|
|
MultipleValueInstruction, None, DoesNotRelease)
|
|
INST_RANGE(MultipleValueInstruction, BeginApplyInst, DestructureTupleInst)
|
|
NODE_RANGE(NonSingleValueInstruction, UnreachableInst, DestructureTupleInst)
|
|
|
|
NODE_RANGE(SILInstruction, AllocStackInst, DestructureTupleInst)
|
|
NODE_RANGE(SILNode, SILPhiArgument, DestructureTupleInst)
|
|
|
|
#undef SINGLE_VALUE_INST_RANGE
|
|
#undef INST_RANGE
|
|
#undef ARGUMENT_RANGE
|
|
#undef VALUE_RANGE
|
|
#undef NODE_RANGE
|
|
#undef ABSTRACT_SINGLE_VALUE_INST
|
|
#undef ABSTRACT_INST
|
|
#undef ABSTRACT_VALUE
|
|
#undef ABSTRACT_NODE
|
|
#undef ABSTRACT_VALUE_AND_INST
|
|
#undef DYNAMICCAST_TERMINATOR
|
|
#undef TERMINATOR
|
|
#undef NON_VALUE_INST
|
|
#undef DYNAMICCAST_NON_VALUE_INST
|
|
#undef MULTIPLE_VALUE_INST_RESULT
|
|
#undef MULTIPLE_VALUE_INST
|
|
#undef DYNAMICCAST_SINGLE_VALUE_INST
|
|
#undef DYNAMICCAST_INST
|
|
#undef SINGLE_VALUE_INST
|
|
#undef FULL_INST
|
|
#undef INST
|
|
#undef ARGUMENT
|
|
#undef VALUE
|
|
#undef NODE
|