[flang-commits] [clang] [flang] [flang] Adding support of -fcoarray flang and init PRIF (PR #151675)
Jean-Didier PAILLEUX via flang-commits
flang-commits at lists.llvm.org
Fri Aug 1 02:05:19 PDT 2025
https://github.com/JDPailleux created https://github.com/llvm/llvm-project/pull/151675
In relation to the approval and merge of the [PRIF](https://github.com/llvm/llvm-project/pull/76088) specification about multi-image features in Flang, here is a first PR to add support for the `-fcoarray` compilation flag and the initialization of the PRIF environment.
Other PRs will follow for adding support of lowering to PRIF.
>From 18eeadc2d43c057e5b8e1a1bad717a3bc48b87a7 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Wed, 28 May 2025 14:54:51 +0200
Subject: [PATCH] [flang] Add support of -fcoarray and init PRIF
---
clang/include/clang/Driver/Options.td | 10 +++-
clang/lib/Driver/ToolChains/Flang.cpp | 2 +
flang/include/flang/Lower/LoweringOptions.def | 4 ++
.../flang/Optimizer/Builder/Runtime/Coarray.h | 50 +++++++++++++++++++
.../flang/Optimizer/Builder/Runtime/Main.h | 2 +-
flang/lib/Frontend/CompilerInvocation.cpp | 4 ++
flang/lib/Lower/Bridge.cpp | 3 +-
flang/lib/Optimizer/Builder/CMakeLists.txt | 1 +
.../lib/Optimizer/Builder/Runtime/Coarray.cpp | 35 +++++++++++++
flang/lib/Optimizer/Builder/Runtime/Main.cpp | 7 ++-
flang/test/Lower/Coarray/coarray-init.f90 | 11 ++++
11 files changed, 124 insertions(+), 5 deletions(-)
create mode 100644 flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
create mode 100644 flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
create mode 100644 flang/test/Lower/Coarray/coarray-init.f90
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index eb53821bbf4d5..a8611a8114de1 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -6962,7 +6962,6 @@ def static_libgfortran : Flag<["-"], "static-libgfortran">, Group<gfortran_Group
// "f" options with values for gfortran.
def fblas_matmul_limit_EQ : Joined<["-"], "fblas-matmul-limit=">, Group<gfortran_Group>;
def fcheck_EQ : Joined<["-"], "fcheck=">, Group<gfortran_Group>;
-def fcoarray_EQ : Joined<["-"], "fcoarray=">, Group<gfortran_Group>;
def ffpe_trap_EQ : Joined<["-"], "ffpe-trap=">, Group<gfortran_Group>;
def ffree_line_length_VALUE : Joined<["-"], "ffree-line-length-">, Group<gfortran_Group>;
def finit_character_EQ : Joined<["-"], "finit-character=">, Group<gfortran_Group>;
@@ -8670,6 +8669,15 @@ def fopenmp_host_ir_file_path : Separate<["-"], "fopenmp-host-ir-file-path">,
} // let Visibility = [CC1Option, FC1Option]
+//===----------------------------------------------------------------------===//
+// Coarray Options
+//===----------------------------------------------------------------------===//
+
+def fcoarray : Flag<["-"], "fcoarray">,
+ Group<f_Group>,
+ Visibility<[FlangOption, FC1Option]>,
+ HelpText<"Enable Coarray features">;
+
//===----------------------------------------------------------------------===//
// SYCL Options
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 7ab41e9b85a04..d5074818de27c 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -178,6 +178,8 @@ void Flang::addCodegenOptions(const ArgList &Args,
options::OPT_fstack_repack_arrays, options::OPT_fno_stack_repack_arrays,
options::OPT_ftime_report, options::OPT_ftime_report_EQ,
options::OPT_funroll_loops, options::OPT_fno_unroll_loops});
+ if (Args.hasArg(clang::driver::options::OPT_fcoarray))
+ CmdArgs.push_back("-fcoarray");
}
void Flang::addPicOptions(const ArgList &Args, ArgStringList &CmdArgs) const {
diff --git a/flang/include/flang/Lower/LoweringOptions.def b/flang/include/flang/Lower/LoweringOptions.def
index 8135704971aa4..4b70d2df9c2f4 100644
--- a/flang/include/flang/Lower/LoweringOptions.def
+++ b/flang/include/flang/Lower/LoweringOptions.def
@@ -74,5 +74,9 @@ ENUM_LOWERINGOPT(SkipExternalRttiDefinition, unsigned, 1, 0)
/// If false, lower to the complex dialect of MLIR.
/// On by default.
ENUM_LOWERINGOPT(ComplexDivisionToRuntime, unsigned, 1, 1)
+
+/// Enable coarrays feature.
+ENUM_LOWERINGOPT(CoarrayFeature, unsigned, 1, 0)
+
#undef LOWERINGOPT
#undef ENUM_LOWERINGOPT
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h b/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
new file mode 100644
index 0000000000000..83561fffc3ff0
--- /dev/null
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
@@ -0,0 +1,50 @@
+//===-- Coarray.h -- generate Coarray intrinsics runtime calls --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COARRAY_H
+#define FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COARRAY_H
+
+#include "flang/Lower/AbstractConverter.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+
+namespace fir {
+class ExtendedValue;
+class FirOpBuilder;
+} // namespace fir
+
+namespace fir::runtime {
+
+// Get the function type for a prif subroutine with a variable number of
+// arguments
+#define PRIF_FUNCTYPE(...) \
+ mlir::FunctionType::get(builder.getContext(), /*inputs*/ {__VA_ARGS__}, \
+ /*result*/ {})
+
+// Default prefix for type of PRIF compiled with LLVM
+#define PRIFTYPE_PREFIX "_QM__prifT"
+#define PRIFTYPE(fmt) \
+ []() { \
+ std::ostringstream oss; \
+ oss << PRIFTYPE_PREFIX << fmt; \
+ return oss.str(); \
+ }()
+
+// Default prefix for subroutines of PRIF compiled with LLVM
+#define PRIFSUB_PREFIX "_QMprifPprif_"
+#define PRIFNAME_SUB(fmt) \
+ []() { \
+ std::ostringstream oss; \
+ oss << PRIFSUB_PREFIX << fmt; \
+ return oss.str(); \
+ }()
+
+/// Generate Call to runtime prif_init
+mlir::Value genInitCoarray(fir::FirOpBuilder &builder, mlir::Location loc);
+
+} // namespace fir::runtime
+#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COARRAY_H
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Main.h b/flang/include/flang/Optimizer/Builder/Runtime/Main.h
index a0586deade42a..d4067b367f73e 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Main.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Main.h
@@ -25,7 +25,7 @@ namespace fir::runtime {
void genMain(fir::FirOpBuilder &builder, mlir::Location loc,
const std::vector<Fortran::lower::EnvironmentDefault> &defs,
- bool initCuda = false);
+ bool initCuda = false, bool initCoarrayEnv = false);
}
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_MAIN_H
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 111c5aa48726f..88065a5b4fb2f 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -1152,6 +1152,10 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
diags.Report(diagID);
}
}
+ // -fcoarray
+ if (args.hasArg(clang::driver::options::OPT_fcoarray))
+ res.getLoweringOpts().setCoarrayFeature(1);
+
return diags.getNumErrors() == numErrorsBefore;
}
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index ac3669c907fbc..9d6eed1d4822d 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -475,7 +475,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
fir::runtime::genMain(*builder, toLocation(),
bridge.getEnvironmentDefaults(),
getFoldingContext().languageFeatures().IsEnabled(
- Fortran::common::LanguageFeature::CUDA));
+ Fortran::common::LanguageFeature::CUDA),
+ getLoweringOptions().getCoarrayFeature());
});
finalizeOpenMPLowering(globalOmpRequiresSymbol);
diff --git a/flang/lib/Optimizer/Builder/CMakeLists.txt b/flang/lib/Optimizer/Builder/CMakeLists.txt
index 31ae395805faf..8fb36a750d433 100644
--- a/flang/lib/Optimizer/Builder/CMakeLists.txt
+++ b/flang/lib/Optimizer/Builder/CMakeLists.txt
@@ -16,6 +16,7 @@ add_flang_library(FIRBuilder
Runtime/Allocatable.cpp
Runtime/ArrayConstructor.cpp
Runtime/Assign.cpp
+ Runtime/Coarray.cpp
Runtime/Character.cpp
Runtime/Command.cpp
Runtime/CUDA/Descriptor.cpp
diff --git a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
new file mode 100644
index 0000000000000..bcc4d63e22f26
--- /dev/null
+++ b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
@@ -0,0 +1,35 @@
+//===-- Coarray.cpp -- runtime API for coarray intrinsics -----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Builder/Runtime/Coarray.h"
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
+#include "flang/Optimizer/HLFIR/HLFIROps.h"
+#include "flang/Optimizer/Support/InternalNames.h"
+#include "flang/Semantics/scope.h"
+#include "flang/Semantics/tools.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "llvm/ADT/TypeSwitch.h"
+
+using namespace Fortran::runtime;
+using namespace Fortran::semantics;
+
+/// Generate Call to runtime prif_init
+mlir::Value fir::runtime::genInitCoarray(fir::FirOpBuilder &builder,
+ mlir::Location loc) {
+ mlir::Type i32Ty = builder.getI32Type();
+ mlir::Value result = builder.createTemporary(loc, i32Ty);
+ mlir::FunctionType ftype = PRIF_FUNCTYPE(builder.getRefType(i32Ty));
+ mlir::func::FuncOp funcOp =
+ builder.createFunction(loc, PRIFNAME_SUB("init"), ftype);
+ llvm::SmallVector<mlir::Value> args =
+ fir::runtime::createArguments(builder, loc, ftype, result);
+ builder.create<fir::CallOp>(loc, funcOp, args);
+ return builder.create<fir::LoadOp>(loc, result);
+}
diff --git a/flang/lib/Optimizer/Builder/Runtime/Main.cpp b/flang/lib/Optimizer/Builder/Runtime/Main.cpp
index d35f687167b05..d303e0ad63842 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Main.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Main.cpp
@@ -10,6 +10,7 @@
#include "flang/Lower/EnvironmentDefault.h"
#include "flang/Optimizer/Builder/BoxValue.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/Runtime/Coarray.h"
#include "flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
#include "flang/Optimizer/Dialect/FIROps.h"
@@ -23,8 +24,8 @@ using namespace Fortran::runtime;
/// Create a `int main(...)` that calls the Fortran entry point
void fir::runtime::genMain(
fir::FirOpBuilder &builder, mlir::Location loc,
- const std::vector<Fortran::lower::EnvironmentDefault> &defs,
- bool initCuda) {
+ const std::vector<Fortran::lower::EnvironmentDefault> &defs, bool initCuda,
+ bool initCoarrayEnv) {
auto *context = builder.getContext();
auto argcTy = builder.getDefaultIntegerType();
auto ptrTy = mlir::LLVM::LLVMPointerType::get(context);
@@ -69,6 +70,8 @@ void fir::runtime::genMain(
loc, RTNAME_STRING(CUFInit), mlir::FunctionType::get(context, {}, {}));
fir::CallOp::create(builder, loc, initFn);
}
+ if (initCoarrayEnv)
+ fir::runtime::genInitCoarray(builder, loc);
fir::CallOp::create(builder, loc, qqMainFn);
fir::CallOp::create(builder, loc, stopFn);
diff --git a/flang/test/Lower/Coarray/coarray-init.f90 b/flang/test/Lower/Coarray/coarray-init.f90
new file mode 100644
index 0000000000000..055bc0fc4da72
--- /dev/null
+++ b/flang/test/Lower/Coarray/coarray-init.f90
@@ -0,0 +1,11 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=ALL,COARRAY
+! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s --check-prefixes=ALL,NOCOARRAY
+
+program test_init
+
+end
+
+! ALL-LABEL: func.func @main
+! ALL: fir.call @_FortranAProgramStart
+! COARRAY: fir.call @_QMprifPprif_init(%[[ARG:.*]]) fastmath<contract> : (!fir.ref<i32>) -> ()
+! NOCOARRAY-NOT: fir.call @_QMprifPprif_init(%[[ARG:.*]]) fastmath<contract> : (!fir.ref<i32>) -> ()
More information about the flang-commits
mailing list