[flang-commits] [flang] [llvm] [flang][OpenMP] Overhaul implementation of ATOMIC construct (PR #137852)
Tom Eccles via flang-commits
flang-commits at lists.llvm.org
Mon Jun 2 04:11:55 PDT 2025
================
@@ -1756,4 +1757,318 @@ bool HadUseError(
}
}
+namespace operation {
+template <typename T> //
+SomeExpr asSomeExpr(const T &x) {
+ auto copy{x};
+ return AsGenericExpr(std::move(copy));
+}
+
+template <bool IgnoreResizingConverts> //
+struct ArgumentExtractor
+ : public evaluate::Traverse<ArgumentExtractor<IgnoreResizingConverts>,
+ std::pair<operation::Operator, std::vector<SomeExpr>>, false> {
+ using Arguments = std::vector<SomeExpr>;
+ using Result = std::pair<operation::Operator, Arguments>;
+ using Base = evaluate::Traverse<ArgumentExtractor<IgnoreResizingConverts>,
+ Result, false>;
+ static constexpr auto IgnoreResizes = IgnoreResizingConverts;
+ static constexpr auto Logical = common::TypeCategory::Logical;
+ ArgumentExtractor() : Base(*this) {}
+
+ Result Default() const { return {}; }
+
+ using Base::operator();
+
+ template <int Kind> //
+ Result operator()(
+ const evaluate::Constant<evaluate::Type<Logical, Kind>> &x) const {
+ if (const auto &val{x.GetScalarValue()}) {
+ return val->IsTrue()
+ ? std::make_pair(operation::Operator::True, Arguments{})
+ : std::make_pair(operation::Operator::False, Arguments{});
+ }
+ return Default();
+ }
+
+ template <typename R> //
+ Result operator()(const evaluate::FunctionRef<R> &x) const {
+ Result result{operation::OperationCode(x.proc()), {}};
+ for (size_t i{0}, e{x.arguments().size()}; i != e; ++i) {
+ if (auto *e{x.UnwrapArgExpr(i)}) {
+ result.second.push_back(*e);
+ }
+ }
+ return result;
+ }
+
+ template <typename D, typename R, typename... Os>
+ Result operator()(const evaluate::Operation<D, R, Os...> &x) const {
+ if constexpr (std::is_same_v<D, evaluate::Parentheses<R>>) {
+ // Ignore top-level parentheses.
+ return (*this)(x.template operand<0>());
+ }
+ if constexpr (IgnoreResizes &&
+ std::is_same_v<D, evaluate::Convert<R, R::category>>) {
+ // Ignore conversions within the same category.
+ // Atomic operations on int(kind=1) may be implicitly widened
+ // to int(kind=4) for example.
+ return (*this)(x.template operand<0>());
+ } else {
+ return std::make_pair(operation::OperationCode(x),
+ OperationArgs(x, std::index_sequence_for<Os...>{}));
+ }
+ }
+
+ template <typename T> //
+ Result operator()(const evaluate::Designator<T> &x) const {
+ return {operation::Operator::Identity, {asSomeExpr(x)}};
+ }
+
+ template <typename T> //
+ Result operator()(const evaluate::Constant<T> &x) const {
+ return {operation::Operator::Identity, {asSomeExpr(x)}};
+ }
+
+ template <typename... Rs> //
+ Result Combine(Result &&result, Rs &&...results) const {
+ // There shouldn't be any combining needed, since we're stopping the
+ // traversal at the top-level operation, but implement one that picks
+ // the first non-empty result.
+ if constexpr (sizeof...(Rs) == 0) {
+ return std::move(result);
+ } else {
+ if (!result.second.empty()) {
+ return std::move(result);
+ } else {
+ return Combine(std::move(results)...);
+ }
+ }
+ }
+
+private:
+ template <typename D, typename R, typename... Os, size_t... Is>
+ Arguments OperationArgs(const evaluate::Operation<D, R, Os...> &x,
+ std::index_sequence<Is...>) const {
+ return Arguments{SomeExpr(x.template operand<Is>())...};
+ }
+};
+} // namespace operation
+
+std::string operation::ToString(operation::Operator op) {
+ switch (op) {
+ default:
----------------
tblah wrote:
I have an error here with -Werror on clang:
```
/home/$USER/llvm-project/flang/lib/Semantics/tools.cpp:1860:3: error: default label in switch which covers all enumeration values [-Werror,-Wcovered-switch-default]
1860 | default:
| ^
1 error generated.
```
https://github.com/llvm/llvm-project/pull/137852
More information about the flang-commits
mailing list