-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[flang] Create temporaries for array sections passed to IGNORE_TKR dummy args #147419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
If argument is marked as IGNORE_TKR, enable contiguity check on it, unless IGNORE_TKR explicitly specifies to ignore contiguity.
… VOLATILE dummy arg Add the check, which partially addresses llvm#137369 Implement HasTriplet().
| if (dummy->ignoreTKR.test(common::IgnoreTKR::Contiguous)) | ||
| return false; | ||
|
|
||
| // TODO: should this check ignore "device" or "managed"? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewers, please answer this question
| return HasVectorSubscriptHelper{}(expr); | ||
| } | ||
|
|
||
| // HasTriplet() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@klausler , could you please review HasTriplet part? I'll add the other reviewers for lowering, once I add the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simply checking for triplets is going to give false positives. A(:) is contiguous when A is; so are A(J:K) and A(J:K:1). There's a general contiguity checking facility in Evaluate that can handle questions of contiguity; have you tried using it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If mustBeMadeContiguous() returns true, then this eventually gets to isSimplyContiguous() which is a helper function that calls Fortran::evaluate::IsSimplyContiguous().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And if mustBeMadeContiguous returns false, then IsSimplyContiguous is not called? Won't that lead to false negatives from e.g. A%X, non-CONTIGUOUS pointers, &c.?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would also be a problem with the current source, without my modifications. I'll check what happens in the cases you mentioned.
| bool isIntentOut() const; | ||
| /// Does the argument have the CONTIGUOUS attribute or have explicit shape? | ||
| bool mustBeMadeContiguous() const; | ||
| bool mustBeMadeContiguous(const bool argHasTriplet = false) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const is never needed in a prototype argument that isn't a reference or a pointer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why "never"? Maybe I just want to make it obvious that the arg shouldn't be modified:
void f(const bool x = false)
{
x = true;
}
$ clang++ -c const.cpp
const.cpp:3:5: error: cannot assign to variable 'x' with const-qualified type 'const bool'
3 | x = true;
| ~ ^
const.cpp:1:19: note: variable 'x' declared const here
1 | void f(const bool x = false)
| ~~~~~~~~~~~^~~~~~~~~
1 error generated.
In any case, this is not important to my change, so I can remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The prototype doesn't need the const here as part of the API, and the implementation is allowed to use const later if desired. So the const in the prototype makes me have to stop and wonder whether a & or * was intended but omitted.
| return HasVectorSubscriptHelper{}(expr); | ||
| } | ||
|
|
||
| // HasTriplet() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simply checking for triplets is going to give false positives. A(:) is contiguous when A is; so are A(J:K) and A(J:K:1). There's a general contiguity checking facility in Evaluate that can handle questions of contiguity; have you tried using it?
…nput, but choose to skip contiguity check
vzakhari
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the changes, Eugene! I have a couple of questions.
| &characteristics->u); | ||
| if (!dummy) | ||
| return false; | ||
| if (dummy->ignoreTKR.test(common::IgnoreTKR::Contiguous)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change makes sense to me, but I am not sure about the code below.
| return false; | ||
|
|
||
| // TODO: should this check ignore "device" or "managed"? | ||
| if (dummy->ignoreTKR.any() && argHasTriplet) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we care about whether the actual argument is an array section or not? Can it be a non-contiguous array (e.g. assumed shape dummy) that is passed as a dummy that is declared as IGNORE_TKR?
To fix #138471, can we return the following at line 1448?
return dummy->type.Rank() > 0 || dummy->ignoreTKR.test(common::IgnoreTKR::Rank);
|
|
||
| subroutine s1() | ||
| !CHECK-LABEL: func.func @_QMtestPs1() | ||
| !CHECK: hlfir.copy_in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this test fail withtout your change? It seems that mustBeMadeContiguous should already return true for this case. I am just trying to understand whether I missed something in the compiler code or that you added this test for completeness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what happens, when one oversimplifies the test. I will upload corrected test tomorrow.
|
I'll be uploading a different PR, so closing this one. |
Enable creation of a temporary, when array section is passed to
IGNORE_TKRdummy argument.CallInterface::mustBeMadeContiguous()now returns "true" forIGNORE_TKRdummy args, when actual args are passed as array section. This triggers contiguity check already done in the caller and results in creation of a temporary.If
IGNORE_TKRincludesc, then don't do contiguity check.Step towards #138471