[flang-commits] [flang] [flang][OpenMP] Rewrite min/max with more than 2 arguments (PR #146423)
Krzysztof Parzyszek via flang-commits
flang-commits at lists.llvm.org
Tue Jul 1 06:04:04 PDT 2025
================
@@ -41,6 +43,178 @@ namespace omp {
using namespace Fortran::lower::omp;
}
+namespace {
+// An example of a type that can be used to get the return value from
+// the visitor:
+// visitor(type_identity<Xyz>) -> result_type
+using SomeArgType = evaluate::Type<common::TypeCategory::Integer, 4>;
+
+struct GetProc
+ : public evaluate::Traverse<GetProc, const evaluate::ProcedureDesignator *,
+ false> {
+ using Result = const evaluate::ProcedureDesignator *;
+ using Base = evaluate::Traverse<GetProc, Result, false>;
+ GetProc() : Base(*this) {}
+
+ using Base::operator();
+
+ static Result Default() { return nullptr; }
+
+ Result operator()(const evaluate::ProcedureDesignator &p) const { return &p; }
+ static Result Combine(Result a, Result b) { return a != nullptr ? a : b; }
+};
+
+struct WithType {
+ WithType(const evaluate::DynamicType &t) : type(t) {
+ assert(type.category() != common::TypeCategory::Derived &&
+ "Type cannot be a derived type");
+ }
+
+ template <typename VisitorTy> //
+ auto visit(VisitorTy &&visitor) const
+ -> std::invoke_result_t<VisitorTy, SomeArgType> {
+ switch (type.category()) {
+ case common::TypeCategory::Integer:
+ switch (type.kind()) {
+ case 1:
+ return visitor(llvm::type_identity<evaluate::Type<Integer, 1>>{});
+ case 2:
+ return visitor(llvm::type_identity<evaluate::Type<Integer, 2>>{});
+ case 4:
+ return visitor(llvm::type_identity<evaluate::Type<Integer, 4>>{});
+ case 8:
+ return visitor(llvm::type_identity<evaluate::Type<Integer, 8>>{});
+ case 16:
+ return visitor(llvm::type_identity<evaluate::Type<Integer, 16>>{});
+ }
+ break;
+ case common::TypeCategory::Unsigned:
+ switch (type.kind()) {
+ case 1:
+ return visitor(llvm::type_identity<evaluate::Type<Unsigned, 1>>{});
+ case 2:
+ return visitor(llvm::type_identity<evaluate::Type<Unsigned, 2>>{});
+ case 4:
+ return visitor(llvm::type_identity<evaluate::Type<Unsigned, 4>>{});
+ case 8:
+ return visitor(llvm::type_identity<evaluate::Type<Unsigned, 8>>{});
+ case 16:
+ return visitor(llvm::type_identity<evaluate::Type<Unsigned, 16>>{});
+ }
+ break;
+ case common::TypeCategory::Real:
+ switch (type.kind()) {
+ case 2:
+ return visitor(llvm::type_identity<evaluate::Type<Real, 2>>{});
+ case 3:
+ return visitor(llvm::type_identity<evaluate::Type<Real, 3>>{});
+ case 4:
+ return visitor(llvm::type_identity<evaluate::Type<Real, 4>>{});
+ case 8:
+ return visitor(llvm::type_identity<evaluate::Type<Real, 8>>{});
+ case 10:
+ return visitor(llvm::type_identity<evaluate::Type<Real, 10>>{});
+ case 16:
+ return visitor(llvm::type_identity<evaluate::Type<Real, 16>>{});
+ }
+ break;
+ case common::TypeCategory::Complex:
+ switch (type.kind()) {
+ case 2:
+ return visitor(llvm::type_identity<evaluate::Type<Complex, 2>>{});
+ case 3:
+ return visitor(llvm::type_identity<evaluate::Type<Complex, 3>>{});
+ case 4:
+ return visitor(llvm::type_identity<evaluate::Type<Complex, 4>>{});
+ case 8:
+ return visitor(llvm::type_identity<evaluate::Type<Complex, 8>>{});
+ case 10:
+ return visitor(llvm::type_identity<evaluate::Type<Complex, 10>>{});
+ case 16:
+ return visitor(llvm::type_identity<evaluate::Type<Complex, 16>>{});
+ }
+ break;
+ case common::TypeCategory::Logical:
+ switch (type.kind()) {
+ case 1:
+ return visitor(llvm::type_identity<evaluate::Type<Logical, 1>>{});
+ case 2:
+ return visitor(llvm::type_identity<evaluate::Type<Logical, 2>>{});
+ case 4:
+ return visitor(llvm::type_identity<evaluate::Type<Logical, 4>>{});
+ case 8:
+ return visitor(llvm::type_identity<evaluate::Type<Logical, 8>>{});
+ }
+ break;
+ case common::TypeCategory::Character:
+ switch (type.kind()) {
+ case 1:
+ return visitor(llvm::type_identity<evaluate::Type<Character, 1>>{});
+ case 2:
+ return visitor(llvm::type_identity<evaluate::Type<Character, 2>>{});
+ case 4:
+ return visitor(llvm::type_identity<evaluate::Type<Character, 4>>{});
+ }
+ break;
+ case common::TypeCategory::Derived:
+ break;
+ }
+ llvm_unreachable("Unhandled type");
+ }
+
+ const evaluate::DynamicType &type;
+
+private:
+ // Shorter names.
+ static constexpr auto Character = common::TypeCategory::Character;
+ static constexpr auto Complex = common::TypeCategory::Complex;
+ static constexpr auto Derived = common::TypeCategory::Derived;
----------------
kparzysz wrote:
Fixed.
https://github.com/llvm/llvm-project/pull/146423
More information about the flang-commits
mailing list