clang 24.0.0git
CIRABIClassifier.h
Go to the documentation of this file.
1//===- CIRABIClassifier.h - ABI classification for CIR ----------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines CIRABIClassifier, the interface CallConvLowering uses to
10// obtain a mlir::abi::FunctionClassification for a CIR signature.
11//
12// CIRABIClassifier is the producer half of CIR's calling-convention lowering.
13// The consumer half is CIRABIRewriteContext, which turns a classification into
14// IR and needs to know nothing about where it came from.
15//
16//===----------------------------------------------------------------------===//
17
18#ifndef CLANG_LIB_CIR_DIALECT_TRANSFORMS_CIRABICLASSIFIER_H
19#define CLANG_LIB_CIR_DIALECT_TRANSFORMS_CIRABICLASSIFIER_H
20
21#include "mlir/ABI/ABIRewriteContext.h"
22#include "mlir/ABI/ABITypeMapper.h"
23#include "mlir/IR/BuiltinOps.h"
24#include "mlir/IR/Diagnostics.h"
25#include "mlir/Interfaces/DataLayoutInterfaces.h"
28#include "llvm/ABI/FunctionInfo.h"
29#include "llvm/ABI/TargetInfo.h"
30#include "llvm/ADT/STLFunctionalExtras.h"
31#include "llvm/ADT/StringRef.h"
32#include "llvm/IR/CallingConv.h"
33
34#include <memory>
35#include <optional>
36
37namespace cir {
38
39/// The target-specific settings a classifier needs beyond what it can read
40/// from the module. Every field names the target it belongs to, because a
41/// classifier for one target ignores the others' settings.
43 // TODO: Make this class target-independent.
44
45 /// The AVX level the x86_64 classifier sizes a native vector at.
46 llvm::abi::X86AVXABILevel x86AvxAbiLevel = llvm::abi::X86AVXABILevel::None;
47
48 /// Whether a function's own recorded target features may raise its x86_64
49 /// AVX level above x86AvxAbiLevel.
51
52 /// The x86_64 flags whose value depends on the target and the requested ABI
53 /// compatibility version.
54 llvm::abi::X86ABICompatInfo x86AbiCompat;
55};
56
57/// Produces the classification CallConvLowering rewrites a signature from.
58///
59/// A subclass supplies one target's rules, or one of the two test drivers that
60/// stand in for a target. The pass holds a single instance for the whole
61/// module. Each method returns std::nullopt after emitting an error on the
62/// operation it was given, including for an operation the subclass does not
63/// support yet.
65public:
66 virtual ~CIRABIClassifier() = default;
67
68 /// Classify \p func's declared signature.
69 virtual std::optional<mlir::abi::FunctionClassification>
70 classifyFunction(cir::FuncOp func) = 0;
71
72 /// Classify a direct call to the variadic function \p callee that passes
73 /// arguments through the ellipsis. The classification covers every operand
74 /// of \p call, and classifies the declared parameters the same way as
75 /// classifyFunction(callee).
76 virtual std::optional<mlir::abi::FunctionClassification>
77 classifyVariadicCall(cir::CIRCallOpInterface call, cir::FuncOp callee) = 0;
78
79 /// Classify \p call, whose callee is resolved at run time, from the
80 /// signature its callee pointer points to.
81 virtual std::optional<mlir::abi::FunctionClassification>
82 classifyIndirectCall(cir::CIRCallOpInterface call) = 0;
83
84 /// Classify the type fetched by \p vaArg as an unnamed argument with a full
85 /// register budget.
86 virtual std::optional<mlir::abi::ArgClassification>
87 classifyVAArg(cir::VAArgOp vaArg) = 0;
88};
89
90/// Classifies through the LLVM ABI Lowering Library. The signature's CIR types
91/// are mapped to llvm::abi types, the target's TargetInfo classifies them, and
92/// each llvm::abi::ArgInfo is converted to an ArgClassification.
93///
94/// A subclass supplies the TargetInfo and classifies `cir.va_arg`, whose
95/// expansion is specific to each target.
97public:
98 std::optional<mlir::abi::FunctionClassification>
99 classifyFunction(cir::FuncOp func) override;
100
101 /// The call is classified at the callee's features, not the caller's,
102 /// because the pass rewrites the definition and its call sites from one
103 /// classification. Classic instead arranges every call site from the
104 /// caller and reports a caller whose features disagree with its callee in
105 /// checkFunctionCallABI, which has no equivalent here yet.
106 std::optional<mlir::abi::FunctionClassification>
107 classifyVariadicCall(cir::CIRCallOpInterface call,
108 cir::FuncOp callee) override;
109
110 /// A callee resolved at run time carries no features of its own, so the
111 /// call is classified at the features of the function containing it, which
112 /// is the declaration classic arranges every call site from. A call that
113 /// passes arguments through an ellipsis is classified from its own
114 /// operands, as a direct one is.
115 std::optional<mlir::abi::FunctionClassification>
116 classifyIndirectCall(cir::CIRCallOpInterface call) override;
117
118protected:
119 CIRABIClassifierCommon(const mlir::DataLayout &dl, mlir::ModuleOp modOp)
120 : dl(dl), modOp(modOp), typeMapper(dl) {}
121
122 /// The library classifier for a function whose recorded target features
123 /// may refine the ABI rules.
124 virtual const llvm::abi::TargetInfo &
125 getTargetInfo(cir::FuncOp featureSource) = 0;
126
127 /// Classify \p ty, the type fetched by a `cir.va_arg`, as an unnamed
128 /// argument with every argument register free.
129 std::optional<mlir::abi::ArgClassification>
130 classifyVarArgType(mlir::Type ty, const llvm::abi::TargetInfo &targetInfo,
131 llvm::function_ref<mlir::InFlightDiagnostic()> emitError);
132
133 const mlir::DataLayout &dl;
134 mlir::ModuleOp modOp;
135 mlir::abi::ABITypeMapper typeMapper;
136
137private:
138 /// Classify a signature returning \p retCIR and taking \p inputs, whose
139 /// first \p required entries are declared parameters, under \p callConv.
140 std::optional<mlir::abi::FunctionClassification>
141 classifySignature(mlir::Type retCIR, mlir::TypeRange inputs,
142 llvm::abi::RequiredArgs required,
143 const llvm::abi::TargetInfo &targetInfo,
144 llvm::CallingConv::ID callConv,
145 llvm::function_ref<mlir::InFlightDiagnostic()> emitError);
146
147 /// Classify \p call, which passes more operands than \p calleeTy declares,
148 /// from the call's operands.
149 std::optional<mlir::abi::FunctionClassification>
150 classifyVariadicCall(cir::CIRCallOpInterface call, cir::FuncType calleeTy,
151 const llvm::abi::TargetInfo &targetInfo,
152 llvm::CallingConv::ID callConv);
153};
154
155/// The MLIR test ABI target's classifier, whose predictable rules approximate
156/// x86_64 SysV.
157std::unique_ptr<CIRABIClassifier>
158createTestTargetABIClassifier(const mlir::DataLayout &dl);
159
160/// A classifier that reads each function's classification from the
161/// DictionaryAttr named \p attrName.
162std::unique_ptr<CIRABIClassifier>
163createInjectedABIClassifier(const mlir::DataLayout &dl,
164 llvm::StringRef attrName);
165
166/// The x86_64 System V classifier.
167std::unique_ptr<CIRABIClassifier>
168createX86_64ABIClassifier(const mlir::DataLayout &dl, mlir::ModuleOp modOp,
169 const ABIClassifierOptions &options);
170
171/// The AMDGPU classifier.
172std::unique_ptr<CIRABIClassifier>
173createAMDGPUABIClassifier(const mlir::DataLayout &dl, mlir::ModuleOp modOp);
174
175/// Map a CIR calling convention to the llvm::CallingConv the ABI classifier
176/// uses. Conventions the classifier does not distinguish fall back to C.
177llvm::CallingConv::ID convertCallingConv(cir::CallingConv cc);
178
179//===----------------------------------------------------------------------===//
180// Classification helpers defined in CallConvLoweringPass.cpp
181//===----------------------------------------------------------------------===//
182
183/// Record on \p fc whether \p returnType is CIR's void.
184std::optional<mlir::abi::FunctionClassification>
185withReturnVoidness(std::optional<mlir::abi::FunctionClassification> fc,
186 mlir::Type returnType);
187
188/// Classify \p func with the test target, or from the attribute named
189/// \p classificationAttrName when that is non-empty.
190std::optional<mlir::abi::FunctionClassification>
191classifyFunction(cir::FuncOp func, const mlir::DataLayout &dl,
192 cir::CallConvTarget target,
193 llvm::StringRef classificationAttrName);
194
195/// Where \p fnTy's declared parameters end and its ellipsis arguments begin.
196llvm::abi::RequiredArgs requiredArgs(cir::FuncType fnTy);
197
198/// The AVX level to classify \p func at: \p base, raised if the function's own
199/// recorded feature list enables a wider vector.
200llvm::abi::X86AVXABILevel funcAvxLevel(cir::FuncOp func,
201 llvm::abi::X86AVXABILevel base);
202
203} // namespace cir
204
205#endif // CLANG_LIB_CIR_DIALECT_TRANSFORMS_CIRABICLASSIFIER_H
std::optional< mlir::abi::FunctionClassification > classifyVariadicCall(cir::CIRCallOpInterface call, cir::FuncOp callee) override
The call is classified at the callee's features, not the caller's, because the pass rewrites the defi...
std::optional< mlir::abi::FunctionClassification > classifyIndirectCall(cir::CIRCallOpInterface call) override
A callee resolved at run time carries no features of its own, so the call is classified at the featur...
CIRABIClassifierCommon(const mlir::DataLayout &dl, mlir::ModuleOp modOp)
const mlir::DataLayout & dl
std::optional< mlir::abi::FunctionClassification > classifyFunction(cir::FuncOp func) override
Classify a cir.func using the LLVM ABI library.
virtual const llvm::abi::TargetInfo & getTargetInfo(cir::FuncOp featureSource)=0
The library classifier for a function whose recorded target features may refine the ABI rules.
mlir::abi::ABITypeMapper typeMapper
std::optional< mlir::abi::ArgClassification > classifyVarArgType(mlir::Type ty, const llvm::abi::TargetInfo &targetInfo, llvm::function_ref< mlir::InFlightDiagnostic()> emitError)
Classify ty, the type fetched by a cir.va_arg, as an unnamed argument with every argument register fr...
Produces the classification CallConvLowering rewrites a signature from.
virtual std::optional< mlir::abi::FunctionClassification > classifyIndirectCall(cir::CIRCallOpInterface call)=0
Classify call, whose callee is resolved at run time, from the signature its callee pointer points to.
virtual std::optional< mlir::abi::FunctionClassification > classifyVariadicCall(cir::CIRCallOpInterface call, cir::FuncOp callee)=0
Classify a direct call to the variadic function callee that passes arguments through the ellipsis.
virtual std::optional< mlir::abi::FunctionClassification > classifyFunction(cir::FuncOp func)=0
Classify func's declared signature.
virtual ~CIRABIClassifier()=default
virtual std::optional< mlir::abi::ArgClassification > classifyVAArg(cir::VAArgOp vaArg)=0
Classify the type fetched by vaArg as an unnamed argument with a full register budget.
std::optional< mlir::abi::FunctionClassification > withReturnVoidness(std::optional< mlir::abi::FunctionClassification > fc, mlir::Type returnType)
Record on fc whether returnType is CIR's void.
std::unique_ptr< CIRABIClassifier > createAMDGPUABIClassifier(const mlir::DataLayout &dl, mlir::ModuleOp modOp)
The AMDGPU classifier.
llvm::abi::X86AVXABILevel funcAvxLevel(cir::FuncOp func, llvm::abi::X86AVXABILevel base)
The AVX level to classify func at: base, raised if the function's own recorded feature list enables a...
std::unique_ptr< CIRABIClassifier > createX86_64ABIClassifier(const mlir::DataLayout &dl, mlir::ModuleOp modOp, const ABIClassifierOptions &options)
The x86_64 System V classifier.
llvm::CallingConv::ID convertCallingConv(cir::CallingConv cc)
Map a CIR calling convention to the llvm::CallingConv the ABI classifier uses.
std::optional< mlir::abi::FunctionClassification > classifyFunction(cir::FuncOp func, const mlir::DataLayout &dl, cir::CallConvTarget target, llvm::StringRef classificationAttrName)
Classify func with the test target, or from the attribute named classificationAttrName when that is n...
std::unique_ptr< CIRABIClassifier > createInjectedABIClassifier(const mlir::DataLayout &dl, llvm::StringRef attrName)
A classifier that reads each function's classification from the DictionaryAttr named attrName.
std::unique_ptr< CIRABIClassifier > createTestTargetABIClassifier(const mlir::DataLayout &dl)
The MLIR test ABI target's classifier, whose predictable rules approximate x86_64 SysV.
CallConvTarget
The ABI target whose calling-convention rules drive CallConvLowering.
Definition Passes.h:23
llvm::abi::RequiredArgs requiredArgs(cir::FuncType fnTy)
Where fnTy's declared parameters end and its ellipsis arguments begin.
The target-specific settings a classifier needs beyond what it can read from the module.
bool allowsX86TargetAttrAvx
Whether a function's own recorded target features may raise its x86_64 AVX level above x86AvxAbiLevel...
llvm::abi::X86ABICompatInfo x86AbiCompat
The x86_64 flags whose value depends on the target and the requested ABI compatibility version.
llvm::abi::X86AVXABILevel x86AvxAbiLevel
The AVX level the x86_64 classifier sizes a native vector at.