<div class="gmail_quote">On Fri, May 25, 2012 at 8:28 AM, Duncan Sands <span dir="ltr"><<a href="mailto:baldrick@free.fr" target="_blank">baldrick@free.fr</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This 44% performance regression was caused by my reassociate changes.  The<br>
reason is pretty interesting though.  I could do with some suggestions.<br>
<br>
> Performance Regressions - Execution Time      Δ       Previous        Current σ       Δ (B)   σ (B)<br>
> SingleSource/Benchmarks/BenchmarkGame/puzzle<br>
> <<a href="http://llvm.org/perf/db_default/v4/nts/789/graph?test.198=2" target="_blank">http://llvm.org/perf/db_default/v4/nts/789/graph?test.198=2</a>> 44.42%  0.4829<br>
> 0.6974        0.0001  43.91%  0.0001<br>
<br>
The change to the optimized IR was:<br>
<br>
    %phi213.i = phi i32 [ %xor1.i, %for.body.i ], [ 0, %for.body.i.preheader ]<br>
    %indvars.iv.next.i = add i64 %indvars.iv.i, 1<br>
    %arrayidx.i = getelementptr inbounds i32* %call, i64 %indvars.iv.i<br>
    %0 = load i32* %arrayidx.i, align 4, !tbaa !0<br>
    %1 = trunc i64 %indvars.iv.next.i to i32<br>
-  %xor.i = xor i32 %0, %phi213.i<br>
-  %xor1.i = xor i32 %xor.i, %1<br>
+  %xor.i = xor i32 %1, %phi213.i<br>
+  %xor1.i = xor i32 %xor.i, %0<br>
    %exitcond = icmp eq i32 %1, 500001<br>
    br i1 %exitcond, label %findDuplicate.exit, label %for.body.i<br>
<br>
The old code computes<br>
   %phi213.i ^ %0 ^ %1<br>
while the new computes<br>
   %phi213.i ^ %1 ^ %0<br>
Here %0 is a load and %1 is a truncation.<br>
<br>
Since reassociate computes the same rank for %0 and %1, there is no reason to<br>
prefer one to the other - it's just a matter of chance which one you get, and<br>
the old code was luckier than the new.<br>
<br>
The reason for the big slowdown is in the different codegen:<br>
<br>
# phi213.i is in %ebx<br>
<br>
+       leaq    1(%rdx), %rsi<br>
+       xorl    %esi, %ebx<br>
         xorl    (%rax,%rdx,4), %ebx<br>
-       incq    %rdx<br>
-       xorl    %edx, %ebx<br>
-       cmpl    $500001, %edx           # imm = 0x7A121<br>
+       cmpl    $500001, %esi           # imm = 0x7A121<br>
+       movq    %rsi, %rdx<br>
<br>
I'm not sure why this codegen difference arises.  Any suggestions?<br></blockquote><div><br></div><div>One, largely uninformed idea is the dependency chains (in addition to the leaq stuff mentioned by Jakob):</div><div>
<br></div><div>Old code, we execute the load+xor first, and while in flight we can increment rdx, and execute the comparison with edx. whenever the load+xor lands, we can execute the second xor.</div><div><br></div><div>New code, the leaq must execute before the first xor, and the first xor must execute before the second xor. That means we may not be able to overlap as much of the load delay.</div>
<div><br></div><div>I'm not sure how to fix this though... It's not clear that there is a good place for reassociate to try to locate likely-to-load operations. Maybe it could try to sink operations with unrelated prerequisite transformations toward the end of a chain?</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
If there is a fairly generic explanation for the different codegen, maybe the<br>
rank function can be tweaked to force the more effective order.<br>
<br>
Ciao, Duncan.<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br>