================
@@ -62,21 +62,60 @@ namespace mlir {
namespace {
//===----------------------------------------------------------------------===//
-// x86_64 System V classifier bridge (scalar types)
+// x86_64 System V classifier bridge (scalar and struct/array types)
//
-// Maps scalar CIR types to llvm::abi::Type, runs the LLVM ABI Lowering
-// Library's SysV x86_64 classifier, and converts the result back into the
+// Maps CIR types to llvm::abi::Type, runs the LLVM ABI Lowering Library's
+// SysV x86_64 classifier, and converts the result back into the
// dialect-agnostic mlir::abi::FunctionClassification that CIRABIRewriteContext
-// consumes. Only integer / pointer / bool / f32 / f64 signatures are handled;
-// aggregates and other leaf types are reported NYI by classifyX86_64Function
+// consumes. Integer / pointer / bool / f32 / f64 scalars and struct / array
+// aggregates are handled; unions, `_BitInt`, `_Complex`, vectors, wider
+// floats, and empty-for-ABI records are reported NYI by classifyX86_64Function
// so an unsupported signature fails the pass instead of being misclassified.
//===----------------------------------------------------------------------===//
-/// The scalar CIR types the x86_64 bridge handles. A regular integer up to
-/// 64 bits, pointer, bool, void, f32, or f64 is a single-register Direct or
-/// Extend argument. `_BitInt`, `__int128`, and wider/other types need
coercion
-/// or indirect passing, which this scalar bridge does not do.
-static bool isSupportedScalarType(mlir::Type ty) {
+/// Proxy for the AST notion of an empty record (a C++ empty class): CIRGen
+/// materializes an empty class as a single padding byte, so a record whose
+/// members are all single-byte i8 arrays is empty for ABI purposes. A real
+/// `char` array of size > 1 is data, not padding. The bridge only uses this
+/// to reject empty records -- classifying them as Ignore is reported NYI in
+/// classifyX86_64Function. A struct that merely contains an empty record is
+/// rejected too, but through the member recursion in isSupportedType.
+static bool recordIsEmptyForABI(cir::RecordType recTy) {
+ for (mlir::Type m : recTy.getMembers()) {
+ auto arr = dyn_cast<cir::ArrayType>(m);
+ if (!arr)
+ return false;
+ auto elt = dyn_cast<cir::IntType>(arr.getElementType());
+ if (!elt || elt.getWidth() != 8 || arr.getSize() != 1)
+ return false;
+ }
+ return true;
+}
+
+/// Whether a struct's declared argument-passing kind (from the module's
+/// record-layout metadata) allows it to be passed in registers. A record with
+/// no layout entry (e.g. an anonymous struct) has no C++ non-trivial reason to
+/// be forced to memory, so it defaults to can-pass-in-registers.
+static bool recordCanPassInRegs(ModuleOp module, cir::RecordType recTy) {
+ mlir::StringAttr name = recTy.getName();
+ if (!name)
+ return true;
+ auto dict = module->getAttrOfType<DictionaryAttr>(
+ cir::CIRDialect::getRecordLayoutsAttrName());
+ auto layout =
+ dict ? dict.getAs<cir::RecordLayoutAttr>(name) : cir::RecordLayoutAttr();
----------------
adams381 wrote:
Done.
https://github.com/llvm/llvm-project/pull/210528
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits