diff options
author | Miguel Saldivar <miguel.saldivar@hpe.com> | 2025-09-03 02:24:21 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-03 10:24:21 +0100 |
commit | be1e50f56af8e270a0396eef8f62626fbbb84996 (patch) | |
tree | 2f3b2909b4c32149e40591214bb49e44ab011aaf | |
parent | 759a2ac5b0ee09be9dbb51ad50143d7db990a94a (diff) | |
download | llvm-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.cpp | 22 |
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)); } |