clang 24.0.0git
CIRABIClassifierX86_64.cpp
Go to the documentation of this file.
1//===- CIRABIClassifierX86_64.cpp - x86_64 System V classification --------===//
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 implements the x86_64 System V classifier, which classifies with
10// the LLVM ABI Lowering Library's SysV x86_64 target.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CIRABIClassifier.h"
15
17
18#include <array>
19
20using namespace mlir;
21using namespace mlir::abi;
22using namespace cir;
23
24namespace {
25
26class X86_64ABIClassifier final : public CIRABIClassifierCommon {
27public:
28 X86_64ABIClassifier(const mlir::DataLayout &dl, mlir::ModuleOp modOp,
29 const ABIClassifierOptions &options)
30 : CIRABIClassifierCommon(dl, modOp), baseAvxLevel(options.x86AvxAbiLevel),
31 allowsTargetAttrAvx(options.allowsX86TargetAttrAvx),
32 abiCompat(options.x86AbiCompat) {}
33
34 /// cir.va_arg is expanded into the SysV register-save-area / overflow-area
35 /// sequence, which reads the fetched type's classification as an unnamed
36 /// argument, as classic's X86_64ABIInfo::EmitVAArg does.
37 std::optional<ArgClassification> classifyVAArg(cir::VAArgOp vaArg) override {
38 return classifyVarArgType(
39 vaArg.getType(), getTargetInfo(vaArg->getParentOfType<cir::FuncOp>()),
40 [&]() { return vaArg->emitOpError(); });
41 }
42
43protected:
44 /// The AVX level starts at the module's and may be raised by
45 /// \p featureSource's recorded target features.
46 const llvm::abi::TargetInfo &
47 getTargetInfo(cir::FuncOp featureSource) override;
48
49private:
50 /// One library classifier per AVX level, built on first use. A
51 /// per-function target attribute can raise the level above the module's.
52 static constexpr unsigned numAvxLevels =
53 static_cast<unsigned>(llvm::abi::X86AVXABILevel::Last) + 1;
54 std::array<std::unique_ptr<llvm::abi::TargetInfo>, numAvxLevels> targets;
55
56 llvm::abi::X86AVXABILevel baseAvxLevel;
57 bool allowsTargetAttrAvx;
58
59 /// The x86_64 flags whose value depends on the target and the requested ABI
60 /// compatibility version.
61 llvm::abi::X86ABICompatInfo abiCompat;
62};
63
64const llvm::abi::TargetInfo &
65X86_64ABIClassifier::getTargetInfo(cir::FuncOp featureSource) {
66 llvm::abi::X86AVXABILevel level = baseAvxLevel;
67 assert(featureSource && "function required for getTargetInfo");
68 if (allowsTargetAttrAvx)
69 level = funcAvxLevel(featureSource, baseAvxLevel);
70 assert(static_cast<unsigned>(level) < numAvxLevels &&
71 "a new X86AVXABILevel must move X86AVXABILevel::Last");
72 std::unique_ptr<llvm::abi::TargetInfo> &slot =
73 targets[static_cast<unsigned>(level)];
74 if (!slot)
75 slot =
76 llvm::abi::createX86_64TargetInfo(typeMapper.getTypeBuilder(), level,
77 /*Has64BitPointers=*/true, abiCompat);
78 return *slot;
79}
80
81} // namespace
82
83std::unique_ptr<CIRABIClassifier>
84cir::createX86_64ABIClassifier(const mlir::DataLayout &dl, mlir::ModuleOp modOp,
85 const ABIClassifierOptions &options) {
86 return std::make_unique<X86_64ABIClassifier>(dl, modOp, options);
87}
Classifies through the LLVM ABI Lowering Library.
static bool allowsX86TargetAttrAvx(const llvm::Triple &triple, clang::LangOptions::ClangABI compat)
Whether __attribute__((target(...))) on a function may raise its AVX ABI level above the command line...
Definition CIRPasses.cpp:45
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.
The target-specific settings a classifier needs beyond what it can read from the module.