mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
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. llvm-svn: 67943
This commit is contained in:
parent
475a59038c
commit
76188bc8a1
@ -2572,26 +2572,40 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
6
test/CodeGen/X86/tailcall-void.ll
Normal file
6
test/CodeGen/X86/tailcall-void.ll
Normal file
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user