| //===--- 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 |