[llvm-dev] RFC: New function attribute HasInaccessibleState

Mehdi Amini via llvm-dev llvm-dev at lists.llvm.org
Fri Dec 11 11:28:05 PST 2015

> On Dec 11, 2015, at 11:16 AM, Joseph Tremoulet <jotrem at microsoft.com> wrote:
> <<<
> I may misunderstand, but it seems to me that this solves only query for aliasing with a pointer known to be pointing only to globals defined in the current compilation unit.
> For any pointer which "may point somewhere else”, you won’t be able to resolve the non-aliasing with the “internal state” for malloc/free, right?
> To take the original example in this thread:
> int *x = malloc(4);
> *x = 2;
> int *y = malloc(4);
> *y = 4;
> A pointer analysis can solve this case, but I’m not sure it scale inter procedurally and will have a limited impact outside of LTO anyway.
> I think you're understanding correctly, but I don't understand what you're saying will go badly with the malloc example.  Quoting the start of the thread:
> <<<
> The intention behind introducing this attribute is to relax the conditions in GlobalsAA as below:
> (this code is in GlobalsAAResult::AnalyzeCallGraph)
>       if (F->isDeclaration()) {
>         // Try to get mod/ref behaviour from function attributes.
> -        if (F->doesNotAccessMemory()) {
> +        if (F->doesNotAccessMemory() || F->onlyAccessesArgMemory()) {
>           // Can't do better than that!
>         } else if (F->onlyReadsMemory()) {
>           FunctionEffect |= Ref;
>           if (!F->isIntrinsic())
>             // This function might call back into the module and read a global -
>             // consider every global as possibly being read by this function.
>             FR.MayReadAnyGlobal = true;
>         } else {
>           FunctionEffect |= ModRef;
>           // Can't say anything useful unless it's an intrinsic - they don't
>           // read or write global variables of the kind considered here.
>           KnowNothing = !F->isIntrinsic();
>         }
>         continue;
>       }
> This relaxation allows functions that (transitively) call library functions (such as printf/malloc) to still maintain and propagate GlobalsAA info. In general, this adds more precision to the description of these functions. 
> Concerns regarding impact on other optimizations (I'm repeating a few examples that Hal mentioned earlier).
> 1. 
>> A readnone function is one whose output is a function only of its inputs, and if you have this:
>> int *x = malloc(4);
>> *x = 2;
>> int *y = malloc(4);
>> *y = 4;
>> you certainly don't want EarlyCSE to replace the second call to malloc with the result of the first (which it will happily do if you mark malloc as readnone).
> It sounded like improving GlobalsAA (and thus disambiguation against globals) was the explicit goal, and that the concern with the malloc case was that you don't want EarlyCSE to start combining those two calls; I may be misunderstanding the code, but I wouldn't expect EarlyCSE to start combining those calls just because they have a new meaningful-only-to-GlobalsAA "almost-readnone" attribute.

Sure, my point is not that your solution would enable CSE where we don’t want, but rather that it is not as powerful as what the attribute “HasInaccessibleState” would model, which I saw as "this function might access globals, but none of these globals can alias with any memory location accessible from the IR being optimized”.

For instance:

void foo(int *x) {
  int *y = malloc(4);
  *x = 2;

If you don’t know anything about x, can you execute the write to *x before the call to malloc?
This is something that the HasInaccessibleState would allow, but I don’t believe would be possible with your categorization.

I’m don’t know how much it matters in practice, but I’d rather be sure we’re on the same track about the various tradeoff.


> To the larger point of whether there are other similar cases that extending GlobalsAA wouldn't allow us to optimize -- yes, certainly.  I'm just saying that I think that the notion of "external state" is much easier to define in the context of a particular analysis than the IR as a whole, and that I'd expect that coordinating the notion across analyses would require methods on the analysis API explicitly for that coordination.
>> Mehdi

More information about the llvm-dev mailing list