<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail-HOEnZb"><div class="gmail-h5"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
</blockquote>
<br></div></div>
Both your functions are equivalent to something like this:<br>
<br>
void widget() {<br>
  int aa = 5;<br>
  int t1 = 0;<br>
  while (true) {<br>
    // dosomething(aa, t1);<br>
    int x = aa; aa = t1 + 1; t1 = x;<br>
  }<br>
}<br>
<br>
They're also equivalent to this:<span class="gmail-"><br>
<br>
define void @widget() {<br>
entry:<br>
  br label %bb2<br>
<br>
bb2:                                              ; preds = %bb4, %entry<br>
  %aa = phi i64 [ 5, %entry ], [ %t5, %bb4]<br></span>
  %t1 = phi i64 [ 0, %entry ], [ %aacopy, %bb4 ]<span class="gmail-"><br>
  br label %bb4<br>
<br>
<br>
bb4:                                              ; preds = %bb3, %bb2<br>
  %t5 = add i64 %t1, 1<br></span>
  %aacopy = add i64 %aa, 0<br>
  br label %bb2<span class="gmail-"><br>
}<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
If you think LangRef isn't clear, suggestions are welcome.<br>
</blockquote>
<br>
I would be explicit that phi nodes may depend on each other, and what<br>
the expected evaluation order actually is (if it's<br>
"as-they-appear-in-IR", say that.)<br>
It looks something like "dependencies are allowed, any order is<br>
allowed despites dependencies".<br>
</blockquote>
<br></span>
There is no evaluation order; alternatively, every possible evaluation order is equivalent.  If a PHI node refers to another PHI node in the same basic block, it's actually referring to the value that PHI node had in the predecessor.</blockquote><div><br></div><div>Okay, if that's actually correct, and no matter what order they appear, no "updates" occur until after all the node are processed.</div><div>(IE it literally *always* refers to the previous value) then we should write that.</div><div><br></div><div><br></div><div>Note that gcc takes, the IMHO, better path, of just using explicit temporaries where necessary to avoid these kinds of "phi nodes":</div><div><div> f (int a, int b, int (*<T3ee>) (int, int) g)</div><div> {</div><div>   int x;</div><div>   int _9;</div><div><br></div><div>   <bb 2>:</div><div>   goto <bb 4>;</div><div><br></div><div>   <bb 3>:</div><div>   x_10 = a_1;</div><div>   a_11 = b_2;</div><div>   b_12 = x_10;</div><div><br></div><div>   <bb 4>:</div><div>   # a_1 = PHI <a_4(D)(2), a_11(3)></div><div>   # b_2 = PHI <b_5(D)(2), b_12(3)></div><div>   _9 = g_7(D) (a_1, b_2);</div><div>   if (_9 != 0)</div><div>     goto <bb 3>;</div><div>   else</div><div>     goto <bb 5>;</div><div><br></div><div>   <bb 5>:</div><div>   return;</div><div><br></div><div> }</div></div><div>It moves the necessary evaluation ordering/cycles out of the phi nodes and into the explicit parts of the IR.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
-----<br>
<br>
Another slightly more complicated case:<br>
<br>
define void @cyclical_adds() {<span class="gmail-"><br>
entry:<br>
  br label %bb2<br>
<br>
bb2:                                              ; preds = %bb4, %entry<br>
  %aa = phi i64 [ 5, %entry ], [ %t5, %bb4]<br></span>
  %t1 = phi i64 [ 0, %entry ], [ %aa1, %bb4 ]<span class="gmail-"><br>
  br label %bb4<br>
<br>
<br>
bb4:                                              ; preds = %bb3, %bb2<br></span>
  ; a bunch of code using aa and t1<span class="gmail-"><br>
  %t5 = add i64 %t1, 1<br></span>
  %aa1 = add i64 %aa, 1<br>
  br label %bb2<br>
}<br>
<br>
If you can optimize the evaluation order here, I think the solution would also cover your original example.<div class="gmail-HOEnZb"><div class="gmail-h5"><br></div></div></blockquote><div><br></div><div>The best order in *all* of these cases is actually pretty easy, AFAIK:<br></div><br></div><div class="gmail_quote">Generate RPO for SSA graph from def-use chains</div><div class="gmail_quote">Generate RPO for CFG </div><div class="gmail_quote"><br></div><div class="gmail_quote">Iterate in CFG order for blocks, and inside each block, RPO order of SSA graph for instructions.</div><div class="gmail_quote"><br></div><div class="gmail_quote">You can't do better than this in general.</div><div class="gmail_quote"><br></div><div class="gmail_quote">Because of the defs dominate uses property, for llvm ir, the second part reduces to "evaluate phi nodes in whatever RPO of the SSA graph ended up, evaluate instructions in block order ".</div><div class="gmail_quote"><br></div><div class="gmail_quote">In gcc, it suffices simply to use the RPO for CFG + walk instructions in a block.</div><div class="gmail_quote"><br></div><div class="gmail_quote">Note that i contrived my example to make both incoming edges reachable at the same time.</div><div class="gmail_quote">Otherwise you are guaranteed another iteration anyway until we discover the edge is reachable.</div><div class="gmail_quote"><br></div><div class="gmail_quote">Anyhoo, i'll generate the above ordering and run it on all my testcases and quantify how much better or worse it is.</div><div class="gmail_quote"> </div><div class="gmail_quote"><br></div></div></div>