<div dir="ltr"><div dir="auto"><div>Hi Jonas,</div><div dir="auto"><br></div><div dir="auto">We've also had this discussion about removing dead loops, and we've introduced two attributes based on which LoopDeletion should know whether or not to remove C/C++ loops. The final patch that modifies LoopDeletion is under review at <a href="https://reviews.llvm.org/D86844">https://reviews.llvm.org/D86844</a>. I still haven't had time to properly address the errors in this patch (it was failing a two stage build), but I hope to get back to it at some point over the next few weeks.<br></div><div dir="auto"><br></div><div>Atmn</div><div><br></div><div dir="auto"><div class="gmail_quote" dir="auto"><div dir="ltr" class="gmail_attr">On Sat, Dec 19, 2020, 3:12 PM Jonas Paulsson via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
It seems that omnetpp runs ~10% faster with gcc than with clang on <br>
SystemZ. This is due to the small function printAddressTable which <br>
contains a loop with a single statement. It is run in "express-mode", <br>
which means that the function will contain mainly an empty loop, which <br>
GCC removes (or at least makes an early exit) while clang emits the loop <br>
to be iterated over.<br>
<br>
The loop is iterating with an std::iterator over an std::map. GCC has <br>
recently changed behavior to remove most (but not intentional ones) <br>
empty loops, and I wonder if clang should do the same? There was a <br>
discussion in the GCC community <br>
(<a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89713" rel="noreferrer noreferrer" target="_blank">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89713</a>) which resulted in <br>
this change to assume that loops are finite based on the "forward <br>
progress guarantee" of the standard, IIUC.<br>
<br>
For instance, this function:<br>
<br>
#include <map><br>
void fun(std::map<int, int> &M) {<br>
   for (std::map<int, int>::iterator I = M.begin(); I != M.end(); I++)<br>
     ;<br>
}<br>
<br>
will result in an empty function by GCC, while clang generates the empty <br>
loop to be iterated over.<br>
<br>
I see a comment in LoopDeletion.cpp:<br>
<br>
/// A loop is considered dead if it does not impact the observable <br>
behavior of<br>
/// the program other than finite running time. This never removes a <br>
loop that<br>
/// might be infinite (unless it is never executed), as doing so could <br>
change<br>
/// the halting/non-halting nature of a program.<br>
<br>
This loop does pass the isLoopDead() check in LoopDeletion.cpp:204, but <br>
the loop is not deleted since ScalarEvolution cannot resolve the trip <br>
count.<br>
<br>
This is of course very important for performance in general and in <br>
particular for the profits of loop unswitching and other passes <br>
producing empty loops. So I wonder if it is the case that we could start <br>
doing this as well in llvm?<br>
<br>
/Jonas<br>
<br>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" rel="noreferrer" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div></div></div>
</div>