<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Dec 7, 2014 at 11:16 PM, Nick Lewycky <span dir="ltr"><<a href="mailto:nicholas@mxc.ca" target="_blank">nicholas@mxc.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">Chengyu Song wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
It's difficult to say without a full example, but I'm very suspicious<br>
of those global declarations. I think the compiler would be entirely<br>
justified in assuming you could *never* get from __start_builtin_fw to<br>
__end_builtin_fw, let alone on the first iteration: they're distinct<br>
array objects and by definition (within C99) can't overlap.<br>
</blockquote>
<br>
I think this should be the root cause. Once I changed the declaration to pointers (instead of arrays):<br>
<br>
extern struct builtin_fw* __start_builtin_fw;<br>
extern struct builtin_fw* __end_builtin_fw;<br>
<br>
The generated code will not skip the first comparison.<br>
<br>
Sadly, Linux kernel may contain more such declarations.<br>
</blockquote>
<br></span>
That's a great point. Maybe clang could issue a warning on these, any for loop that declares a pointer to the address of a non-weak object, compares it to a different object, and increments only the pointer (without doing other changes to the pointer inside the loop body). We know that's a buggy pattern. Could you file a feature request for this on <a href="http://llvm.org/bugs" target="_blank">llvm.org/bugs</a> ?</blockquote><div><br></div><div>How is detecting the "buggy" pattern helpful to the user? The linker has provided them with the interface of __start_my_section and __end_my_section symbols, and they are using it in the most obvious way possible. I have personally written this pattern before. I can't think of any other way to use this interface.</div><div><br></div><div>What will the user do if the compiler tells them their code is wrong and optimizes it away? They will probably just mutilate the code until the compiler fails to warn and optimize on this case. We need something better.</div><div><br></div><div>We need a way to express iteration over the concatenated contents of a section in LLVM IR that has a logical lowering from C. We should either adopt the GNU binutils convention of special __start_* / __end_* symbols, or invent a new representation that is compelling.</div><div><br></div><div>Joerg suggested adding 'weak' as a workaround, but it doesn't seem particularly compelling to me:</div><div><br></div><div>extern void *__start_my_ptr_section[];</div><div>extern void *__end_my_ptr_section[] __attribute__((weak)); // I'm assuming Joerg implied the attribute goes here...<br></div><div>void iterate_my_section() {<br></div><div> for (void **i = __start_my_ptr_section; i != __end_my_ptr_section; i++) {</div><div> use_ptr(*i);<br> }</div><div>}</div><div><br></div><div>LLVM has had the concept of "appending" globals for a very long time, but it doesn't have an actual object file lowering. It also provides no mechanism for iteration, because it is impossible to determine the ending point of the concatenated array after linking.</div></div></div></div>