aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Saldivar <miguel.saldivar@hpe.com>2025-09-03 02:24:21 -0700
committerGitHub <noreply@github.com>2025-09-03 10:24:21 +0100
commitbe1e50f56af8e270a0396eef8f62626fbbb84996 (patch)
tree2f3b2909b4c32149e40591214bb49e44ab011aaf
parent759a2ac5b0ee09be9dbb51ad50143d7db990a94a (diff)
downloadllvm-be1e50f56af8e270a0396eef8f62626fbbb84996.zip
llvm-be1e50f56af8e270a0396eef8f62626fbbb84996.tar.gz
llvm-be1e50f56af8e270a0396eef8f62626fbbb84996.tar.bz2
[flang] Avoid unnecessary looping for constants (#156403)
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
-rw-r--r--flang/lib/Lower/ConvertConstant.cpp22
1 files changed, 21 insertions, 1 deletions
diff --git a/flang/lib/Lower/ConvertConstant.cpp b/flang/lib/Lower/ConvertConstant.cpp
index 768a237..376ec12 100644
--- a/flang/lib/Lower/ConvertConstant.cpp
+++ b/flang/lib/Lower/ConvertConstant.cpp
@@ -145,6 +145,9 @@ private:
fir::FirOpBuilder &builder,
const Fortran::evaluate::Constant<Fortran::evaluate::Type<TC, KIND>>
&constant) {
+ using Element =
+ Fortran::evaluate::Scalar<Fortran::evaluate::Type<TC, KIND>>;
+
static_assert(TC != Fortran::common::TypeCategory::Character,
"must be numerical or logical");
auto attrTc = TC == Fortran::common::TypeCategory::Logical
@@ -152,7 +155,24 @@ private:
: TC;
attributeElementType =
Fortran::lower::getFIRType(builder.getContext(), attrTc, KIND, {});
- for (auto element : constant.values())
+
+ const std::vector<Element> &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<TC, KIND>(builder, values.front(),
+ attributeElementType);
+ attributes.assign(values.size(), attr);
+ return;
+ }
+
+ for (auto element : values)
attributes.push_back(
convertToAttribute<TC, KIND>(builder, element, attributeElementType));
}