Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 1 | //===- Intrinsics.h - LLVM Intrinsic Function Handling ----------*- C++ -*-===// |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 2 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // This file defines a set of enums which allow processing of intrinsic |
| 10 | // functions. Values of these enum types are returned by |
| 11 | // Function::getIntrinsicID. |
| 12 | // |
| 13 | //===----------------------------------------------------------------------===// |
| 14 | |
| 15 | #ifndef LLVM_IR_INTRINSICS_H |
| 16 | #define LLVM_IR_INTRINSICS_H |
| 17 | |
| 18 | #include "llvm/ADT/ArrayRef.h" |
| 19 | #include "llvm/ADT/None.h" |
| 20 | #include "llvm/ADT/Optional.h" |
| 21 | #include <string> |
| 22 | |
| 23 | namespace llvm { |
| 24 | |
| 25 | class Type; |
| 26 | class FunctionType; |
| 27 | class Function; |
| 28 | class LLVMContext; |
| 29 | class Module; |
| 30 | class AttributeList; |
| 31 | |
| 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 | enum ID : unsigned { |
| 37 | not_intrinsic = 0, // Must be zero |
| 38 | |
| 39 | // Get the intrinsic enums generated from Intrinsics.td |
| 40 | #define GET_INTRINSIC_ENUM_VALUES |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 41 | #include "llvm/IR/IntrinsicEnums.inc" |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 42 | #undef GET_INTRINSIC_ENUM_VALUES |
| 43 | , num_intrinsics |
| 44 | }; |
| 45 | |
| 46 | /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx". |
| 47 | /// Note, this version is for intrinsics with no overloads. Use the other |
| 48 | /// version of getName if overloads are required. |
| 49 | StringRef getName(ID id); |
| 50 | |
| 51 | /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx". |
| 52 | /// Note, this version of getName supports overloads, but is less efficient |
| 53 | /// than the StringRef version of this function. If no overloads are |
| 54 | /// requried, it is safe to use this version, but better to use the StringRef |
| 55 | /// version. |
| 56 | std::string getName(ID id, ArrayRef<Type*> Tys); |
| 57 | |
| 58 | /// Return the function type for an intrinsic. |
| 59 | FunctionType *getType(LLVMContext &Context, ID id, |
| 60 | ArrayRef<Type*> Tys = None); |
| 61 | |
| 62 | /// Returns true if the intrinsic can be overloaded. |
| 63 | bool isOverloaded(ID id); |
| 64 | |
| 65 | /// Returns true if the intrinsic is a leaf, i.e. it does not make any calls |
| 66 | /// itself. Most intrinsics are leafs, the exceptions being the patchpoint |
| 67 | /// and statepoint intrinsics. These call (or invoke) their "target" argument. |
| 68 | bool isLeaf(ID id); |
| 69 | |
| 70 | /// Return the attributes for an intrinsic. |
| 71 | AttributeList getAttributes(LLVMContext &C, ID id); |
| 72 | |
| 73 | /// Create or insert an LLVM Function declaration for an intrinsic, and return |
| 74 | /// it. |
| 75 | /// |
| 76 | /// The Tys parameter is for intrinsics with overloaded types (e.g., those |
| 77 | /// using iAny, fAny, vAny, or iPTRAny). For a declaration of an overloaded |
| 78 | /// intrinsic, Tys must provide exactly one type for each overloaded type in |
| 79 | /// the intrinsic. |
| 80 | Function *getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys = None); |
| 81 | |
| 82 | /// Looks up Name in NameTable via binary search. NameTable must be sorted |
| 83 | /// and all entries must start with "llvm.". If NameTable contains an exact |
| 84 | /// match for Name or a prefix of Name followed by a dot, its index in |
| 85 | /// NameTable is returned. Otherwise, -1 is returned. |
| 86 | int lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable, |
| 87 | StringRef Name); |
| 88 | |
| 89 | /// Map a GCC builtin name to an intrinsic ID. |
| 90 | ID getIntrinsicForGCCBuiltin(const char *Prefix, StringRef BuiltinName); |
| 91 | |
| 92 | /// Map a MS builtin name to an intrinsic ID. |
| 93 | ID getIntrinsicForMSBuiltin(const char *Prefix, StringRef BuiltinName); |
| 94 | |
| 95 | /// This is a type descriptor which explains the type requirements of an |
| 96 | /// intrinsic. This is returned by getIntrinsicInfoTableEntries. |
| 97 | struct IITDescriptor { |
| 98 | enum IITDescriptorKind { |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 99 | Void, VarArg, MMX, Token, Metadata, Half, Float, Double, Quad, |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 100 | Integer, Vector, Pointer, Struct, |
| 101 | Argument, ExtendArgument, TruncArgument, HalfVecArgument, |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame^] | 102 | SameVecWidthArgument, PtrToArgument, PtrToElt, VecOfAnyPtrsToElt, |
| 103 | VecElementArgument |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 104 | } Kind; |
| 105 | |
| 106 | union { |
| 107 | unsigned Integer_Width; |
| 108 | unsigned Float_Width; |
| 109 | unsigned Vector_Width; |
| 110 | unsigned Pointer_AddressSpace; |
| 111 | unsigned Struct_NumElements; |
| 112 | unsigned Argument_Info; |
| 113 | }; |
| 114 | |
| 115 | enum ArgKind { |
| 116 | AK_Any, |
| 117 | AK_AnyInteger, |
| 118 | AK_AnyFloat, |
| 119 | AK_AnyVector, |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame^] | 120 | AK_AnyPointer, |
| 121 | AK_MatchType = 7 |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 122 | }; |
| 123 | |
| 124 | unsigned getArgumentNumber() const { |
| 125 | assert(Kind == Argument || Kind == ExtendArgument || |
| 126 | Kind == TruncArgument || Kind == HalfVecArgument || |
| 127 | Kind == SameVecWidthArgument || Kind == PtrToArgument || |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame^] | 128 | Kind == PtrToElt || Kind == VecElementArgument); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 129 | return Argument_Info >> 3; |
| 130 | } |
| 131 | ArgKind getArgumentKind() const { |
| 132 | assert(Kind == Argument || Kind == ExtendArgument || |
| 133 | Kind == TruncArgument || Kind == HalfVecArgument || |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame^] | 134 | Kind == SameVecWidthArgument || Kind == PtrToArgument || |
| 135 | Kind == VecElementArgument); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 136 | return (ArgKind)(Argument_Info & 7); |
| 137 | } |
| 138 | |
| 139 | // VecOfAnyPtrsToElt uses both an overloaded argument (for address space) |
| 140 | // and a reference argument (for matching vector width and element types) |
| 141 | unsigned getOverloadArgNumber() const { |
| 142 | assert(Kind == VecOfAnyPtrsToElt); |
| 143 | return Argument_Info >> 16; |
| 144 | } |
| 145 | unsigned getRefArgNumber() const { |
| 146 | assert(Kind == VecOfAnyPtrsToElt); |
| 147 | return Argument_Info & 0xFFFF; |
| 148 | } |
| 149 | |
| 150 | static IITDescriptor get(IITDescriptorKind K, unsigned Field) { |
| 151 | IITDescriptor Result = { K, { Field } }; |
| 152 | return Result; |
| 153 | } |
| 154 | |
| 155 | static IITDescriptor get(IITDescriptorKind K, unsigned short Hi, |
| 156 | unsigned short Lo) { |
| 157 | unsigned Field = Hi << 16 | Lo; |
| 158 | IITDescriptor Result = {K, {Field}}; |
| 159 | return Result; |
| 160 | } |
| 161 | }; |
| 162 | |
| 163 | /// Return the IIT table descriptor for the specified intrinsic into an array |
| 164 | /// of IITDescriptors. |
| 165 | void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T); |
| 166 | |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame^] | 167 | enum MatchIntrinsicTypesResult { |
| 168 | MatchIntrinsicTypes_Match = 0, |
| 169 | MatchIntrinsicTypes_NoMatchRet = 1, |
| 170 | MatchIntrinsicTypes_NoMatchArg = 2, |
| 171 | }; |
| 172 | |
| 173 | /// Match the specified function type with the type constraints specified by |
| 174 | /// the .td file. If the given type is an overloaded type it is pushed to the |
| 175 | /// ArgTys vector. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 176 | /// |
| 177 | /// Returns false if the given type matches with the constraints, true |
| 178 | /// otherwise. |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame^] | 179 | MatchIntrinsicTypesResult |
| 180 | matchIntrinsicSignature(FunctionType *FTy, ArrayRef<IITDescriptor> &Infos, |
| 181 | SmallVectorImpl<Type *> &ArgTys); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 182 | |
| 183 | /// Verify if the intrinsic has variable arguments. This method is intended to |
| 184 | /// be called after all the fixed arguments have been matched first. |
| 185 | /// |
| 186 | /// This method returns true on error. |
| 187 | bool matchIntrinsicVarArg(bool isVarArg, ArrayRef<IITDescriptor> &Infos); |
| 188 | |
| 189 | // Checks if the intrinsic name matches with its signature and if not |
| 190 | // returns the declaration with the same signature and remangled name. |
| 191 | llvm::Optional<Function*> remangleIntrinsicFunction(Function *F); |
| 192 | |
| 193 | } // End Intrinsic namespace |
| 194 | |
| 195 | } // End llvm namespace |
| 196 | |
| 197 | #endif |