<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 3, 2015, at 11:58 PM, Vaivaswatha Nagaraj <<a href="mailto:vn@compilertree.com" class="">vn@compilertree.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class=""><div class="">>is this "internal state” supposed to be private to the function?<br class=""></div>It could be private or not. Hence the name "inaccessible", to mean that the program under compilation has no access to the state. So while printf and malloc (for example) could share state in libc, the program under compilation cannot access this state.<br class=""></div></div></div></blockquote><div><br class=""></div><div>This is still not clear to me, you’re saying “it could be private or not”: what is a non-public state that no-one but you can access? (I’d call that private).</div><div><br class=""></div><div>Now, from the point of view of the compiler, malloc and free are two separate functions, if you’re attribute is saying they have some internal state, then malloc() cannot access the state of free() and vice versa.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">>how this flag would prevent the last “optimization” you’re illustrating<br class=""></div>Assuming you are referring to the quoted examples, currently these optimizations are not happening anyway (from what I understand). The issue is that, after malloc/free are tagged with "ReadNone", such transforms may happen. Hence to prevent that, the additional flag denoting that these functions maintain an internal state. <br class=""></div></div></blockquote><div><br class=""></div><div>I’m questioning why would this flag solve that, it does not seem to to me. It would prevent to swap two mallocs but not moving freely a malloc with respect to a free.</div><div><br class=""></div><div>— </div><div>Mehdi</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div></div><div class="gmail_extra"><br clear="all" class=""><div class=""><div class="gmail_signature"><div dir="ltr" class="">  - Vaivaswatha<br class=""></div></div></div>
<br class=""><div class="gmail_quote">On Fri, Dec 4, 2015 at 12:20 PM, Mehdi Amini <span dir="ltr" class=""><<a href="mailto:mehdi.amini@apple.com" target="_blank" class="">mehdi.amini@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="">Hi,<div class=""><br class=""></div><div class=""><div class=""><div class=""><div class="h5"><blockquote type="cite" class=""><div class="">On Dec 3, 2015, at 10:33 PM, Vaivaswatha Nagaraj via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank" class="">llvm-dev@lists.llvm.org</a>> wrote:</div><br class=""><div class=""><div dir="ltr" class=""><div class=""><div class="">Hi,<br class=""><br class=""></div>This email is in continuation to the mail thread <a href="http://lists.llvm.org/pipermail/llvm-dev/2015-December/092996.html" target="_blank" class="">http://lists.llvm.org/pipermail/llvm-dev/2015-December/092996.html</a>, to propose a new function attribute that can convey that a function maintains state, but this state is inaccessible to the rest of the program under compilation.<br class=""><br class=""></div>Such a flag could be added to most libc/system calls such as printf/malloc/free. (libc and system calls do access/modify internal variables such as errno).<br class=""><div class=""><div class=""><br class=""></div><div class="">Example attributes (in addition to what are already set):<br class=""></div><div class="">malloc/free: HasInaccessibleState, ReadNone<br class=""></div><div class="">printf: HasInaccessibleState, ArgMemOnly<br class=""></div><div class="">realloc: HasInaccessibleState, ReadOnly (not sure).<br class=""><br class=""></div><div class="">The intention behind introducing this attribute is to relax the conditions in GlobalsAA as below:<br class=""></div><div class="">(this code is in GlobalsAAResult::AnalyzeCallGraph)<br class=""></div><div class=""><pre class="">       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;
       }</pre>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. <br class=""><br class=""></div><div class="">Concerns regarding impact on other optimizations (I'm repeating a few examples that Hal mentioned earlier).<br class=""><br class="">1. <br class="">><span class="">A readnone 
function is one whose output is a function only of its inputs, and if 
you have this:<br class="">
><br class="">
>  int *x = malloc(4);<br class="">
>  *x = 2;<br class="">
>  int *y = malloc(4);<br class="">
>  *y = 4;<br class="">
</span><span class="">> 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).<br class=""><br class=""></span></div><div class=""><span class=""><span class=""><span class="">For malloc, even though ReadNone is set now (as proposed above), EarlyCSE should be taught to respect the HasInaccessibleState and not combine functions that maintain internal states.</span> <span class="">Similarly other optimizations (such as DCE) must be taught to respect the flag.</span><br class=""><br class="">2.<br class=""></span></span><span class=""><span class="">>void foo(char * restrict s1, char * restrict s2) {<br class="">
>  printf(s1);<br class="">
>  printf(s2);<br class="">>}<br class="">
<br class="">>If printf is argmemonly, then we could interchange the two printf calls.<br class=""><br class=""></span></span></div><div class=""><span class=""><span class="">In this example too, printf maintains an internal state, preventing the calls from being internchanged</span>. <span class="">Also, it is now correct to add ArgMemOnly to printf as it does not access any other program memory.</span> <br class=""><br class="">3.<br class=""></span>>For malloc this is still a problem, in the following sense, if we have:<br class="">
><br class="">>  p1 = malloc(really_big);<br class="">>  ...<br class="">>  free(p1);<br class="">
><br class="">> p2 = malloc(really_big);<br class="">>  ...<br class="">> free(p2);<br class="">
>allowing a transformation into:<br class="">
>   p1 = malloc(really_big);<br class="">>   p2 = malloc(really_big);<br class="">
>    ...<br class="">
>   free(p1); free(p2);<br class="">
>could be problematic.</div><div class=""><span class=""><br class=""></span></div><div class=""><span class=""><span class="">Both free and malloc would be marked with having an internal state. This should prevent this kind of an optimization</span>. <span class="">Note that having the ReadNone attribute should not cause problems anymore.</span><br class=""></span></div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div class=""><div class="">Something is not clear to me: is this "internal state” supposed to be private to the function?</div><div class="">How does it deal with malloc/free which can be seen as sharing a state? Especially it is not clear to me how this flag would prevent the last “optimization” you’re illustrating.</div><div class=""><br class=""></div><div class="">— </div><span class="HOEnZb"><font color="#888888" class=""><div class="">Mehdi</div><div class=""><br class=""></div><div class=""><br class=""><div class=""><blockquote type="cite" class=""></blockquote></div></div></font></span></div></div><br class=""></div></div></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></body></html>