diff --git a/docs/LangRef.rst b/docs/LangRef.rst index 9adbea5e9ee..7f719cb375a 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -4,7 +4,7 @@ LLVM Language Reference Manual .. contents:: :local: - :depth: 3 + :depth: 4 Abstract ======== @@ -1476,80 +1476,94 @@ transformation. A strong type system makes it easier to read the generated code and enables novel analyses and transformations that are not feasible to perform on normal three address code representations. -.. _typeclassifications: +.. _t_void: -Type Classifications --------------------- +Void Type +--------- -The types fall into a few useful classifications: +Overview: +^^^^^^^^^ + +The void type does not represent any value and has no size. + +Syntax: +^^^^^^^ + +:: + + void -.. list-table:: - :header-rows: 1 +.. _t_function: - * - Classification - - Types +Function Type +------------- - * - :ref:`integer ` - - ``i1``, ``i2``, ``i3``, ... ``i8``, ... ``i16``, ... ``i32``, ... - ``i64``, ... +Overview: +^^^^^^^^^ - * - :ref:`floating point ` - - ``half``, ``float``, ``double``, ``x86_fp80``, ``fp128``, - ``ppc_fp128`` +The function type can be thought of as a function signature. It consists of a +return type and a list of formal parameter types. The return type of a function +type is a void type or first class type --- except for :ref:`label ` +and :ref:`metadata ` types. +Syntax: +^^^^^^^ - * - first class +:: - .. _t_firstclass: + () - - :ref:`integer `, :ref:`floating point `, - :ref:`pointer `, :ref:`vector `, - :ref:`structure `, :ref:`array `, - :ref:`label `, :ref:`metadata `. +...where '````' is a comma-separated list of type +specifiers. Optionally, the parameter list may include a type ``...``, which +indicates that the function takes a variable number of arguments. Variable +argument functions can access their arguments with the :ref:`variable argument +handling intrinsic ` functions. '````' is any type +except :ref:`label ` and :ref:`metadata `. - * - :ref:`primitive ` - - :ref:`label `, - :ref:`void `, - :ref:`integer `, - :ref:`floating point `, - :ref:`x86mmx `, - :ref:`metadata `. +Examples: +^^^^^^^^^ - * - :ref:`derived ` - - :ref:`array `, - :ref:`function `, - :ref:`pointer `, - :ref:`structure `, - :ref:`vector `, - :ref:`opaque `. ++---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``i32 (i32)`` | function taking an ``i32``, returning an ``i32`` | ++---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``float (i16, i32 *) *`` | :ref:`Pointer ` to a function that takes an ``i16`` and a :ref:`pointer ` to ``i32``, returning ``float``. | ++---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``i32 (i8*, ...)`` | A vararg function that takes at least one :ref:`pointer ` to ``i8`` (char in C), which returns an integer. This is the signature for ``printf`` in LLVM. | ++---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``{i32, i32} (i32)`` | A function taking an ``i32``, returning a :ref:`structure ` containing two ``i32`` values | ++---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +.. _t_firstclass: + +First Class Types +----------------- The :ref:`first class ` types are perhaps the most important. Values of these types are the only ones which can be produced by instructions. -.. _t_primitive: +.. _t_single_value: -Primitive Types ---------------- +Single Value Types +^^^^^^^^^^^^^^^^^^ -The primitive types are the fundamental building blocks of the LLVM -system. +These are the types that are valid in registers from CodeGen's perspective. .. _t_integer: Integer Type -^^^^^^^^^^^^ +"""""""""""" Overview: -""""""""" +********* The integer type is a very simple type that simply specifies an arbitrary bit width for the integer type desired. Any bit width from 1 bit to 2\ :sup:`23`\ -1 (about 8 million) can be specified. Syntax: -""""""" +******* :: @@ -1559,7 +1573,7 @@ The number of bits the integer will occupy is specified by the ``N`` value. Examples: -""""""""" +********* +----------------+------------------------------------------------+ | ``i1`` | a single-bit integer. | @@ -1572,7 +1586,7 @@ Examples: .. _t_floating: Floating Point Types -^^^^^^^^^^^^^^^^^^^^ +"""""""""""""""""""" .. list-table:: :header-rows: 1 @@ -1601,10 +1615,10 @@ Floating Point Types .. _t_x86mmx: X86mmx Type -^^^^^^^^^^^ +""""""""""" Overview: -""""""""" +********* The x86mmx type represents a value held in an MMX register on an x86 machine. The operations allowed on it are quite limited: parameters and @@ -1614,28 +1628,87 @@ and/or results of this type. There are no arrays, vectors or constants of this type. Syntax: -""""""" +******* :: x86mmx -.. _t_void: -Void Type -^^^^^^^^^ +.. _t_pointer: + +Pointer Type +"""""""""""" Overview: -""""""""" +********* -The void type does not represent any value and has no size. +The pointer type is used to specify memory locations. Pointers are +commonly used to reference objects in memory. + +Pointer types may have an optional address space attribute defining the +numbered address space where the pointed-to object resides. The default +address space is number zero. The semantics of non-zero address spaces +are target-specific. + +Note that LLVM does not permit pointers to void (``void*``) nor does it +permit pointers to labels (``label*``). Use ``i8*`` instead. Syntax: -""""""" +******* :: - void + * + +Examples: +********* + ++-------------------------+--------------------------------------------------------------------------------------------------------------+ +| ``[4 x i32]*`` | A :ref:`pointer ` to :ref:`array ` of four ``i32`` values. | ++-------------------------+--------------------------------------------------------------------------------------------------------------+ +| ``i32 (i32*) *`` | A :ref:`pointer ` to a :ref:`function ` that takes an ``i32*``, returning an ``i32``. | ++-------------------------+--------------------------------------------------------------------------------------------------------------+ +| ``i32 addrspace(5)*`` | A :ref:`pointer ` to an ``i32`` value that resides in address space #5. | ++-------------------------+--------------------------------------------------------------------------------------------------------------+ + +.. _t_vector: + +Vector Type +""""""""""" + +Overview: +********* + +A vector type is a simple derived type that represents a vector of +elements. Vector types are used when multiple primitive data are +operated in parallel using a single instruction (SIMD). A vector type +requires a size (number of elements) and an underlying primitive data +type. Vector types are considered :ref:`first class `. + +Syntax: +******* + +:: + + < <# elements> x > + +The number of elements is a constant integer value larger than 0; +elementtype may be any integer or floating point type, or a pointer to +these types. Vectors of size zero are not allowed. + +Examples: +********* + ++-------------------+--------------------------------------------------+ +| ``<4 x i32>`` | Vector of 4 32-bit integer values. | ++-------------------+--------------------------------------------------+ +| ``<8 x float>`` | Vector of 8 32-bit floating-point values. | ++-------------------+--------------------------------------------------+ +| ``<2 x i64>`` | Vector of 2 64-bit integer values. | ++-------------------+--------------------------------------------------+ +| ``<4 x i64*>`` | Vector of 4 pointers to 64-bit integer values. | ++-------------------+--------------------------------------------------+ .. _t_label: @@ -1672,18 +1745,6 @@ Syntax: metadata -.. _t_derived: - -Derived Types -------------- - -The real power in LLVM comes from the derived types in the system. This -is what allows a programmer to represent arrays, functions, pointers, -and other useful types. Each of these types contain one or more element -types which may be a primitive type, or another derived type. For -example, it is possible to have a two dimensional array, using an array -as the element type of another array. - .. _t_aggregate: Aggregate Types @@ -1697,17 +1758,17 @@ aggregate types. .. _t_array: Array Type -^^^^^^^^^^ +"""""""""" Overview: -""""""""" +********* The array type is a very simple derived type that arranges elements sequentially in memory. The array type requires a size (number of elements) and an underlying data type. Syntax: -""""""" +******* :: @@ -1717,7 +1778,7 @@ The number of elements is a constant integer value; ``elementtype`` may be any type with a size. Examples: -""""""""" +********* +------------------+--------------------------------------+ | ``[40 x i32]`` | Array of 40 32-bit integer values. | @@ -1745,53 +1806,13 @@ LLVM with a zero length array type. An implementation of 'pascal style arrays' in LLVM could use the type "``{ i32, [0 x float]}``", for example. -.. _t_function: - -Function Type -^^^^^^^^^^^^^ - -Overview: -""""""""" - -The function type can be thought of as a function signature. It consists of a -return type and a list of formal parameter types. The return type of a function -type is a void type or first class type --- except for :ref:`label ` -and :ref:`metadata ` types. - -Syntax: -""""""" - -:: - - () - -...where '````' is a comma-separated list of type -specifiers. Optionally, the parameter list may include a type ``...``, which -indicates that the function takes a variable number of arguments. Variable -argument functions can access their arguments with the :ref:`variable argument -handling intrinsic ` functions. '````' is any type -except :ref:`label ` and :ref:`metadata `. - -Examples: -""""""""" - -+---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``i32 (i32)`` | function taking an ``i32``, returning an ``i32`` | -+---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``float (i16, i32 *) *`` | :ref:`Pointer ` to a function that takes an ``i16`` and a :ref:`pointer ` to ``i32``, returning ``float``. | -+---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``i32 (i8*, ...)`` | A vararg function that takes at least one :ref:`pointer ` to ``i8`` (char in C), which returns an integer. This is the signature for ``printf`` in LLVM. | -+---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``{i32, i32} (i32)`` | A function taking an ``i32``, returning a :ref:`structure ` containing two ``i32`` values | -+---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - .. _t_struct: Structure Type -^^^^^^^^^^^^^^ +"""""""""""""" Overview: -""""""""" +********* The structure type is used to represent a collection of data members together in memory. The elements of a structure may be any type that has @@ -1816,7 +1837,7 @@ or opaque since there is no way to write one. Identified types can be recursive, can be opaqued, and are never uniqued. Syntax: -""""""" +******* :: @@ -1824,7 +1845,7 @@ Syntax: %T2 = type <{ }> ; Identified packed struct type Examples: -""""""""" +********* +------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``{ i32, i32, i32 }`` | A triple of three ``i32`` values | @@ -1837,17 +1858,17 @@ Examples: .. _t_opaque: Opaque Structure Types -^^^^^^^^^^^^^^^^^^^^^^ +"""""""""""""""""""""" Overview: -""""""""" +********* Opaque structure types are used to represent named structure types that do not have a body specified. This corresponds (for example) to the C notion of a forward declared structure. Syntax: -""""""" +******* :: @@ -1855,87 +1876,12 @@ Syntax: %52 = type opaque Examples: -""""""""" +********* +--------------+-------------------+ | ``opaque`` | An opaque type. | +--------------+-------------------+ -.. _t_pointer: - -Pointer Type -^^^^^^^^^^^^ - -Overview: -""""""""" - -The pointer type is used to specify memory locations. Pointers are -commonly used to reference objects in memory. - -Pointer types may have an optional address space attribute defining the -numbered address space where the pointed-to object resides. The default -address space is number zero. The semantics of non-zero address spaces -are target-specific. - -Note that LLVM does not permit pointers to void (``void*``) nor does it -permit pointers to labels (``label*``). Use ``i8*`` instead. - -Syntax: -""""""" - -:: - - * - -Examples: -""""""""" - -+-------------------------+--------------------------------------------------------------------------------------------------------------+ -| ``[4 x i32]*`` | A :ref:`pointer ` to :ref:`array ` of four ``i32`` values. | -+-------------------------+--------------------------------------------------------------------------------------------------------------+ -| ``i32 (i32*) *`` | A :ref:`pointer ` to a :ref:`function ` that takes an ``i32*``, returning an ``i32``. | -+-------------------------+--------------------------------------------------------------------------------------------------------------+ -| ``i32 addrspace(5)*`` | A :ref:`pointer ` to an ``i32`` value that resides in address space #5. | -+-------------------------+--------------------------------------------------------------------------------------------------------------+ - -.. _t_vector: - -Vector Type -^^^^^^^^^^^ - -Overview: -""""""""" - -A vector type is a simple derived type that represents a vector of -elements. Vector types are used when multiple primitive data are -operated in parallel using a single instruction (SIMD). A vector type -requires a size (number of elements) and an underlying primitive data -type. Vector types are considered :ref:`first class `. - -Syntax: -""""""" - -:: - - < <# elements> x > - -The number of elements is a constant integer value larger than 0; -elementtype may be any integer or floating point type, or a pointer to -these types. Vectors of size zero are not allowed. - -Examples: -""""""""" - -+-------------------+--------------------------------------------------+ -| ``<4 x i32>`` | Vector of 4 32-bit integer values. | -+-------------------+--------------------------------------------------+ -| ``<8 x float>`` | Vector of 8 32-bit floating-point values. | -+-------------------+--------------------------------------------------+ -| ``<2 x i64>`` | Vector of 2 64-bit integer values. | -+-------------------+--------------------------------------------------+ -| ``<4 x i64*>`` | Vector of 4 pointers to 64-bit integer values. | -+-------------------+--------------------------------------------------+ - Constants ========= diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h index 730c4fe30ad..5773b6717c3 100644 --- a/include/llvm/IR/Type.h +++ b/include/llvm/IR/Type.h @@ -71,10 +71,7 @@ public: StructTyID, ///< 12: Structures ArrayTyID, ///< 13: Arrays PointerTyID, ///< 14: Pointers - VectorTyID, ///< 15: SIMD 'packed' format, or other vector type - - LastPrimitiveTyID = X86_MMXTyID, - FirstDerivedTyID = IntegerTyID + VectorTyID ///< 15: SIMD 'packed' format, or other vector type }; private: @@ -239,12 +236,6 @@ public: /// elements or all its elements are empty. bool isEmptyTy() const; - /// Here are some useful little methods to query what type derived types are - /// Note that all other types can just compare to see if this == Type::xxxTy; - /// - bool isPrimitiveType() const { return getTypeID() <= LastPrimitiveTyID; } - bool isDerivedType() const { return getTypeID() >= FirstDerivedTyID; } - /// isFirstClassType - Return true if the type is "first class", meaning it /// is a valid type for a Value. /// @@ -257,9 +248,8 @@ public: /// and array types. /// bool isSingleValueType() const { - return (getTypeID() != VoidTyID && isPrimitiveType()) || - getTypeID() == IntegerTyID || getTypeID() == PointerTyID || - getTypeID() == VectorTyID; + return isFloatingPointTy() || isX86_MMXTy() || isIntegerTy() || + isPointerTy() || isVectorTy(); } /// isAggregateType - Return true if the type is an aggregate type. This diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index ddc7a66c9f3..07a9db35a1f 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -361,25 +361,25 @@ void CppWriter::printEscapedString(const std::string &Str) { } std::string CppWriter::getCppName(Type* Ty) { - // First, handle the primitive types .. easy - if (Ty->isPrimitiveType() || Ty->isIntegerTy()) { - switch (Ty->getTypeID()) { - case Type::VoidTyID: return "Type::getVoidTy(mod->getContext())"; - case Type::IntegerTyID: { - unsigned BitWidth = cast(Ty)->getBitWidth(); - return "IntegerType::get(mod->getContext(), " + utostr(BitWidth) + ")"; - } - case Type::X86_FP80TyID: return "Type::getX86_FP80Ty(mod->getContext())"; - case Type::FloatTyID: return "Type::getFloatTy(mod->getContext())"; - case Type::DoubleTyID: return "Type::getDoubleTy(mod->getContext())"; - case Type::LabelTyID: return "Type::getLabelTy(mod->getContext())"; - case Type::X86_MMXTyID: return "Type::getX86_MMXTy(mod->getContext())"; - default: - error("Invalid primitive type"); - break; - } - // shouldn't be returned, but make it sensible + switch (Ty->getTypeID()) { + default: + break; + case Type::VoidTyID: return "Type::getVoidTy(mod->getContext())"; + case Type::IntegerTyID: { + unsigned BitWidth = cast(Ty)->getBitWidth(); + return "IntegerType::get(mod->getContext(), " + utostr(BitWidth) + ")"; + } + case Type::X86_FP80TyID: + return "Type::getX86_FP80Ty(mod->getContext())"; + case Type::FloatTyID: + return "Type::getFloatTy(mod->getContext())"; + case Type::DoubleTyID: + return "Type::getDoubleTy(mod->getContext())"; + case Type::LabelTyID: + return "Type::getLabelTy(mod->getContext())"; + case Type::X86_MMXTyID: + return "Type::getX86_MMXTy(mod->getContext())"; } // Now, see if we've seen the type before and return that @@ -537,7 +537,8 @@ void CppWriter::printAttributes(const AttributeSet &PAL, void CppWriter::printType(Type* Ty) { // We don't print definitions for primitive types - if (Ty->isPrimitiveType() || Ty->isIntegerTy()) + if (Ty->isFloatingPointTy() || Ty->isX86_MMXTy() || Ty->isIntegerTy() || + Ty->isLabelTy() || Ty->isMetadataTy() || Ty->isVoidTy()) return; // If we already defined this type, we don't need to define it again. diff --git a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp index cd4f6981476..a2cf245c30c 100644 --- a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -430,7 +430,7 @@ void NVPTXAsmPrinter::printReturnValStr(const Function *F, raw_ostream &O) { O << " ("; if (isABI) { - if (Ty->isPrimitiveType() || Ty->isIntegerTy()) { + if (Ty->isFloatingPointTy() || Ty->isIntegerTy()) { unsigned size = 0; if (const IntegerType *ITy = dyn_cast(Ty)) { size = ITy->getBitWidth(); @@ -1207,7 +1207,7 @@ void NVPTXAsmPrinter::printModuleLevelGV(const GlobalVariable *GVar, else O << " .align " << GVar->getAlignment(); - if (ETy->isPrimitiveType() || ETy->isIntegerTy() || isa(ETy)) { + if (ETy->isSingleValueType()) { O << " ."; // Special case: ABI requires that we use .u8 for predicates if (ETy->isIntegerTy(1)) @@ -1378,7 +1378,7 @@ void NVPTXAsmPrinter::emitPTXGlobalVariable(const GlobalVariable *GVar, else O << " .align " << GVar->getAlignment(); - if (ETy->isPrimitiveType() || ETy->isIntegerTy() || isa(ETy)) { + if (ETy->isSingleValueType()) { O << " ."; O << getPTXFundamentalTypeStr(ETy); O << " "; @@ -1410,7 +1410,7 @@ void NVPTXAsmPrinter::emitPTXGlobalVariable(const GlobalVariable *GVar, } static unsigned int getOpenCLAlignment(const DataLayout *TD, Type *Ty) { - if (Ty->isPrimitiveType() || Ty->isIntegerTy() || isa(Ty)) + if (Ty->isSingleValueType()) return TD->getPrefTypeAlignment(Ty); const ArrayType *ATy = dyn_cast(Ty); diff --git a/lib/Target/NVPTX/NVPTXISelLowering.cpp b/lib/Target/NVPTX/NVPTXISelLowering.cpp index 6a8be753c87..d8151761e05 100644 --- a/lib/Target/NVPTX/NVPTXISelLowering.cpp +++ b/lib/Target/NVPTX/NVPTXISelLowering.cpp @@ -361,7 +361,7 @@ NVPTXTargetLowering::getPrototype(Type *retTy, const ArgListTy &Args, O << "()"; } else { O << "("; - if (retTy->isPrimitiveType() || retTy->isIntegerTy()) { + if (retTy->isFloatingPointTy() || retTy->isIntegerTy()) { unsigned size = 0; if (const IntegerType *ITy = dyn_cast(retTy)) { size = ITy->getBitWidth(); @@ -856,8 +856,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // .param .align 16 .b8 retval0[], or // .param .b retval0 unsigned resultsz = TD->getTypeAllocSizeInBits(retTy); - if (retTy->isPrimitiveType() || retTy->isIntegerTy() || - retTy->isPointerTy()) { + if (retTy->isSingleValueType()) { // Scalar needs to be at least 32bit wide if (resultsz < 32) resultsz = 32;