Skip to content

Commit a760320

Browse files
Removed the old way to integrate copy-in/copy-out check
1 parent 24c2040 commit a760320

File tree

3 files changed

+2
-215
lines changed

3 files changed

+2
-215
lines changed

flang/include/flang/Evaluate/call.h

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ using SymbolRef = common::Reference<const Symbol>;
5252

5353
class ActualArgument {
5454
public:
55-
ENUM_CLASS(Attr, PassedObject, PercentVal, PercentRef, CopyIn, CopyOut);
55+
ENUM_CLASS(Attr, PassedObject, PercentVal, PercentRef);
5656
using Attrs = common::EnumSet<Attr, Attr_enumSize>;
5757

5858
// Dummy arguments that are TYPE(*) can be forwarded as actual arguments.
@@ -131,6 +131,7 @@ class ActualArgument {
131131
return *this;
132132
}
133133

134+
bool Matches(const characteristics::DummyArgument &) const;
134135
common::Intent dummyIntent() const { return dummyIntent_; }
135136
ActualArgument &set_dummyIntent(common::Intent intent) {
136137
dummyIntent_ = intent;
@@ -160,20 +161,6 @@ class ActualArgument {
160161
return *this;
161162
}
162163

163-
// This actual argument may need copy-in before the procedure call
164-
bool GetMayNeedCopyIn() const { return attrs_.test(Attr::CopyIn); };
165-
ActualArgument &SetMayNeedCopyIn() {
166-
attrs_ = attrs_ + Attr::CopyIn;
167-
return *this;
168-
}
169-
170-
// This actual argument may need copy-out after the procedure call
171-
bool GetMayNeedCopyOut() const { return attrs_.test(Attr::CopyOut); };
172-
ActualArgument &SetMayNeedCopyOut() {
173-
attrs_ = attrs_ + Attr::CopyOut;
174-
return *this;
175-
}
176-
177164
private:
178165
// Subtlety: There is a distinction that must be maintained here between an
179166
// actual argument expression that is a variable and one that is not,
@@ -285,8 +272,6 @@ class ProcedureRef {
285272
bool operator==(const ProcedureRef &) const;
286273
llvm::raw_ostream &AsFortran(llvm::raw_ostream &) const;
287274

288-
void DetermineCopyInOut();
289-
290275
protected:
291276
ProcedureDesignator proc_;
292277
ActualArguments arguments_;

flang/lib/Evaluate/call.cpp

Lines changed: 0 additions & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include "flang/Evaluate/check-expression.h"
1313
#include "flang/Evaluate/expression.h"
1414
#include "flang/Evaluate/tools.h"
15-
#include "flang/Semantics/semantics.h"
1615
#include "flang/Semantics/symbol.h"
1716
#include "flang/Support/Fortran.h"
1817

@@ -248,199 +247,4 @@ ProcedureRef::~ProcedureRef() {}
248247

249248
void ProcedureRef::Deleter(ProcedureRef *p) { delete p; }
250249

251-
// We don't know the dummy argument info (e.g., procedure with implicit
252-
// interface
253-
static void DetermineCopyInOutArgument(
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.SetMayNeedCopyIn();
263-
} else if (bool actualIsArray{actual.Rank() > 0};
264-
actualIsArray && !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.SetMayNeedCopyIn();
268-
if (!HasVectorSubscript(actual)) {
269-
actual.SetMayNeedCopyOut();
270-
}
271-
} else if (ExtractCoarrayRef(actual)) {
272-
// Coindexed actual args need copy-in and copy-out
273-
actual.SetMayNeedCopyIn();
274-
actual.SetMayNeedCopyOut();
275-
}
276-
}
277-
278-
static void DetermineCopyInOutArgument(
279-
const characteristics::Procedure &procInfo, ActualArgument &actual,
280-
characteristics::DummyArgument &dummy, semantics::SemanticsContext &sc) {
281-
assert(procInfo.HasExplicitInterface() && "expect explicit interface proc");
282-
if (actual.isAlternateReturn()) {
283-
return;
284-
}
285-
if (!evaluate::IsVariable(actual)) {
286-
// Actual argument expressions that aren’t variables are copy-in, but
287-
// not copy-out.
288-
actual.SetMayNeedCopyIn();
289-
return;
290-
}
291-
const auto *dummyObj{std::get_if<characteristics::DummyDataObject>(&dummy.u)};
292-
if (!dummyObj) {
293-
// Only DummyDataObject has the information we need
294-
return;
295-
}
296-
// Pass by value, always copy-in, never copy-out
297-
bool dummyIsValue{
298-
dummyObj->attrs.test(characteristics::DummyDataObject::Attr::Value)};
299-
if (dummyIsValue) {
300-
actual.SetMayNeedCopyIn();
301-
return;
302-
}
303-
// All the checks below are for arrays
304-
305-
bool actualIsAssumedRank{evaluate::IsAssumedRank(actual)};
306-
bool actualIsArray{actualIsAssumedRank || actual.Rank() > 0};
307-
bool dummyIsAssumedRank{dummyObj->type.attrs().test(
308-
characteristics::TypeAndShape::Attr::AssumedRank)};
309-
bool dummyIsArray{dummyIsAssumedRank || dummyObj->type.Rank() > 0};
310-
bool treatDummyScalarAsArray{dummyObj->type.Rank() == 0 &&
311-
dummyObj->ignoreTKR.test(common::IgnoreTKR::Rank)};
312-
if (!actualIsArray || !(dummyIsArray || treatDummyScalarAsArray)) {
313-
return;
314-
}
315-
316-
bool dummyIntentIn{dummyObj->intent == common::Intent::In};
317-
bool dummyIntentOut{dummyObj->intent == common::Intent::Out};
318-
auto setCopyIn = [&]() {
319-
if (!dummyIntentOut) {
320-
// INTENT(OUT) dummy args never need copy-in
321-
actual.SetMayNeedCopyIn();
322-
}
323-
};
324-
auto setCopyOut = [&]() {
325-
if (!dummyIntentIn) {
326-
// INTENT(IN) dummy args never need copy-out
327-
actual.SetMayNeedCopyOut();
328-
}
329-
};
330-
331-
// Check actual contiguity, unless dummy doesn't care
332-
bool actualTreatAsContiguous{
333-
dummyObj->ignoreTKR.test(common::IgnoreTKR::Contiguous) ||
334-
IsSimplyContiguous(actual, sc.foldingContext())};
335-
bool actualHasVectorSubscript{HasVectorSubscript(actual)};
336-
bool dummyIsExplicitShape{dummyObj->type.IsExplicitShape()};
337-
bool dummyIsAssumedSize{dummyObj->type.attrs().test(
338-
characteristics::TypeAndShape::Attr::AssumedSize)};
339-
bool dummyIsPolymorphic{dummyObj->type.type().IsPolymorphic()};
340-
// Explicit shape and assumed size arrays must be contiguous
341-
bool dummyNeedsContiguity{dummyIsExplicitShape || dummyIsAssumedSize ||
342-
// Polymorphic dummy is descriptor based, so should be able to handle
343-
// discontigunity.
344-
(treatDummyScalarAsArray && !dummyIsPolymorphic) ||
345-
dummyObj->attrs.test(characteristics::DummyDataObject::Attr::Contiguous)};
346-
if (!actualTreatAsContiguous && dummyNeedsContiguity) {
347-
setCopyIn();
348-
// Cannot do copy-out for vector subscripts: there could be repeated
349-
// indices, for example
350-
if (!actualHasVectorSubscript) {
351-
setCopyOut();
352-
}
353-
return;
354-
}
355-
356-
bool dummyIsAssumedShape{dummyObj->type.attrs().test(
357-
characteristics::TypeAndShape::Attr::AssumedShape)};
358-
bool actualIsAssumedShape{IsAssumedShape(actual)};
359-
if ((actualIsAssumedRank && dummyIsAssumedRank) ||
360-
(actualIsAssumedShape && dummyIsAssumedShape)) {
361-
// Assumed-rank and assumed-shape arrays are represented by descriptors,
362-
// so don't need to do polymorphic check.
363-
} else if (!dummyObj->ignoreTKR.test(common::IgnoreTKR::Type)) {
364-
// flang supports limited cases of passing polymorphic to non-polimorphic.
365-
// These cases require temporary of non-polymorphic type. (For example,
366-
// the actual argument could be polymorphic array of child type,
367-
// while the dummy argument could be non-polymorphic array of parent type.)
368-
auto actualType{characteristics::TypeAndShape::Characterize(
369-
actual, sc.foldingContext())};
370-
bool actualIsPolymorphic{actualType->type().IsPolymorphic()};
371-
if (actualIsPolymorphic && !dummyIsPolymorphic) {
372-
setCopyIn();
373-
setCopyOut();
374-
}
375-
}
376-
}
377-
378-
void ProcedureRef::DetermineCopyInOut() {
379-
if (!proc_.GetSymbol()) {
380-
return;
381-
}
382-
// Get folding context of the call site owner
383-
semantics::SemanticsContext &sc{proc_.GetSymbol()->owner().context()};
384-
FoldingContext &fc{sc.foldingContext()};
385-
auto procInfo{
386-
characteristics::Procedure::Characterize(proc_, fc, /*emitError=*/true)};
387-
if (!procInfo) {
388-
return;
389-
}
390-
if (!procInfo->HasExplicitInterface()) {
391-
for (auto &actual : arguments_) {
392-
if (!actual) {
393-
continue;
394-
}
395-
DetermineCopyInOutArgument(*procInfo, *actual, sc);
396-
}
397-
return;
398-
}
399-
// Don't change anything about actual or dummy arguments, except for
400-
// computing copy-in/copy-out information. If detect something wrong with
401-
// the arguments, stop processing and let semantic analysis generate the
402-
// error messages.
403-
size_t index{0};
404-
std::set<std::string> processedKeywords;
405-
bool seenKeyword{false};
406-
for (auto &actual : arguments_) {
407-
if (!actual) {
408-
continue;
409-
}
410-
if (index >= procInfo->dummyArguments.size()) {
411-
// More actual arguments than dummy arguments. Semantic analysis will
412-
// deal with the error.
413-
return;
414-
}
415-
if (actual->keyword()) {
416-
seenKeyword = true;
417-
auto actualName{actual->keyword()->ToString()};
418-
if (processedKeywords.find(actualName) != processedKeywords.end()) {
419-
// Actual arguments with duplicate keywords. Semantic analysis will
420-
// deal with the error.
421-
return;
422-
} else {
423-
processedKeywords.insert(actualName);
424-
if (auto it{std::find_if(procInfo->dummyArguments.begin(),
425-
procInfo->dummyArguments.end(),
426-
[&](const characteristics::DummyArgument &dummy) {
427-
return dummy.name == actualName;
428-
})};
429-
it != procInfo->dummyArguments.end()) {
430-
DetermineCopyInOutArgument(*procInfo, *actual, *it, sc);
431-
}
432-
}
433-
} else if (seenKeyword) {
434-
// Non-keyword actual argument after have seen at least one keyword
435-
// actual argument. Semantic analysis will deal with the error.
436-
return;
437-
} else {
438-
// Positional argument processing
439-
DetermineCopyInOutArgument(
440-
*procInfo, *actual, procInfo->dummyArguments[index], sc);
441-
}
442-
++index;
443-
}
444-
}
445-
446250
} // namespace Fortran::evaluate

flang/lib/Semantics/expression.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3464,7 +3464,6 @@ void ExpressionAnalyzer::Analyze(const parser::CallStmt &callStmt) {
34643464
HasAlternateReturns(callee->arguments)},
34653465
ProcedureRef::Deleter);
34663466
DEREF(callStmt.typedCall.get()).set_chevrons(std::move(*chevrons));
3467-
DEREF(callStmt.typedCall.get()).DetermineCopyInOut();
34683467
return;
34693468
}
34703469
}
@@ -4389,7 +4388,6 @@ MaybeExpr ExpressionAnalyzer::MakeFunctionRef(parser::CharBlock callSite,
43894388
if (chars->functionResult) {
43904389
const auto &result{*chars->functionResult};
43914390
ProcedureRef procRef{std::move(proc), std::move(arguments)};
4392-
procRef.DetermineCopyInOut();
43934391
if (result.IsProcedurePointer()) {
43944392
return Expr<SomeType>{std::move(procRef)};
43954393
} else {

0 commit comments

Comments
 (0)