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

Reply via email to