Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions llvm/lib/Target/Mips/Mips16ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,8 @@ Mips16TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
}

bool Mips16TargetLowering::isEligibleForTailCallOptimization(
const CCState &CCInfo, unsigned NextStackOffset,
const MipsFunctionInfo &FI) const {
const CCState &CCInfo, unsigned NextStackOffset, const MipsFunctionInfo &FI,
bool IsMustTail) const {
// No tail call optimization for mips16.
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/Mips/Mips16ISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace llvm {
private:
bool isEligibleForTailCallOptimization(
const CCState &CCInfo, unsigned NextStackOffset,
const MipsFunctionInfo &FI) const override;
const MipsFunctionInfo &FI, bool IsMustTail = false) const override;

void setMips16HardFloatLibCalls();

Expand Down
22 changes: 13 additions & 9 deletions llvm/lib/Target/Mips/MipsISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3407,18 +3407,22 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// Check if it's really possible to do a tail call. Restrict it to functions
// that are part of this compilation unit.
bool InternalLinkage = false;
bool IsMustTail = CLI.CB && CLI.CB->isMustTailCall();
if (IsTailCall) {
IsTailCall = isEligibleForTailCallOptimization(
CCInfo, StackSize, *MF.getInfo<MipsFunctionInfo>());
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
InternalLinkage = G->getGlobal()->hasInternalLinkage();
IsTailCall &= (InternalLinkage || G->getGlobal()->hasLocalLinkage() ||
G->getGlobal()->hasPrivateLinkage() ||
G->getGlobal()->hasHiddenVisibility() ||
G->getGlobal()->hasProtectedVisibility());
}
CCInfo, StackSize, *MF.getInfo<MipsFunctionInfo>(), IsMustTail);
if (IsTailCall) {
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
InternalLinkage = G->getGlobal()->hasInternalLinkage();
IsTailCall &= (InternalLinkage || G->getGlobal()->hasLocalLinkage() ||
G->getGlobal()->isDSOLocal() ||
G->getGlobal()->hasPrivateLinkage() ||
G->getGlobal()->hasHiddenVisibility() ||
G->getGlobal()->hasProtectedVisibility());
}
}
}
if (!IsTailCall && CLI.CB && CLI.CB->isMustTailCall())
if (!IsTailCall && IsMustTail)
report_fatal_error("failed to perform tail call elimination on a call "
"site marked musttail");

Expand Down
7 changes: 3 additions & 4 deletions llvm/lib/Target/Mips/MipsISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -595,10 +595,9 @@ class TargetRegisterClass;

/// isEligibleForTailCallOptimization - Check whether the call is eligible
/// for tail call optimization.
virtual bool
isEligibleForTailCallOptimization(const CCState &CCInfo,
unsigned NextStackOffset,
const MipsFunctionInfo &FI) const = 0;
virtual bool isEligibleForTailCallOptimization(
const CCState &CCInfo, unsigned NextStackOffset,
const MipsFunctionInfo &FI, bool IsMustTail = false) const = 0;

/// copyByValArg - Copy argument registers which were used to pass a byval
/// argument to the stack. Create a stack frame object for the byval
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Target/Mips/MipsSEISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1179,9 +1179,9 @@ MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
}

bool MipsSETargetLowering::isEligibleForTailCallOptimization(
const CCState &CCInfo, unsigned NextStackOffset,
const MipsFunctionInfo &FI) const {
if (!UseMipsTailCalls)
const CCState &CCInfo, unsigned NextStackOffset, const MipsFunctionInfo &FI,
bool IsMustTail) const {
if (!UseMipsTailCalls && !IsMustTail)
return false;

// Exception has to be cleared with eret.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/Mips/MipsSEISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class TargetRegisterClass;
private:
bool isEligibleForTailCallOptimization(
const CCState &CCInfo, unsigned NextStackOffset,
const MipsFunctionInfo &FI) const override;
const MipsFunctionInfo &FI, bool IsMustTail = false) const override;

void
getOpndList(SmallVectorImpl<SDValue> &Ops,
Expand Down
23 changes: 23 additions & 0 deletions llvm/test/CodeGen/Mips/musttail.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=mips-unknown-linux-gnu < %s | FileCheck %s --check-prefix=MIPS32
; RUN: llc -mtriple=mips64-unknown-linux-gnu < %s | FileCheck %s --check-prefix=MIPS64

; Test musttail support for MIPS

define dso_local i32 @callee_args(i32 %a, i32 %b, i32 %c) {
ret i32 %a;
}

define i32 @test_musttail_args(i32 %x, i32 %y, i32 %z) {
; MIPS32-LABEL: test_musttail_args:
; MIPS32: # %bb.0:
; MIPS32-NEXT: j callee_args
; MIPS32-NEXT: nop
;
; MIPS64-LABEL: test_musttail_args:
; MIPS64: # %bb.0:
; MIPS64-NEXT: j callee_args
; MIPS64-NEXT: nop
%ret = musttail call i32 @callee_args(i32 %x, i32 %y, i32 %z)
ret i32 %ret
}
Loading