From: "Raul Silvera" <rsilvera@google.com>
To: "Hal Finkel" <hfinkel@anl.gov>
Cc: "Chandler Carruth" <chandlerc@google.com>, "LLVM Developers Mailing List" <llvmdev@cs.uiuc.edu>
Sent: Monday, November 24, 2014 7:20:04 PM
Subject: Re: [LLVMdev] Upcoming Changes/Additions to Scoped-NoAlias metadata
I'm going to have to read N4150 before commenting on your second
point, but in the meantime, a few questions. In the original
proposal, if you have:
T A,B;
void foo(T *restrict a, T* restrict b) {
A = *b;
*a = A;
}
How is this going to be modeled so that B is aliased to *a and *b,
but A isn't? What if the references to A are in a call made from
foo, which will be inlined later on?
Within the current AA framework, this question has no well-defined meaning. AA only answers queries sensibly regarding values that are simultaneously live and referenced at some point in the function's control flow. Metadata aside, even with the current function argument attributes, querying alias('B', '*b') will respond with NoAlias (for both values, llvm::isIdentifiedObject will return true -- it will return true for both GlobalVariables and for noalias arguments).
This is another example of why you cannot use our current AA framework for IPA, doing so simply does not make sense. The metadata/intrinsics scheme I've proposed does not change this.
Also, what if the reference is in a side path, like this:
T A, B;
void foo(T *restrict a, T *restrict b, bool c) {
T tmp = *b;
if (c) {
A = tmp;
}
*a = *b;
}
Will you alias A to *a and *b? Seems to me you have to, as foo(&A,
&B, false) has well-defined semantics.
No, and it does not do so now. Querying A or B (global variables) vs. *a or *b will return NoAlias. There is no point in the CFG of this function where an object accessed through *a or *b can legally be A or B.
Now to the proposed metadata/intrinsics, let's assume that A and B are local variables in the caller. It is true that *a and *b will be based on a @llvm.noalias result, but that noalias result will only be used if the access is tagged with the associated metadata scope (which will be true for *a, *b and the A within the inlined function, but not true otherwise, thus the semantics will be identical after inlining.
On the scheme I proposed
there is no need, as the exit barrier would separate *a from
references to A after the call. Not aliasing A *b will save the
reload of *b after the conditional.
I agree your scheme will also capture this.
Thanks again,
Hal