Intrinsics.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- Intrinsics.h - LLVM Intrinsic Function Handling ----------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines a set of enums which allow processing of intrinsic
  15. // functions. Values of these enum types are returned by
  16. // Function::getIntrinsicID.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_IR_INTRINSICS_H
  20. #define LLVM_IR_INTRINSICS_H
  21. #include "llvm/ADT/ArrayRef.h"
  22. #include "llvm/Support/TypeSize.h"
  23. #include <optional>
  24. #include <string>
  25. namespace llvm {
  26. class Type;
  27. class FunctionType;
  28. class Function;
  29. class LLVMContext;
  30. class Module;
  31. class AttributeList;
  32. /// This namespace contains an enum with a value for every intrinsic/builtin
  33. /// function known by LLVM. The enum values are returned by
  34. /// Function::getIntrinsicID().
  35. namespace Intrinsic {
  36. // Abstraction for the arguments of the noalias intrinsics
  37. static const int NoAliasScopeDeclScopeArg = 0;
  38. // Intrinsic ID type. This is an opaque typedef to facilitate splitting up
  39. // the enum into target-specific enums.
  40. typedef unsigned ID;
  41. enum IndependentIntrinsics : unsigned {
  42. not_intrinsic = 0, // Must be zero
  43. // Get the intrinsic enums generated from Intrinsics.td
  44. #define GET_INTRINSIC_ENUM_VALUES
  45. #include "llvm/IR/IntrinsicEnums.inc"
  46. #undef GET_INTRINSIC_ENUM_VALUES
  47. };
  48. /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
  49. /// Note, this version is for intrinsics with no overloads. Use the other
  50. /// version of getName if overloads are required.
  51. StringRef getName(ID id);
  52. /// Return the LLVM name for an intrinsic, without encoded types for
  53. /// overloading, such as "llvm.ssa.copy".
  54. StringRef getBaseName(ID id);
  55. /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx" or
  56. /// "llvm.ssa.copy.p0s_s.1". Note, this version of getName supports overloads.
  57. /// This is less efficient than the StringRef version of this function. If no
  58. /// overloads are required, it is safe to use this version, but better to use
  59. /// the StringRef version. If one of the types is based on an unnamed type, a
  60. /// function type will be computed. Providing FT will avoid this computation.
  61. std::string getName(ID Id, ArrayRef<Type *> Tys, Module *M,
  62. FunctionType *FT = nullptr);
  63. /// Return the LLVM name for an intrinsic. This is a special version only to
  64. /// be used by LLVMIntrinsicCopyOverloadedName. It only supports overloads
  65. /// based on named types.
  66. std::string getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys);
  67. /// Return the function type for an intrinsic.
  68. FunctionType *getType(LLVMContext &Context, ID id,
  69. ArrayRef<Type *> Tys = std::nullopt);
  70. /// Returns true if the intrinsic can be overloaded.
  71. bool isOverloaded(ID id);
  72. /// Return the attributes for an intrinsic.
  73. AttributeList getAttributes(LLVMContext &C, ID id);
  74. /// Create or insert an LLVM Function declaration for an intrinsic, and return
  75. /// it.
  76. ///
  77. /// The Tys parameter is for intrinsics with overloaded types (e.g., those
  78. /// using iAny, fAny, vAny, or iPTRAny). For a declaration of an overloaded
  79. /// intrinsic, Tys must provide exactly one type for each overloaded type in
  80. /// the intrinsic.
  81. Function *getDeclaration(Module *M, ID id,
  82. ArrayRef<Type *> Tys = std::nullopt);
  83. /// Looks up Name in NameTable via binary search. NameTable must be sorted
  84. /// and all entries must start with "llvm.". If NameTable contains an exact
  85. /// match for Name or a prefix of Name followed by a dot, its index in
  86. /// NameTable is returned. Otherwise, -1 is returned.
  87. int lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
  88. StringRef Name);
  89. /// Map a Clang builtin name to an intrinsic ID.
  90. ID getIntrinsicForClangBuiltin(const char *Prefix, StringRef BuiltinName);
  91. /// Map a MS builtin name to an intrinsic ID.
  92. ID getIntrinsicForMSBuiltin(const char *Prefix, StringRef BuiltinName);
  93. /// This is a type descriptor which explains the type requirements of an
  94. /// intrinsic. This is returned by getIntrinsicInfoTableEntries.
  95. struct IITDescriptor {
  96. enum IITDescriptorKind {
  97. Void,
  98. VarArg,
  99. MMX,
  100. Token,
  101. Metadata,
  102. Half,
  103. BFloat,
  104. Float,
  105. Double,
  106. Quad,
  107. Integer,
  108. Vector,
  109. Pointer,
  110. Struct,
  111. Argument,
  112. ExtendArgument,
  113. TruncArgument,
  114. HalfVecArgument,
  115. SameVecWidthArgument,
  116. PtrToArgument,
  117. PtrToElt,
  118. VecOfAnyPtrsToElt,
  119. VecElementArgument,
  120. Subdivide2Argument,
  121. Subdivide4Argument,
  122. VecOfBitcastsToInt,
  123. AMX,
  124. PPCQuad,
  125. AnyPtrToElt,
  126. } Kind;
  127. union {
  128. unsigned Integer_Width;
  129. unsigned Float_Width;
  130. unsigned Pointer_AddressSpace;
  131. unsigned Struct_NumElements;
  132. unsigned Argument_Info;
  133. ElementCount Vector_Width;
  134. };
  135. enum ArgKind {
  136. AK_Any,
  137. AK_AnyInteger,
  138. AK_AnyFloat,
  139. AK_AnyVector,
  140. AK_AnyPointer,
  141. AK_MatchType = 7
  142. };
  143. unsigned getArgumentNumber() const {
  144. assert(Kind == Argument || Kind == ExtendArgument ||
  145. Kind == TruncArgument || Kind == HalfVecArgument ||
  146. Kind == SameVecWidthArgument || Kind == PtrToArgument ||
  147. Kind == PtrToElt || Kind == VecElementArgument ||
  148. Kind == Subdivide2Argument || Kind == Subdivide4Argument ||
  149. Kind == VecOfBitcastsToInt);
  150. return Argument_Info >> 3;
  151. }
  152. ArgKind getArgumentKind() const {
  153. assert(Kind == Argument || Kind == ExtendArgument ||
  154. Kind == TruncArgument || Kind == HalfVecArgument ||
  155. Kind == SameVecWidthArgument || Kind == PtrToArgument ||
  156. Kind == VecElementArgument || Kind == Subdivide2Argument ||
  157. Kind == Subdivide4Argument || Kind == VecOfBitcastsToInt);
  158. return (ArgKind)(Argument_Info & 7);
  159. }
  160. // VecOfAnyPtrsToElt and AnyPtrToElt uses both an overloaded argument (for
  161. // address space) and a reference argument (for matching vector width and
  162. // element types)
  163. unsigned getOverloadArgNumber() const {
  164. assert(Kind == VecOfAnyPtrsToElt || Kind == AnyPtrToElt);
  165. return Argument_Info >> 16;
  166. }
  167. unsigned getRefArgNumber() const {
  168. assert(Kind == VecOfAnyPtrsToElt || Kind == AnyPtrToElt);
  169. return Argument_Info & 0xFFFF;
  170. }
  171. static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
  172. IITDescriptor Result = { K, { Field } };
  173. return Result;
  174. }
  175. static IITDescriptor get(IITDescriptorKind K, unsigned short Hi,
  176. unsigned short Lo) {
  177. unsigned Field = Hi << 16 | Lo;
  178. IITDescriptor Result = {K, {Field}};
  179. return Result;
  180. }
  181. static IITDescriptor getVector(unsigned Width, bool IsScalable) {
  182. IITDescriptor Result = {Vector, {0}};
  183. Result.Vector_Width = ElementCount::get(Width, IsScalable);
  184. return Result;
  185. }
  186. };
  187. /// Return the IIT table descriptor for the specified intrinsic into an array
  188. /// of IITDescriptors.
  189. void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T);
  190. enum MatchIntrinsicTypesResult {
  191. MatchIntrinsicTypes_Match = 0,
  192. MatchIntrinsicTypes_NoMatchRet = 1,
  193. MatchIntrinsicTypes_NoMatchArg = 2,
  194. };
  195. /// Match the specified function type with the type constraints specified by
  196. /// the .td file. If the given type is an overloaded type it is pushed to the
  197. /// ArgTys vector.
  198. ///
  199. /// Returns false if the given type matches with the constraints, true
  200. /// otherwise.
  201. MatchIntrinsicTypesResult
  202. matchIntrinsicSignature(FunctionType *FTy, ArrayRef<IITDescriptor> &Infos,
  203. SmallVectorImpl<Type *> &ArgTys);
  204. /// Verify if the intrinsic has variable arguments. This method is intended to
  205. /// be called after all the fixed arguments have been matched first.
  206. ///
  207. /// This method returns true on error.
  208. bool matchIntrinsicVarArg(bool isVarArg, ArrayRef<IITDescriptor> &Infos);
  209. /// Gets the type arguments of an intrinsic call by matching type contraints
  210. /// specified by the .td file. The overloaded types are pushed into the
  211. /// AgTys vector.
  212. ///
  213. /// Returns false if the given function is not a valid intrinsic call.
  214. bool getIntrinsicSignature(Function *F, SmallVectorImpl<Type *> &ArgTys);
  215. // Checks if the intrinsic name matches with its signature and if not
  216. // returns the declaration with the same signature and remangled name.
  217. // An existing GlobalValue with the wanted name but with a wrong prototype
  218. // or of the wrong kind will be renamed by adding ".renamed" to the name.
  219. std::optional<Function *> remangleIntrinsicFunction(Function *F);
  220. } // End Intrinsic namespace
  221. } // End llvm namespace
  222. #endif
  223. #ifdef __GNUC__
  224. #pragma GCC diagnostic pop
  225. #endif