clang 24.0.0git
CallConvLoweringPass.cpp
Go to the documentation of this file.
1//===- CallConvLoweringPass.cpp - Lower CIR to ABI calling convention ----===//
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 pass walks every cir.func and cir.call in the module, computes a
10// FunctionClassification for it (via either an ABI target or a pre-built
11// classification injected as a function attribute), and dispatches to
12// CIRABIRewriteContext to perform the actual IR rewriting.
13//
14// Two driver modes (mutually exclusive):
15//
16// target=test
17// Use the MLIR test ABI target (mlir/lib/ABI/Targets/Test/) to classify
18// each function. Predictable rules that approximate x86_64 SysV. Real
19// targets (x86_64, AArch64) will be added once the LLVM ABI library
20// ships them.
21//
22// classification-attr=<name>
23// Read a DictionaryAttr named <name> from each cir.func and parse it via
24// mlir::abi::test::parseClassificationAttr. Used by tests to inject any
25// classification (including shapes the test target itself does not
26// produce) without depending on a real ABI target.
27//
28// The pass requires a `dlti.dl_spec` attribute on the module so the
29// classifier can query type sizes and alignments.
30//
31//===----------------------------------------------------------------------===//
32
33#include "PassDetail.h"
35
36#include "mlir/ABI/ABIRewriteContext.h"
37#include "mlir/ABI/ABITypeMapper.h"
38#include "mlir/ABI/Targets/Test/TestTarget.h"
39#include "mlir/Dialect/DLTI/DLTI.h"
40#include "mlir/IR/Builders.h"
41#include "mlir/IR/BuiltinOps.h"
42#include "mlir/IR/SymbolTable.h"
43#include "mlir/Interfaces/DataLayoutInterfaces.h"
44#include "mlir/Pass/Pass.h"
48#include "llvm/ABI/FunctionInfo.h"
49#include "llvm/ABI/TargetInfo.h"
50#include "llvm/ABI/Types.h"
51#include "llvm/ADT/StringExtras.h"
52#include "llvm/ADT/TypeSwitch.h"
53#include "llvm/IR/CallingConv.h"
54#include "llvm/Support/MathExtras.h"
55
56#include <algorithm>
57#include <array>
58
59using namespace mlir;
60using namespace mlir::abi;
61using namespace cir;
62
63namespace mlir {
64#define GEN_PASS_DEF_CALLCONVLOWERING
65#include "clang/CIR/Dialect/Passes.h.inc"
66} // namespace mlir
67
68namespace {
69
70//===----------------------------------------------------------------------===//
71// x86_64 System V classifier bridge
72//
73// Maps CIR types to llvm::abi::Type, runs the LLVM ABI Lowering Library's SysV
74// x86_64 classifier, and converts the result back into the dialect-agnostic
75// mlir::abi::FunctionClassification that CIRABIRewriteContext consumes.
76// Integer (including `_BitInt` up to 128 bits) / pointer / vtable pointer /
77// bool / floating-point scalars are handled, as are struct / union / array
78// aggregates, `_Complex`, and a fixed-width vector whose width is a power
79// of two. Other vectors, a padded record reached through a named bit-field
80// access unit, a record holding an empty-for-ABI member that occupies bytes
81// or a zero-sized one off its own alignment, a union no member of which spans
82// its declared size, and a union with a bit-field access unit no spanning
83// member of which supplies data are reported NYI by classifyX86_64Function
84// so an unsupported signature fails the pass instead of being misclassified.
85//===----------------------------------------------------------------------===//
86
87/// Whether a struct's declared argument-passing kind (from the module's
88/// record-layout metadata) allows it to be passed in registers. A record with
89/// no layout entry (e.g. an anonymous struct) has no C++ non-trivial reason to
90/// be forced to memory, so it defaults to can-pass-in-registers.
91static bool recordCanPassInRegs(ModuleOp modOp, cir::RecordType recTy) {
92 auto layout = cir::tryGetRecordLayout(modOp, recTy.getName());
93 if (!layout)
94 return true;
95 return layout.getArgPassingKind() == cir::ArgPassingKind::CanPassInRegs;
96}
97
98/// Whether a member is an empty record, looking through arrays, since an array
99/// of empty records supplies no bytes either.
100static bool memberIsEmptyRecord(mlir::Type ty) {
101 while (auto arrTy = dyn_cast<cir::ArrayType>(ty))
102 ty = arrTy.getElementType();
103 auto recTy = dyn_cast<cir::RecordType>(ty);
104 return recTy && recTy.isEmptyForABI();
105}
106
107/// A record's declared alignment, which the ABI uses for the byval and sret
108/// alignment of an indirect argument. DataLayout derives alignment from the
109/// members, so it cannot see `__attribute__((aligned(N)))`. The declared value
110/// comes from the module's record-layout metadata instead. CIRGen emits an
111/// entry for every record it names, so the computed fallback only serves
112/// hand-written CIR.
113static llvm::Align recordDeclaredAlign(ModuleOp modOp, cir::RecordType recTy,
114 const DataLayout &dl) {
115 auto layout = cir::tryGetRecordLayout(modOp, recTy.getName());
116 if (!layout)
117 return llvm::Align(dl.getTypeABIAlignment(recTy));
118 return llvm::Align(layout.getRecordAlign());
119}
120
121/// Whether \p ty reaches a bit-field access unit holding a named bit-field,
122/// looking through member records and array element types.
123static bool reachesNamedBitFieldUnit(mlir::Type ty) {
124 if (auto arrTy = dyn_cast<cir::ArrayType>(ty))
125 return reachesNamedBitFieldUnit(arrTy.getElementType());
126 auto recTy = dyn_cast<cir::RecordType>(ty);
127 if (!recTy)
128 return false;
129 // A zero-length array under the bit-field mark is a zero-width bit-field, not
130 // an access unit, and it carries its declared type rather than a unit width.
131 for (auto [memberTy, kind] :
132 llvm::zip_equal(recTy.getMembers(), recTy.getMemberKinds()))
134 !cir::isZeroWidthBitField(memberTy, kind))
135 return true;
136 return llvm::any_of(recTy.getMembers(), reachesNamedBitFieldUnit);
137}
138
139/// Whether \p ty, or an aggregate member/element reached by value (never
140/// through a pointer), is an incomplete record. Such a record has no known
141/// layout, so no eightbyte classification can be built for it.
142static bool hasIncompleteRecordByValue(mlir::Type ty) {
143 if (auto recTy = dyn_cast<cir::RecordType>(ty))
144 return !recTy.isComplete() ||
145 llvm::any_of(recTy.getMembers(), hasIncompleteRecordByValue);
146 if (auto arrTy = dyn_cast<cir::ArrayType>(ty))
147 return hasIncompleteRecordByValue(arrTy.getElementType());
148 return false;
149}
150
151/// The CIR types the x86_64 bridge handles. Scalars: an integer up to 128
152/// bits (including `_BitInt` and `__int128`), pointer, vtable pointer, bool,
153/// void, or any floating-point type. Aggregates: a complete struct or union
154/// whose members are all themselves supported, or an array of a supported
155/// element type. Also a `_Complex`, or a fixed-width vector, of a supported
156/// element type. Everything else is reported NYI at the reject() choke point
157/// in classifyX86_64Function.
158static bool isSupportedType(mlir::Type ty, const DataLayout &dl) {
159 // A pointer is only handled in the default address space (null) or an
160 // already-lowered target address space. A LangAddressSpaceAttr must be
161 // lowered before this pass, so reject it rather than silently dropping it.
162 if (auto ptrTy = dyn_cast<cir::PointerType>(ty))
163 return !ptrTy.getAddrSpace() ||
164 mlir::isa<cir::TargetAddressSpaceAttr>(ptrTy.getAddrSpace());
165 // cir::VPtrType carries no address-space parameter yet, so its target
166 // address space cannot be checked here even though it is not always the
167 // default one.
168 if (isa<cir::VPtrType>(ty)) {
170 return true;
171 }
172 if (isa<cir::VoidType, cir::BoolType>(ty))
173 return true;
174 // Every CIR floating-point type carries the semantics the classifier
175 // switches on, so all of them are handled.
176 if (isa<cir::FPTypeInterface>(ty))
177 return true;
178 if (auto intTy = dyn_cast<cir::IntType>(ty)) {
179 // Integers up to 64 bits, __int128, and _BitInt up to 128 bits are
180 // handled: the classifier extends a width below 32, widens 33 through 63
181 // to i64, coerces 65 through 127 to a {i64, i64} pair, and passes 32, 64,
182 // and 128 in the natural type. A wider _BitInt classifies Indirect,
183 // where at a multiple of 8 the byval attributes the rewriter appends
184 // duplicate the llvm.noundef CIRGen already emitted and trip the
185 // uniqueness assertion on the merged dictionary. The bound is a blanket
186 // 128 because the widths that do not collide reach that same untested
187 // Indirect path. Non-_BitInt intermediate widths (65..127) do not arise
188 // from C. Both stay rejected.
189 if (intTy.getIsBitInt())
190 return intTy.getWidth() <= 128;
191 return intTy.getWidth() <= 64 || intTy.getWidth() == 128;
192 }
193 if (auto complexTy = dyn_cast<cir::ComplexType>(ty))
194 return isSupportedType(complexTy.getElementType(), dl);
195 if (auto vecTy = dyn_cast<cir::VectorType>(ty)) {
196 // A scalable vector has no size the SysV eightbyte rules can read, and
197 // x86_64 has no calling convention for one.
198 if (vecTy.getIsScalable())
199 return false;
200 // The classifier sizes a vector as element count times element width, so
201 // an element is only usable where that width is the one clang gives it.
202 // It is not for bool (a bit to clang, a byte here), for a _BitInt narrower
203 // than a byte (clang rounds to the storage container), or for x87 long
204 // double (80 bits here against clang's 128). A pointer is excluded for a
205 // different reason, its pointee being what abiTypeToCIR drops.
206 mlir::Type elemTy = vecTy.getElementType();
207 if (auto elemInt = dyn_cast<cir::IntType>(elemTy)) {
208 if (elemInt.getWidth() % 8)
209 return false;
210 } else if (auto elemFp = dyn_cast<cir::FPTypeInterface>(elemTy)) {
211 if (&elemFp.getFloatSemantics() == &llvm::APFloat::x87DoubleExtended())
212 return false;
213 } else {
214 return false;
215 }
216 // Clang also rounds the vector's own width up to a power of two, and the
217 // classifier branches on the exact width, so a three-char vector would be
218 // classified at 24 bits where clang uses 32.
219 if (!llvm::isPowerOf2_64(dl.getTypeSizeInBits(ty).getFixedValue()))
220 return false;
221 return isSupportedType(elemTy, dl);
222 }
223 if (auto arrTy = dyn_cast<cir::ArrayType>(ty))
224 return isSupportedType(arrTy.getElementType(), dl);
225 if (auto recTy = dyn_cast<cir::RecordType>(ty)) {
226 // An incomplete record has no layout to classify.
227 if (!recTy.isComplete())
228 return false;
229 if (recTy.isUnion()) {
230 // The classifier sizes a union's eightbytes from the union itself, which
231 // is only sound when some member spans that size. Short of that, the
232 // remaining bytes are either tail padding or the rest of a bitfield
233 // storage unit, and the CIR type cannot tell those apart even though
234 // classic CodeGen coerces them to i32 and i8 respectively.
235 llvm::ArrayRef<mlir::Type> members = recTy.getMembers();
236 uint64_t recordBits = dl.getTypeSizeInBits(recTy).getFixedValue();
237 if (members.empty()) {
238 // A member-less union is all padding, which classifies Ignore up to two
239 // eightbytes. Past that SysV says MEMORY regardless of content, and
240 // there is no member here to build the Indirect coercion from.
241 if (recordBits > 128)
242 return false;
243 } else {
244 auto spansRecord = [&](mlir::Type m) {
245 return dl.getTypeSizeInBits(m).getFixedValue() == recordBits;
246 };
247 if (!llvm::any_of(members, spansRecord))
248 return false;
249 // A bit-field access unit's width may not match the bits it actually
250 // stores, so some member (the unit itself or another one) must both
251 // match the union's size and hold data.
253 if (llvm::any_of(kinds, cir::isBitFieldAccessUnit) &&
254 !llvm::any_of(llvm::zip_equal(members, kinds),
255 [&](const auto &pair) {
256 auto [memberTy, kind] = pair;
257 return spansRecord(memberTy) &&
258 cir::holdsDataForABI(memberTy, kind) &&
259 !memberIsEmptyRecord(memberTy);
260 }))
261 return false;
262 }
263 } else if (recTy.getPadded() && reachesNamedBitFieldUnit(recTy)) {
264 // A named access unit can be narrower than the type its bit-fields were
265 // declared with, and that declared type is what classic CodeGen coerces
266 // from. CIR does not record it, so classifying here would coerce to the
267 // unit's width instead.
268 return false;
269 }
270 // An `empty` member that occupies bytes is later read as an unnamed access
271 // unit. One that is itself an empty-for-ABI record can occupy bytes by
272 // holding a unit of its own, which classic CodeGen reaches through the
273 // member's fields rather than as one unit. A zero-sized one is dropped
274 // before classification, so a misaligned one never reaches the rule that
275 // sends its record to memory.
276 for (auto [idx, memberTy, kind] :
277 llvm::enumerate(recTy.getMembers(), recTy.getMemberKinds())) {
278 if (kind != cir::RecordMemberKind::Empty)
279 continue;
280 if (dl.getTypeSizeInBits(memberTy).getFixedValue()) {
281 if (memberIsEmptyRecord(memberTy))
282 return false;
283 } else if (recTy.getElementOffset(dl, idx) %
284 dl.getTypeABIAlignment(memberTy)) {
285 return false;
286 }
287 }
288 return llvm::all_of(recTy.getMembers(),
289 [&](mlir::Type m) { return isSupportedType(m, dl); });
290 }
291 return false;
292}
293
294/// Convert an llvm::abi::Type coercion type back to a scalar CIR type.
295static mlir::Type abiTypeToCIR(const llvm::abi::Type *ty, MLIRContext *ctx) {
296 if (!ty)
297 return nullptr;
298 return llvm::TypeSwitch<const llvm::abi::Type *, mlir::Type>(ty)
299 .Case(
300 [&](const llvm::abi::VoidType *) { return cir::VoidType::get(ctx); })
301 .Case([&](const llvm::abi::IntegerType *intTy) {
302 return cir::IntType::get(ctx, intTy->getSizeInBits().getFixedValue(),
303 intTy->isSigned(), intTy->isBitInt());
304 })
305 .Case([&](const llvm::abi::FloatType *fltTy) {
306 return cir::getFloatingPointType(*fltTy->getSemantics(), ctx);
307 })
308 .Case([&](const llvm::abi::PointerType *) {
309 return cir::PointerType::get(cir::VoidType::get(ctx));
310 })
311 .Case([&](const llvm::abi::VectorType *vecTy) -> mlir::Type {
312 mlir::Type elemCIR = abiTypeToCIR(vecTy->getElementType(), ctx);
313 if (!elemCIR)
314 return nullptr;
315 return cir::VectorType::get(elemCIR,
316 vecTy->getNumElements().getFixedValue());
317 })
318 .Case([&](const llvm::abi::RecordType *recTy) -> mlir::Type {
319 SmallVector<mlir::Type> fieldTypes;
320 fieldTypes.reserve(recTy->getFields().size());
321 for (const auto &field : recTy->getFields()) {
322 mlir::Type fieldCIR = abiTypeToCIR(field.FieldType, ctx);
323 if (!fieldCIR)
324 return nullptr;
325 fieldTypes.push_back(fieldCIR);
326 }
327 // Coercion types are plain register tuples, not the source record.
328 return cir::StructType::get(
329 ctx, fieldTypes, /*packed=*/false,
330 /*is_class=*/false, cir::RecordType::getAllDataKinds(fieldTypes));
331 })
332 .Default([](const llvm::abi::Type *) -> mlir::Type { return nullptr; });
333}
334
335/// Map a CIR type to an llvm::abi::Type. classifyX86_64Function pre-filters
336/// the signature, so only the scalar and struct/array types handled here can
337/// reach this function.
338static const llvm::abi::Type *mapCIRType(mlir::Type type,
339 mlir::abi::ABITypeMapper &typeMapper,
340 const DataLayout &dl, ModuleOp modOp) {
341 llvm::abi::TypeBuilder &tb = typeMapper.getTypeBuilder();
342 return llvm::TypeSwitch<mlir::Type, const llvm::abi::Type *>(type)
343 .Case([&](cir::IntType intTy) {
344 return tb.getIntegerType(intTy.getWidth(),
345 llvm::Align(dl.getTypeABIAlignment(type)),
346 intTy.isSigned(), intTy.getIsBitInt());
347 })
348 .Case([&](cir::PointerType ptrTy) {
349 unsigned addrSpace = 0;
350 if (auto targetAsAttr =
351 dyn_cast_if_present<cir::TargetAddressSpaceAttr>(
352 ptrTy.getAddrSpace()))
353 addrSpace = targetAsAttr.getValue();
354 return tb.getPointerType(dl.getTypeSizeInBits(type),
355 llvm::Align(dl.getTypeABIAlignment(type)),
356 addrSpace);
357 })
358 .Case([&](cir::VPtrType) {
359 // cir::VPtrType carries no address-space parameter yet, so this
360 // always maps into the default one until that gap closes.
362 return tb.getPointerType(dl.getTypeSizeInBits(type),
363 llvm::Align(dl.getTypeABIAlignment(type)));
364 })
365 .Case([&](cir::BoolType) {
366 return tb.getIntegerType(dl.getTypeSizeInBits(type),
367 llvm::Align(dl.getTypeABIAlignment(type)),
368 /*Signed=*/false);
369 })
370 .Case([&](cir::VoidType) { return tb.getVoidType(); })
371 .Case([&](cir::FPTypeInterface fpTy) {
372 // LongDoubleType reports its underlying format's semantics, so the
373 // classifier sees x87 or IEEE quad rather than the wrapper.
374 return tb.getFloatType(fpTy.getFloatSemantics(),
375 llvm::Align(dl.getTypeABIAlignment(type)));
376 })
377 .Case([&](cir::ComplexType complexTy) {
378 return tb.getComplexType(
379 mapCIRType(complexTy.getElementType(), typeMapper, dl, modOp),
380 llvm::Align(dl.getTypeABIAlignment(type)));
381 })
382 .Case([&](cir::VectorType vecTy) {
383 // isSupportedType rejects a scalable vector, so the element count is
384 // always fixed here.
385 return tb.getVectorType(
386 mapCIRType(vecTy.getElementType(), typeMapper, dl, modOp),
387 llvm::ElementCount::getFixed(vecTy.getSize()),
388 llvm::Align(dl.getTypeABIAlignment(type)));
389 })
390 .Case([&](cir::ArrayType arrTy) {
391 const llvm::abi::Type *elemAbi =
392 mapCIRType(arrTy.getElementType(), typeMapper, dl, modOp);
393 return tb.getArrayType(elemAbi, arrTy.getSize(),
394 dl.getTypeSizeInBits(type).getFixedValue());
395 })
396 .Case([&](cir::RecordType recTy) -> const llvm::abi::Type * {
397 llvm::abi::RecordFlags flags = llvm::abi::RecordFlags::None;
398 if (recordCanPassInRegs(modOp, recTy))
399 flags = flags | llvm::abi::RecordFlags::CanPassInRegisters;
400 llvm::TypeSize sizeBits = llvm::TypeSize::getFixed(
401 dl.getTypeSizeInBits(type).getFixedValue());
402 llvm::Align align = recordDeclaredAlign(modOp, recTy, dl);
403
404 // Mapped with no fields, an empty record reaches Ignore on its own.
405 // The size still matters: past two eightbytes SysV says memory whatever
406 // the content.
407 if (recTy.isEmptyForABI())
408 return tb.getRecordType(
409 /*Fields=*/{}, sizeBits, align, llvm::abi::StructPacking::Default,
410 /*BaseClasses=*/{}, /*VirtualBaseClasses=*/{}, flags);
411
413 fields.reserve(recTy.getMembers().size());
414
415 // The size passed here spans the tail padding, so an eightbyte covers
416 // the whole union rather than just the member the classifier reduces
417 // it to.
418 if (recTy.isUnion()) {
419 // Classify only the members that hold data for the ABI. A member
420 // that holds none, such as an unnamed bit-field's storage, is
421 // skipped so it does not appear as a spurious argument.
422 for (auto [fieldTy, kind] :
423 llvm::zip_equal(recTy.getMembers(), recTy.getMemberKinds()))
424 if (cir::holdsDataForABI(fieldTy, kind))
425 fields.push_back(llvm::abi::FieldInfo(
426 mapCIRType(fieldTy, typeMapper, dl, modOp)));
427 return tb.getUnionType(fields, sizeBits, align,
428 llvm::abi::StructPacking::Default, flags);
429 }
430
431 // Padding is dropped, so the eightbyte rules see its bytes as holding
432 // nothing, while the record's full size set above still spans them. An
433 // unnamed bit-field access unit is flagged rather than dropped, since
434 // classic CodeGen ignores it when assigning eightbyte classes but
435 // counts it when choosing the coerce type, and a member's presence
436 // alone cannot say both.
437 for (auto [idx, fieldTy, kind] :
438 llvm::enumerate(recTy.getMembers(), recTy.getMemberKinds())) {
439 if (kind == cir::RecordMemberKind::Pad)
440 continue;
441 // A zero-width bit-field occupies nothing, so its declared type is
442 // what the ABI counts, and that is the element type it carries.
443 mlir::Type countedTy = fieldTy;
444 bool isUnnamedUnit = kind == cir::RecordMemberKind::Empty;
445 if (cir::isZeroWidthBitField(fieldTy, kind)) {
446 countedTy = cast<cir::ArrayType>(fieldTy).getElementType();
447 isUnnamedUnit = true;
448 }
449 uint64_t widthBits = dl.getTypeSizeInBits(countedTy).getFixedValue();
450 if (isUnnamedUnit && widthBits == 0)
451 continue;
452 assert((!isUnnamedUnit || !memberIsEmptyRecord(countedTy)) &&
453 "an empty-for-ABI member must not reach the classifier as an "
454 "unnamed bit-field");
455 // A named access unit is a bit-field to the classifier as well. Its
456 // eightbyte classes come from the bits it spans, and the rule that
457 // sends a record with an unaligned field to memory does not apply to
458 // a bit-field, which may sit at any offset.
459 bool isAccessUnit = isUnnamedUnit || cir::isBitFieldAccessUnit(kind);
460 fields.push_back(llvm::abi::FieldInfo(
461 mapCIRType(countedTy, typeMapper, dl, modOp),
462 recTy.getElementOffset(dl, idx) * 8,
463 /*IsBitField=*/isAccessUnit, isAccessUnit ? widthBits : 0,
464 /*IsUnnamedBitField=*/isUnnamedUnit));
465 }
466
467 return tb.getRecordType(
468 fields, sizeBits, align, llvm::abi::StructPacking::Default,
469 /*BaseClasses=*/{}, /*VirtualBaseClasses=*/{}, flags);
470 })
471 .Default([](mlir::Type) -> const llvm::abi::Type * {
472 llvm_unreachable(
473 "mapCIRType: type not pre-filtered by classifyX86_64Function");
474 });
475}
476
477/// Convert an llvm::abi::ArgInfo into the ArgClassification consumed by
478/// CIRABIRewriteContext.
479///
480/// Direct: the value passes in register(s). A coercion is forwarded in the
481/// three cases where the value has to be rebuilt on the wire: an aggregate
482/// unpacked into the register(s) holding it, a scalar too wide for one register
483/// split into a tuple of them, and a scalar the classifier widens to fill its
484/// eightbyte. getDirect keeps canFlatten set so the rewriter can split a
485/// multi-field coerced struct into individual wire arguments. Any other scalar
486/// passes in its natural CIR type, which a null coercion denotes. A coercion
487/// this bridge cannot represent yields std::nullopt so the caller reports NYI
488/// rather than silently passing the value unchanged.
489///
490/// Extend: bool or a sub-register integer needs a signext/zeroext attribute.
491/// The x86_64 classifier (llvm/lib/ABI/Targets/X86.cpp) only returns Extend
492/// for an integer or bool operand, so any other origTy is asserted rather
493/// than silently handled.
494///
495/// Indirect: an aggregate that does not fit in registers is passed via a
496/// pointer (sret for returns, byval for arguments).
497///
498/// Ignore: a void return, or an empty record dropped from the signature.
499static std::optional<ArgClassification>
500convertABIArgInfo(const llvm::abi::ArgInfo &info, MLIRContext *ctx,
501 mlir::Type origTy) {
502 if (info.isDirect()) {
503 // The rewriter reads a coercion from the start of the value's storage, so a
504 // classification naming an offset into it has no representation here. The
505 // classifier names one when the low eightbyte holds no field.
506 if (info.getDirectOffset())
507 return std::nullopt;
508 // The classifier names a coerce type even where it matches the natural
509 // type, so a non-null coerce does not by itself mean a rewrite is needed.
510 const llvm::abi::Type *coerceAbi = info.getCoerceToType();
511 bool isAggregate = isa_and_present<cir::RecordType, cir::ArrayType>(origTy);
512 // For a _Complex or a vector the classifier's coerce is only sometimes the
513 // natural type, so it has to be read rather than assumed.
514 bool comparesAgainstCoerce =
515 coerceAbi && isa_and_present<cir::ComplexType, cir::VectorType>(origTy);
516 bool coerceIsRegisterTuple =
517 isa_and_present<llvm::abi::RecordType>(coerceAbi);
518 // Compare widths rather than identity: a coerce no wider than the natural
519 // type carries the same value and needs no rewrite.
520 auto origInt = dyn_cast_if_present<cir::IntType>(origTy);
521 const auto *coerceInt =
522 dyn_cast_if_present<llvm::abi::IntegerType>(coerceAbi);
523 bool coerceWidensScalar =
524 origInt && coerceInt &&
525 coerceInt->getSizeInBits().getFixedValue() > origInt.getWidth();
526 // Leaving the rest alone also avoids a lossy round trip: abiTypeToCIR
527 // drops the LongDoubleType wrapper and a pointer's pointee, so comparing a
528 // scalar against its own coerce would report a difference that is not one.
529 if (!isAggregate && !comparesAgainstCoerce && !coerceIsRegisterTuple &&
530 !coerceWidensScalar)
531 return ArgClassification::getDirect(nullptr);
532 mlir::Type coerced = abiTypeToCIR(coerceAbi, ctx);
533 if (!coerced)
534 return std::nullopt;
535 // Coercing a value to the type it already has would add a memory round
536 // trip for nothing.
537 if (comparesAgainstCoerce && coerced == origTy)
538 return ArgClassification::getDirect(nullptr);
539 return ArgClassification::getDirect(coerced);
540 }
541 if (info.isExtend()) {
542 if (isa_and_present<cir::BoolType>(origTy))
543 return ArgClassification::getExtend(nullptr, info.isSignExt());
544 assert((!origTy || isa<cir::IntType>(origTy)) &&
545 "the x86_64 classifier only returns Extend for integers and bool");
546 mlir::Type extendedTy = abiTypeToCIR(info.getCoerceToType(), ctx);
547 return ArgClassification::getExtend(extendedTy, info.isSignExt());
548 }
549 if (info.isIndirect())
550 return ArgClassification::getIndirect(info.getIndirectAlign(),
551 info.getIndirectByVal());
552 assert(info.isIgnore() && "Unexpected classification");
553 return ArgClassification::getIgnore();
554}
555
556/// Where \p fnTy's declared parameters end and its ellipsis arguments begin.
557///
558/// The only x86_64 rule that reads this boundary sends an unnamed vector wider
559/// than 128 bits to memory.
560static llvm::abi::RequiredArgs requiredArgs(cir::FuncType fnTy) {
561 if (!fnTy.isVarArg())
562 return llvm::abi::RequiredArgs::All;
563 return llvm::abi::RequiredArgs(fnTy.getNumInputs());
564}
565
566/// Classify an x86_64 SysV signature (return type + argument types) using the
567/// LLVM ABI library. Shared by the cir.func path, the variadic-call path and
568/// the indirect-call path (the latter classifies from the callee function
569/// pointer's pointee FuncType). \p required marks where the declared
570/// parameters in \p inputs end. The classifier treats every argument past that
571/// point as passed through an ellipsis. Returns std::nullopt and emits an NYI
572/// error via \p emitError if the signature uses a type the bridge does not
573/// handle yet.
574static std::optional<FunctionClassification> classifyX86_64Signature(
575 mlir::Type retCIR, mlir::TypeRange inputs, llvm::abi::RequiredArgs required,
576 MLIRContext *ctx, const DataLayout &dl,
577 mlir::abi::ABITypeMapper &typeMapper,
578 const llvm::abi::TargetInfo &targetInfo, ModuleOp modOp,
579 llvm::function_ref<mlir::InFlightDiagnostic()> emitError) {
580 assert(retCIR && "signature return type must be non-null");
581 assert((!required.allowsOptionalArgs() ||
582 required.getNumRequiredArgs() <= inputs.size()) &&
583 "declared parameters cannot outnumber the classified arguments");
584 bool voidRet = isa<cir::VoidType>(retCIR);
585
586 auto reject = [&](mlir::Type t) -> bool {
587 if (isSupportedType(t, dl))
588 return false;
589 emitError()
590 << "x86_64 calling-convention lowering not yet implemented for type "
591 << t;
592 return true;
593 };
594 if (!voidRet && reject(retCIR))
595 return std::nullopt;
596 for (mlir::Type a : inputs)
597 if (reject(a))
598 return std::nullopt;
599
600 const llvm::abi::Type *retAbi =
601 voidRet ? typeMapper.getTypeBuilder().getVoidType()
602 : mapCIRType(retCIR, typeMapper, dl, modOp);
604 for (mlir::Type a : inputs)
605 argAbi.push_back(mapCIRType(a, typeMapper, dl, modOp));
606
607 std::unique_ptr<llvm::abi::FunctionInfo> fi = llvm::abi::FunctionInfo::create(
608 llvm::CallingConv::C, retAbi, argAbi, required);
609 targetInfo.computeInfo(*fi);
610
611 // convertABIArgInfo returns nullopt when the classifier picks a coercion this
612 // bridge cannot represent.
613 auto nyiCoercion = [&](mlir::Type t) {
614 emitError() << "x86_64 calling-convention lowering not yet "
615 "implemented for the ABI coercion of type "
616 << t;
617 };
618
619 FunctionClassification fc;
620 fc.returnsVoid = voidRet;
621 mlir::Type origRet = voidRet ? mlir::Type() : retCIR;
622 std::optional<ArgClassification> retAc =
623 convertABIArgInfo(fi->getReturnInfo(), ctx, origRet);
624 if (!retAc) {
625 nyiCoercion(retCIR);
626 return std::nullopt;
627 }
628 fc.returnInfo = *retAc;
629 for (unsigned i = 0, e = fi->arg_size(); i < e; ++i) {
630 mlir::Type origArg = i < inputs.size() ? inputs[i] : mlir::Type();
631 std::optional<ArgClassification> ac =
632 convertABIArgInfo(fi->getArgInfo(i).Info, ctx, origArg);
633 if (!ac) {
634 nyiCoercion(origArg);
635 return std::nullopt;
636 }
637 fc.argInfos.push_back(*ac);
638 }
639 return fc;
640}
641
642/// The AVX level to classify \p func at: \p base, raised if the function's own
643/// recorded feature list enables a wider vector.
644static llvm::abi::X86AVXABILevel funcAvxLevel(cir::FuncOp func,
645 llvm::abi::X86AVXABILevel base) {
646 // Only a `target` attribute may raise the level. A multiversioned function
647 // carries a raised feature list too, and must stay at the module's level.
649
650 auto features = func->getAttrOfType<mlir::StringAttr>("cir.target-features");
651 if (!features)
652 return base;
653 // A '-' entry disables the feature, so match a whole '+' entry rather than
654 // searching for the name. avx512f implies avx, so both entries are present:
655 // return on the wider name so one pass suffices.
656 bool avx = false;
657 for (llvm::StringRef feature : llvm::split(features.getValue(), ',')) {
658 if (!feature.consume_front("+"))
659 continue;
660 if (feature == "avx512f")
661 return std::max(base, llvm::abi::X86AVXABILevel::AVX512);
662 avx |= feature == "avx";
663 }
664 return avx ? std::max(base, llvm::abi::X86AVXABILevel::AVX) : base;
665}
666
667/// Classify a cir.func for x86_64 SysV using the LLVM ABI library. Returns
668/// std::nullopt and emits an NYI error if the signature uses a type the bridge
669/// does not handle yet.
670static std::optional<FunctionClassification>
671classifyX86_64Function(cir::FuncOp func, const DataLayout &dl,
672 mlir::abi::ABITypeMapper &typeMapper,
673 const llvm::abi::TargetInfo &targetInfo,
674 ModuleOp modOp) {
675 cir::FuncType fnTy = func.getFunctionType();
676 return classifyX86_64Signature(fnTy.getReturnType(), fnTy.getInputs(),
677 requiredArgs(fnTy), func->getContext(), dl,
678 typeMapper, targetInfo, modOp,
679 [&]() { return func.emitOpError(); });
680}
681
682/// Classify a call that passes arguments through an ellipsis. The callee's
683/// own classification covers only its declared parameters, but an ellipsis
684/// argument competes for the same argument registers as a declared one, so
685/// what the ABI does with it depends on the whole argument list: the same
686/// small struct is passed in registers early in the list and in memory once
687/// the integer registers are gone. Classifying from the call's operands
688/// rather than the callee's signature is what makes that accounting right.
689static std::optional<FunctionClassification> classifyX86_64VariadicCall(
690 cir::CIRCallOpInterface call, cir::FuncType calleeTy, const DataLayout &dl,
691 mlir::abi::ABITypeMapper &typeMapper,
692 const llvm::abi::TargetInfo &targetInfo, ModuleOp modOp) {
693 assert(calleeTy.isVarArg() &&
694 "only a variadic callee can take more operands than it declares");
695 Operation *op = call.getOperation();
696 return classifyX86_64Signature(
697 calleeTy.getReturnType(), call.getArgOperands().getTypes(),
698 requiredArgs(calleeTy), op->getContext(), dl, typeMapper, targetInfo,
699 modOp, [&]() { return op->emitOpError(); });
700}
701
702#ifndef NDEBUG
703/// Whether \p callFc classifies a call's leading arguments and its return
704/// exactly as \p calleeFc classifies the callee's declared parameters and
705/// return. A function definition and its call sites are rewritten from
706/// separate classifications, so the two would silently disagree on the wire
707/// format if an ellipsis argument could ever change how a declared parameter
708/// is passed.
709static bool classifiesSamePrefix(const FunctionClassification &calleeFc,
710 const FunctionClassification &callFc) {
711 if (callFc.argInfos.size() < calleeFc.argInfos.size())
712 return false;
713 return calleeFc.returnInfo == callFc.returnInfo &&
714 std::equal(calleeFc.argInfos.begin(), calleeFc.argInfos.end(),
715 callFc.argInfos.begin());
716}
717#endif
718
719struct CallConvLoweringPass
720 : public impl::CallConvLoweringBase<CallConvLoweringPass> {
721 using CallConvLoweringBase::CallConvLoweringBase;
722
723 CallConvLoweringPass(const CallConvLoweringOptions &options,
724 const llvm::abi::ABICompatInfo &x86AbiCompat)
725 : CallConvLoweringBase(options), x86AbiCompat(x86AbiCompat) {}
726
727 void runOnOperation() override;
728
729 /// The x86_64 flags whose value depends on the target and the requested ABI
730 /// compatibility version. Carried outside the pass options because the
731 /// struct has no command-line parser, so a cir-opt run gets the library
732 /// defaults rather than a target's values.
733 llvm::abi::ABICompatInfo x86AbiCompat;
734};
735
736/// Record on \p fc whether \p returnType is CIR's void. The x86_64 classifier
737/// answers this itself, but the other two drivers cannot: the test target is
738/// dialect-neutral and has no notion of CIR's void, and the
739/// classification-attr schema carries no return type at all. Both route
740/// through here so a classification always reaches needsRewrite paired with
741/// the return type it was built from.
742static std::optional<FunctionClassification>
743withReturnVoidness(std::optional<FunctionClassification> fc,
744 mlir::Type returnType) {
745 if (fc)
746 fc->returnsVoid = mlir::isa<cir::VoidType>(returnType);
747 return fc;
748}
749
750/// Classify \p func using whichever driver mode is configured. Returns
751/// std::nullopt and emits an error on the function if classification fails
752/// (e.g. injection-driver mode but the function is missing the attribute,
753/// or the attribute is malformed).
754std::optional<FunctionClassification>
755classifyFunction(cir::FuncOp func, const DataLayout &dl,
756 cir::CallConvTarget target, StringRef classificationAttrName) {
757 ArrayRef<Type> argTypes = func.getFunctionType().getInputs();
758 Type returnType = func.getFunctionType().getReturnType();
759
760 if (!classificationAttrName.empty()) {
761 auto attr = func->getAttrOfType<DictionaryAttr>(classificationAttrName);
762 if (!attr) {
763 func.emitOpError()
764 << "missing classification attribute '" << classificationAttrName
765 << "' (CallConvLowering driver mode 'classification-attr')";
766 return std::nullopt;
767 }
768 return withReturnVoidness(mlir::abi::test::parseClassificationAttr(
769 attr, [&]() { return func.emitOpError(); }),
770 returnType);
771 }
772
773 // The x86_64 target is handled directly in runOnOperation (it needs a shared
774 // ABITypeMapper and TargetInfo), so only the test target reaches here.
775 assert(target == cir::CallConvTarget::Test &&
776 "classifyFunction only handles the test target");
777 return withReturnVoidness(mlir::abi::test::classify(argTypes, returnType, dl),
778 returnType);
779}
780
781/// Find the cir.func declaration matching a direct cir.call / cir.try_call
782/// callee, if any. Returns nullptr if the callee is indirect or the symbol
783/// cannot be resolved. Takes a SymbolTable instead of a ModuleOp so the
784/// symbol lookup is amortized across all the call sites the driver walks
785/// (ModuleOp::lookupSymbol is linear per call).
786cir::FuncOp lookupCallee(Operation *callOp, SymbolTable &symbolTable) {
787 FlatSymbolRefAttr callee;
788 if (auto call = dyn_cast<cir::CallOp>(callOp))
789 callee = call.getCalleeAttr();
790 else if (auto tryCall = dyn_cast<cir::TryCallOp>(callOp))
791 callee = tryCall.getCalleeAttr();
792 else
793 return nullptr;
794 if (!callee)
795 return nullptr;
796 return symbolTable.lookup<cir::FuncOp>(callee.getValue());
797}
798
799/// The signature an indirect call reaches its callee through, or a null type
800/// for a direct call. The callee's pointer-to-function shape is asserted
801/// rather than verified: the dialect checks operand types against the callee
802/// only for a direct call, so IR that breaks it fails here instead of in the
803/// verifier.
804cir::FuncType indirectCalleeType(cir::CIRCallOpInterface call) {
805 if (!call.isIndirect())
806 return {};
807 return cast<cir::FuncType>(
808 cast<cir::PointerType>(call.getIndirectCall().getType()).getPointee());
809}
810
811void CallConvLoweringPass::runOnOperation() {
812 ModuleOp moduleOp = getOperation();
813 MLIRContext *ctx = &getContext();
814
815 bool haveTarget = target != cir::CallConvTarget::None;
816 bool haveAttr = !classificationAttr.empty();
817 if (haveTarget == haveAttr) {
818 moduleOp.emitOpError() << "CallConvLowering requires exactly one of "
819 "'target' or 'classification-attr' pass options";
820 signalPassFailure();
821 return;
822 }
823
824 if (!moduleOp->hasAttr(DLTIDialect::kDataLayoutAttrName)) {
825 moduleOp.emitOpError()
826 << "CallConvLowering requires a DataLayout (dlti.dl_spec attribute "
827 "on the module)";
828 signalPassFailure();
829 return;
830 }
831
832 DataLayout dl(moduleOp);
833 CIRABIRewriteContext rewriteCtx(moduleOp, dl);
834 SymbolTable symbolTable(moduleOp);
835
836 // A per-function target attribute can raise the AVX level, so one classifier
837 // per module would misclassify a wide vector in such a function.
838 static constexpr unsigned numAvxLevels =
839 static_cast<unsigned>(llvm::abi::X86AVXABILevel::Last) + 1;
840 bool isX86 = target == cir::CallConvTarget::X86_64;
841 std::optional<mlir::abi::ABITypeMapper> x86TypeMapper;
842 std::array<std::unique_ptr<llvm::abi::TargetInfo>, numAvxLevels> x86Targets;
843 if (isX86)
844 x86TypeMapper.emplace(dl);
845 auto x86TargetFor =
846 [&](llvm::abi::X86AVXABILevel level) -> const llvm::abi::TargetInfo & {
847 assert(static_cast<unsigned>(level) < numAvxLevels &&
848 "a new X86AVXABILevel must move X86AVXABILevel::Last");
849 std::unique_ptr<llvm::abi::TargetInfo> &slot =
850 x86Targets[static_cast<unsigned>(level)];
851 if (!slot)
852 slot = llvm::abi::createX86_64TargetInfo(
853 x86TypeMapper->getTypeBuilder(), level,
854 /*Has64BitPointers=*/true, x86AbiCompat);
855 return *slot;
856 };
857 llvm::abi::X86AVXABILevel baseAvxLevel = x86AvxAbiLevel.getValue();
858 auto avxLevelFor = [&](cir::FuncOp func) -> llvm::abi::X86AVXABILevel {
859 if (!allowsX86TargetAttrAvx || !func)
860 return baseAvxLevel;
861 return funcAvxLevel(func, baseAvxLevel);
862 };
863
864 // Classify every cir.func up front. No IR mutation happens here, so
865 // later walks can consult any function's classification regardless of
866 // visitation order.
867 llvm::MapVector<cir::FuncOp, FunctionClassification> classifications;
868 bool anyFailed = false;
869 moduleOp.walk([&](cir::FuncOp f) {
870 // A complete type is required at any call or definition, so only a
871 // declaration can carry an incomplete-by-value parameter or return type,
872 // and no translation unit can ever call or define it with real argument
873 // data. Leave it unclassified.
874 cir::FuncType fnTy = f.getFunctionType();
875 if (f.isDeclaration() &&
876 (hasIncompleteRecordByValue(fnTy.getReturnType()) ||
877 llvm::any_of(fnTy.getInputs(), hasIncompleteRecordByValue)))
878 return;
879 std::optional<FunctionClassification> fc;
880 if (isX86)
881 fc = classifyX86_64Function(f, dl, *x86TypeMapper,
882 x86TargetFor(avxLevelFor(f)), moduleOp);
883 else
884 fc = classifyFunction(f, dl, target, classificationAttr);
885 if (!fc) {
886 anyFailed = true;
887 return;
888 }
889 classifications.insert({f, std::move(*fc)});
890 });
891 if (anyFailed) {
892 signalPassFailure();
893 return;
894 }
895
896 // Build a callee-to-callers index. One module walk collects every direct
897 // cir.call / cir.try_call to each cir.func; the loop below rewrites a
898 // function and all of its call sites together. Indirect or unresolved
899 // callees are skipped here; rewriteCallSite errors on those at the end.
900 //
901 // A call that passes arguments through an ellipsis gets its own
902 // classification, recorded here while every signature is still in its
903 // original form. The callee's classification covers only its declared
904 // parameters and cannot describe those extra arguments.
905 llvm::DenseMap<cir::FuncOp, SmallVector<Operation *>> callers;
906 // Keyed on the call op collected below, looked up once when that same op is
907 // rewritten. A key must never come from an op created during the rewrite:
908 // a recycled address could match an unrelated entry.
909 llvm::DenseMap<Operation *, FunctionClassification> variadicCallSites;
910 moduleOp.walk([&](Operation *op) {
911 auto call = dyn_cast<cir::CIRCallOpInterface>(op);
912 if (!call)
913 return;
914 cir::FuncOp callee = lookupCallee(op, symbolTable);
915 if (!callee)
916 return;
917 callers[callee].push_back(op);
918
919 // Only the x86_64 driver classifies per call site. Under the other
920 // drivers the classification comes from a fixed per-function source, so
921 // such a call stays short a classification and rewriteCallSite reports it.
922 cir::FuncType calleeTy = callee.getFunctionType();
923 if (!isX86 || call.getNumArgOperands() <= calleeTy.getNumInputs())
924 return;
925 // A callee declared without a prototype also takes more operands than it
926 // declares, and the verifier allows it. Those extra arguments are named
927 // rather than passed through an ellipsis, so the accounting below does not
928 // describe them.
929 if (!calleeTy.isVarArg()) {
930 op->emitOpError() << "extra arguments to a callee without a prototype "
931 "not yet implemented in CallConvLowering";
932 anyFailed = true;
933 return;
934 }
935 // The callee's level, not the caller's: this pass rewrites the definition
936 // and its call sites from one classification, so they have to agree.
937 // Classic instead arranges every call site from the caller and reports a
938 // caller whose level disagrees with its callee in checkFunctionCallABI,
939 // which has no equivalent here yet.
940 std::optional<FunctionClassification> fc =
941 classifyX86_64VariadicCall(call, calleeTy, dl, *x86TypeMapper,
942 x86TargetFor(avxLevelFor(callee)), moduleOp);
943 if (!fc) {
944 anyFailed = true;
945 return;
946 }
947 variadicCallSites.insert({op, std::move(*fc)});
948 });
949 if (anyFailed) {
950 signalPassFailure();
951 return;
952 }
953
954 // A cir.get_global holding a function's address carries the signature the
955 // source wrote, which the verifier ties to the callee, so it goes stale when
956 // that callee is rewritten. A function address in a global initializer is a
957 // GlobalViewAttr instead, whose recorded type the verifier does not tie to
958 // the callee and which is dropped at opaque-pointer lowering, so it needs no
959 // counterpart.
960 llvm::DenseMap<cir::FuncOp, SmallVector<cir::GetGlobalOp>> addressTakers;
961 moduleOp.walk([&](cir::GetGlobalOp getGlobal) {
962 auto ptrTy = cast<cir::PointerType>(getGlobal.getAddr().getType());
963 if (!isa<cir::FuncType>(ptrTy.getPointee()))
964 return;
965 // A get_global's pointee must equal the named symbol's type, and the
966 // GlobalOp verifier rejects a function type there, so this names a
967 // cir.func.
968 auto callee = cast<cir::FuncOp>(symbolTable.lookup(getGlobal.getName()));
969 addressTakers[callee].push_back(getGlobal);
970 });
971
972 // Rewrite each function together with every direct call to it and every op
973 // holding its address. By the time we move on to function F+1, F's
974 // signature and every reference to F have already been brought into
975 // alignment, and F+1..FN are still in their original (mutually consistent)
976 // form, so the IR is verifier-clean at every outer-iteration boundary.
977 //
978 // There is still a brief inner window where F's signature has been
979 // rewritten but its references have not yet caught up -- we have no way to
980 // mutate both sides of a call atomically. No verifier runs inside the
981 // pass, and at pass exit the module is verifier-clean. Fusing the inner
982 // loops here keeps the invalid window per-function rather than module-wide.
983 OpBuilder builder(ctx);
984 for (auto &kv : classifications) {
985 cir::FuncOp func = kv.first;
986 const FunctionClassification &fc = kv.second;
987 if (failed(rewriteCtx.rewriteFunctionDefinition(func, fc, builder))) {
988 signalPassFailure();
989 return;
990 }
991 for (Operation *callOp : callers.lookup(func)) {
992 const FunctionClassification *callFc = &fc;
993 if (auto it = variadicCallSites.find(callOp);
994 it != variadicCallSites.end()) {
995 callFc = &it->second;
996 assert(classifiesSamePrefix(fc, *callFc) &&
997 "a call site's declared parameters must be classified the same "
998 "way as the callee's");
999 }
1000 if (failed(rewriteCtx.rewriteCallSite(callOp, *callFc, builder))) {
1001 signalPassFailure();
1002 return;
1003 }
1004 }
1005 for (cir::GetGlobalOp addrOp : addressTakers.lookup(func))
1006 rewriteCtx.rewriteFunctionAddress(addrOp, func, builder);
1007 }
1008
1009 // Rewrite indirect call sites. The callee is opaque, so classify from the
1010 // function pointer's pointee FuncType and let rewriteCallSite retype the
1011 // callee pointer to match the coerced signature. Collect the calls first:
1012 // when an sret rewrite reuses a single-use store's destination as the return
1013 // slot it erases that store, which is the operation a live walk has already
1014 // cached as the next one to visit.
1015 SmallVector<cir::CIRCallOpInterface> indirectCalls;
1016 moduleOp.walk([&](cir::CIRCallOpInterface c) {
1017 if (indirectCalleeType(c))
1018 indirectCalls.push_back(c);
1019 });
1020 for (cir::CIRCallOpInterface c : indirectCalls) {
1021 // classification-attr mode injects a per-function classification, which
1022 // cannot describe a callee resolved at run time. Report it rather than
1023 // leave the indirect call unrewritten while direct calls are coerced.
1024 if (!classificationAttr.empty()) {
1025 c->emitOpError() << "indirect call cannot be classified in the "
1026 "'classification-attr' driver mode";
1027 signalPassFailure();
1028 return;
1029 }
1030 cir::FuncType funcTy = indirectCalleeType(c);
1031 auto classifySignature =
1032 [&](mlir::TypeRange argTypes) -> std::optional<FunctionClassification> {
1033 // A callee resolved at run time carries no features of its own, so the
1034 // level comes from the function containing the call, which is the
1035 // declaration classic arranges every call site from.
1036 if (isX86)
1037 return classifyX86_64Signature(
1038 funcTy.getReturnType(), argTypes, requiredArgs(funcTy), ctx, dl,
1039 *x86TypeMapper,
1040 x86TargetFor(avxLevelFor(c->getParentOfType<cir::FuncOp>())),
1041 moduleOp, [&]() { return c->emitOpError(); });
1042 return withReturnVoidness(
1043 mlir::abi::test::classify(argTypes, funcTy.getReturnType(), dl),
1044 funcTy.getReturnType());
1045 };
1046
1047 // An argument passed through an ellipsis has no counterpart in the
1048 // pointee's parameter list, so classify the call's own operands to learn
1049 // what the ABI does with it. If nothing in the full list needs a rewrite
1050 // the call already carries its wire form and can stand as written.
1051 // Anything else needs a rewrite the pointee's signature cannot describe,
1052 // since it has no entry for the arguments past the ellipsis.
1053 if (c.getNumArgOperands() > funcTy.getNumInputs()) {
1054 std::optional<FunctionClassification> callFc =
1055 classifySignature(c.getArgOperands().getTypes());
1056 if (!callFc) {
1057 signalPassFailure();
1058 return;
1059 }
1060 if (!callFc->needsRewrite())
1061 continue;
1062 c->emitOpError() << "variadic arguments to an indirect call not yet "
1063 "implemented in CallConvLowering";
1064 signalPassFailure();
1065 return;
1066 }
1067
1068 std::optional<FunctionClassification> fc =
1069 classifySignature(funcTy.getInputs());
1070 if (!fc) {
1071 signalPassFailure();
1072 return;
1073 }
1074 if (failed(rewriteCtx.rewriteCallSite(c.getOperation(), *fc, builder))) {
1075 signalPassFailure();
1076 return;
1077 }
1078 }
1079}
1080
1081} // namespace
1082
1083std::unique_ptr<Pass> mlir::createCallConvLoweringPass() {
1084 return std::make_unique<CallConvLoweringPass>();
1085}
1086
1088 cir::CallConvTarget target, llvm::abi::X86AVXABILevel x86AvxAbiLevel,
1089 bool allowsX86TargetAttrAvx, const llvm::abi::ABICompatInfo &x86AbiCompat) {
1090 CallConvLoweringOptions options;
1091 options.target = target;
1092 options.x86AvxAbiLevel = x86AvxAbiLevel;
1093 options.allowsX86TargetAttrAvx = allowsX86TargetAttrAvx;
1094 return std::make_unique<CallConvLoweringPass>(options, x86AbiCompat);
1095}
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
C++ view class that accepts both !cir.struct and !cir.union types.
Definition CIRTypes.h:143
bool isUnion() const
Definition CIRTypes.h:169
bool isComplete() const
Definition CIRTypes.h:162
bool isEmptyForABI() const
Whether no member holds data.
Definition CIRTypes.cpp:703
llvm::ArrayRef< mlir::Type > getMembers() const
Definition CIRTypes.cpp:603
static llvm::SmallVector< RecordMemberKind > getAllDataKinds(llvm::ArrayRef< mlir::Type > members)
One Data kind per member.
Definition CIRTypes.cpp:168
mlir::StringAttr getName() const
Definition CIRTypes.cpp:608
bool getPadded() const
Definition CIRTypes.cpp:623
llvm::ArrayRef< RecordMemberKind > getMemberKinds() const
Definition CIRTypes.cpp:628
uint64_t getElementOffset(const mlir::DataLayout &dataLayout, unsigned idx) const
Definition CIRTypes.cpp:661
RecordLayoutAttr tryGetRecordLayout(mlir::ModuleOp mod, mlir::StringAttr name)
Same lookup as getRecordLayout, but returns a null attribute instead of asserting when the record has...
Definition CIRAttrs.cpp:923
cir::FPTypeInterface getFloatingPointType(const llvm::fltSemantics &sem, mlir::MLIRContext *ctx)
Returns the CIR floating-point type for the given semantics, or a null type if CIR has no type for it...
Definition CIRTypes.cpp:42
bool isZeroWidthBitField(mlir::Type memberTy, RecordMemberKind kind)
Whether a record member is a zero-width bit-field, spelled as a zero-length array of the bit-field's ...
Definition CIRTypes.cpp:696
bool holdsDataForABI(mlir::Type memberTy, RecordMemberKind kind)
Whether a member holds data for argument passing.
Definition CIRTypes.h:53
bool isBitFieldAccessUnit(RecordMemberKind kind)
Whether a member of this kind is a bit-field access unit holding data.
Definition CIRTypes.h:76
static bool allowsX86TargetAttrAvx(const clang::ASTContext &astContext)
Whether __attribute__((target(...))) on a function may raise its AVX ABI level above the command line...
Definition CIRPasses.cpp:45
CallConvTarget
The ABI target whose calling-convention rules drive CallConvLowering.
Definition Passes.h:23
const internal::VariadicAllOfMatcher< Attr > attr
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition PrimType.h:213
void info(bool Verbose, unsigned Level, const char *Fmt, Ts &&...Args)
Prints an indented note to stderr when Verbose is set.
Definition Utils.h:57
@ Default
Set to the current date and time.
std::unique_ptr< Pass > createCallConvLoweringPass()
static bool addressSpace()
static bool opFuncMultiVersioning()