Skip to content

Commit de06d25

Browse files
Initial implementation of DetermineCopyInOutArgument() for implicit
interfaces. Certain helper routines gained overloads to work with ActualArgument.
1 parent 698b865 commit de06d25

File tree

5 files changed

+54
-11
lines changed

5 files changed

+54
-11
lines changed

flang/include/flang/Evaluate/check-expression.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ std::optional<bool> IsContiguous(const A &, FoldingContext &,
118118
extern template std::optional<bool> IsContiguous(const Expr<SomeType> &,
119119
FoldingContext &, bool namedConstantSectionsAreContiguous,
120120
bool firstDimensionStride1);
121+
extern template std::optional<bool> IsContiguous(const ActualArgument &,
122+
FoldingContext &, bool namedConstantSectionsAreContiguous,
123+
bool firstDimensionStride1);
121124
extern template std::optional<bool> IsContiguous(const ArrayRef &,
122125
FoldingContext &, bool namedConstantSectionsAreContiguous,
123126
bool firstDimensionStride1);

flang/include/flang/Evaluate/tools.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,7 @@ extern template semantics::UnorderedSymbolSet CollectCudaSymbols(
11231123

11241124
// Predicate: does a variable contain a vector-valued subscript (not a triplet)?
11251125
bool HasVectorSubscript(const Expr<SomeType> &);
1126+
bool HasVectorSubscript(const ActualArgument &);
11261127

11271128
// Predicate: does an expression contain constant?
11281129
bool HasConstant(const Expr<SomeType> &);

flang/lib/Evaluate/call.cpp

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -251,25 +251,48 @@ void ProcedureRef::Deleter(ProcedureRef *p) { delete p; }
251251
// We don't know the dummy argument info (e.g., procedure with implicit
252252
// interface
253253
static void DetermineCopyInOutArgument(
254-
const characteristics::Procedure &procInfo, ActualArgument &actual) {
255-
256-
// Only check that actual argument is contiguous
257-
// For non-contiguous, do copy-in
254+
const characteristics::Procedure &procInfo, ActualArgument &actual,
255+
semantics::SemanticsContext &sc) {
256+
if (actual.isAlternateReturn()) {
257+
return;
258+
}
259+
if (!evaluate::IsVariable(actual)) {
260+
// Actual argument expressions that aren’t variables are copy-in, but
261+
// not copy-out.
262+
actual.set_mayNeedCopyIn();
263+
}
264+
else if (!IsSimplyContiguous(actual, sc.foldingContext())) {
265+
// Actual arguments that are variables are copy-in when non-contiguous.
266+
// They are copy-out when don't have vector subscripts
267+
actual.set_mayNeedCopyIn();
268+
if (!HasVectorSubscript(actual)) {
269+
actual.set_mayNeedCopyOut();
270+
}
271+
}
272+
else if (ExtractCoarrayRef(actual)) {
273+
// Coindexed actual args need copy-in and copy-out
274+
actual.set_mayNeedCopyIn();
275+
actual.set_mayNeedCopyOut();
276+
}
258277
}
259278

260279
static void DetermineCopyInOutArgument(
261280
const characteristics::Procedure &procInfo, ActualArgument &actual,
262-
characteristics::DummyArgument &dummy) {
263-
264-
// TODO: assert? procInfo.HasExplicitInterface()
281+
characteristics::DummyArgument &dummy, semantics::SemanticsContext &sc) {
282+
assert(procInfo.HasExplicitInterface() && "expect explicit interface proc");
283+
if (actual.isAlternateReturn()) {
284+
return;
285+
}
286+
// TODO
265287
}
266288

267289
void ProcedureRef::DetermineCopyInOut() {
268290
if (!proc_.GetSymbol()) {
269291
return;
270292
}
271293
// Get folding context of the call site owner
272-
FoldingContext &fc{proc_.GetSymbol()->owner().context().foldingContext()};
294+
semantics::SemanticsContext &sc{proc_.GetSymbol()->owner().context()};
295+
FoldingContext &fc{sc.foldingContext()};
273296
auto procInfo{
274297
characteristics::Procedure::Characterize(proc_, fc, /*emitError=*/true)};
275298
if (!procInfo) {
@@ -280,7 +303,7 @@ void ProcedureRef::DetermineCopyInOut() {
280303
if (!actual) {
281304
continue;
282305
}
283-
DetermineCopyInOutArgument(*procInfo, *actual);
306+
DetermineCopyInOutArgument(*procInfo, *actual, sc);
284307
}
285308
return;
286309
}
@@ -315,7 +338,7 @@ void ProcedureRef::DetermineCopyInOut() {
315338
return dummy.name == actualName;
316339
});
317340
it != procInfo->dummyArguments.end()) {
318-
DetermineCopyInOutArgument(*procInfo, *actual, *it);
341+
DetermineCopyInOutArgument(*procInfo, *actual, *it, sc);
319342
}
320343
}
321344
} else if (seenKeyword) {
@@ -325,7 +348,7 @@ void ProcedureRef::DetermineCopyInOut() {
325348
} else {
326349
// Positional argument processing
327350
DetermineCopyInOutArgument(
328-
*procInfo, *actual, procInfo->dummyArguments[index]);
351+
*procInfo, *actual, procInfo->dummyArguments[index], sc);
329352
}
330353

331354
++index;

flang/lib/Evaluate/check-expression.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,9 +1198,20 @@ std::optional<bool> IsContiguous(const A &x, FoldingContext &context,
11981198
}
11991199
}
12001200

1201+
std::optional<bool> IsContiguous(const ActualArgument &actual,
1202+
FoldingContext &fc, bool namedConstantSectionsAreContiguous,
1203+
bool firstDimensionStride1) {
1204+
auto *expr{actual.UnwrapExpr()};
1205+
return expr && IsContiguous(*expr, fc, namedConstantSectionsAreContiguous,
1206+
firstDimensionStride1);
1207+
}
1208+
12011209
template std::optional<bool> IsContiguous(const Expr<SomeType> &,
12021210
FoldingContext &, bool namedConstantSectionsAreContiguous,
12031211
bool firstDimensionStride1);
1212+
template std::optional<bool> IsContiguous(const ActualArgument &,
1213+
FoldingContext &, bool namedConstantSectionsAreContiguous,
1214+
bool firstDimensionStride1);
12041215
template std::optional<bool> IsContiguous(const ArrayRef &, FoldingContext &,
12051216
bool namedConstantSectionsAreContiguous, bool firstDimensionStride1);
12061217
template std::optional<bool> IsContiguous(const Substring &, FoldingContext &,

flang/lib/Evaluate/tools.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,11 @@ bool HasVectorSubscript(const Expr<SomeType> &expr) {
12031203
return HasVectorSubscriptHelper{}(expr);
12041204
}
12051205

1206+
bool HasVectorSubscript(const ActualArgument &actual) {
1207+
auto expr = actual.UnwrapExpr();
1208+
return expr && HasVectorSubscript(*expr);
1209+
}
1210+
12061211
// HasConstant()
12071212
struct HasConstantHelper : public AnyTraverse<HasConstantHelper, bool,
12081213
/*TraverseAssocEntityDetails=*/false> {

0 commit comments

Comments
 (0)