For ISD::RET, if # of operands >= 2, try selection the real data dep. operand
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
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index 6c32308..03f56eb 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -356,15 +356,22 @@
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 @@
}
}
case 1:
+ Chain = Select(Chain);
break;
}
if (X86Lowering.getBytesToPopOnReturn() == 0)