blob: 770fec19b4370acff0cb296829693fc8782834b5 [file] [log] [blame]
//===--- 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.
//
//===----------------------------------------------------------------------===//
/// VALUE(Id, Parent)
/// The expression enumerator value is a 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)
#endif
/// ARGUMENT(Id, Parent)
/// The expression enumerator value is a ValueKind. The node's class name is
/// Id and the name of its base class (in the SILValue hierarchy) is Parent.
#ifndef ARGUMENT
#define ARGUMENT(Id, Parent) VALUE(Id, Parent)
#endif
/// INST(Id, Parent, TextualName, MemBehavior, MayRelease)
///
/// The expression enumerator value is a ValueKind. The node's class name is
/// Id, and the name of its base class (in the SILInstruction hierarchy) is
/// Parent. TextualName is the textual name of the instruction. 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 INST
#define INST(Id, Parent, TextualName, MemBehavior, MayRelease) VALUE(Id, Parent)
#endif
/// TERMINATOR(Id, Parent, TextualName, MemBehavior, MayRelease)
/// Expands for terminator instructions. The expression enumerator value is a
/// ValueKind. The node's class name is Id, and the name of its base class
/// (in the SILInstruction hierarchy) is Parent. TextualName is the name of
/// the instruction in textual SIL. 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 TERMINATOR
#define TERMINATOR(Id, Parent, TextualName, MemBehavior, MayRelease) \
INST(Id, Parent, TextualName, MemBehavior, MayRelease)
#endif
/// An abstract value base is an abstract base class in the hierarchy; it is
/// never a most-derived type, and it does not have an enumerator in ValueKind.
///
/// Most metaprograms do not care about abstract expressions, so the default
/// is to ignore them.
#ifndef ABSTRACT_VALUE
#define ABSTRACT_VALUE(Id, Parent)
#endif
/// A convenience for determining the range of values. These will always
/// appear immediately after the last member.
#ifndef VALUE_RANGE
#define VALUE_RANGE(Id, First, Last)
#endif
ABSTRACT_VALUE(SILArgument, ValueBase)
ARGUMENT(SILPHIArgument, SILArgument)
ARGUMENT(SILFunctionArgument, SILArgument)
VALUE_RANGE(SILArgument, SILPHIArgument, SILFunctionArgument)
VALUE(SILUndef, ValueBase)
// Please keep the order of instructions consistent with the order of their
// descriptions in the SIL reference in docs/SIL.rst.
ABSTRACT_VALUE(SILInstruction, ValueBase)
// Allocation instructions.
ABSTRACT_VALUE(AllocationInst, SILInstruction)
INST(AllocStackInst, AllocationInst, alloc_stack, None, DoesNotRelease)
INST(AllocRefInst, AllocationInst, alloc_ref, None, DoesNotRelease)
INST(AllocRefDynamicInst, AllocationInst, alloc_ref_dynamic, None, DoesNotRelease)
INST(AllocValueBufferInst, AllocationInst, alloc_value_buffer, None, DoesNotRelease)
INST(AllocBoxInst, AllocationInst, alloc_box, None, DoesNotRelease)
INST(AllocExistentialBoxInst, AllocationInst, alloc_existential_box, MayWrite, DoesNotRelease)
VALUE_RANGE(AllocationInst, AllocStackInst, AllocExistentialBoxInst)
// Deallocation instructions.
ABSTRACT_VALUE(DeallocationInst, SILInstruction)
INST(DeallocStackInst, DeallocationInst, dealloc_stack, MayHaveSideEffects, DoesNotRelease)
INST(DeallocRefInst, DeallocationInst, dealloc_ref, MayHaveSideEffects, DoesNotRelease)
INST(DeallocPartialRefInst, DeallocationInst, dealloc_partial_ref, MayHaveSideEffects,
DoesNotRelease)
INST(DeallocValueBufferInst, DeallocationInst, dealloc_value_buffer, MayHaveSideEffects,
DoesNotRelease)
INST(DeallocBoxInst, DeallocationInst, dealloc_box, MayHaveSideEffects, DoesNotRelease)
INST(DeallocExistentialBoxInst, DeallocationInst, dealloc_existential_box, MayHaveSideEffects,
DoesNotRelease)
VALUE_RANGE(DeallocationInst, DeallocStackInst, DeallocExistentialBoxInst)
// Accessing memory
INST(LoadInst, SILInstruction, load, MayRead, DoesNotRelease)
INST(LoadBorrowInst, SILInstruction, load_borrow, MayRead, DoesNotRelease)
INST(BeginBorrowInst, SILInstruction, begin_borrow, MayHaveSideEffects, DoesNotRelease)
INST(EndBorrowInst, SILInstruction, end_borrow, MayHaveSideEffects, DoesNotRelease)
INST(EndBorrowArgumentInst, SILInstruction, end_borrow_argument, MayHaveSideEffects, DoesNotRelease)
INST(LoadUnownedInst, SILInstruction, load_unowned, MayRead, DoesNotRelease)
INST(LoadWeakInst, SILInstruction, load_weak, MayRead, DoesNotRelease)
INST(StoreInst, SILInstruction, store, MayWrite, DoesNotRelease)
INST(StoreBorrowInst, SILInstruction, store_borrow, MayWrite, DoesNotRelease)
INST(AssignInst, SILInstruction, assign, MayWrite, DoesNotRelease)
INST(MarkUninitializedInst, SILInstruction, mark_uninitialized, None, DoesNotRelease)
INST(MarkUninitializedBehaviorInst, SILInstruction, mark_uninitialized_behavior, None, DoesNotRelease)
INST(MarkFunctionEscapeInst, SILInstruction, mark_function_escape, None, DoesNotRelease)
INST(DebugValueInst, SILInstruction, debug_value, None, DoesNotRelease)
INST(DebugValueAddrInst, SILInstruction, debug_value_addr, None, DoesNotRelease)
INST(StoreUnownedInst, SILInstruction, store_unowned, MayWrite, DoesNotRelease)
INST(StoreWeakInst, SILInstruction, store_weak, MayWrite, DoesNotRelease)
INST(CopyAddrInst, SILInstruction, copy_addr, MayHaveSideEffects, MayRelease)
INST(DestroyAddrInst, SILInstruction, destroy_addr, MayHaveSideEffects, MayRelease)
INST(ProjectValueBufferInst, SILInstruction, project_value_buffer, MayRead, DoesNotRelease)
INST(ProjectBoxInst, SILInstruction, project_box, None, DoesNotRelease)
INST(ProjectExistentialBoxInst, SILInstruction, project_existential_box, None, DoesNotRelease)
ABSTRACT_VALUE(IndexingInst, SILInstruction)
INST(IndexAddrInst, IndexingInst, index_addr, None, DoesNotRelease)
INST(TailAddrInst, IndexingInst, tail_addr, None, DoesNotRelease)
INST(IndexRawPointerInst, IndexingInst, index_raw_pointer, None, DoesNotRelease)
VALUE_RANGE(IndexingInst, IndexAddrInst, IndexRawPointerInst)
// 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.
INST(BindMemoryInst, SILInstruction, bind_memory, MayWrite, DoesNotRelease)
// Reference Counting
ABSTRACT_VALUE(RefCountingInst, SILInstruction)
INST(StrongRetainInst, RefCountingInst, strong_retain, MayHaveSideEffects, DoesNotRelease)
INST(StrongReleaseInst, RefCountingInst, strong_release, MayHaveSideEffects, MayRelease)
INST(StrongRetainUnownedInst, RefCountingInst, strong_retain_unowned, MayHaveSideEffects,
DoesNotRelease)
INST(StrongPinInst, SILInstruction, strong_pin, MayHaveSideEffects, DoesNotRelease)
INST(StrongUnpinInst, SILInstruction, strong_unpin, MayHaveSideEffects, DoesNotRelease)
INST(UnownedRetainInst, RefCountingInst, unowned_retain, MayHaveSideEffects, DoesNotRelease)
INST(UnownedReleaseInst, RefCountingInst, unowned_release, MayHaveSideEffects,
MayRelease)
INST(RetainValueInst, RefCountingInst, retain_value, MayHaveSideEffects, DoesNotRelease)
INST(ReleaseValueInst, RefCountingInst, release_value, MayHaveSideEffects, MayRelease)
INST(SetDeallocatingInst, RefCountingInst, set_deallocating, MayHaveSideEffects,
DoesNotRelease)
INST(AutoreleaseValueInst, RefCountingInst, autorelease_value, MayHaveSideEffects,
DoesNotRelease)
VALUE_RANGE(RefCountingInst, StrongRetainInst, AutoreleaseValueInst)
// FIXME: Is MayHaveSideEffects appropriate?
INST(FixLifetimeInst, SILInstruction, fix_lifetime, MayHaveSideEffects, DoesNotRelease)
INST(MarkDependenceInst, SILInstruction, mark_dependence, None, DoesNotRelease)
INST(CopyBlockInst, SILInstruction, copy_block, MayHaveSideEffects, DoesNotRelease)
INST(CopyValueInst, SILInstruction, copy_value, MayHaveSideEffects, DoesNotRelease)
INST(UnmanagedRetainValueInst, RefCountingInst, unmanaged_retain_value, MayHaveSideEffects, DoesNotRelease)
INST(UnmanagedReleaseValueInst, RefCountingInst, unmanaged_release_value, MayHaveSideEffects, MayRelease)
INST(UnmanagedAutoreleaseValueInst, RefCountingInst, unmanaged_autorelease_value, MayHaveSideEffects, DoesNotRelease)
INST(CopyUnownedValueInst, SILInstruction, copy_unowned_value, MayHaveSideEffects, DoesNotRelease)
INST(DestroyValueInst, SILInstruction, destroy_value, MayHaveSideEffects, MayRelease)
// 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.
INST(IsUniqueInst, SILInstruction, is_unique, MayHaveSideEffects, DoesNotRelease)
INST(IsUniqueOrPinnedInst, SILInstruction, is_unique_or_pinned, MayHaveSideEffects, DoesNotRelease)
INST(AllocGlobalInst, SILInstruction, alloc_global, MayHaveSideEffects, DoesNotRelease)
// Literals
ABSTRACT_VALUE(LiteralInst, SILInstruction)
INST(FunctionRefInst, LiteralInst, function_ref, None, DoesNotRelease)
INST(GlobalAddrInst, LiteralInst, global_addr, None, DoesNotRelease)
INST(IntegerLiteralInst, LiteralInst, integer_literal, None, DoesNotRelease)
INST(FloatLiteralInst, LiteralInst, float_literal, None, DoesNotRelease)
INST(StringLiteralInst, LiteralInst, string_literal, None, DoesNotRelease)
VALUE_RANGE(LiteralInst, FunctionRefInst, StringLiteralInst)
// Dynamic Dispatch
ABSTRACT_VALUE(MethodInst, SILInstruction)
INST(ClassMethodInst, MethodInst, class_method, None, DoesNotRelease)
INST(SuperMethodInst, MethodInst, super_method, None, DoesNotRelease)
INST(WitnessMethodInst, MethodInst, witness_method, None, DoesNotRelease)
INST(DynamicMethodInst, MethodInst, dynamic_method, None, DoesNotRelease)
VALUE_RANGE(MethodInst, ClassMethodInst, DynamicMethodInst)
// Function Application
INST(ApplyInst, SILInstruction, apply, MayHaveSideEffects, MayRelease)
INST(PartialApplyInst, SILInstruction, partial_apply, MayHaveSideEffects, DoesNotRelease)
INST(BuiltinInst, SILInstruction, builtin, MayHaveSideEffects, MayRelease)
// Metatypes
INST(MetatypeInst, SILInstruction, metatype, None, DoesNotRelease)
INST(ValueMetatypeInst, SILInstruction, value_metatype, None, DoesNotRelease)
INST(ExistentialMetatypeInst, SILInstruction, existential_metatype, MayRead, DoesNotRelease)
INST(ObjCProtocolInst, SILInstruction, objc_protocol, None, DoesNotRelease)
// Aggregate Types
INST(TupleInst, SILInstruction, tuple, None, DoesNotRelease)
INST(TupleExtractInst, SILInstruction, tuple_extract, None, DoesNotRelease)
INST(TupleElementAddrInst, SILInstruction, tuple_element_addr, None, DoesNotRelease)
INST(StructInst, SILInstruction, struct, None, DoesNotRelease)
INST(StructExtractInst, SILInstruction, struct_extract, None, DoesNotRelease)
INST(StructElementAddrInst, SILInstruction, struct_element_addr, None, DoesNotRelease)
INST(RefElementAddrInst, SILInstruction, ref_element_addr, None, DoesNotRelease)
INST(RefTailAddrInst, SILInstruction, ref_tail_addr, None, DoesNotRelease)
// Enums
INST(EnumInst, SILInstruction, enum, None, DoesNotRelease)
INST(UncheckedEnumDataInst, SILInstruction, unchecked_enum_data, None, DoesNotRelease)
INST(InitEnumDataAddrInst, SILInstruction, init_enum_data_addr, None, DoesNotRelease)
INST(UncheckedTakeEnumDataAddrInst, SILInstruction, unchecked_take_enum_data_addr, MayWrite, DoesNotRelease)
INST(InjectEnumAddrInst, SILInstruction, inject_enum_addr, MayWrite, DoesNotRelease)
INST(SelectEnumInst, SILInstruction, select_enum, None, DoesNotRelease)
INST(SelectEnumAddrInst, SILInstruction, select_enum_addr, MayRead, DoesNotRelease)
INST(SelectValueInst, SILInstruction, select_value, None, DoesNotRelease)
// Protocol and Protocol Composition Types
INST(InitExistentialAddrInst, SILInstruction, init_existential_addr, MayWrite, DoesNotRelease)
INST(InitExistentialOpaqueInst, SILInstruction, init_existential_opaque, MayWrite, DoesNotRelease)
INST(DeinitExistentialAddrInst, SILInstruction, deinit_existential_addr, MayHaveSideEffects,
DoesNotRelease)
INST(DeinitExistentialOpaqueInst, SILInstruction, deinit_existential_opaque, MayHaveSideEffects,
DoesNotRelease)
INST(OpenExistentialAddrInst, SILInstruction, open_existential_addr, MayRead, DoesNotRelease)
INST(InitExistentialRefInst, SILInstruction, init_existential_ref, None, DoesNotRelease)
INST(OpenExistentialRefInst, SILInstruction, open_existential_ref, None, DoesNotRelease)
INST(InitExistentialMetatypeInst, SILInstruction, init_existential_metatype, None, DoesNotRelease)
INST(OpenExistentialMetatypeInst, SILInstruction, open_existential_metatype, None, DoesNotRelease)
INST(OpenExistentialBoxInst, SILInstruction, open_existential_box, MayRead, DoesNotRelease)
INST(OpenExistentialOpaqueInst, SILInstruction, open_existential_opaque, MayRead, DoesNotRelease)
// Blocks
INST(ProjectBlockStorageInst, SILInstruction, project_block_storage, None, DoesNotRelease)
INST(InitBlockStorageHeaderInst, SILInstruction, init_block_storage_header, None, DoesNotRelease)
// Conversions
ABSTRACT_VALUE(ConversionInst, SILInstruction)
INST(UpcastInst, ConversionInst, upcast, None, DoesNotRelease)
INST(AddressToPointerInst, ConversionInst, address_to_pointer, None, DoesNotRelease)
INST(PointerToAddressInst, ConversionInst, pointer_to_address, None, DoesNotRelease)
INST(UncheckedRefCastInst, ConversionInst, unchecked_ref_cast, None, DoesNotRelease)
INST(UncheckedAddrCastInst, ConversionInst, unchecked_addr_cast, None, DoesNotRelease)
INST(UncheckedTrivialBitCastInst, ConversionInst, unchecked_trivial_bit_cast, None, DoesNotRelease)
INST(UncheckedBitwiseCastInst, ConversionInst, unchecked_bitwise_cast, None, DoesNotRelease)
INST(RefToRawPointerInst, ConversionInst, ref_to_raw_pointer, None, DoesNotRelease)
INST(RawPointerToRefInst, ConversionInst, raw_pointer_to_ref, None, DoesNotRelease)
INST(RefToUnownedInst, ConversionInst, ref_to_unowned, None, DoesNotRelease)
INST(UnownedToRefInst, ConversionInst, unowned_to_ref, None, DoesNotRelease)
INST(RefToUnmanagedInst, ConversionInst, ref_to_unmanaged, None, DoesNotRelease)
INST(UnmanagedToRefInst, ConversionInst, unmanaged_to_ref, None, DoesNotRelease)
INST(ConvertFunctionInst, ConversionInst, convert_function, None, DoesNotRelease)
INST(ThinFunctionToPointerInst, ConversionInst, thin_function_to_pointer, None, DoesNotRelease)
INST(PointerToThinFunctionInst, ConversionInst, pointer_to_thin_function, None, DoesNotRelease)
INST(RefToBridgeObjectInst, ConversionInst, ref_to_bridge_object, None, DoesNotRelease)
INST(BridgeObjectToRefInst, ConversionInst, bridge_object_to_ref, None, DoesNotRelease)
INST(BridgeObjectToWordInst, ConversionInst, bridge_object_to_word, None, DoesNotRelease)
INST(ThinToThickFunctionInst, ConversionInst, thin_to_thick_function, None, DoesNotRelease)
INST(ThickToObjCMetatypeInst, ConversionInst, thick_to_objc_metatype, None, DoesNotRelease)
INST(ObjCToThickMetatypeInst, ConversionInst, objc_to_thick_metatype, None, DoesNotRelease)
INST(ObjCMetatypeToObjectInst, ConversionInst, objc_metatype_to_object, None, DoesNotRelease)
INST(ObjCExistentialMetatypeToObjectInst, ConversionInst, objc_existential_metatype_to_object, None,
DoesNotRelease)
INST(UnconditionalCheckedCastOpaqueInst, ConversionInst, unconditional_checked_cast_opaque, None, DoesNotRelease)
INST(UnconditionalCheckedCastInst, ConversionInst, unconditional_checked_cast, None, DoesNotRelease)
VALUE_RANGE(ConversionInst, UpcastInst, UnconditionalCheckedCastInst)
INST(IsNonnullInst, SILInstruction, is_nonnull, None, DoesNotRelease)
INST(UnconditionalCheckedCastAddrInst, SILInstruction, unconditional_checked_cast_addr, MayHaveSideEffects,
MayRelease)
INST(UncheckedRefCastAddrInst, SILInstruction, unchecked_ref_cast_addr, MayHaveSideEffects,
DoesNotRelease)
// Runtime failure
// FIXME: Special MemBehavior for runtime failure?
INST(CondFailInst, SILInstruction, cond_fail, MayHaveSideEffects, DoesNotRelease)
// Terminators
ABSTRACT_VALUE(TermInst, SILInstruction)
TERMINATOR(UnreachableInst, TermInst, unreachable, None, DoesNotRelease)
TERMINATOR(ReturnInst, TermInst, return, None, DoesNotRelease)
TERMINATOR(ThrowInst, TermInst, throw, None, DoesNotRelease)
TERMINATOR(TryApplyInst, TermInst, try_apply, MayHaveSideEffects, MayRelease)
TERMINATOR(BranchInst, TermInst, br, None, DoesNotRelease)
TERMINATOR(CondBranchInst, TermInst, cond_br, None, DoesNotRelease)
TERMINATOR(SwitchValueInst, TermInst, switch_value, None, DoesNotRelease)
TERMINATOR(SwitchEnumInst, TermInst, switch_enum, None, DoesNotRelease)
TERMINATOR(SwitchEnumAddrInst, TermInst, switch_enum_addr, MayRead, DoesNotRelease)
TERMINATOR(DynamicMethodBranchInst, TermInst, dynamic_method_br, None, DoesNotRelease)
TERMINATOR(CheckedCastBranchInst, TermInst, checked_cast_br, None, DoesNotRelease)
TERMINATOR(CheckedCastAddrBranchInst, TermInst, checked_cast_addr_br, MayHaveSideEffects,
MayRelease)
VALUE_RANGE(TermInst, UnreachableInst, CheckedCastAddrBranchInst)
VALUE_RANGE(SILInstruction, AllocStackInst, CheckedCastAddrBranchInst)
#undef VALUE_RANGE
#undef ABSTRACT_VALUE
#undef TERMINATOR
#undef INST
#undef ARGUMENT
#undef VALUE