https://github.com/agozillon updated https://github.com/llvm/llvm-project/pull/228748
>From 98df6adda4ac0d514bf0e10db6fd5a0d1bcc75af Mon Sep 17 00:00:00 2001 From: agozillon <[email protected]> Date: Fri, 2 Oct 2026 06:45:12 -0500 Subject: [PATCH 1/2] [Flang][OpenMP] Flag for switching off implicit allocatable member mapping via default declare mapper Part of the OpenMP specification requires implicitly mappiing allocatable members in derived types. However, it is quite an expensive overhead to perform implicit allocatable member mapping as it requires a mapper to do so due to the nature of possibly nested allocatable derived types etc. Alongside a fairly comprehensive map of the record, this in particular comes at a fairly substantial cost for arrays of derived types that trigger this behaviour. Some of this may or may not be mitigatable over time. But for the moment this PR seeks to follow the example of other Fortran OpenMP compilers (Cray in particular I think) and utilise a flag that can switch this behaviour on and off, so that applications not depending on the crutch of this implicit mapping can deactivte it and not pay the overhead, and those that like the compiler to do this for them can continue to do so. --- clang/include/clang/Options/FlangOptions.td | 6 ++ clang/lib/Driver/ToolChains/Flang.cpp | 10 +++ .../include/flang/Frontend/CodeGenOptions.def | 1 + flang/include/flang/Support/Flags.h | 1 + flang/lib/Frontend/CompilerInvocation.cpp | 5 ++ flang/lib/Frontend/FrontendActions.cpp | 6 ++ flang/lib/Lower/OpenMP/OpenMP.cpp | 4 +- flang/lib/Lower/OpenMP/Utils.cpp | 13 ++- flang/lib/Lower/OpenMP/Utils.h | 3 +- flang/lib/Support/Flags.cpp | 6 ++ flang/test/Driver/omp-driver-offload.f90 | 41 ++++++++++ ...efault-mapper-allocatable-members-flag.f90 | 81 +++++++++++++++++++ 12 files changed, 172 insertions(+), 5 deletions(-) create mode 100644 flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag.f90 diff --git a/clang/include/clang/Options/FlangOptions.td b/clang/include/clang/Options/FlangOptions.td index 662360725afea0..7447ba458954f1 100644 --- a/clang/include/clang/Options/FlangOptions.td +++ b/clang/include/clang/Options/FlangOptions.td @@ -318,6 +318,12 @@ def fdo_concurrent_to_openmp_EQ : Joined<["-"], "fdo-concurrent-to-openmp=">, HelpText<"Try to map `do concurrent` loops to OpenMP [none|host|device]">, Values<"none, host, device">; +def fimplicit_default_mapper_allocatable_members : Flag<["-"], "fimplicit-default-mapper-allocatable-members">, + Group<f_Group>, HelpText<"Enable implicit allocatable member maps in compiler-generated OpenMP default mappers">; +def fno_implicit_default_mapper_allocatable_members : Flag<["-"], "fno-implicit-default-mapper-allocatable-members">, + Group<f_Group>, HelpText<"Disable implicit allocatable member maps in compiler-generated OpenMP default mappers">; + + def J : JoinedOrSeparate<["-"], "J">, Flags<[RenderJoined]>, Group<gfortran_Group>, Alias<module_dir>; diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 97d9dd1c501d99..97e181febf775b 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -882,6 +882,16 @@ void Flang::addOffloadOptions(Compilation &C, const InputInfoList &Inputs, /*Default=*/false)) CmdArgs.push_back("-fopenmp-assume-threads-oversubscription"); + // This forwards the option to switch off/on mapper generation for scenarios + // where the compiler considers it neccessary to generate a mapper to cover + // implicit allocatable member mapping inside of derived types to adhere to + // specification compliance. + if (!Args.hasFlag( + options::OPT_fimplicit_default_mapper_allocatable_members, + options::OPT_fno_implicit_default_mapper_allocatable_members, + /*Default=*/true)) + CmdArgs.push_back("-fno-implicit-default-mapper-allocatable-members"); + if (IsOpenMPDevice) { // -fopenmp-is-target-device is passed along to tell the frontend that it is // generating code for a device, so that only the relevant code is emitted. diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def index 569a6aa289ca31..bae78887f4ce09 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.def +++ b/flang/include/flang/Frontend/CodeGenOptions.def @@ -63,6 +63,7 @@ CODEGENOPT(DwarfVersion, 3, 0) ///< Dwarf version CODEGENOPT(DebugInfoForProfiling, 1, 0) ///< Emit extra debug info to make sample profile more accurate. CODEGENOPT(PseudoProbeForProfiling, 1, 0) ///< Emit pseudo probes for sample profiling. CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Append MD5 hash to internal linkage symbols. +CODEGENOPT(ImplicitDefaultMapperAllocatableMembers, 1, 1) ///< Map allocatable members in generated OpenMP default mappers. CODEGENOPT(Underscoring, 1, 1) ENUM_CODEGENOPT(FPMaxminBehavior, Fortran::common::FPMaxminBehavior, 2, Fortran::common::FPMaxminBehavior::Legacy) diff --git a/flang/include/flang/Support/Flags.h b/flang/include/flang/Support/Flags.h index bcbb72f8e50d05..1dbfa249b87bd0 100644 --- a/flang/include/flang/Support/Flags.h +++ b/flang/include/flang/Support/Flags.h @@ -13,5 +13,6 @@ extern llvm::cl::opt<bool> enableDelayedPrivatization; extern llvm::cl::opt<bool> enableDelayedPrivatizationStaging; +extern llvm::cl::opt<bool> enableImplicitDefaultMapperAllocatableMembers; #endif // FORTRAN_SUPPORT_FLAGS_H_ diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 3db32a62c363f6..ddcdc92fc95264 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -565,6 +565,11 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, opts.Underscoring = 0; } + opts.ImplicitDefaultMapperAllocatableMembers = args.hasFlag( + clang::options::OPT_fimplicit_default_mapper_allocatable_members, + clang::options::OPT_fno_implicit_default_mapper_allocatable_members, + /*Default=*/true); + if (const llvm::opt::Arg *arg = args.getLastArg(clang::options::OPT_complex_range_EQ)) { llvm::StringRef argValue = llvm::StringRef(arg->getValue()); diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index 95cd8ac0eff532..c2bb21759b6b88 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -27,6 +27,7 @@ #include "flang/Optimizer/Transforms/Passes.h" #include "flang/Semantics/runtime-type-info.h" #include "flang/Semantics/unparse-with-symbols.h" +#include "flang/Support/Flags.h" #include "flang/Support/default-kinds.h" #include "flang/Tools/CrossToolHelpers.h" @@ -255,6 +256,11 @@ bool CodeGenAction::beginSourceFileAction() { if (!res) return res; + enableImplicitDefaultMapperAllocatableMembers.setValue( + ci.getInvocation() + .getCodeGenOpts() + .ImplicitDefaultMapperAllocatableMembers); + timingScopeParse.stop(); mlir::TimingScope timingScopeMLIRGen = timingScopeRoot.nest( mlir::TimingIdentifier::get(timingIdMLIRGen, timingMgr)); diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 0569e93d8c0a76..308bee555966e4 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -4254,7 +4254,9 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable, // where the record type contains an allocatable. if (!isPointer && (hasDefaultMapper || - (requiresImplicitDefaultDeclareMapper(*typeSpec)))) { + (requiresImplicitDefaultDeclareMapper( + *typeSpec, + enableImplicitDefaultMapperAllocatableMembers)))) { if (!hasDefaultMapper) { if (auto recordType = mlir::dyn_cast_or_null<fir::RecordType>( converter.genType(*typeSpec))) diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp index 9e37c02eac3f1f..636c8037a2a524 100644 --- a/flang/lib/Lower/OpenMP/Utils.cpp +++ b/flang/lib/Lower/OpenMP/Utils.cpp @@ -37,6 +37,7 @@ #include <flang/Semantics/symbol.h> #include <flang/Semantics/tools.h> #include <flang/Semantics/type.h> +#include <flang/Support/Flags.h> #include <flang/Utils/OpenMP.h> #include <llvm/ADT/STLExtras.h> #include <llvm/ADT/SmallPtrSet.h> @@ -76,7 +77,13 @@ namespace Fortran { namespace lower { namespace omp { bool requiresImplicitDefaultDeclareMapper( - const semantics::DerivedTypeSpec &typeSpec) { + const semantics::DerivedTypeSpec &typeSpec, + bool enableImplicitDefaultMapperAllocatableMembers) { + // If disabled via -fno-implicit-default-mapper-allocatable-members + // return false, as we do not need to emit allocatable member maps. + if (!enableImplicitDefaultMapperAllocatableMembers) + return false; + llvm::SmallPtrSet<const semantics::DerivedTypeSpec *, 8> visited; std::function<bool(const semantics::DerivedTypeSpec &)> requiresMapper = @@ -1266,8 +1273,8 @@ mlir::FlatSymbolRefAttr resolveMapperId( bool isImplicitMap = (mapTypeBits & mlir::omp::ClauseMapFlags::implicit) == mlir::omp::ClauseMapFlags::implicit; - bool needsDefaultMapper = - requiresImplicitDefaultDeclareMapper(*objectTypeSpec); + bool needsDefaultMapper = requiresImplicitDefaultDeclareMapper( + *objectTypeSpec, enableImplicitDefaultMapperAllocatableMembers); // For implicit captures, avoid synthesizing default mappers for // pointer entities (which can over-map pointer payloads) and for // plain non-allocatable/non-pointer entities. Keep implicit mapper diff --git a/flang/lib/Lower/OpenMP/Utils.h b/flang/lib/Lower/OpenMP/Utils.h index c769380aabbb01..6112d0c639b975 100644 --- a/flang/lib/Lower/OpenMP/Utils.h +++ b/flang/lib/Lower/OpenMP/Utils.h @@ -146,7 +146,8 @@ mlir::Value createParentSymAndGenIntermediateMaps( mlir::omp::ClauseMapFlags mapTypeBits); bool requiresImplicitDefaultDeclareMapper( - const semantics::DerivedTypeSpec &typeSpec); + const semantics::DerivedTypeSpec &typeSpec, + bool enableImplicitDefaultMapperAllocatableMembers); omp::ObjectList gatherObjectsOf(omp::Object derivedTypeMember, semantics::SemanticsContext &semaCtx); diff --git a/flang/lib/Support/Flags.cpp b/flang/lib/Support/Flags.cpp index 250232448ee94e..ea5428590e5d91 100644 --- a/flang/lib/Support/Flags.cpp +++ b/flang/lib/Support/Flags.cpp @@ -18,3 +18,9 @@ llvm::cl::opt<bool> enableDelayedPrivatizationStaging( llvm::cl::desc("For partially supported constructs, emit private/local " "variables as clauses/specifiers on MLIR ops."), llvm::cl::init(false)); + +llvm::cl::opt<bool> enableImplicitDefaultMapperAllocatableMembers( + "enable-implicit-default-mapper-allocatable-members", + llvm::cl::desc("Emit implicit mappers for implicit allocatable member " + "mapping in derived types for specification compliance"), + llvm::cl::init(true)); diff --git a/flang/test/Driver/omp-driver-offload.f90 b/flang/test/Driver/omp-driver-offload.f90 index fccd0771d040cb..4d8c9148592ce7 100644 --- a/flang/test/Driver/omp-driver-offload.f90 +++ b/flang/test/Driver/omp-driver-offload.f90 @@ -230,3 +230,44 @@ ! OFFLOAD-TARGETS-NOT: --offload-targets ! OFFLOAD-TARGETS: "{{[^"]*}}flang{{[^"]*}}" "-fc1" "-triple" "x86_64-unknown-linux-gnu" ! OFFLOAD-TARGETS-SAME: "--offload-targets=amdgpu-amd-amdhsa" + +! Verify the implicit default mapper allocatable members flags are applied to both host +! and device phases of the offload compilation when the negative flag is used and ignored +! in the positive case as it is the default. + +! RUN: %flang -S -### %s -o %t 2>&1 \ +! RUN: -fopenmp -fimplicit-default-mapper-allocatable-members --offload-arch=gfx90a \ +! RUN: --target=x86_64-unknown-linux-gnu -nogpulib \ +! RUN: | FileCheck %s --check-prefix=ENABLE-IMP-MAPPER + +! ENABLE-IMP-MAPPER: "{{[^"]*}}flang{{[^"]*}}" "-fc1" "-triple" "x86_64-unknown-linux-gnu" +! ENABLE-IMP-MAPPER-SAME: "-fopenmp" +! ENABLE-IMP-MAPPER-SAME: "--offload-targets=amdgpu-amd-amdhsa" +! ENABLE-IMP-MAPPER-NOT: implicit-default-mapper-allocatable-members +! ENABLE-IMP-MAPPER-NEXT: "{{[^"]*}}flang{{[^"]*}}" "-fc1" "-triple" "amdgpu9.0a-amd-amdhsa" +! ENABLE-IMP-MAPPER-SAME: "-fopenmp" +! ENABLE-IMP-MAPPER-NOT: implicit-default-mapper-allocatable-members + +! RUN: %flang -S -### %s -o %t 2>&1 \ +! RUN: -fopenmp -fno-implicit-default-mapper-allocatable-members --offload-arch=gfx90a \ +! RUN: --target=x86_64-unknown-linux-gnu -nogpulib \ +! RUN: | FileCheck %s --check-prefix=DISABLE-IMP-MAPPER + +! DISABLE-IMP-MAPPER: "{{[^"]*}}flang{{[^"]*}}" "-fc1" "-triple" "x86_64-unknown-linux-gnu" +! DISABLE-IMP-MAPPER-SAME: "-fopenmp" {{.*}} "-fno-implicit-default-mapper-allocatable-members" +! DISABLE-IMP-MAPPER-NEXT: "{{[^"]*}}flang{{[^"]*}}" "-fc1" "-triple" "amdgpu9.0a-amd-amdhsa" +! DISABLE-IMP-MAPPER-SAME: "-fopenmp" {{.*}} "-fno-implicit-default-mapper-allocatable-members" + +! Verify when multiple flags passed the final flag wins out + +! RUN: %flang -S -### %s -o %t 2>&1 \ +! RUN: -fopenmp -fimplicit-default-mapper-allocatable-members \ +! RUN: -fimplicit-default-mapper-allocatable-members \ +! RUN: --offload-arch=gfx90a -fno-implicit-default-mapper-allocatable-members \ +! RUN: --target=x86_64-unknown-linux-gnu -nogpulib \ +! RUN: | FileCheck %s --check-prefix=MULTI-IMP-MAPPER + +! MULTI-IMP-MAPPER: "{{[^"]*}}flang{{[^"]*}}" "-fc1" "-triple" "x86_64-unknown-linux-gnu" +! MULTI-IMP-MAPPER-SAME: "-fopenmp" {{.*}} "-fno-implicit-default-mapper-allocatable-members" +! MULTI-IMP-MAPPER-NEXT: "{{[^"]*}}flang{{[^"]*}}" "-fc1" "-triple" "amdgpu9.0a-amd-amdhsa" +! MULTI-IMP-MAPPER-SAME: "-fopenmp" {{.*}} "-fno-implicit-default-mapper-allocatable-members" diff --git a/flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag.f90 b/flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag.f90 new file mode 100644 index 00000000000000..2504dc86eb95d5 --- /dev/null +++ b/flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag.f90 @@ -0,0 +1,81 @@ +! RUN: rm -rf %t && split-file %s %t +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/implicit.f90 -o - | FileCheck %s --check-prefix=IMPLICIT-ON +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -fimplicit-default-mapper-allocatable-members %t/implicit.f90 -o - | FileCheck %s --check-prefix=IMPLICIT-ON +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -fno-implicit-default-mapper-allocatable-members %t/implicit.f90 -o - | FileCheck %s --check-prefix=IMPLICIT-OFF +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/explicit.f90 -o - | FileCheck %s --check-prefix=EXPLICIT-ON +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -fimplicit-default-mapper-allocatable-members %t/explicit.f90 -o - | FileCheck %s --check-prefix=EXPLICIT-ON +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -fno-implicit-default-mapper-allocatable-members %t/explicit.f90 -o - | FileCheck %s --check-prefix=EXPLICIT-OFF + +! Check the -f[no-]implicit-default-mapper-allocatable-members switch. +! +! With the default/on setting, compiler-generated implicit default mappers for +! derived types include maps for allocatable and nested-record components. +! With the off setting, those component maps are suppressed. Cover both: +! 1. an implicit target-region capture; and +! 2. an explicit whole-object map that would otherwise synthesize a default +! mapper for the derived type. + +!--- implicit.f90 +program implicit_capture + implicit none + + type :: t + integer, allocatable :: a(:) + end type + + type(t) :: x + + allocate(x%a(1)) + + !$omp target + x%a(1) = 1 + !$omp end target +end program + +!--- explicit.f90 +program explicit_whole_object_map + implicit none + + type :: t + integer :: scalar + integer, allocatable :: a(:) + end type + + type(t) :: x + + allocate(x%a(1)) + x%scalar = 1 + + !$omp target map(tofrom: x) + x%scalar = x%scalar + 1 + x%a(1) = x%a(1) + 1 + !$omp end target +end program + +! IMPLICIT-ON: omp.declare_mapper @[[IM_MAPPER:_QQFt_omp_default_mapper]] +! IMPLICIT-ON: %[[COORD:.*]] = fir.coordinate_of %{{.*}}#0, a +! IMPLICIT-ON: %[[PTEE:.*]] = omp.map.info var_ptr(%[[COORD]] {{.*}}) map_clauses(implicit, tofrom, ref_ptee) +! IMPLICIT-ON: %[[ATTACH:.*]] = omp.map.info var_ptr(%[[COORD]] {{.*}}) map_clauses(attach, ref_ptee) +! IMPLICIT-ON: %[[PARENT:.*]] = omp.map.info {{.*}}members(%[[PTEE]] : [0] +! IMPLICIT-ON: omp.declare_mapper.info map_entries(%[[PARENT]], %[[PTEE]], %[[ATTACH]] +! IMPLICIT-ON: omp.map.info {{.*}}map_clauses(implicit, tofrom) capture(ByRef) mapper(@[[IM_MAPPER]]) name("x") +! IMPLICIT-ON: omp.target + +! IMPLICIT-OFF-NOT: omp.declare_mapper +! IMPLICIT-OFF: %[[IM_MAP:.*]] = omp.map.info var_ptr(%{{.*}}) map_clauses(implicit, tofrom) capture(ByRef) name("x") +! IMPLICIT-OFF-NOT: mapper( +! IMPLICIT-OFF: omp.target {{.*}}map_entries(%[[IM_MAP]] -> + +! EXPLICIT-ON: omp.declare_mapper @[[EX_MAPPER:_QQFt_omp_default_mapper]] +! EXPLICIT-ON: %[[COORD:.*]] = fir.coordinate_of %{{.*}}#0, a +! EXPLICIT-ON: %[[PTEE:.*]] = omp.map.info var_ptr(%[[COORD]] {{.*}}) map_clauses(implicit, tofrom, ref_ptee) +! EXPLICIT-ON: %[[ATTACH:.*]] = omp.map.info var_ptr(%[[COORD]] {{.*}}) map_clauses(attach, ref_ptee) +! EXPLICIT-ON: %[[PARENT:.*]] = omp.map.info {{.*}}members(%[[PTEE]] : [1] +! EXPLICIT-ON: omp.declare_mapper.info map_entries(%[[PARENT]], %[[PTEE]], %[[ATTACH]] +! EXPLICIT-ON: omp.map.info {{.*}}map_clauses(tofrom) capture(ByRef) mapper(@[[EX_MAPPER]]) name("x") +! EXPLICIT-ON: omp.target + +! EXPLICIT-OFF-NOT: omp.declare_mapper +! EXPLICIT-OFF: %[[EX_MAP:.*]] = omp.map.info var_ptr(%{{.*}}) map_clauses(tofrom) capture(ByRef) name("x") +! EXPLICIT-OFF-NOT: mapper( +! EXPLICIT-OFF: omp.target {{.*}}map_entries(%[[EX_MAP]] -> >From b08245efc6eabd9b72752715762e98fa1e047d0f Mon Sep 17 00:00:00 2001 From: agozillon <[email protected]> Date: Thu, 22 Oct 2026 13:14:02 -0500 Subject: [PATCH 2/2] [Flang][OpenMP] Address recent comments --- flang/test/Driver/omp-driver-offload.f90 | 51 ++++++------ ...-allocatable-members-flag-explicit-map.f90 | 39 +++++++++ ...ocatable-members-flag-implicit-capture.f90 | 40 +++++++++ ...efault-mapper-allocatable-members-flag.f90 | 81 ------------------- 4 files changed, 106 insertions(+), 105 deletions(-) create mode 100644 flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag-explicit-map.f90 create mode 100644 flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag-implicit-capture.f90 delete mode 100644 flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag.f90 diff --git a/flang/test/Driver/omp-driver-offload.f90 b/flang/test/Driver/omp-driver-offload.f90 index 4d8c9148592ce7..88fd7284a3ee8b 100644 --- a/flang/test/Driver/omp-driver-offload.f90 +++ b/flang/test/Driver/omp-driver-offload.f90 @@ -235,39 +235,42 @@ ! and device phases of the offload compilation when the negative flag is used and ignored ! in the positive case as it is the default. -! RUN: %flang -S -### %s -o %t 2>&1 \ +! RUN: %flang -### %s 2>&1 \ ! RUN: -fopenmp -fimplicit-default-mapper-allocatable-members --offload-arch=gfx90a \ ! RUN: --target=x86_64-unknown-linux-gnu -nogpulib \ -! RUN: | FileCheck %s --check-prefix=ENABLE-IMP-MAPPER +! RUN: | FileCheck %s --check-prefix=NO-MAPPER-FLAG-FORWARD -! ENABLE-IMP-MAPPER: "{{[^"]*}}flang{{[^"]*}}" "-fc1" "-triple" "x86_64-unknown-linux-gnu" -! ENABLE-IMP-MAPPER-SAME: "-fopenmp" -! ENABLE-IMP-MAPPER-SAME: "--offload-targets=amdgpu-amd-amdhsa" -! ENABLE-IMP-MAPPER-NOT: implicit-default-mapper-allocatable-members -! ENABLE-IMP-MAPPER-NEXT: "{{[^"]*}}flang{{[^"]*}}" "-fc1" "-triple" "amdgpu9.0a-amd-amdhsa" -! ENABLE-IMP-MAPPER-SAME: "-fopenmp" -! ENABLE-IMP-MAPPER-NOT: implicit-default-mapper-allocatable-members +! Verify when no implicit-default-mapper flags passed we do not inadvertently add the flag -! RUN: %flang -S -### %s -o %t 2>&1 \ +! RUN: %flang -### %s 2>&1 \ +! RUN: -fopenmp --offload-arch=gfx90a \ +! RUN: --target=x86_64-unknown-linux-gnu -nogpulib \ +! RUN: | FileCheck %s --check-prefix=NO-MAPPER-FLAG-FORWARD + +! NO-MAPPER-FLAG-FORWARD: "-fc1" "-triple" "x86_64-unknown-linux-gnu" +! NO-MAPPER-FLAG-FORWARD-SAME: "-fopenmp" +! NO-MAPPER-FLAG-FORWARD-SAME: "--offload-targets=amdgpu-amd-amdhsa" +! NO-MAPPER-FLAG-FORWARD-NOT: implicit-default-mapper-allocatable-members +! NO-MAPPER-FLAG-FORWARD-NEXT: "-fc1" "-triple" "amdgpu9.0a-amd-amdhsa" +! NO-MAPPER-FLAG-FORWARD-SAME: "-fopenmp" +! NO-MAPPER-FLAG-FORWARD-NOT: implicit-default-mapper-allocatable-members + +! RUN: %flang -### %s 2>&1 \ ! RUN: -fopenmp -fno-implicit-default-mapper-allocatable-members --offload-arch=gfx90a \ ! RUN: --target=x86_64-unknown-linux-gnu -nogpulib \ ! RUN: | FileCheck %s --check-prefix=DISABLE-IMP-MAPPER -! DISABLE-IMP-MAPPER: "{{[^"]*}}flang{{[^"]*}}" "-fc1" "-triple" "x86_64-unknown-linux-gnu" -! DISABLE-IMP-MAPPER-SAME: "-fopenmp" {{.*}} "-fno-implicit-default-mapper-allocatable-members" -! DISABLE-IMP-MAPPER-NEXT: "{{[^"]*}}flang{{[^"]*}}" "-fc1" "-triple" "amdgpu9.0a-amd-amdhsa" -! DISABLE-IMP-MAPPER-SAME: "-fopenmp" {{.*}} "-fno-implicit-default-mapper-allocatable-members" - ! Verify when multiple flags passed the final flag wins out -! RUN: %flang -S -### %s -o %t 2>&1 \ -! RUN: -fopenmp -fimplicit-default-mapper-allocatable-members \ -! RUN: -fimplicit-default-mapper-allocatable-members \ -! RUN: --offload-arch=gfx90a -fno-implicit-default-mapper-allocatable-members \ +! RUN: %flang -### %s 2>&1 \ +! RUN: -fopenmp --offload-arch=gfx90a \ +! RUN: -fimplicit-default-mapper-allocatable-members \ +! RUN: -fimplicit-default-mapper-allocatable-members \ +! RUN: -fno-implicit-default-mapper-allocatable-members \ ! RUN: --target=x86_64-unknown-linux-gnu -nogpulib \ -! RUN: | FileCheck %s --check-prefix=MULTI-IMP-MAPPER +! RUN: | FileCheck %s --check-prefix=DISABLE-IMP-MAPPER -! MULTI-IMP-MAPPER: "{{[^"]*}}flang{{[^"]*}}" "-fc1" "-triple" "x86_64-unknown-linux-gnu" -! MULTI-IMP-MAPPER-SAME: "-fopenmp" {{.*}} "-fno-implicit-default-mapper-allocatable-members" -! MULTI-IMP-MAPPER-NEXT: "{{[^"]*}}flang{{[^"]*}}" "-fc1" "-triple" "amdgpu9.0a-amd-amdhsa" -! MULTI-IMP-MAPPER-SAME: "-fopenmp" {{.*}} "-fno-implicit-default-mapper-allocatable-members" +! DISABLE-IMP-MAPPER: "-fc1" "-triple" "x86_64-unknown-linux-gnu" +! DISABLE-IMP-MAPPER-SAME: "-fopenmp" {{.*}} "-fno-implicit-default-mapper-allocatable-members" +! DISABLE-IMP-MAPPER-NEXT: "-fc1" "-triple" "amdgpu9.0a-amd-amdhsa" +! DISABLE-IMP-MAPPER-SAME: "-fopenmp" {{.*}} "-fno-implicit-default-mapper-allocatable-members" diff --git a/flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag-explicit-map.f90 b/flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag-explicit-map.f90 new file mode 100644 index 00000000000000..ad95fcfb05aa1d --- /dev/null +++ b/flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag-explicit-map.f90 @@ -0,0 +1,39 @@ +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %s -o - | FileCheck %s --check-prefix=ON +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -fimplicit-default-mapper-allocatable-members %s -o - | FileCheck %s --check-prefix=ON +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -fno-implicit-default-mapper-allocatable-members %s -o - | FileCheck %s --check-prefix=OFF + +! Check the -f[no-]implicit-default-mapper-allocatable-members switch for +! explicit maps that synthesize an implicit default mapper for a derived +! type containing an allocatable. +! +! With the default/on setting, compiler-generated implicit default mappers for +! derived types include maps for allocatable components. With the off setting, +! those component maps are suppressed. + +program explicit_map + implicit none + + type :: t + integer :: scalar + integer, allocatable :: a(:) + end type + + type(t) :: x + + !$omp target map(tofrom: x) + !$omp end target +end program + +! ON: omp.declare_mapper @[[MAPPER:_QQFt_omp_default_mapper]] +! ON: %[[COORD:.*]] = fir.coordinate_of %{{.*}}#0, a +! ON: %[[PTEE:.*]] = omp.map.info var_ptr(%[[COORD]] {{.*}}) map_clauses(implicit, tofrom, ref_ptee) +! ON: %[[ATTACH:.*]] = omp.map.info var_ptr(%[[COORD]] {{.*}}) map_clauses(attach, ref_ptee) +! ON: %[[PARENT:.*]] = omp.map.info {{.*}}members(%[[PTEE]] : [1] +! ON: omp.declare_mapper.info map_entries(%[[PARENT]], %[[PTEE]], %[[ATTACH]] +! ON: omp.map.info {{.*}}map_clauses(tofrom) capture(ByRef) mapper(@[[MAPPER]]) name("x") +! ON: omp.target + +! OFF-NOT: omp.declare_mapper +! OFF: %[[MAP:.*]] = omp.map.info var_ptr(%{{.*}}) map_clauses(tofrom) capture(ByRef) name("x") +! OFF-NOT: mapper( +! OFF: omp.target {{.*}}map_entries(%[[MAP]] -> diff --git a/flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag-implicit-capture.f90 b/flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag-implicit-capture.f90 new file mode 100644 index 00000000000000..3ed87985df0f7c --- /dev/null +++ b/flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag-implicit-capture.f90 @@ -0,0 +1,40 @@ +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %s -o - | FileCheck %s --check-prefix=ON +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -fimplicit-default-mapper-allocatable-members %s -o - | FileCheck %s --check-prefix=ON +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -fno-implicit-default-mapper-allocatable-members %s -o - | FileCheck %s --check-prefix=OFF + +! Check the -f[no-]implicit-default-mapper-allocatable-members switch for +! compiler-generated implicit target-region captures that synthesize an implicit +! default mapper for a derived type containing an allocatable. +! +! With the default/on setting, compiler-generated implicit default mappers for +! derived types include maps for allocatable components. With the off setting, +! those component maps are suppressed. + + +program implicit_capture + implicit none + + type :: t + integer, allocatable :: a(:) + end type + + type(t) :: x + + !$omp target + x%a(1) = 1 + !$omp end target +end program + +! ON: omp.declare_mapper @[[MAPPER:_QQFt_omp_default_mapper]] +! ON: %[[COORD:.*]] = fir.coordinate_of %{{.*}}#0, a +! ON: %[[PTEE:.*]] = omp.map.info var_ptr(%[[COORD]] {{.*}}) map_clauses(implicit, tofrom, ref_ptee) +! ON: %[[ATTACH:.*]] = omp.map.info var_ptr(%[[COORD]] {{.*}}) map_clauses(attach, ref_ptee) +! ON: %[[PARENT:.*]] = omp.map.info {{.*}}members(%[[PTEE]] : [0] +! ON: omp.declare_mapper.info map_entries(%[[PARENT]], %[[PTEE]], %[[ATTACH]] +! ON: omp.map.info {{.*}}map_clauses(implicit, tofrom) capture(ByRef) mapper(@[[MAPPER]]) name("x") +! ON: omp.target + +! OFF-NOT: omp.declare_mapper +! OFF: %[[MAP:.*]] = omp.map.info var_ptr(%{{.*}}) map_clauses(implicit, tofrom) capture(ByRef) name("x") +! OFF-NOT: mapper( +! OFF: omp.target {{.*}}map_entries(%[[MAP]] -> diff --git a/flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag.f90 b/flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag.f90 deleted file mode 100644 index 2504dc86eb95d5..00000000000000 --- a/flang/test/Lower/OpenMP/implicit-default-mapper-allocatable-members-flag.f90 +++ /dev/null @@ -1,81 +0,0 @@ -! RUN: rm -rf %t && split-file %s %t -! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/implicit.f90 -o - | FileCheck %s --check-prefix=IMPLICIT-ON -! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -fimplicit-default-mapper-allocatable-members %t/implicit.f90 -o - | FileCheck %s --check-prefix=IMPLICIT-ON -! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -fno-implicit-default-mapper-allocatable-members %t/implicit.f90 -o - | FileCheck %s --check-prefix=IMPLICIT-OFF -! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/explicit.f90 -o - | FileCheck %s --check-prefix=EXPLICIT-ON -! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -fimplicit-default-mapper-allocatable-members %t/explicit.f90 -o - | FileCheck %s --check-prefix=EXPLICIT-ON -! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -fno-implicit-default-mapper-allocatable-members %t/explicit.f90 -o - | FileCheck %s --check-prefix=EXPLICIT-OFF - -! Check the -f[no-]implicit-default-mapper-allocatable-members switch. -! -! With the default/on setting, compiler-generated implicit default mappers for -! derived types include maps for allocatable and nested-record components. -! With the off setting, those component maps are suppressed. Cover both: -! 1. an implicit target-region capture; and -! 2. an explicit whole-object map that would otherwise synthesize a default -! mapper for the derived type. - -!--- implicit.f90 -program implicit_capture - implicit none - - type :: t - integer, allocatable :: a(:) - end type - - type(t) :: x - - allocate(x%a(1)) - - !$omp target - x%a(1) = 1 - !$omp end target -end program - -!--- explicit.f90 -program explicit_whole_object_map - implicit none - - type :: t - integer :: scalar - integer, allocatable :: a(:) - end type - - type(t) :: x - - allocate(x%a(1)) - x%scalar = 1 - - !$omp target map(tofrom: x) - x%scalar = x%scalar + 1 - x%a(1) = x%a(1) + 1 - !$omp end target -end program - -! IMPLICIT-ON: omp.declare_mapper @[[IM_MAPPER:_QQFt_omp_default_mapper]] -! IMPLICIT-ON: %[[COORD:.*]] = fir.coordinate_of %{{.*}}#0, a -! IMPLICIT-ON: %[[PTEE:.*]] = omp.map.info var_ptr(%[[COORD]] {{.*}}) map_clauses(implicit, tofrom, ref_ptee) -! IMPLICIT-ON: %[[ATTACH:.*]] = omp.map.info var_ptr(%[[COORD]] {{.*}}) map_clauses(attach, ref_ptee) -! IMPLICIT-ON: %[[PARENT:.*]] = omp.map.info {{.*}}members(%[[PTEE]] : [0] -! IMPLICIT-ON: omp.declare_mapper.info map_entries(%[[PARENT]], %[[PTEE]], %[[ATTACH]] -! IMPLICIT-ON: omp.map.info {{.*}}map_clauses(implicit, tofrom) capture(ByRef) mapper(@[[IM_MAPPER]]) name("x") -! IMPLICIT-ON: omp.target - -! IMPLICIT-OFF-NOT: omp.declare_mapper -! IMPLICIT-OFF: %[[IM_MAP:.*]] = omp.map.info var_ptr(%{{.*}}) map_clauses(implicit, tofrom) capture(ByRef) name("x") -! IMPLICIT-OFF-NOT: mapper( -! IMPLICIT-OFF: omp.target {{.*}}map_entries(%[[IM_MAP]] -> - -! EXPLICIT-ON: omp.declare_mapper @[[EX_MAPPER:_QQFt_omp_default_mapper]] -! EXPLICIT-ON: %[[COORD:.*]] = fir.coordinate_of %{{.*}}#0, a -! EXPLICIT-ON: %[[PTEE:.*]] = omp.map.info var_ptr(%[[COORD]] {{.*}}) map_clauses(implicit, tofrom, ref_ptee) -! EXPLICIT-ON: %[[ATTACH:.*]] = omp.map.info var_ptr(%[[COORD]] {{.*}}) map_clauses(attach, ref_ptee) -! EXPLICIT-ON: %[[PARENT:.*]] = omp.map.info {{.*}}members(%[[PTEE]] : [1] -! EXPLICIT-ON: omp.declare_mapper.info map_entries(%[[PARENT]], %[[PTEE]], %[[ATTACH]] -! EXPLICIT-ON: omp.map.info {{.*}}map_clauses(tofrom) capture(ByRef) mapper(@[[EX_MAPPER]]) name("x") -! EXPLICIT-ON: omp.target - -! EXPLICIT-OFF-NOT: omp.declare_mapper -! EXPLICIT-OFF: %[[EX_MAP:.*]] = omp.map.info var_ptr(%{{.*}}) map_clauses(tofrom) capture(ByRef) name("x") -! EXPLICIT-OFF-NOT: mapper( -! EXPLICIT-OFF: omp.target {{.*}}map_entries(%[[EX_MAP]] -> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
