<div dir="ltr"><div>Hi Craig,</div><div><br></div><div>Please let me know how to move this topic to cfe-dev.<br></div><div><br></div><div><br></div>Hi Kevin,<div><br></div><div>Basically, we didn't want Haskell like semantics since people are so used to logging things in the middle of their pure code that they will never use it (also, we have some legacy code which will require massive refactoring). The "call_impure" is not absolutely necessary, but its mainly there to avoid accidental calls to impure code from pure code. Most of our code is crypto code and impure calls need some form of prior encryption/authentication, so we would like to avoid accidental impure calls. </div><div><br></div><div>Given the size of LLVM+Clang code base, I don't have a good sense of how much effort it will be to add a functionality like this, and will really appreciate feedback on this.</div><div><br></div><div>Thanks in advance.</div><div>Best Regards</div><div>Suman</div><div><br></div><div><br></div><div class="gmail_extra"><div class="gmail_quote">On Sun, Apr 9, 2017 at 3:25 PM, Flamedoge <span dir="ltr"><<a href="mailto:code.kchoi@gmail.com" target="_blank">code.kchoi@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Hi Suman,<br><br></div><div>I think you can ascertain pureness automatically leveraging the compiler instead of manually tagging attribute to each method and call-site. It would seem like impurity should be a transitive attribute. So this would conflict with below.</div><br><div><font face="monospace, monospace">_</font><span style="font-family:monospace,monospace">_attribute__((annotate("pure"<wbr>)))</span></div><div><font face="monospace, monospace">int add(uint32_t a, uint32_t b)  {    // impure by calling printf...</font></div><div><font face="monospace, monospace">...</font></div><span class=""><div><font face="monospace, monospace">  printf("%d + %d = %d\n", a, b, c) __attribute__((annotate("call_<wbr>impure")));<br><br></font></div></span><div><font face="arial, helvetica, sans-serif">Finding purity of functions should be possible by parsing each function across files and build up a call dag tree. You can traverse bottom-up to mark each function as impure from callees and using the definition of pure-ness. From there you could find two sets of functions, put them into export files, and use them to link the two libraries as you want.</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">Regards,</font></div><div><font face="arial, helvetica, sans-serif">Kevin</font></div><div><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Apr 9, 2017 at 12:33 PM, Craig Topper via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>This probably a better question for the clang developer list cfe-dev.</div><div><br><div class="gmail_quote"><div><div class="m_-2361247960751862996m_7552497844613773686h5"><div>On Sun, Apr 9, 2017 at 12:01 PM Suman Thakur via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br></div></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="m_-2361247960751862996m_7552497844613773686h5"><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg">Hello folks,<div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg">I'm not a compiler expert or subscribed to this mailing list, but I have a unique problem. I need to split a large piece of C/C++ code into two separate libraries: one library that only has pure code (i.e., code that doesn't require operating system interactions) and other library that can have both pure code and side-effecting code. </div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg">I was was wondering if it's possible to achieve this by adding something like __attribute__((annotate("pure"<wbr>))) and __attribute__((annotate("call_<wbr>impure"))) and how much effort will it be to add such a functionality. Basically, I want "pure" attribute to be sticky, in the sense that every function that's pure, can only call pure code unless explicitly marked inside the function to make impure call. For example, the following code should create one library for pure code, and a driver which has all the impure code.<br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">__attribute__((annotate("pure"<wbr>))</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">int increment(int x){</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">    return x + 1;</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">}</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">_</font><span style="font-family:monospace,monospace" class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg">_attribute__((annotate("pure"<wbr>)))</span></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">int add(uint32_t a, uint32_t b)  {</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">  int c = a;</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">  /* addition via pieno arithmetic */</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">  while(b != 0){</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">    c = increment(c);  // Okay to call pure code directly.</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">    b--;</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">  }</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">  printf("%d + %d = %d\n", a, b, c) __attribute__((annotate("call_<wbr>impure")));</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">  // calling impure code requires explicit annotation</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">  // all the arguments to the function are copied </font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">  // and don't share the same stack as pure code</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">  return c;</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">}</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">int main(int argc, char* argvp[]){</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">   a = 1;</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">   b = 2;.</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">   c = add(a,b)</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">   printf("%d + %d = %d", a, b); // okay to call impure from impure</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><font class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" face="monospace, monospace">}</font></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg">The call to printf in pure code should create a stub function call printf_impure_call(), which in the impure library just calls printf. </div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg">I know very little about compilers (mathematician by training), but I will really appreciate if someone can comment about the feasibility of this.</div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg">Thanks</div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg">Suman</div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg"></div><div class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg">PS: I'm not subscribed to LLVM mailing list so please reply-all.</div></div></div></div>
______________________________<wbr>_________________<br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg">
LLVM Developers mailing list<br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg">
<a href="mailto:llvm-dev@lists.llvm.org" class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><span class="m_-2361247960751862996m_7552497844613773686HOEnZb"><font color="#888888"><br class="m_-2361247960751862996m_7552497844613773686m_-8183063386693109137gmail_msg">
</font></span></blockquote></div></div><span class="m_-2361247960751862996m_7552497844613773686HOEnZb"><font color="#888888"><div dir="ltr">-- <br></div><div data-smartmail="gmail_signature">~Craig</div>
</font></span><br>______________________________<wbr>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
<br></blockquote></div><br></div></div></div></div>
</blockquote></div><br></div></div>