<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 7, 2020 at 5:17 PM Johannes Doerfert 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:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Metadata to encode what exactly?<br>
<br>
The idea is that loops which do not match the `maynotprogress` defined<br>
via the attribute can be annotated. Thus, if the function is not<br>
`maynotprogress` there is no need for the annotation. If the function<br>
is, loops that do not match `maynotprogress` would at some point be<br>
annotated, either by the frontend or inliner (= the two places that add<br>
`maynotprogress`).<br>
<br>
You cannot use metadata in the other direction, thus to opt-in to<br>
`maynotprogress`. You can make `maynotprogress` the default and use<br>
metadata to opt-out, sure. In addition to the regressions we might see,<br>
we basically end up with metadata on almost every C/C++ loop, unsure if<br>
that is a good idea.</blockquote><div><br></div><div>So, just to reiterate, the proposal is that Clang will look at each function, and:</div><div>- if a function contains any loops which may not progress, will emit "maynotprogress" attribute on the function definition, and "mustprogress" metadata on each loop other than those that may be infinite.</div><div>- otherwise, it will not emit the function attribute "maynotprogress", and will not emit "mustprogress" metadata on the loops.</div><div><br></div><div>And then, whenever LLVM inlines code into another function:<br></div><div>- If the outer function has maynotprogress, and the inner does not: add mustprogress metadata to all the loops (?)  from the inner function.</div><div>- If the outer function does not have maynotprogress, and the inner does: add maynotprogress to the outer function, and add mustprogress to all loops in the outer.</div><div>(But, how do you identify the "loop" to put the metadata on?)</div><div><br></div><div>An alternative scheme suggested was to do without the function attribute, and for clang to emit "mustprogress" metadata on every loop which has this property.</div><div><br></div><div>Some potential reasons to want not to do the simpler scheme have been expressed:</div><div>- Would deoptimize code emitted by previous frontends which don't know about mustprogress.</div><div>- Concern that the loop metadata may be lost during other transforms, thus losing the optimization.</div><div><br></div><div><br></div><div>I'd like to raise another issue, that I haven't seen anyone bring up yet -- the definition of a "loop" in the context of these "infinite loop" optimizations does not seem to have been made clear, and, I think, is problematic. In the current state of LLVM, I believe a candidate "loop" to delete can be derived from <i>any</i> control flow, it does not need to be derived from an explicit source-language loop construct. Under this proposal, that would still be the case. (unless the function was annotated with maynotprogress.)</div><div><br></div><div>For C code, that is incorrect. C only has a must-progress requirement explicitly for iteration statements ("for", "while", and "do"). (And of those, only ones which do not have a constant controlling expression). Quoting C11, 6.8.5 Iteration statements, p6, "An iteration statement whose controlling expression is not a constant expression, that
performs no input/output operations, does not access volatile objects, and performs no
synchronization or atomic operations in its body, controlling expression, or (in the case of for statement) its expression-3, may be assumed by the implementation to
terminate."</div></div><div class="gmail_quote"><div><br></div><div>So, compiling C code, ISTM that every C function needs to be "maynotprogress", and <i>only</i> for "for", "while", or "do" loops without a constant loop-controlling-expression, can we add the "mustprogress" metadata. </div><div><br></div><div><div>On the other hand, in C++, it would appear that by [intro.progress] there is a guarantee of progress for <i>all</i> control flow in a function, even if you've built it out of explicit goto statements. </div></div><div><br></div><div>That is, I believe in C++ this function can be optimized away, but not in C.</div><div>  void loop_weirdly(int should_loop) {<br>      label:<br>      if (should_loop) goto label;<br>  }</div><div><br></div><div>While this may be optimized away in both C and C++:</div><div>  void loop(int should_loop) {</div><div>    while (should_loop) ;</div><div>  }</div><div><br></div><div><div>Another question -- can we actually be sure that other control flow won't get merged into the loop -- is it possible for the "mustprogress" metadata to get applied to a wider scope than it should've been, after other control flow optimizations occur?</div><div></div></div></div></div>