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