diff options
| -rw-r--r-- | llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 21 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 4 | ||||
| -rw-r--r-- | llvm/test/CodeGen/ARM/call-tc.ll | 13 | ||||
| -rw-r--r-- | llvm/test/CodeGen/Thumb2/thumb2-call-tc.ll | 10 | ||||
| -rw-r--r-- | llvm/utils/TableGen/ARMDecoderEmitter.cpp | 4 | 
6 files changed, 43 insertions, 12 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]>; diff --git a/llvm/test/CodeGen/ARM/call-tc.ll b/llvm/test/CodeGen/ARM/call-tc.ll index 2bbdb91c90b..f1269d5bd2b 100644 --- a/llvm/test/CodeGen/ARM/call-tc.ll +++ b/llvm/test/CodeGen/ARM/call-tc.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -march=arm | FileCheck %s -check-prefix=CHECKV4 -; RUN: llc < %s -march=arm -mattr=+v5t | FileCheck %s -check-prefix=CHECKV5 +; RUN: llc < %s -mtriple=arm-apple-darwin -march=arm | FileCheck %s -check-prefix=CHECKV4 +; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin -mattr=+v5t | FileCheck %s -check-prefix=CHECKV5  ; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi\  ; RUN:   -relocation-model=pic | FileCheck %s -check-prefix=CHECKELF @@ -37,3 +37,12 @@ BB0:    %10 = call i32* %9(i32 %0, i32* null, i32 %1, i32* %2, i32* %3, i32* %4) ; <i32*> [#uses=1]    ret i32* %10  } + +define void @t4() { +; CHECKV4: t4: +; CHECKV4: b _t2  @ TAILCALL +; CHECKV5: t4: +; CHECKV5: b _t2  @ TAILCALL +        tail call void @t2( )            ; <i32> [#uses=0] +        ret void +} diff --git a/llvm/test/CodeGen/Thumb2/thumb2-call-tc.ll b/llvm/test/CodeGen/Thumb2/thumb2-call-tc.ll index fe47e348ab2..24502b0338c 100644 --- a/llvm/test/CodeGen/Thumb2/thumb2-call-tc.ll +++ b/llvm/test/CodeGen/Thumb2/thumb2-call-tc.ll @@ -25,3 +25,13 @@ define void @h() {          %tmp.upgrd.2 = tail call i32 %tmp( )            ; <i32> [#uses=0]          ret void  } + +define void @j() { +; DARWIN: j: +; DARWIN: b.w _f  @ TAILCALL + +; LINUX: j: +; LINUX: b.w f  @ TAILCALL +        tail call void @f() +        ret void +} diff --git a/llvm/utils/TableGen/ARMDecoderEmitter.cpp b/llvm/utils/TableGen/ARMDecoderEmitter.cpp index d03e0b96cc6..50256919bbe 100644 --- a/llvm/utils/TableGen/ARMDecoderEmitter.cpp +++ b/llvm/utils/TableGen/ARMDecoderEmitter.cpp @@ -1578,8 +1578,8 @@ bool ARMDecoderEmitter::ARMDEBackend::populateInstruction(      // Tail calls are other patterns that generate existing instructions.      if (Name == "TCRETURNdi" || Name == "TCRETURNdiND" ||          Name == "TCRETURNri" || Name == "TCRETURNriND" || -        Name == "TAILJMPd"  || Name == "TAILJMPdND" || -        Name == "TAILJMPdNDt" || +        Name == "TAILJMPd"  || Name == "TAILJMPdt" || +        Name == "TAILJMPdND" || Name == "TAILJMPdNDt" ||          Name == "TAILJMPr"  || Name == "TAILJMPrND" ||          Name == "MOVr_TC")        return false;  | 

