summaryrefslogtreecommitdiff
path: root/lib/Target/Mips
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@mips.com>2012-10-30 20:16:31 +0000
committerAkira Hatanaka <ahatanaka@mips.com>2012-10-30 20:16:31 +0000
commit2f34d754d00fbe2e4a98762d71d0fae5f4b0cf45 (patch)
tree4363eef803f374eb502a65e87910b47744c5e8ec /lib/Target/Mips
parentdfa4cecb1e549d96f800f7ebc793a342d8df1244 (diff)
downloadllvm-2f34d754d00fbe2e4a98762d71d0fae5f4b0cf45.tar.gz
llvm-2f34d754d00fbe2e4a98762d71d0fae5f4b0cf45.tar.bz2
llvm-2f34d754d00fbe2e4a98762d71d0fae5f4b0cf45.tar.xz
[mips] Allow tail-call optimization for vararg functions and functions which
use the caller's stack. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167048 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips')
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp30
-rw-r--r--lib/Target/Mips/MipsISelLowering.h5
2 files changed, 20 insertions, 15 deletions
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index 862790b4d2..47a4f1a14a 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -2660,8 +2660,9 @@ static unsigned getNextIntArgReg(unsigned Reg) {
/// IsEligibleForTailCallOptimization - Check whether the call is eligible
/// for tail call optimization.
bool MipsTargetLowering::
-IsEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, bool IsVarArg,
- unsigned NextStackOffset) const {
+IsEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
+ unsigned NextStackOffset,
+ const MipsFunctionInfo& FI) const {
if (!EnableMipsTailCalls)
return false;
@@ -2669,11 +2670,13 @@ IsEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, bool IsVarArg,
if (Subtarget->inMips16Mode())
return false;
- if (MipsCCInfo.hasByValArg() || IsVarArg)
+ // Return false if either the callee or caller has a byval argument.
+ if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
return false;
- // Return true if no arguments are passed on stack.
- return MipsCCInfo.reservedArgArea() == NextStackOffset;
+ // Return true if the callee's next stack offset is no larger than the
+ // caller's.
+ return NextStackOffset <= FI.nextStackOffset();
}
SDValue
@@ -2725,13 +2728,12 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// Get a count of how many bytes are to be pushed on the stack.
unsigned NextStackOffset = CCInfo.getNextStackOffset();
- unsigned StackAlignment = TFL->getStackAlignment();
- NextStackOffset = RoundUpToAlignment(NextStackOffset, StackAlignment);
// Check if it's really possible to do a tail call.
if (isTailCall)
- isTailCall = IsEligibleForTailCallOptimization(MipsCCInfo, isVarArg,
- NextStackOffset);
+ isTailCall =
+ IsEligibleForTailCallOptimization(MipsCCInfo, NextStackOffset,
+ *MF.getInfo<MipsFunctionInfo>());
if (isTailCall)
++NumTailCalls;
@@ -2739,6 +2741,8 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// Chain is the output chain of the last Load/Store or CopyToReg node.
// ByValChain is the output chain of the last Memcpy node created for copying
// byval arguments to the stack.
+ unsigned StackAlignment = TFL->getStackAlignment();
+ NextStackOffset = RoundUpToAlignment(NextStackOffset, StackAlignment);
SDValue NextStackOffsetVal = DAG.getIntPtrConstant(NextStackOffset, true);
if (!isTailCall)
@@ -2765,6 +2769,8 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
assert(Flags.getByValSize() &&
"ByVal args of size 0 should have been ignored by front-end.");
assert(ByValArg != MipsCCInfo.byval_end());
+ assert(!isTailCall &&
+ "Do not tail-call optimize if there is a byval argument.");
passByValArg(Chain, dl, RegsToPass, MemOpChains, StackPtr, MFI, DAG, Arg,
MipsCCInfo, *ByValArg, Flags, Subtarget->isLittle());
++ByValArg;
@@ -2817,10 +2823,8 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// emit ISD::STORE whichs stores the
// parameter value to a stack Location
- SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr,
- DAG.getIntPtrConstant(VA.getLocMemOffset()));
- MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
- MachinePointerInfo(), false, false, 0));
+ MemOpChains.push_back(passArgOnStack(StackPtr, VA.getLocMemOffset(),
+ Chain, Arg, dl, isTailCall, DAG));
}
// Transform all store nodes into one single node because all store
diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h
index 4f1ce0cd1c..8b80dff89b 100644
--- a/lib/Target/Mips/MipsISelLowering.h
+++ b/lib/Target/Mips/MipsISelLowering.h
@@ -141,6 +141,7 @@ namespace llvm {
//===--------------------------------------------------------------------===//
// TargetLowering Implementation
//===--------------------------------------------------------------------===//
+ class MipsFunctionInfo;
class MipsTargetLowering : public TargetLowering {
public:
@@ -275,8 +276,8 @@ namespace llvm {
/// IsEligibleForTailCallOptimization - Check whether the call is eligible
/// for tail call optimization.
bool IsEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
- bool IsVarArg,
- unsigned NextStackOffset) const;
+ unsigned NextStackOffset,
+ const MipsFunctionInfo& FI) const;
/// copyByValArg - Copy argument registers which were used to pass a byval
/// argument to the stack. Create a stack frame object for the byval