// Copyright 2015 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_CODEGEN_TNODE_H_ #define V8_CODEGEN_TNODE_H_ #include "src/codegen/machine-type.h" namespace v8 { namespace internal { class HeapNumber; class BigInt; class Object; class Smi; class TaggedIndex; namespace compiler { class Node; } // namespace compiler struct UntaggedT {}; struct IntegralT : UntaggedT {}; struct WordT : IntegralT { static const MachineRepresentation kMachineRepresentation = MachineType::PointerRepresentation(); }; struct RawPtrT : WordT { static constexpr MachineType kMachineType = MachineType::Pointer(); }; // A RawPtrT that is guaranteed to point into the sandbox. struct SandboxedPtrT : WordT { static constexpr MachineType kMachineType = MachineType::SandboxedPointer(); }; template struct RawPtr : RawPtrT {}; struct Word32T : IntegralT { static const MachineRepresentation kMachineRepresentation = MachineRepresentation::kWord32; }; struct Int32T : Word32T { static constexpr MachineType kMachineType = MachineType::Int32(); }; struct Uint32T : Word32T { static constexpr MachineType kMachineType = MachineType::Uint32(); }; struct Int16T : Int32T { static constexpr MachineType kMachineType = MachineType::Int16(); }; struct Uint16T : Uint32T, Int32T { static constexpr MachineType kMachineType = MachineType::Uint16(); }; struct Int8T : Int16T { static constexpr MachineType kMachineType = MachineType::Int8(); }; struct Uint8T : Uint16T, Int16T { static constexpr MachineType kMachineType = MachineType::Uint8(); }; struct Word64T : IntegralT { static const MachineRepresentation kMachineRepresentation = MachineRepresentation::kWord64; }; struct Int64T : Word64T { static constexpr MachineType kMachineType = MachineType::Int64(); }; struct Uint64T : Word64T { static constexpr MachineType kMachineType = MachineType::Uint64(); }; struct IntPtrT : WordT { static constexpr MachineType kMachineType = MachineType::IntPtr(); }; struct UintPtrT : WordT { static constexpr MachineType kMachineType = MachineType::UintPtr(); }; // An index into the external pointer table. #ifdef V8_SANDBOXED_EXTERNAL_POINTERS struct ExternalPointerT : Uint32T { static constexpr MachineType kMachineType = MachineType::Uint32(); }; #else struct ExternalPointerT : UntaggedT { static constexpr MachineType kMachineType = MachineType::Pointer(); }; #endif struct Float32T : UntaggedT { static const MachineRepresentation kMachineRepresentation = MachineRepresentation::kFloat32; static constexpr MachineType kMachineType = MachineType::Float32(); }; struct Float64T : UntaggedT { static const MachineRepresentation kMachineRepresentation = MachineRepresentation::kFloat64; static constexpr MachineType kMachineType = MachineType::Float64(); }; #ifdef V8_COMPRESS_POINTERS using TaggedT = Int32T; #else using TaggedT = IntPtrT; #endif // Result of a comparison operation. struct BoolT : Word32T {}; // Value type of a Turbofan node with two results. template struct PairT {}; struct Simd128T : UntaggedT { static const MachineRepresentation kMachineRepresentation = MachineRepresentation::kSimd128; static constexpr MachineType kMachineType = MachineType::Simd128(); }; struct I8x16T : Simd128T {}; struct I16x8T : Simd128T {}; struct I32x2T : Simd128T {}; inline constexpr MachineType CommonMachineType(MachineType type1, MachineType type2) { return (type1 == type2) ? type1 : ((type1.IsTagged() && type2.IsTagged()) ? MachineType::AnyTagged() : MachineType::None()); } template struct MachineTypeOf { static constexpr MachineType value = Type::kMachineType; }; template constexpr MachineType MachineTypeOf::value; template <> struct MachineTypeOf { static constexpr MachineType value = MachineType::AnyTagged(); }; template <> struct MachineTypeOf { static constexpr MachineType value = MachineType::AnyTagged(); }; template <> struct MachineTypeOf { static constexpr MachineType value = MachineType::TaggedSigned(); }; template <> struct MachineTypeOf { static constexpr MachineType value = MachineType::Pointer(); }; template struct MachineTypeOf::value>::type> { static constexpr MachineType value = MachineType::TaggedPointer(); }; template <> struct MachineTypeOf { static constexpr MachineType value = MachineType::Pointer(); }; template constexpr MachineType MachineTypeOf< HeapObjectSubtype, typename std::enable_if::value>::type>::value; template struct MachineRepresentationOf { static const MachineRepresentation value = Type::kMachineRepresentation; }; // If T defines kMachineType, then we take the machine representation from // there. template struct MachineRepresentationOf> { static const MachineRepresentation value = T::kMachineType.representation(); }; template struct MachineRepresentationOf< T, typename std::enable_if::value>::type> { static const MachineRepresentation value = MachineTypeOf::value.representation(); }; template struct MachineRepresentationOf< T, typename std::enable_if::value>::type> { static const MachineRepresentation value = MachineTypeOf::value.representation(); }; template <> struct MachineRepresentationOf { static const MachineRepresentation value = RawPtrT::kMachineRepresentation; }; template constexpr bool IsMachineRepresentationOf(MachineRepresentation r) { return MachineRepresentationOf::value == r; } template constexpr MachineRepresentation PhiMachineRepresentationOf = std::is_base_of::value ? MachineRepresentation::kWord32 : MachineRepresentationOf::value; template struct is_valid_type_tag { static const bool value = std::is_base_of::value || std::is_base_of::value || std::is_base_of::value || std::is_same::value; static const bool is_tagged = std::is_base_of::value || std::is_base_of::value; }; template struct is_valid_type_tag> { static const bool value = is_valid_type_tag::value && is_valid_type_tag::value; static const bool is_tagged = false; }; template struct UnionT; template struct is_valid_type_tag> { static const bool is_tagged = is_valid_type_tag::is_tagged && is_valid_type_tag::is_tagged; static const bool value = is_tagged; }; template struct UnionT { static constexpr MachineType kMachineType = CommonMachineType(MachineTypeOf::value, MachineTypeOf::value); static const MachineRepresentation kMachineRepresentation = kMachineType.representation(); static_assert(kMachineRepresentation != MachineRepresentation::kNone, "no common representation"); static_assert(is_valid_type_tag::is_tagged && is_valid_type_tag::is_tagged, "union types are only possible for tagged values"); }; using AnyTaggedT = UnionT; using Number = UnionT; using Numeric = UnionT; using ContextOrEmptyContext = UnionT; // A pointer to a builtin function, used by Torque's function pointers. using BuiltinPtr = Smi; template struct is_subtype { static const bool value = std::disjunction, std::conjunction, std::is_convertible>>::value; }; template struct is_subtype, U> { static const bool value = is_subtype::value && is_subtype::value; }; template struct is_subtype> { static const bool value = is_subtype::value || is_subtype::value; }; template struct is_subtype, UnionT> { static const bool value = (is_subtype::value || is_subtype::value) && (is_subtype::value || is_subtype::value); }; template <> struct is_subtype { static const bool value = true; }; template struct types_have_common_values { static const bool value = is_subtype::value || is_subtype::value; }; template struct types_have_common_values { static const bool value = types_have_common_values::value; }; template struct types_have_common_values { static const bool value = types_have_common_values::value; }; template struct types_have_common_values { static const bool value = types_have_common_values::value; }; template struct types_have_common_values { static const bool value = types_have_common_values::value; }; template struct types_have_common_values { static const bool value = types_have_common_values::value; }; template struct types_have_common_values { static const bool value = types_have_common_values::value; }; template struct types_have_common_values { static const bool value = types_have_common_values::value; }; template struct types_have_common_values, U> { static const bool value = types_have_common_values::value || types_have_common_values::value; }; template struct types_have_common_values> { static const bool value = types_have_common_values::value || types_have_common_values::value; }; template struct types_have_common_values, UnionT> { static const bool value = types_have_common_values::value || types_have_common_values::value || types_have_common_values::value || types_have_common_values::value; }; // TNode is an SSA value with the static type tag T, which is one of the // following: // - MaybeObject represents the type of all tagged values, including weak // pointers. // - a subclass of internal::Object represents a non-weak tagged type. // - a subclass of internal::UntaggedT represents an untagged type // - ExternalReference // - PairT for an operation returning two values, with types T1 // and T2 // - UnionT represents either a value of type T1 or of type T2. template class TNode { public: template ::value, int>::type = 0> TNode(const TNode& other) : node_(other) { LazyTemplateChecks(); } TNode(const TNode& other) : node_(other) { LazyTemplateChecks(); } TNode() : TNode(nullptr) {} TNode operator=(TNode other) { DCHECK_NOT_NULL(other.node_); node_ = other.node_; return *this; } operator compiler::Node*() const { return node_; } static TNode UncheckedCast(compiler::Node* node) { return TNode(node); } private: explicit TNode(compiler::Node* node) : node_(node) { LazyTemplateChecks(); } // These checks shouldn't be checked before TNode is actually used. void LazyTemplateChecks() { static_assert(is_valid_type_tag::value, "invalid type tag"); } compiler::Node* node_; }; } // namespace internal } // namespace v8 #endif // V8_CODEGEN_TNODE_H_