mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-11 10:25:41 +00:00
Eliminate iOS-specific tail call instructions.
After register masks were introdruced to represent the call clobbers, it is no longer necessary to have duplicate instruction for iOS. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154209 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -422,17 +422,16 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
|
|||||||
if (AFI->getGPRCalleeSavedArea1Size()) MBBI++;
|
if (AFI->getGPRCalleeSavedArea1Size()) MBBI++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNdiND ||
|
if (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNri) {
|
||||||
RetOpcode == ARM::TCRETURNri || RetOpcode == ARM::TCRETURNriND) {
|
|
||||||
// Tail call return: adjust the stack pointer and jump to callee.
|
// Tail call return: adjust the stack pointer and jump to callee.
|
||||||
MBBI = MBB.getLastNonDebugInstr();
|
MBBI = MBB.getLastNonDebugInstr();
|
||||||
MachineOperand &JumpTarget = MBBI->getOperand(0);
|
MachineOperand &JumpTarget = MBBI->getOperand(0);
|
||||||
|
|
||||||
// Jump to label or value in register.
|
// Jump to label or value in register.
|
||||||
if (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNdiND) {
|
if (RetOpcode == ARM::TCRETURNdi) {
|
||||||
unsigned TCOpcode = (RetOpcode == ARM::TCRETURNdi)
|
unsigned TCOpcode = STI.isThumb() ?
|
||||||
? (STI.isThumb() ? ARM::tTAILJMPd : ARM::TAILJMPd)
|
(STI.isTargetIOS() ? ARM::tTAILJMPd : ARM::tTAILJMPdND) :
|
||||||
: (STI.isThumb() ? ARM::tTAILJMPdND : ARM::TAILJMPdND);
|
ARM::TAILJMPd;
|
||||||
MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(TCOpcode));
|
MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(TCOpcode));
|
||||||
if (JumpTarget.isGlobal())
|
if (JumpTarget.isGlobal())
|
||||||
MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
|
MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
|
||||||
@@ -449,10 +448,6 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
|
|||||||
BuildMI(MBB, MBBI, dl,
|
BuildMI(MBB, MBBI, dl,
|
||||||
TII.get(STI.isThumb() ? ARM::tTAILJMPr : ARM::TAILJMPr)).
|
TII.get(STI.isThumb() ? ARM::tTAILJMPr : ARM::TAILJMPr)).
|
||||||
addReg(JumpTarget.getReg(), RegState::Kill);
|
addReg(JumpTarget.getReg(), RegState::Kill);
|
||||||
} else if (RetOpcode == ARM::TCRETURNriND) {
|
|
||||||
BuildMI(MBB, MBBI, dl,
|
|
||||||
TII.get(STI.isThumb() ? ARM::tTAILJMPrND : ARM::TAILJMPrND)).
|
|
||||||
addReg(JumpTarget.getReg(), RegState::Kill);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineInstr *NewMI = prior(MBBI);
|
MachineInstr *NewMI = prior(MBBI);
|
||||||
@@ -648,9 +643,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
|
|||||||
DebugLoc DL = MI->getDebugLoc();
|
DebugLoc DL = MI->getDebugLoc();
|
||||||
unsigned RetOpcode = MI->getOpcode();
|
unsigned RetOpcode = MI->getOpcode();
|
||||||
bool isTailCall = (RetOpcode == ARM::TCRETURNdi ||
|
bool isTailCall = (RetOpcode == ARM::TCRETURNdi ||
|
||||||
RetOpcode == ARM::TCRETURNdiND ||
|
RetOpcode == ARM::TCRETURNri);
|
||||||
RetOpcode == ARM::TCRETURNri ||
|
|
||||||
RetOpcode == ARM::TCRETURNriND);
|
|
||||||
|
|
||||||
SmallVector<unsigned, 4> Regs;
|
SmallVector<unsigned, 4> Regs;
|
||||||
unsigned i = CSI.size();
|
unsigned i = CSI.size();
|
||||||
|
@@ -2026,45 +2026,22 @@ def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
|
|||||||
|
|
||||||
// Tail calls.
|
// Tail calls.
|
||||||
|
|
||||||
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
|
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in {
|
||||||
// IOS versions.
|
def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
|
||||||
let Uses = [SP] in {
|
IIC_Br, []>;
|
||||||
def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
|
|
||||||
IIC_Br, []>, Requires<[IsIOS]>;
|
|
||||||
|
|
||||||
def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
|
def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
|
||||||
IIC_Br, []>, Requires<[IsIOS]>;
|
IIC_Br, []>;
|
||||||
|
|
||||||
def TAILJMPd : ARMPseudoExpand<(outs), (ins br_target:$dst, variable_ops),
|
def TAILJMPd : ARMPseudoExpand<(outs), (ins br_target:$dst, variable_ops),
|
||||||
4, IIC_Br, [],
|
4, IIC_Br, [],
|
||||||
(Bcc br_target:$dst, (ops 14, zero_reg))>,
|
(Bcc br_target:$dst, (ops 14, zero_reg))>,
|
||||||
Requires<[IsARM, IsIOS]>;
|
Requires<[IsARM]>;
|
||||||
|
|
||||||
def TAILJMPr : ARMPseudoExpand<(outs), (ins tcGPR:$dst, variable_ops),
|
def TAILJMPr : ARMPseudoExpand<(outs), (ins tcGPR:$dst, variable_ops),
|
||||||
4, IIC_Br, [],
|
4, IIC_Br, [],
|
||||||
(BX GPR:$dst)>,
|
(BX GPR:$dst)>,
|
||||||
Requires<[IsARM, IsIOS]>;
|
Requires<[IsARM]>;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Non-IOS versions (the difference is R9).
|
|
||||||
let Uses = [SP] in {
|
|
||||||
def TCRETURNdiND : PseudoInst<(outs), (ins i32imm:$dst, variable_ops),
|
|
||||||
IIC_Br, []>, Requires<[IsNotIOS]>;
|
|
||||||
|
|
||||||
def TCRETURNriND : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
|
|
||||||
IIC_Br, []>, Requires<[IsNotIOS]>;
|
|
||||||
|
|
||||||
def TAILJMPdND : ARMPseudoExpand<(outs), (ins brtarget:$dst, variable_ops),
|
|
||||||
4, IIC_Br, [],
|
|
||||||
(Bcc br_target:$dst, (ops 14, zero_reg))>,
|
|
||||||
Requires<[IsARM, IsNotIOS]>;
|
|
||||||
|
|
||||||
def TAILJMPrND : ARMPseudoExpand<(outs), (ins tcGPR:$dst, variable_ops),
|
|
||||||
4, IIC_Br, [],
|
|
||||||
(BX GPR:$dst)>,
|
|
||||||
Requires<[IsARM, IsNotIOS]>;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Secure Monitor Call is a system instruction.
|
// Secure Monitor Call is a system instruction.
|
||||||
@@ -4829,24 +4806,10 @@ def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
|
|||||||
|
|
||||||
// TODO: add,sub,and, 3-instr forms?
|
// TODO: add,sub,and, 3-instr forms?
|
||||||
|
|
||||||
// Tail calls
|
// Tail calls. These patterns also apply to Thumb mode.
|
||||||
def : ARMPat<(ARMtcret tcGPR:$dst),
|
def : Pat<(ARMtcret tcGPR:$dst), (TCRETURNri tcGPR:$dst)>;
|
||||||
(TCRETURNri tcGPR:$dst)>, Requires<[IsIOS]>;
|
def : Pat<(ARMtcret (i32 tglobaladdr:$dst)), (TCRETURNdi texternalsym:$dst)>;
|
||||||
|
def : Pat<(ARMtcret (i32 texternalsym:$dst)), (TCRETURNdi texternalsym:$dst)>;
|
||||||
def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
|
|
||||||
(TCRETURNdi texternalsym:$dst)>, Requires<[IsIOS]>;
|
|
||||||
|
|
||||||
def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
|
|
||||||
(TCRETURNdi texternalsym:$dst)>, Requires<[IsIOS]>;
|
|
||||||
|
|
||||||
def : ARMPat<(ARMtcret tcGPR:$dst),
|
|
||||||
(TCRETURNriND tcGPR:$dst)>, Requires<[IsNotIOS]>;
|
|
||||||
|
|
||||||
def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
|
|
||||||
(TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotIOS]>;
|
|
||||||
|
|
||||||
def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
|
|
||||||
(TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotIOS]>;
|
|
||||||
|
|
||||||
// Direct calls
|
// Direct calls
|
||||||
def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
|
def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
|
||||||
|
@@ -504,24 +504,20 @@ let isBranch = 1, isTerminator = 1 in
|
|||||||
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
|
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
|
||||||
// IOS versions.
|
// IOS versions.
|
||||||
let Uses = [SP] in {
|
let Uses = [SP] in {
|
||||||
// tTAILJMPd: IOS version uses a Thumb2 branch (no Thumb1 tail calls
|
|
||||||
// on IOS), so it's in ARMInstrThumb2.td.
|
|
||||||
def tTAILJMPr : tPseudoExpand<(outs), (ins tcGPR:$dst, variable_ops),
|
def tTAILJMPr : tPseudoExpand<(outs), (ins tcGPR:$dst, variable_ops),
|
||||||
4, IIC_Br, [],
|
4, IIC_Br, [],
|
||||||
(tBX GPR:$dst, (ops 14, zero_reg))>,
|
(tBX GPR:$dst, (ops 14, zero_reg))>,
|
||||||
Requires<[IsThumb, IsIOS]>;
|
Requires<[IsThumb]>;
|
||||||
}
|
}
|
||||||
// Non-IOS versions (the difference is R9).
|
// tTAILJMPd: IOS version uses a Thumb2 branch (no Thumb1 tail calls
|
||||||
|
// on IOS), so it's in ARMInstrThumb2.td.
|
||||||
|
// Non-IOS version:
|
||||||
let Uses = [SP] in {
|
let Uses = [SP] in {
|
||||||
def tTAILJMPdND : tPseudoExpand<(outs),
|
def tTAILJMPdND : tPseudoExpand<(outs),
|
||||||
(ins t_brtarget:$dst, pred:$p, variable_ops),
|
(ins t_brtarget:$dst, pred:$p, variable_ops),
|
||||||
4, IIC_Br, [],
|
4, IIC_Br, [],
|
||||||
(tB t_brtarget:$dst, pred:$p)>,
|
(tB t_brtarget:$dst, pred:$p)>,
|
||||||
Requires<[IsThumb, IsNotIOS]>;
|
Requires<[IsThumb, IsNotIOS]>;
|
||||||
def tTAILJMPrND : tPseudoExpand<(outs), (ins tcGPR:$dst, variable_ops),
|
|
||||||
4, IIC_Br, [],
|
|
||||||
(tBX GPR:$dst, (ops 14, zero_reg))>,
|
|
||||||
Requires<[IsThumb, IsNotIOS]>;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user