For ISD::RET, if # of operands >= 2, try selection the real data dep. operand
authorEvan Cheng <evan.cheng@apple.com>
Mon, 12 Dec 2005 20:32:18 +0000 (20:32 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Mon, 12 Dec 2005 20:32:18 +0000 (20:32 +0000)
first before the chain.
e.g.
int X;

int foo(int x)
{
  x += X + 37;
  return x;
}

If chain operand is selected first, we would generate:
movl X, %eax
movl 4(%esp), %ecx
leal 37(%ecx,%eax), %eax

rather than
movl $37, %eax
addl 4(%esp), %eax
addl X, %eax

which does not require %ecx. (Due to ADD32rm not matching.)

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

lib/Target/X86/X86ISelDAGToDAG.cpp

index 6c32308e07650d7d555142bfb93d2becf0f63659..03f56ebdcda65b0591cf5d9456731dba7661bae4 100644 (file)
@@ -356,15 +356,22 @@ SDOperand X86DAGToDAGISel::Select(SDOperand Op) {
       break;
 
     case ISD::RET: {
-      SDOperand Chain = Select(N->getOperand(0));     // Token chain.
-      switch (N->getNumOperands()) {
+      SDOperand Chain = N->getOperand(0);     // Token chain.
+      unsigned NumOps = N->getNumOperands();
+
+      // Note: A bit of a hack / optimization... Try to delay chain selection
+      // as much as possible. So it's more likely it has already been selected
+      // for a  real use.
+      switch (NumOps) {
         default:
           assert(0 && "Unknown return instruction!");
         case 3:
+          Chain = Select(Chain);
           assert(0 && "Not yet handled return instruction!");
           break;
         case 2: {
           SDOperand Val = Select(N->getOperand(1));
+          Chain = Select(Chain);
           switch (N->getOperand(1).getValueType()) {
             default:
               assert(0 && "All other types should have been promoted!!");
@@ -378,6 +385,7 @@ SDOperand X86DAGToDAGISel::Select(SDOperand Op) {
           }
         }
         case 1:
+          Chain = Select(Chain);
           break;
       }
       if (X86Lowering.getBytesToPopOnReturn() == 0)