================
@@ -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

Reply via email to