<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Oct 17, 2013, at 6:25 AM, Hal Finkel <<a href="mailto:hfinkel@anl.gov">hfinkel@anl.gov</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">----- Original Message -----<br><blockquote type="cite"><br>On Oct 16, 2013, at 4:20 PM, Hal Finkel <<a href="mailto:hfinkel@anl.gov">hfinkel@anl.gov</a>> wrote:<br><br><blockquote type="cite">----- Original Message -----<br><blockquote type="cite"><br>On Oct 16, 2013, at 3:37 PM, Hal Finkel <<a href="mailto:hfinkel@anl.gov">hfinkel@anl.gov</a>> wrote:<br><br><blockquote type="cite">----- Original Message -----<br><blockquote type="cite"><br>On Oct 16, 2013, at 1:14 PM, Hal Finkel <<a href="mailto:hfinkel@anl.gov">hfinkel@anl.gov</a>> wrote:<br><br><blockquote type="cite">----- Original Message -----<br><blockquote type="cite"><br><br><br>On Oct 16, 2013, at 9:18 AM, Hal Finkel < <a href="mailto:hfinkel@anl.gov">hfinkel@anl.gov</a> ><br>wrote:<br><br><br><br>----- Original Message -----<br><br><br><br>On 15 October 2013 22:11, Hal Finkel < <a href="mailto:hfinkel@anl.gov">hfinkel@anl.gov</a> ><br>wrote:<br><br><br><br><br><br><br>I made use of SCEV everywhere that I could (I think). SCEV is<br>used<br>to<br>analyze the induction variables, and then at the end to help<br>with<br>the rewriting. I don't think that I can use SCEV everywhere,<br>however. For one thing, I need to check for equivalence of<br>instructions, with certain substitutions, for instructions<br>(like<br>function calls) that SCEV does not interpret.<br><br><br>Hi Hal,<br><br><br>This is probably my lack of understanding of all that SCEV<br>does<br>than<br>anything else.<br><br><br>My comment was to the fact that you seem to be investigating<br>specific<br>cases (multiply, adding, increment size near line 240), which<br>SCEV<br>could get that as an expression, and possibly making it<br>slightly<br>easier to work with. I'll let other SCEV/LV experts to chime<br>in,<br>because I basically don't know what I'm talking about, here.<br>;)<br><br>Okay, I see what you mean. The code in this block:<br>if (Inc == 1) {<br>// This is a special case: here we're looking for all uses<br>(except<br>for<br>// the increment) to be multiplied by a common factor. The<br>increment<br>must<br>// be by one.<br>if (I->first->getNumUses() != 2)<br>continue;<br><br>This code does not use SCEV because, IMHO, there is no need.<br>It<br>is<br>looking for a very particular instruction pattern where the<br>induction variable has only two uses: one which increments it<br>by<br>one<br>(SCEV has already been used to determine that the increment is<br>1),<br>and the other is a multiply by a small constant. It is to<br>catch<br>cases like this:<br><br>for (int i = 0; i < 500; ++i) {<br>foo(3*i);<br>foo(3*i+1);<br>foo(3*i+2);<br>}<br><br>And so, aside from the increment, all uses of the IV are via<br>the<br>multiply. If we find this pattern, then instead of attempting<br>to<br>classify all IV uses as functions of i, i+1, i+2, ... we<br>attempt<br>to<br>classify all uses of the multiplied IV that way.<br><br><br><br><br>I think the more general SCEV-based way to do this would be to<br>recursively walk the def-use chains starting at phis, looking<br>past<br>simple arithmetic until reaching an IV users (see<br>IVUsers::AddUsersIfInteresting). Then you group the users by<br>their<br>IV operand's SCEV expression. If the SCEVs advance by the same<br>constant, then you have your unrolled iterations and it<br>doesn't<br>matter how the induction variable was computed.<br>LSRInstance::CollectChains does something similar.<br></blockquote><br>Thanks! Collecting all IV users may be overkill here, but this<br>is<br>something that I should play with.<br><br>While I have your attention (hopefully), why does SCEV not have<br>a<br>signed division representation? I suspect that it why SCEV<br>won't<br>give be a backedge-taken count for a loop like:<br><br>for (int i = 0; i < n; i += 5) {<br>...<br>}<br></blockquote><br><br>I don’t think division by a negative divisor lends itself to<br>algebraic simplification. Hacker’s guide might say something<br>about<br>this.<br><br>The reason you don’t get a trip count is that ‘i' might step<br>beyond<br>’n’ and overflow. If ’n’ is a constant less than INT_MAX-4 then<br>you<br>get a trip count.<br><br>The NSW flags are supposed to handle this case. Did you lose<br>them<br>during loop unrolling?<br></blockquote><br>I think that this is the key point. No, I tried this with<br>optimized<br>code straight out of Clang and it did not work (I don't think<br>that<br>it has anything to do with the loop body).<br></blockquote><br>Right. How could I forget. This is the infamous case where we<br>ignore<br>NSW. The problem is that we don’t know how the backedge taken<br>count<br>will be used. We do know that if the loop exits via the current<br>branch, it will be at iteration ’n'. However, we don’t know if the<br>loop will continue iterating beyond that point.<br></blockquote><br>But it seems, that being the case, we could still return 'n/5' for<br>loops with only one exiting block? I thought that is what<br>SE->hasLoopInvariantBackedgeTakenCount(L) was for. It would only<br>say that there was a backedge-taken count if the loop structure<br>was simple enough that there was one unambiguous answer. Is this<br>just an implementation oversight, or are there additional<br>complications?<br><br><blockquote type="cite"><br>So you could get a minimum taken count for a particular loop back<br>edge in this case if we adapt the SCEV API to communicate<br>properly.<br></blockquote><br>I recall discussing this before, and so I apologize, but can you<br>elaborate on what 'communicate properly' will entail?<br></blockquote><br>I’m open to anything. For each branch exit we could distinguish<br>between a min vs. exact backedge taken count. We just have to be<br>careful how we present it to the public API and error on the side of<br>caution. If a user simply asks for the loop trip count, I don’t<br>think it’s correct to return ’n’, since subsequent iterations may<br>run before hitting undefined behavior. There have been bugs related<br>to this in the past.<br><br>If the client either asks for a minimum trip count, or the iteration<br>count at which we may observe a loop exit, then we can safely<br>provide an answer. In your case, you’re asking for an equivalent<br>loop test, so is it safe? I think it only works for you because you<br>know the loop contains no calls, so the program has no way to<br>terminate before hitting undefined behavior.<br><br>Maybe the high level SCEV interface should take a loop-may-terminate<br>parameter. The client can set this to false if it goes to the<br>trouble of proving it.<br></blockquote><br>This sounds like a good idea. However, do all of these concerns not equally apply for a constant 'n'?<br></div></blockquote></div><br><div>If the loop is testing less-than constant ’n’, I think we already handle it (knowing n < INT_MAX-stride). I’m not sure what we do for equals ’n’.</div><div><br></div><div>-Andy</div></body></html>