[TwoAddressInstructionPass] Try 3 Addr Conversion After Commuting.
authorQuentin Colombet <qcolombet@apple.com>
Wed, 1 Jul 2015 23:12:13 +0000 (23:12 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Wed, 1 Jul 2015 23:12:13 +0000 (23:12 +0000)
TwoAddressInstructionPass stops after a successful commuting but 3 Addr
conversion might be good for some cases.

Consider:

int foo(int a, int b) {
  return a + b;
}

Before this commit, we emit:

addl %esi, %edi
movl %edi, %eax
ret

After this commit, we try 3 Addr conversion:

leal (%rsi,%rdi), %eax
ret

Patch by Volkan Keles <vkeles@apple.com>!

Differential Revision: http://reviews.llvm.org/D10851

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241206 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/TwoAddressInstructionPass.cpp
test/CodeGen/X86/commute-two-addr.ll
test/CodeGen/X86/twoaddr-lea.ll
test/CodeGen/X86/win64_params.ll
test/Transforms/LoopStrengthReduce/X86/ivchain-stress-X86.ll

index 6bceccca778b624c74b8b4f892aa6b478d9f96f5..e84bea63995e5cb17ec4c772a8d6935c0b580732 100644 (file)
@@ -1207,12 +1207,24 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi,
     }
   }
 
+  // If the instruction is convertible to 3 Addr, instead
+  // of returning try 3 Addr transformation aggresively and
+  // use this variable to check later. Because it might be better.
+  // For example, we can just use `leal (%rsi,%rdi), %eax` and `ret`
+  // instead of the following code.
+  //   addl    %esi, %edi
+  //   movl    %edi, %eax
+  //   ret
+  bool commuted = false;
+
   // If it's profitable to commute, try to do so.
   if (TryCommute && commuteInstruction(mi, regB, regC, Dist)) {
+    commuted = true;
     ++NumCommuted;
     if (AggressiveCommute)
       ++NumAggrCommuted;
-    return false;
+    if (!MI.isConvertibleTo3Addr())
+      return false;
   }
 
   if (shouldOnlyCommute)
@@ -1220,7 +1232,7 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi,
 
   // If there is one more use of regB later in the same MBB, consider
   // re-schedule this MI below it.
-  if (EnableRescheduling && rescheduleMIBelowKill(mi, nmi, regB)) {
+  if (!commuted && EnableRescheduling && rescheduleMIBelowKill(mi, nmi, regB)) {
     ++NumReSchedDowns;
     return true;
   }
@@ -1237,6 +1249,10 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi,
     }
   }
 
+  // Return if it is commuted but 3 addr conversion is failed.
+  if (commuted)
+    return false;
+
   // If there is one more use of regB later in the same MBB, consider
   // re-schedule it before this MI if it's legal.
   if (EnableRescheduling && rescheduleKillAboveMI(mi, nmi, regB)) {
index 656c385e2bc7d6ace081da6dbed5808c09e9cc83..5b01e2f4e90d52b80156b9972ed7d4d863be89ec 100644 (file)
@@ -39,7 +39,7 @@ define %0 @t3(i32 %lb, i8 zeroext %has_lb, i8 zeroext %lb_inclusive, i32 %ub, i8
 entry:
 ; DARWIN-LABEL: t3:
 ; DARWIN: shlq $32, %rcx
-; DARWIN-NEXT: orq %rcx, %rax
+; DARWIN-NEXT: leaq (%rax,%rcx), %rax
 ; DARWIN-NEXT: shll $8
 ; DARWIN-NOT: leaq
   %tmp21 = zext i32 %lb to i64
index b5ca0275d8d698308a963cc40eba3f55d95cc6ea..5779cf33ac84ceb8a0cbfc2085305752201d7f80 100644 (file)
@@ -25,8 +25,7 @@ define i32 @test2(i32 inreg %a, i32 inreg %b, i32 %c, i32 %d) nounwind {
 entry:
 ; CHECK-LABEL: test2:
 ; CHECK: leal
-; CHECK-NOT: leal
-; CHECK-NOT: mov
+; CHECK-NEXT: addl
 ; CHECK-NEXT: addl
 ; CHECK-NEXT: ret
  %add = add i32 %b, %a
index 9718c86300c25c4a13eab7a9d8531482febaf9f0..a0b552d4d5847eecdc8ee7fdea9dde64e84dc292 100644 (file)
@@ -7,8 +7,7 @@ define i32 @f6(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5, i32 %p6) nounwind re
 entry:
 ; CHECK: movl    48(%rsp), %eax
 ; CHECK: addl    40(%rsp), %eax
-; LINUX: addl    %r9d, %r8d
-; LINUX: movl    %r8d, %eax
+; LINUX: leal    (%r8,%r9), %eax
   %add = add nsw i32 %p6, %p5
   ret i32 %add
 }
@@ -27,10 +26,8 @@ entry:
 ; on other platforms here (note the x86_64_sysvcc calling convention).
 define x86_64_sysvcc i32 @f8(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5, i32 %p6) nounwind readnone optsize {
 entry:
-; CHECK: addl    %r9d, %r8d
-; CHECK: movl    %r8d, %eax
-; LINUX: addl    %r9d, %r8d
-; LINUX: movl    %r8d, %eax
+; CHECK: leal    (%r8,%r9), %eax
+; LINUX: leal    (%r8,%r9), %eax
   %add = add nsw i32 %p6, %p5
   ret i32 %add
 }
index 7925bf01020e8951231bc5fb8df2daa2f066d5dd..24be0dc42d6d4415ec0b0224f02c819d7220ea40 100644 (file)
@@ -23,7 +23,7 @@
 ; X32: add
 ; X32: add
 ; X32: add
-; X32: add
+; X32: leal
 ; X32: %for.body.3
 define void @sharedidx(i8* nocapture %a, i8* nocapture %b, i8* nocapture %c, i32 %s, i32 %len) nounwind ssp {
 entry: