[flang-commits] [flang] [flang][DRAFT] Copy-in/Copy-out determination (PR #151408)
Eugene Epshteyn via flang-commits
flang-commits at lists.llvm.org
Thu Aug 7 09:09:22 PDT 2025
https://github.com/eugeneepshteyn updated https://github.com/llvm/llvm-project/pull/151408
>From 54c0158dcce9b5ebb6a3658298dedcda72b41f52 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 30 Jul 2025 17:08:06 -0400
Subject: [PATCH 1/4] [flang][DRAFT] Copy-in/Copy-out determination
Plumbing/API for copy-in/copy-out
---
flang/include/flang/Evaluate/call.h | 19 +++++++++++++++++--
flang/lib/Evaluate/call.cpp | 16 ++++++++++++++++
2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/flang/include/flang/Evaluate/call.h b/flang/include/flang/Evaluate/call.h
index 2a5929b873d74..ac11527e4ecaa 100644
--- a/flang/include/flang/Evaluate/call.h
+++ b/flang/include/flang/Evaluate/call.h
@@ -52,7 +52,7 @@ using SymbolRef = common::Reference<const Symbol>;
class ActualArgument {
public:
- ENUM_CLASS(Attr, PassedObject, PercentVal, PercentRef);
+ ENUM_CLASS(Attr, PassedObject, PercentVal, PercentRef, CopyIn, CopyOut);
using Attrs = common::EnumSet<Attr, Attr_enumSize>;
// Dummy arguments that are TYPE(*) can be forwarded as actual arguments.
@@ -131,7 +131,6 @@ class ActualArgument {
return *this;
}
- bool Matches(const characteristics::DummyArgument &) const;
common::Intent dummyIntent() const { return dummyIntent_; }
ActualArgument &set_dummyIntent(common::Intent intent) {
dummyIntent_ = intent;
@@ -161,6 +160,20 @@ class ActualArgument {
return *this;
}
+ // This actual argument may need copy-in before the procedure call
+ bool mayNeedCopyIn() const { return attrs_.test(Attr::CopyIn); };
+ ActualArgument &set_mayNeedCopyIn() {
+ attrs_ = attrs_ + Attr::CopyIn;
+ return *this;
+ }
+
+ // This actual argument may need copy-out after the procedure call
+ bool mayNeedCopyOut() const { return attrs_.test(Attr::CopyOut); };
+ ActualArgument &set_mayNeedCopyOut() {
+ attrs_ = attrs_ + Attr::CopyOut;
+ return *this;
+ }
+
private:
// Subtlety: There is a distinction that must be maintained here between an
// actual argument expression that is a variable and one that is not,
@@ -272,6 +285,8 @@ class ProcedureRef {
bool operator==(const ProcedureRef &) const;
llvm::raw_ostream &AsFortran(llvm::raw_ostream &) const;
+ void DetermineCopyInOut();
+
protected:
ProcedureDesignator proc_;
ActualArguments arguments_;
diff --git a/flang/lib/Evaluate/call.cpp b/flang/lib/Evaluate/call.cpp
index f77df92a7597a..1e582a516a694 100644
--- a/flang/lib/Evaluate/call.cpp
+++ b/flang/lib/Evaluate/call.cpp
@@ -13,6 +13,7 @@
#include "flang/Evaluate/expression.h"
#include "flang/Evaluate/tools.h"
#include "flang/Semantics/symbol.h"
+#include "flang/Semantics/semantics.h"
#include "flang/Support/Fortran.h"
namespace Fortran::evaluate {
@@ -247,4 +248,19 @@ ProcedureRef::~ProcedureRef() {}
void ProcedureRef::Deleter(ProcedureRef *p) { delete p; }
+void ProcedureRef::DetermineCopyInOut() {
+ if (!proc().GetSymbol()) {
+ return;
+ }
+ // Get folding context of the call site owner
+ FoldingContext &fc{proc_.GetSymbol()->owner().context().foldingContext()};
+ auto procInfo{characteristics::Procedure::Characterize(
+ proc(), fc, /*emitError=*/false)};
+ if (!procInfo) {
+ return;
+ }
+ // TODO: at this point have dummy arguments as procInfo->dummyArguments
+ // and have actual arguments via arguments_
+}
+
} // namespace Fortran::evaluate
>From 808fb20c3e4d6dc80b7e3793fb28b4f7854b07f8 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 30 Jul 2025 17:44:37 -0400
Subject: [PATCH 2/4] Call DetermineCopyInOut() from lowering
---
flang/include/flang/Lower/CallInterface.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/flang/include/flang/Lower/CallInterface.h b/flang/include/flang/Lower/CallInterface.h
index 72bc9dd890a94..eca697d474c47 100644
--- a/flang/include/flang/Lower/CallInterface.h
+++ b/flang/include/flang/Lower/CallInterface.h
@@ -284,6 +284,9 @@ class CallerInterface : public CallInterface<CallerInterface> {
CallerInterface(const Fortran::evaluate::ProcedureRef &p,
Fortran::lower::AbstractConverter &c)
: CallInterface{c}, procRef{p} {
+ // Ensure that procRef gathers necessary information to determine the
+ // need for copy-in and copy-out
+ const_cast<Fortran::evaluate::ProcedureRef &>(procRef).DetermineCopyInOut();
declare();
mapPassedEntities();
actualInputs.resize(getNumFIRArguments());
>From 28bc5bd95f83f131c4a905f69e402fc97a1b7e9d Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 30 Jul 2025 18:20:23 -0400
Subject: [PATCH 3/4] clang-format
---
flang/lib/Evaluate/call.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/lib/Evaluate/call.cpp b/flang/lib/Evaluate/call.cpp
index 1e582a516a694..0cfad4cfae17e 100644
--- a/flang/lib/Evaluate/call.cpp
+++ b/flang/lib/Evaluate/call.cpp
@@ -12,8 +12,8 @@
#include "flang/Evaluate/check-expression.h"
#include "flang/Evaluate/expression.h"
#include "flang/Evaluate/tools.h"
-#include "flang/Semantics/symbol.h"
#include "flang/Semantics/semantics.h"
+#include "flang/Semantics/symbol.h"
#include "flang/Support/Fortran.h"
namespace Fortran::evaluate {
>From f44b9459f6e2c0f60d6f66d00ec37d383befe021 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 30 Jul 2025 19:54:01 -0400
Subject: [PATCH 4/4] DetermineCopyInOut() is now called from ProcedureRef
constructor
---
flang/include/flang/Evaluate/call.h | 8 ++++++--
flang/include/flang/Lower/CallInterface.h | 3 ---
flang/lib/Evaluate/call.cpp | 2 +-
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/flang/include/flang/Evaluate/call.h b/flang/include/flang/Evaluate/call.h
index ac11527e4ecaa..56338901b22bb 100644
--- a/flang/include/flang/Evaluate/call.h
+++ b/flang/include/flang/Evaluate/call.h
@@ -248,7 +248,11 @@ class ProcedureRef {
ProcedureRef(ProcedureDesignator &&p, ActualArguments &&a,
bool hasAlternateReturns = false)
: proc_{std::move(p)}, arguments_{std::move(a)},
- hasAlternateReturns_{hasAlternateReturns} {}
+ hasAlternateReturns_{hasAlternateReturns} {
+ // Gathers necessary information to determine the need for copy-in and
+ // copy-out
+ DetermineCopyInOut();
+ }
~ProcedureRef();
static void Deleter(ProcedureRef *);
@@ -285,9 +289,9 @@ class ProcedureRef {
bool operator==(const ProcedureRef &) const;
llvm::raw_ostream &AsFortran(llvm::raw_ostream &) const;
+protected:
void DetermineCopyInOut();
-protected:
ProcedureDesignator proc_;
ActualArguments arguments_;
Chevrons chevrons_;
diff --git a/flang/include/flang/Lower/CallInterface.h b/flang/include/flang/Lower/CallInterface.h
index eca697d474c47..72bc9dd890a94 100644
--- a/flang/include/flang/Lower/CallInterface.h
+++ b/flang/include/flang/Lower/CallInterface.h
@@ -284,9 +284,6 @@ class CallerInterface : public CallInterface<CallerInterface> {
CallerInterface(const Fortran::evaluate::ProcedureRef &p,
Fortran::lower::AbstractConverter &c)
: CallInterface{c}, procRef{p} {
- // Ensure that procRef gathers necessary information to determine the
- // need for copy-in and copy-out
- const_cast<Fortran::evaluate::ProcedureRef &>(procRef).DetermineCopyInOut();
declare();
mapPassedEntities();
actualInputs.resize(getNumFIRArguments());
diff --git a/flang/lib/Evaluate/call.cpp b/flang/lib/Evaluate/call.cpp
index 0cfad4cfae17e..c558335c16545 100644
--- a/flang/lib/Evaluate/call.cpp
+++ b/flang/lib/Evaluate/call.cpp
@@ -255,7 +255,7 @@ void ProcedureRef::DetermineCopyInOut() {
// Get folding context of the call site owner
FoldingContext &fc{proc_.GetSymbol()->owner().context().foldingContext()};
auto procInfo{characteristics::Procedure::Characterize(
- proc(), fc, /*emitError=*/false)};
+ proc_, fc, /*emitError=*/true)};
if (!procInfo) {
return;
}
More information about the flang-commits
mailing list