1
+ // ===- CIRIntrinsics.h - CIR Intrinsic Function Handling ----------*- C++
2
+ // -*-===//
3
+ //
4
+ // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5
+ // See https://llvm.org/LICENSE.txt for license information.
6
+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7
+ //
8
+ // ===----------------------------------------------------------------------===//
9
+ //
10
+ // This file defines a set of enums which allow processing of intrinsic
11
+ // functions. Values of these enum types are returned by
12
+ // Function::getIntrinsicID.
13
+ //
14
+ // ===----------------------------------------------------------------------===//
15
+
16
+ #ifndef LLVM_CLANG_CIR_DIALECT_INTRINSICS_H
17
+ #define LLVM_CLANG_CIR_DIALECT_INTRINSICS_H
18
+
19
+ #include " mlir/IR/BuiltinAttributes.h"
20
+ #include " mlir/IR/SymbolTable.h"
21
+ #include " clang/CIR/Dialect/IR/CIRDialect.h"
22
+ #include " llvm/ADT/ArrayRef.h"
23
+ #include " llvm/ADT/StringRef.h"
24
+ #include " llvm/IR/Intrinsics.h"
25
+ #include " llvm/Support/TypeSize.h"
26
+ #include < optional>
27
+ #include < string>
28
+ // #include "mlir/IR/Types.h"
29
+ #include " mlir/Interfaces/DataLayoutInterfaces.h"
30
+ #include " clang/CIR/Dialect/IR/CIROpsEnums.h"
31
+ #include " clang/CIR/Interfaces/ASTAttrInterfaces.h"
32
+ #include " clang/CIR/Interfaces/CIRFPTypeInterface.h"
33
+
34
+ namespace mlir {
35
+ class Type ;
36
+ class ModuleOp ;
37
+ class MLIRContext ;
38
+ } // namespace mlir
39
+
40
+ namespace llvm {
41
+ class StringRef ;
42
+
43
+ namespace Intrinsic {
44
+ struct IITDescriptor ; // No need to duplicate the definition here
45
+ } // namespace Intrinsic
46
+
47
+ } // namespace llvm
48
+ namespace cir {
49
+ class LLVMIntrinsicCallOp ;
50
+ class FuncOp ;
51
+ // FIXME: Unsure if we need a proper function type
52
+
53
+ namespace Intrinsic {
54
+
55
+ // Abstraction for the arguments of the noalias intrinsics
56
+ static const int NoAliasScopeDeclScopeArg = 0 ;
57
+
58
+ // Intrinsic ID type. This is an opaque typedef to facilitate splitting up
59
+ // the enum into target-specific enums.
60
+ typedef unsigned ID;
61
+
62
+ enum IndependentIntrinsics : unsigned {
63
+ not_intrinsic = 0 , // Must be zero
64
+
65
+ // Get the intrinsic enums generated from Intrinsics.td
66
+ #define GET_INTRINSIC_ENUM_VALUES
67
+ #include " llvm/IR/IntrinsicEnums.inc"
68
+ #undef GET_INTRINSIC_ENUM_VALUES
69
+ };
70
+
71
+ // / Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
72
+ // / Note, this version is for intrinsics with no overloads. Use the other
73
+ // / version of getName if overloads are required.
74
+ llvm::StringRef getName (ID id);
75
+
76
+ // / Return the LLVM name for an intrinsic, without encoded types for
77
+ // / overloading, such as "llvm.ssa.copy".
78
+ llvm::StringRef getBaseName (ID id);
79
+
80
+ // / Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx" or
81
+ // / "llvm.ssa.copy.p0s_s.1". Note, this version of getName supports overloads.
82
+ // / This is less efficient than the StringRef version of this function. If no
83
+ // / overloads are required, it is safe to use this version, but better to use
84
+ // / the StringRef version. If one of the types is based on an unnamed type, a
85
+ // / function type will be computed. Providing FT will avoid this computation.
86
+ std::string getName (ID Id, llvm::ArrayRef<mlir::Type> Tys, mlir::ModuleOp M,
87
+ mlir::Type FT = nullptr );
88
+
89
+ // / Return the LLVM name for an intrinsic. This is a special version only to
90
+ // / be used by LLVMIntrinsicCopyOverloadedName. It only supports overloads
91
+ // / based on named types.
92
+ std::string getNameNoUnnamedTypes (ID Id, llvm::ArrayRef<mlir::Type> Tys);
93
+
94
+ // / Return the function type for an intrinsic.
95
+ mlir::Type *getType (mlir::MLIRContext& Context, ID id,
96
+ llvm::ArrayRef<mlir::Type> Tys = {});
97
+
98
+ // / Returns true if the intrinsic can be overloaded.
99
+ bool isOverloaded (ID id);
100
+
101
+ ID lookupIntrinsicID (llvm::StringRef Name);
102
+
103
+ // FIXME: Uses table from LLVM, but we don't have it yet.
104
+ // / Return the attributes for an intrinsic.
105
+ // AttributeList getAttributes(mlir::MLIRContext &C, ID id);
106
+ // this is also defined as:
107
+ // /// This defines the "Intrinsic::getAttributes(ID id)" method.
108
+ // #define GET_INTRINSIC_ATTRIBUTES
109
+ // #include "llvm/IR/IntrinsicImpl.inc"
110
+ // #undef GET_INTRINSIC_ATTRIBUTES
111
+
112
+ // / Look up the Function declaration of the intrinsic \p id in the Module
113
+ // / \p M. If it does not exist, add a declaration and return it. Otherwise,
114
+ // / return the existing declaration.
115
+ // /
116
+ // / The \p Tys parameter is for intrinsics with overloaded types (e.g., those
117
+ // / using iAny, fAny, vAny, or pAny). For a declaration of an overloaded
118
+ // / intrinsic, Tys must provide exactly one type for each overloaded type in
119
+ // / the intrinsic.
120
+ LLVMIntrinsicCallOp getOrInsertDeclaration (mlir::ModuleOp M, ID id,
121
+ llvm::ArrayRef<mlir::Type> Tys = {});
122
+
123
+ // / Look up the Function declaration of the intrinsic \p id in the Module
124
+ // / \p M and return it if it exists. Otherwise, return nullptr. This version
125
+ // / supports non-overloaded intrinsics.
126
+ LLVMIntrinsicCallOp getDeclarationIfExists (const mlir::ModuleOp *M, ID id);
127
+
128
+ // / This version supports overloaded intrinsics.
129
+ LLVMIntrinsicCallOp getDeclarationIfExists (mlir::ModuleOp M, ID id,
130
+ llvm::ArrayRef<mlir::Type> Tys,
131
+ mlir::Type FT = nullptr );
132
+
133
+ // / Map a Clang builtin name to an intrinsic ID.
134
+ ID getIntrinsicForClangBuiltin (llvm::StringRef TargetPrefix,
135
+ llvm::StringRef BuiltinName);
136
+
137
+ // / Map a MS builtin name to an intrinsic ID.
138
+ ID getIntrinsicForMSBuiltin (llvm::StringRef TargetPrefix,
139
+ llvm::StringRef BuiltinName);
140
+
141
+ // FIXME: Uses table from LLVM, but we don't have it yet.
142
+ // /// Returns true if the intrinsic ID is for one of the "Constrained
143
+ // /// Floating-Point Intrinsics".
144
+ // bool isConstrainedFPIntrinsic(ID QID);
145
+
146
+ // /// Returns true if the intrinsic ID is for one of the "Constrained
147
+ // /// Floating-Point Intrinsics" that take rounding mode metadata.
148
+ // bool hasConstrainedFPRoundingModeOperand(ID QID);
149
+
150
+ // / Return the IIT table descriptor for the specified intrinsic into an array
151
+ // / of IITDescriptors.
152
+ void getIntrinsicInfoTableEntries (
153
+ ID id, llvm::SmallVectorImpl<llvm::Intrinsic::IITDescriptor> &T);
154
+
155
+ enum MatchIntrinsicTypesResult {
156
+ MatchIntrinsicTypes_Match = 0 ,
157
+ MatchIntrinsicTypes_NoMatchRet = 1 ,
158
+ MatchIntrinsicTypes_NoMatchArg = 2 ,
159
+ };
160
+
161
+ // / Match the specified function type with the type constraints specified by
162
+ // / the .td file. If the given type is an overloaded type it is pushed to the
163
+ // / ArgTys vector.
164
+ // /
165
+ // / Returns false if the given type matches with the constraints, true
166
+ // / otherwise.
167
+ MatchIntrinsicTypesResult
168
+ matchIntrinsicSignature (FuncOp FTy,
169
+ llvm::ArrayRef<llvm::Intrinsic::IITDescriptor> &Infos,
170
+ llvm::SmallVectorImpl<mlir::Type> &ArgTys);
171
+
172
+ // / Verify if the intrinsic has variable arguments. This method is intended to
173
+ // / be called after all the fixed arguments have been matched first.
174
+ // /
175
+ // / This method returns true on error.
176
+ bool matchIntrinsicVarArg (
177
+ bool isVarArg, llvm::ArrayRef<llvm::Intrinsic::IITDescriptor> &Infos);
178
+
179
+ // / Gets the type arguments of an intrinsic call by matching type contraints
180
+ // / specified by the .td file. The overloaded types are pushed into the
181
+ // / AgTys vector.
182
+ // /
183
+ // / Returns false if the given ID and function type combination is not a
184
+ // / valid intrinsic call.
185
+ bool getIntrinsicSignature (Intrinsic::ID, mlir::Type FT,
186
+ llvm::SmallVectorImpl<mlir::Type> &ArgTys);
187
+
188
+ // / Same as previous, but accepts a Function instead of ID and FunctionType.
189
+ bool getIntrinsicSignature (FuncOp F, llvm::SmallVectorImpl<mlir::Type> &ArgTys);
190
+
191
+ // Checks if the intrinsic name matches with its signature and if not
192
+ // returns the declaration with the same signature and remangled name.
193
+ // An existing GlobalValue with the wanted name but with a wrong prototype
194
+ // or of the wrong kind will be renamed by adding ".renamed" to the name.
195
+ std::optional<LLVMIntrinsicCallOp> remangleIntrinsicFunction (FuncOp F);
196
+
197
+ } // namespace Intrinsic
198
+ } // namespace cir
199
+
200
+ #endif // LLVM_CLANG_CIR_DIALECT_INTRINSICS_H
0 commit comments