mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-01 15:40:53 +00:00
Enable tail call optimization for functions that return a struct (bug 3664) and for functions that return types that need extending (e.g i1).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67934 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1717f3af08
commit
e75fd69f15
@ -1206,18 +1206,7 @@ public:
|
||||
/// preceeds the RET node and whether the return uses the result of the node
|
||||
/// or is a void return. This function can be used by the target to determine
|
||||
/// eligiblity of tail call optimization.
|
||||
static bool CheckTailCallReturnConstraints(CallSDNode *TheCall, SDValue Ret) {
|
||||
unsigned NumOps = Ret.getNumOperands();
|
||||
if ((NumOps == 1 &&
|
||||
(Ret.getOperand(0) == SDValue(TheCall,1) ||
|
||||
Ret.getOperand(0) == SDValue(TheCall,0))) ||
|
||||
(NumOps > 1 &&
|
||||
Ret.getOperand(0) == SDValue(TheCall,
|
||||
TheCall->getNumValues()-1) &&
|
||||
Ret.getOperand(1) == SDValue(TheCall,0)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
static bool CheckTailCallReturnConstraints(CallSDNode *TheCall, SDValue Ret);
|
||||
|
||||
/// GetPossiblePreceedingTailCall - Get preceeding TailCallNodeOpCode node if
|
||||
/// it exists. Skip a possible ISD::TokenFactor.
|
||||
|
@ -2571,3 +2571,27 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
|
||||
DAG.getConstant(magics.s-1, getShiftAmountTy()));
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
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)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
6
test/CodeGen/X86/tailcall-i1.ll
Normal file
6
test/CodeGen/X86/tailcall-i1.ll
Normal file
@ -0,0 +1,6 @@
|
||||
; RUN: llvm-as < %s | llc -march=x86 -tailcallopt | grep TAILCALL
|
||||
define fastcc i1 @i1test(i32, i32, i32, i32) {
|
||||
entry:
|
||||
%4 = tail call fastcc i1 @i1test( i32 %0, i32 %1, i32 %2, i32 %3)
|
||||
ret i1 %4
|
||||
}
|
6
test/CodeGen/X86/tailcall-structret.ll
Normal file
6
test/CodeGen/X86/tailcall-structret.ll
Normal file
@ -0,0 +1,6 @@
|
||||
; RUN: llvm-as < %s | llc -march=x86 -tailcallopt | grep TAILCALL
|
||||
define fastcc { { i8*, i8* }*, i8*} @init({ { i8*, i8* }*, i8*}, i32) {
|
||||
entry:
|
||||
%2 = tail call fastcc { { i8*, i8* }*, i8* } @init({ { i8*, i8*}*, i8*} %0, i32 %1)
|
||||
ret { { i8*, i8* }*, i8*} %2
|
||||
}
|
Loading…
Reference in New Issue
Block a user