From 22ee837ec0ae5c097fa8e2cf49bfc504664f5ebe Mon Sep 17 00:00:00 2001 From: jeanPerier Date: Wed, 25 Jun 2025 11:51:07 +0200 Subject: [PATCH] [flang][NFC] do not copy fields in fir::RecordType::getTypeList (#145530) For historical reason, `fir::RecordType::getTypeList` was returning an std::vector, causing the entire field list to be copied when called. It is called a lot indirectly in all type helpers, which themselves are called a lot in derived type heavy code like WRF. The `fir::hasDynamicType` helper is also called a lot, and it can just check for length parameters to avoid looping on all derived type components in most cases. --- flang/include/flang/Optimizer/Dialect/FIRTypes.td | 3 ++- flang/lib/Optimizer/Dialect/FIRType.cpp | 6 ++++-- flang/test/Fir/convert-to-llvm.fir | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/flang/include/flang/Optimizer/Dialect/FIRTypes.td b/flang/include/flang/Optimizer/Dialect/FIRTypes.td index 6fad77dffd9b..0ead54df3ca9 100644 --- a/flang/include/flang/Optimizer/Dialect/FIRTypes.td +++ b/flang/include/flang/Optimizer/Dialect/FIRTypes.td @@ -330,7 +330,8 @@ def fir_RecordType : FIR_Type<"Record", "type"> { let extraClassDeclaration = [{ using TypePair = std::pair; - using TypeList = std::vector; + using TypeList = llvm::ArrayRef; + using TypeVector = llvm::SmallVector; TypeList getTypeList() const; TypeList getLenParamList() const; diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp index 78571f1f4bc2..2ff1d6d945ba 100644 --- a/flang/lib/Optimizer/Dialect/FIRType.cpp +++ b/flang/lib/Optimizer/Dialect/FIRType.cpp @@ -261,6 +261,8 @@ mlir::Type dyn_cast_ptrOrBoxEleTy(mlir::Type t) { } static bool hasDynamicSize(fir::RecordType recTy) { + if (recTy.getLenParamList().empty()) + return false; for (auto field : recTy.getTypeList()) { if (auto arr = mlir::dyn_cast(field.second)) { if (sequenceWithNonConstantShape(arr)) @@ -1006,7 +1008,7 @@ mlir::Type fir::RecordType::parse(mlir::AsmParser &parser) { return {}; RecordType result = RecordType::get(parser.getContext(), name); - RecordType::TypeList lenParamList; + RecordType::TypeVector lenParamList; if (!parser.parseOptionalLParen()) { while (true) { llvm::StringRef lenparam; @@ -1024,7 +1026,7 @@ mlir::Type fir::RecordType::parse(mlir::AsmParser &parser) { return {}; } - RecordType::TypeList typeList; + RecordType::TypeVector typeList; if (!parser.parseOptionalLess()) { result.pack(true); } diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir index 6d8a8bb606b9..0e2bfe48a807 100644 --- a/flang/test/Fir/convert-to-llvm.fir +++ b/flang/test/Fir/convert-to-llvm.fir @@ -1817,8 +1817,8 @@ func.func private @custom_typeP.field_1.offset() -> i32 func.func private @custom_typeP.field_2.offset() -> i32 func.func @field_index_dynamic_size() -> () { - %1 = fir.field_index field_1, !fir.type}> - %2 = fir.field_index field_2, !fir.type}> + %1 = fir.field_index field_1, !fir.type}> + %2 = fir.field_index field_2, !fir.type}> return }