================
@@ -0,0 +1,195 @@
+//===- CIRABIClassifier.h - ABI classification for CIR ----------*- C++
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines CIRABIClassifier, the interface CallConvLowering uses to
+// obtain a mlir::abi::FunctionClassification for a CIR signature.
+//
+// CIRABIClassifier is the producer half of CIR's calling-convention lowering.
+// The consumer half is CIRABIRewriteContext, which turns a classification into
+// IR and needs to know nothing about where it came from.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LIB_CIR_DIALECT_TRANSFORMS_CIRABICLASSIFIER_H
+#define CLANG_LIB_CIR_DIALECT_TRANSFORMS_CIRABICLASSIFIER_H
+
+#include "mlir/ABI/ABIRewriteContext.h"
+#include "mlir/ABI/ABITypeMapper.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/IR/Diagnostics.h"
+#include "mlir/Interfaces/DataLayoutInterfaces.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+#include "clang/CIR/Dialect/Passes.h"
+#include "llvm/ABI/FunctionInfo.h"
+#include "llvm/ABI/TargetInfo.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <memory>
+#include <optional>
+
+namespace cir {
+
+/// The target-specific settings a classifier needs beyond what it can read
+/// from the module. Every field names the target it belongs to, because a
+/// classifier for one target ignores the others' settings.
+struct ABIClassifierOptions {
+ // TODO: Make this class target-independent.
+
+ /// The AVX level the x86_64 classifier sizes a native vector at.
+ llvm::abi::X86AVXABILevel x86AvxAbiLevel = llvm::abi::X86AVXABILevel::None;
+
+ /// Whether a function's own recorded target features may raise its x86_64
+ /// AVX level above x86AvxAbiLevel.
+ bool allowsX86TargetAttrAvx = true;
+
+ /// The x86_64 flags whose value depends on the target and the requested ABI
+ /// compatibility version.
+ llvm::abi::X86ABICompatInfo x86AbiCompat;
+};
+
+/// Produces the classification CallConvLowering rewrites a signature from.
+///
+/// A subclass supplies one target's rules, or one of the two test drivers that
+/// stand in for a target. The pass holds a single instance for the whole
+/// module. Each method returns std::nullopt after emitting an error on the
+/// operation it was given, including for an operation the subclass does not
+/// support yet.
+class CIRABIClassifier {
+public:
+ virtual ~CIRABIClassifier() = default;
+
+ /// Classify \p func's declared signature.
+ virtual std::optional<mlir::abi::FunctionClassification>
+ classifyFunction(cir::FuncOp func) = 0;
+
+ /// Classify a direct call to the variadic function \p callee that passes
+ /// arguments through the ellipsis. The classification covers every operand
+ /// of \p call, and classifies the declared parameters the same way as
+ /// classifyFunction(callee).
+ virtual std::optional<mlir::abi::FunctionClassification>
+ classifyVariadicCall(cir::CIRCallOpInterface call, cir::FuncOp callee) = 0;
+
+ /// Classify \p call, whose callee is resolved at run time, from the
+ /// signature its callee pointer points to.
+ virtual std::optional<mlir::abi::FunctionClassification>
+ classifyIndirectCall(cir::CIRCallOpInterface call) = 0;
+
+ /// Classify the type fetched by \p vaArg as an unnamed argument with a full
+ /// register budget.
+ virtual std::optional<mlir::abi::ArgClassification>
+ classifyVAArg(cir::VAArgOp vaArg) = 0;
+};
+
+/// Classifies through the LLVM ABI Lowering Library. The signature's CIR
types
+/// are mapped to llvm::abi types, the target's TargetInfo classifies them, and
+/// each llvm::abi::ArgInfo is converted to an ArgClassification.
+///
+/// A subclass supplies the TargetInfo and classifies `cir.va_arg`, whose
+/// expansion is specific to each target.
+class CIRABIClassifierCommon : public CIRABIClassifier {
+public:
+ std::optional<mlir::abi::FunctionClassification>
+ classifyFunction(cir::FuncOp func) override;
+
+ /// The call is classified at the callee's features, not the caller's,
+ /// because the pass rewrites the definition and its call sites from one
+ /// classification. Classic instead arranges every call site from the
+ /// caller and reports a caller whose features disagree with its callee in
+ /// checkFunctionCallABI, which has no equivalent here yet.
+ std::optional<mlir::abi::FunctionClassification>
+ classifyVariadicCall(cir::CIRCallOpInterface call,
+ cir::FuncOp callee) override;
+
+ /// A callee resolved at run time carries no features of its own, so the
+ /// call is classified at the features of the function containing it, which
+ /// is the declaration classic arranges every call site from. A call that
+ /// passes arguments through an ellipsis is classified from its own
+ /// operands, as a direct one is.
+ std::optional<mlir::abi::FunctionClassification>
+ classifyIndirectCall(cir::CIRCallOpInterface call) override;
+
+protected:
+ CIRABIClassifierCommon(const mlir::DataLayout &dl, mlir::ModuleOp modOp)
+ : dl(dl), modOp(modOp), typeMapper(dl) {}
+
+ /// The library classifier for a function whose recorded target features
+ /// may refine the ABI rules, or for the module's rules when
+ /// \p featureSource is null.
+ virtual const llvm::abi::TargetInfo &
+ getTargetInfo(cir::FuncOp featureSource) = 0;
----------------
andykaylor wrote:
I'm not sure this will ever be null. I'm not sure why it was written to allow
that. What this is actually intended to do is allow a different TargetInfo to
be used when classifying a function that has a different target attribute than
the module-level default. For example, you can compile a TU with AVX2 but have
specific functions marked for AVX512 using
`__attribute__((target("arch=x86-64-v4")))`.
I'll clean this up and make it require a function.
https://github.com/llvm/llvm-project/pull/233639
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits