summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2010-07-08 01:18:23 +0000
committerDale Johannesen <dalej@apple.com>2010-07-08 01:18:23 +0000
commite2289285ae2f054b6a697e1fe49f0eea4f2613c2 (patch)
treec4a7fe7a728f1a382edff47cec46a97323a6e554 /llvm/lib
parente75704369db335e523287ca851eccf3a77b1557a (diff)
downloadbcm5719-llvm-e2289285ae2f054b6a697e1fe49f0eea4f2613c2.tar.gz
bcm5719-llvm-e2289285ae2f054b6a697e1fe49f0eea4f2613c2.zip
Changes to ARM tail calls, mostly cosmetic.
Add explicit testcases for tail calls within the same module. Duplicate some code to humor those who think .w doesn't apply on ARM. Leave this disabled on Thumb1, and add some comments explaining why it's hard and won't gain much. llvm-svn: 107851
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp3
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp21
-rw-r--r--llvm/lib/Target/ARM/ARMInstrInfo.td4
3 files changed, 20 insertions, 8 deletions
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 3cd28b486b4..8f22d177c2a 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -1663,7 +1663,8 @@ emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {
// Jump to label or value in register.
if (RetOpcode == ARM::TCRETURNdi) {
- BuildMI(MBB, MBBI, dl, TII.get(ARM::TAILJMPd)).
+ BuildMI(MBB, MBBI, dl,
+ TII.get(STI.isThumb() ? ARM::TAILJMPdt : ARM::TAILJMPd)).
addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
JumpTarget.getTargetFlags());
} else if (RetOpcode == ARM::TCRETURNdiND) {
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 8f82c7498a2..8670d37c836 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -1338,13 +1338,7 @@ bool MatchingStackOffset(SDValue Arg, unsigned Offset, ISD::ArgFlagsTy Flags,
if (!TII->isLoadFromStackSlot(Def, FI))
return false;
} else {
-// unsigned Opcode = Def->getOpcode();
-// if ((Opcode == X86::LEA32r || Opcode == X86::LEA64r) &&
-// Def->getOperand(1).isFI()) {
-// FI = Def->getOperand(1).getIndex();
-// Bytes = Flags.getByValSize();
-// } else
- return false;
+ return false;
}
} else if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Arg)) {
if (Flags.isByVal())
@@ -1400,6 +1394,12 @@ ARMTargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
// FIXME: Completely disable sibcall for Thumb1 since Thumb1RegisterInfo::
// emitEpilogue is not ready for them.
+ // Doing this is tricky, since the LDM/POP instruction on Thumb doesn't take
+ // LR. This means if we need to reload LR, it takes an extra instructions,
+ // which outweighs the value of the tail call; but here we don't know yet
+ // whether LR is going to be used. Probably the right approach is to
+ // generate the tail call here and turn it back into CALL/RET in
+ // emitEpilogue if LR is used.
if (Subtarget->isThumb1Only())
return false;
@@ -1409,6 +1409,13 @@ ARMTargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
// (We could do this by loading the address of the callee into a register;
// that is an extra instruction over the direct call and burns a register
// as well, so is not likely to be a win.)
+
+ // It might be safe to remove this restriction on non-Darwin.
+
+ // Thumb1 PIC calls to external symbols use BX, so they can be tail calls,
+ // but we need to make sure there are enough registers; the only valid
+ // registers are the 4 used for parameters. We don't currently do this
+ // case.
if (isa<ExternalSymbolSDNode>(Callee))
return false;
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index 16d94093b04..c73e204a26b 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -1049,6 +1049,10 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
"@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
+ IIC_Br, "b\t$dst @ TAILCALL",
+ []>, Requires<[IsDarwin]>;
+
+ def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
IIC_Br, "b.w\t$dst @ TAILCALL",
[]>, Requires<[IsDarwin]>;
OpenPOWER on IntegriCloud