From 5524192d13ca0d9ba3415f590034d55398035fd7 Mon Sep 17 00:00:00 2001 From: Miguel Saldivar Date: Mon, 1 Sep 2025 23:48:37 -0500 Subject: [PATCH] [flang] Avoid unnecessary looping for constants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going through and doing `convertToAttribute` for all elements, if they are the same can be costly. If the elements are the same, we can just call `convertToAttribute` once. This does give us a significant speed-up: ```console $ hyperfine --warmup 1 --runs 5 ./slow.sh ./fast.sh Benchmark 1: ./slow.sh Time (mean ± σ): 1.606 s ± 0.014 s [User: 1.393 s, System: 0.087 s] Range (min … max): 1.591 s … 1.628 s 5 runs Benchmark 2: ./fast.sh Time (mean ± σ): 452.9 ms ± 7.6 ms [User: 249.9 ms, System: 83.3 ms] Range (min … max): 443.9 ms … 461.7 ms 5 runs Summary ./fast.sh ran 3.55 ± 0.07 times faster than ./slow.sh ``` Fixes #125444 --- flang/lib/Lower/ConvertConstant.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/flang/lib/Lower/ConvertConstant.cpp b/flang/lib/Lower/ConvertConstant.cpp index 768a237c92396..376ec12150c71 100644 --- a/flang/lib/Lower/ConvertConstant.cpp +++ b/flang/lib/Lower/ConvertConstant.cpp @@ -145,6 +145,9 @@ class DenseGlobalBuilder { fir::FirOpBuilder &builder, const Fortran::evaluate::Constant> &constant) { + using Element = + Fortran::evaluate::Scalar>; + static_assert(TC != Fortran::common::TypeCategory::Character, "must be numerical or logical"); auto attrTc = TC == Fortran::common::TypeCategory::Logical @@ -152,7 +155,24 @@ class DenseGlobalBuilder { : TC; attributeElementType = Fortran::lower::getFIRType(builder.getContext(), attrTc, KIND, {}); - for (auto element : constant.values()) + + const std::vector &values = constant.values(); + auto sameElements = [&]() -> bool { + if (values.empty()) + return false; + + return std::all_of(values.begin(), values.end(), + [&](const auto &v) { return v == values.front(); }); + }; + + if (sameElements()) { + auto attr = convertToAttribute(builder, values.front(), + attributeElementType); + attributes.assign(values.size(), attr); + return; + } + + for (auto element : values) attributes.push_back( convertToAttribute(builder, element, attributeElementType)); }