[llvm-commits] [llvm] r67943 - in /llvm/trunk: lib/CodeGen/SelectionDAG/TargetLowering.cpp test/CodeGen/X86/tailcall-void.ll
Arnold Schwaighofer
arnold.schwaighofer at gmail.com
Sat Mar 28 05:36:38 PDT 2009
Author: arnolds
Date: Sat Mar 28 07:36:29 2009
New Revision: 67943
URL: http://llvm.org/viewvc/llvm-project?rev=67943&view=rev
Log:
Make check in CheckTailCallReturnConstraints for ignorable instructions between
a CALL and a RET node more generic. Add a test for tail calls with a void
return.
Added:
llvm/trunk/test/CodeGen/X86/tailcall-void.ll
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=67943&r1=67942&r2=67943&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Sat Mar 28 07:36:29 2009
@@ -2572,26 +2572,40 @@
}
}
-bool TargetLowering::CheckTailCallReturnConstraints(CallSDNode *TheCall, SDValue Ret) {
+/// IgnoreHarmlessInstructions - Ignore instructions between a CALL and RET
+/// node that don't prevent tail call optimization.
+static SDValue IgnoreHarmlessInstructions(SDValue node) {
+ // Found call return.
+ if (node.getOpcode() == ISD::CALL) return node;
+ // Ignore MERGE_VALUES. Will have at least one operand.
+ if (node.getOpcode() == ISD::MERGE_VALUES)
+ return IgnoreHarmlessInstructions(node.getOperand(0));
+ // Ignore ANY_EXTEND node.
+ if (node.getOpcode() == ISD::ANY_EXTEND)
+ return IgnoreHarmlessInstructions(node.getOperand(0));
+ if (node.getOpcode() == ISD::TRUNCATE)
+ return IgnoreHarmlessInstructions(node.getOperand(0));
+ // Any other node type.
+ return node;
+}
+
+bool TargetLowering::CheckTailCallReturnConstraints(CallSDNode *TheCall,
+ SDValue Ret) {
unsigned NumOps = Ret.getNumOperands();
- // Struct return.
- if(NumOps >= 5&&
- Ret.getOperand(1).getOpcode()==ISD::MERGE_VALUES &&
- Ret.getOperand(1).getOperand(0) == SDValue(TheCall, 0))
+ // ISD::CALL results:(value0, ..., valuen, chain)
+ // ISD::RET operands:(chain, value0, flag0, ..., valuen, flagn)
+ // Value return:
+ // Check that operand of the RET node sources from the CALL node. The RET node
+ // has at least two operands. Operand 0 holds the chain. Operand 1 holds the
+ // value.
+ if (NumOps > 1 &&
+ IgnoreHarmlessInstructions(Ret.getOperand(1)) == SDValue(TheCall,0))
return true;
- if ((NumOps == 1 &&
- (Ret.getOperand(0) == SDValue(TheCall,1) ||
- Ret.getOperand(0) == SDValue(TheCall,0))) ||
- (NumOps == 3 &&
- Ret.getOperand(1).getOpcode() == ISD::ANY_EXTEND &&
- Ret.getOperand(1).getNumOperands()>0 &&
- Ret.getOperand(1).getOperand(0).getOpcode() == ISD::TRUNCATE &&
- Ret.getOperand(1).getOperand(0).getNumOperands()>0 &&
- Ret.getOperand(1).getOperand(0).getOperand(0) == SDValue(TheCall, 0)) ||
- (NumOps > 1 &&
- Ret.getOperand(0) == SDValue(TheCall,
- TheCall->getNumValues()-1) &&
- Ret.getOperand(1) == SDValue(TheCall,0)))
+ // void return: The RET node has the chain result value of the CALL node as
+ // input.
+ if (NumOps == 1 &&
+ Ret.getOperand(0) == SDValue(TheCall, TheCall->getNumValues()-1))
return true;
+
return false;
}
Added: llvm/trunk/test/CodeGen/X86/tailcall-void.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcall-void.ll?rev=67943&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/tailcall-void.ll (added)
+++ llvm/trunk/test/CodeGen/X86/tailcall-void.ll Sat Mar 28 07:36:29 2009
@@ -0,0 +1,6 @@
+; RUN: llvm-as < %s | llc -march=x86 -tailcallopt | grep TAILCALL
+define fastcc void @i1test(i32, i32, i32, i32) {
+ entry:
+ tail call fastcc void @i1test( i32 %0, i32 %1, i32 %2, i32 %3)
+ ret void
+}
More information about the llvm-commits
mailing list