diff options
author | Jim Grosbach <grosbach@apple.com> | 2011-06-30 22:10:46 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2011-06-30 22:10:46 +0000 |
commit | 63b46faeb8acae9b7e5f865b7417dc00b9b9dad3 (patch) | |
tree | 9dd91095e265db1ecbefc5b968d2f0ee04a7fdc0 | |
parent | 2541c41f3e2af94585e14353a91f02facd65e415 (diff) |
Thumb1 register to register MOV instruction is predicable.
Fix a FIXME and allow predication (in Thumb2) for the T1 register to
register MOV instructions. This allows some better codegen with
if-conversion (as seen in the test updates), plus it lays the groundwork
for pseudo-izing the tMOVCC instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134197 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMAsmPrinter.cpp | 8 | ||||
-rw-r--r-- | lib/Target/ARM/ARMFrameLowering.cpp | 24 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb.td | 23 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 3 | ||||
-rw-r--r-- | lib/Target/ARM/Thumb1FrameLowering.cpp | 13 | ||||
-rw-r--r-- | lib/Target/ARM/Thumb1InstrInfo.cpp | 4 | ||||
-rw-r--r-- | lib/Target/ARM/Thumb1RegisterInfo.cpp | 22 | ||||
-rw-r--r-- | lib/Target/ARM/Thumb2InstrInfo.cpp | 14 | ||||
-rw-r--r-- | test/CodeGen/Thumb2/2011-06-07-TwoAddrEarlyClobber.ll | 10 | ||||
-rw-r--r-- | test/CodeGen/Thumb2/thumb2-ifcvt1.ll | 5 |
10 files changed, 67 insertions, 59 deletions
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 300cff518b..0988ff1f95 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -1223,6 +1223,9 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { TmpInst.setOpcode(ARM::tMOVr); TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); + // Add predicate operands. + TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); + TmpInst.addOperand(MCOperand::CreateReg(0)); OutStreamer.EmitInstruction(TmpInst); } { @@ -1610,8 +1613,9 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { TmpInst.setOpcode(ARM::tMOVgpr2tgpr); TmpInst.addOperand(MCOperand::CreateReg(ValReg)); TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); - // 's' bit operand - TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); + // Predicate. + TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); + TmpInst.addOperand(MCOperand::CreateReg(0)); OutStreamer.AddComment("eh_setjmp begin"); OutStreamer.EmitInstruction(TmpInst); } diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp index 4ef26660a7..2b801458f8 100644 --- a/lib/Target/ARM/ARMFrameLowering.cpp +++ b/lib/Target/ARM/ARMFrameLowering.cpp @@ -268,14 +268,14 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const { // bic r4, r4, MaxAlign // mov sp, r4 // FIXME: It will be better just to find spare register here. - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2tgpr), ARM::R4) - .addReg(ARM::SP, RegState::Kill); + AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2tgpr), ARM::R4) + .addReg(ARM::SP, RegState::Kill)); AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::t2BICri), ARM::R4) .addReg(ARM::R4, RegState::Kill) .addImm(MaxAlign-1))); - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::SP) - .addReg(ARM::R4, RegState::Kill); + AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::SP) + .addReg(ARM::R4, RegState::Kill)); } AFI->setShouldRestoreSPFromFP(true); @@ -293,9 +293,9 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const { .addReg(ARM::SP) .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); else - BuildMI(MBB, MBBI, dl, - TII.get(ARM::tMOVgpr2gpr), RegInfo->getBaseRegister()) - .addReg(ARM::SP); + AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), + RegInfo->getBaseRegister()) + .addReg(ARM::SP)); } // If the frame has variable sized objects then the epilogue must restore @@ -364,8 +364,9 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF, "No scratch register to restore SP from FP!"); emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes, ARMCC::AL, 0, TII); - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), ARM::SP) - .addReg(ARM::R4); + AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), + ARM::SP) + .addReg(ARM::R4)); } } else { // Thumb2 or ARM. @@ -373,8 +374,9 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF, BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP) .addReg(FramePtr).addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); else - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), ARM::SP) - .addReg(FramePtr); + AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), + ARM::SP) + .addReg(FramePtr)); } } else if (NumBytes) emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes); diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 10476335bd..b2bf344e42 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -409,7 +409,7 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, hasExtraDefRegAllocReq = 1 in def tPOP_RET : tPseudoInst<(outs), (ins pred:$p, reglist:$regs, variable_ops), - Size4Bytes, IIC_iPop_Br, []>; + Size2Bytes, IIC_iPop_Br, []>; // All calls clobber the non-callee saved registers. SP is marked as a use to // prevent stack-pointer assignments that appear immediately before calls from @@ -1054,9 +1054,9 @@ def tMOVi8 : T1sI<(outs tGPR:$Rd), (ins imm0_255:$imm8), IIC_iMOVi, // TODO: A7-73: MOV(2) - mov setting flag. let neverHasSideEffects = 1 in { -// FIXME: Make this predicable. -def tMOVr : T1I<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iMOVr, - "mov\t$Rd, $Rm", []>, +def tMOVr : Thumb1pI<(outs tGPR:$Rd), (ins tGPR:$Rm), AddrModeNone, + Size2Bytes, IIC_iMOVr, + "mov", "\t$Rd, $Rm", "", []>, T1Special<0b1000> { // A8.6.97 bits<4> Rd; @@ -1076,9 +1076,10 @@ def tMOVSr : T1I<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iMOVr, let Inst{2-0} = Rd; } -// FIXME: Make these predicable. -def tMOVgpr2tgpr : T1I<(outs tGPR:$Rd), (ins GPR:$Rm), IIC_iMOVr, - "mov\t$Rd, $Rm", []>, +// FIXME: Do we really need separate instructions for GPR<-->tGPR like this? +// They all map to the same instruction (MOV encoding T1). +def tMOVgpr2tgpr : Thumb1pI<(outs tGPR:$Rd), (ins GPR:$Rm), AddrModeNone, + Size2Bytes, IIC_iMOVr, "mov", "\t$Rd, $Rm", "", []>, T1Special<{1,0,0,?}> { // A8.6.97 bits<4> Rd; @@ -1087,8 +1088,8 @@ def tMOVgpr2tgpr : T1I<(outs tGPR:$Rd), (ins GPR:$Rm), IIC_iMOVr, let Inst{6-3} = Rm; let Inst{2-0} = Rd{2-0}; } -def tMOVtgpr2gpr : T1I<(outs GPR:$Rd), (ins tGPR:$Rm), IIC_iMOVr, - "mov\t$Rd, $Rm", []>, +def tMOVtgpr2gpr : Thumb1pI<(outs GPR:$Rd), (ins tGPR:$Rm), AddrModeNone, + Size2Bytes, IIC_iMOVr, "mov", "\t$Rd, $Rm", "", []>, T1Special<{1,0,?,0}> { // A8.6.97 bits<4> Rd; @@ -1098,8 +1099,8 @@ def tMOVtgpr2gpr : T1I<(outs GPR:$Rd), (ins tGPR:$Rm), IIC_iMOVr, let Inst{5-3} = Rm{2-0}; let Inst{2-0} = Rd{2-0}; } -def tMOVgpr2gpr : T1I<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVr, - "mov\t$Rd, $Rm", []>, +def tMOVgpr2gpr : Thumb1pI<(outs GPR:$Rd), (ins GPR:$Rm), AddrModeNone, + Size2Bytes, IIC_iMOVr, "mov", "\t$Rd, $Rm", "", []>, T1Special<{1,0,?,?}> { // A8.6.97 bits<4> Rd; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 178fe5229d..6952c384f4 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -1882,8 +1882,7 @@ GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, if (isThumb) if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || - Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp" || - (Mnemonic == "mov" && isThumbOne)) + Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") CanAcceptPredicationCode = false; } diff --git a/lib/Target/ARM/Thumb1FrameLowering.cpp b/lib/Target/ARM/Thumb1FrameLowering.cpp index 80b57c9545..326d4af198 100644 --- a/lib/Target/ARM/Thumb1FrameLowering.cpp +++ b/lib/Target/ARM/Thumb1FrameLowering.cpp @@ -160,7 +160,8 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { // will be allocated after this, so we can still use the base pointer // to reference locals. if (RegInfo->hasBasePointer(MF)) - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), BasePtr).addReg(ARM::SP); + AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), BasePtr) + .addReg(ARM::SP)); // If the frame has variable sized objects then the epilogue must restore // the sp from fp. We can assume there's an FP here since hasFP already @@ -239,11 +240,13 @@ void Thumb1FrameLowering::emitEpilogue(MachineFunction &MF, "No scratch register to restore SP from FP!"); emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes, TII, *RegInfo); - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::SP) - .addReg(ARM::R4); + AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), + ARM::SP) + .addReg(ARM::R4)); } else - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::SP) - .addReg(FramePtr); + AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), + ARM::SP) + .addReg(FramePtr)); } else { if (MBBI->getOpcode() == ARM::tBX_RET && &MBB.front() != MBBI && diff --git a/lib/Target/ARM/Thumb1InstrInfo.cpp b/lib/Target/ARM/Thumb1InstrInfo.cpp index e5d3a89dab..614ba816b1 100644 --- a/lib/Target/ARM/Thumb1InstrInfo.cpp +++ b/lib/Target/ARM/Thumb1InstrInfo.cpp @@ -46,8 +46,8 @@ void Thumb1InstrInfo::copyPhysReg(MachineBasicBlock &MBB, else if (tDest) Opc = ARM::tMOVgpr2tgpr; - BuildMI(MBB, I, DL, get(Opc), DestReg) - .addReg(SrcReg, getKillRegState(KillSrc)); + AddDefaultPred(BuildMI(MBB, I, DL, get(Opc), DestReg) + .addReg(SrcReg, getKillRegState(KillSrc))); assert(ARM::GPRRegClass.contains(DestReg, SrcReg) && "Thumb1 can only copy GPR registers"); } diff --git a/lib/Target/ARM/Thumb1RegisterInfo.cpp b/lib/Target/ARM/Thumb1RegisterInfo.cpp index c485c8eca3..95fbe8cbe4 100644 --- a/lib/Target/ARM/Thumb1RegisterInfo.cpp +++ b/lib/Target/ARM/Thumb1RegisterInfo.cpp @@ -244,8 +244,8 @@ void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB, AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg).setMIFlags(MIFlags)); AddDefaultPred(MIB.addReg(BaseReg, RegState::Kill).addImm(ThisVal)); } else { - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg) - .addReg(BaseReg, RegState::Kill) + AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg) + .addReg(BaseReg, RegState::Kill)) .setMIFlags(MIFlags); } BaseReg = DestReg; @@ -419,11 +419,10 @@ rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx, // Turn it into a move. MI.setDesc(TII.get(ARM::tMOVgpr2tgpr)); MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); - // Remove offset and remaining explicit predicate operands. - do MI.RemoveOperand(FrameRegIdx+1); - while (MI.getNumOperands() > FrameRegIdx+1 && - (!MI.getOperand(FrameRegIdx+1).isReg() || - !MI.getOperand(FrameRegIdx+1).isImm())); + // Remove offset and add predicate operands. + MI.RemoveOperand(FrameRegIdx+1); + MachineInstrBuilder MIB(&MI); + AddDefaultPred(MIB); return true; } @@ -565,8 +564,9 @@ Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB, // the function, the offset will be negative. Use R12 instead since that's // a call clobbered register that we know won't be used in Thumb1 mode. DebugLoc DL; - BuildMI(MBB, I, DL, TII.get(ARM::tMOVtgpr2gpr)). - addReg(ARM::R12, RegState::Define).addReg(Reg, RegState::Kill); + AddDefaultPred(BuildMI(MBB, I, DL, TII.get(ARM::tMOVtgpr2gpr)) + .addReg(ARM::R12, RegState::Define) + .addReg(Reg, RegState::Kill)); // The UseMI is where we would like to restore the register. If there's // interference with R12 before then, however, we'll need to restore it @@ -589,8 +589,8 @@ Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB, } } // Restore the register from R12 - BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVgpr2tgpr)). - addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill); + AddDefaultPred(BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVgpr2tgpr)). + addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill)); return true; } diff --git a/lib/Target/ARM/Thumb2InstrInfo.cpp b/lib/Target/ARM/Thumb2InstrInfo.cpp index b1991f1715..d958693d36 100644 --- a/lib/Target/ARM/Thumb2InstrInfo.cpp +++ b/lib/Target/ARM/Thumb2InstrInfo.cpp @@ -122,8 +122,8 @@ void Thumb2InstrInfo::copyPhysReg(MachineBasicBlock &MBB, else if (tDest) Opc = ARM::tMOVgpr2tgpr; - BuildMI(MBB, I, DL, get(Opc), DestReg) - .addReg(SrcReg, getKillRegState(KillSrc)); + AddDefaultPred(BuildMI(MBB, I, DL, get(Opc), DestReg) + .addReg(SrcReg, getKillRegState(KillSrc))); } void Thumb2InstrInfo:: @@ -231,8 +231,8 @@ void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB, unsigned Opc = 0; if (DestReg == ARM::SP && BaseReg != ARM::SP) { // mov sp, rn. Note t2MOVr cannot be used. - BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr),DestReg) - .addReg(BaseReg).setMIFlags(MIFlags); + AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr),DestReg) + .addReg(BaseReg).setMIFlags(MIFlags)); BaseReg = ARM::SP; continue; } @@ -413,9 +413,9 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); // Remove offset and remaining explicit predicate operands. do MI.RemoveOperand(FrameRegIdx+1); - while (MI.getNumOperands() > FrameRegIdx+1 && - (!MI.getOperand(FrameRegIdx+1).isReg() || - !MI.getOperand(FrameRegIdx+1).isImm())); + while (MI.getNumOperands() > FrameRegIdx+1); + MachineInstrBuilder MIB(&MI); + AddDefaultPred(MIB); return true; } diff --git a/test/CodeGen/Thumb2/2011-06-07-TwoAddrEarlyClobber.ll b/test/CodeGen/Thumb2/2011-06-07-TwoAddrEarlyClobber.ll index 9e6d78e75d..b1ce3bb935 100644 --- a/test/CodeGen/Thumb2/2011-06-07-TwoAddrEarlyClobber.ll +++ b/test/CodeGen/Thumb2/2011-06-07-TwoAddrEarlyClobber.ll @@ -1,13 +1,11 @@ -; RUN: llc < %s | FileCheck %s -target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32" -target triple = "thumbv7-apple-darwin10" +; RUN: llc -mtriple=thumbv7-apple-darwin10 < %s | FileCheck %s %struct.op = type { %struct.op*, %struct.op*, %struct.op* ()*, i32, i16, i16, i8, i8 } ; CHECK: Perl_ck_sort -; CHECK: ldr -; CHECK: mov [[REGISTER:(r[0-9]+)|(lr)]] -; CHECK: str {{(r[0-9])|(lr)}}, {{\[}}[[REGISTER]]{{\]}}, #24 +; CHECK: ldreq +; CHECK: moveq [[REGISTER:(r[0-9]+)|(lr)]] +; CHECK: streq {{(r[0-9])|(lr)}}, {{\[}}[[REGISTER]]{{\]}}, #24 define void @Perl_ck_sort() nounwind optsize { entry: diff --git a/test/CodeGen/Thumb2/thumb2-ifcvt1.ll b/test/CodeGen/Thumb2/thumb2-ifcvt1.ll index d842d4d879..1533040671 100644 --- a/test/CodeGen/Thumb2/thumb2-ifcvt1.ll +++ b/test/CodeGen/Thumb2/thumb2-ifcvt1.ll @@ -70,8 +70,9 @@ entry: define void @t3(i32 %a, i32 %b) nounwind { entry: ; CHECK: t3: -; CHECK: it lt -; CHECK: poplt {r7, pc} +; CHECK: itt ge +; CHECK: movge r0, r1 +; CHECK: blge _foo %tmp1 = icmp sgt i32 %a, 10 ; <i1> [#uses=1] br i1 %tmp1, label %cond_true, label %UnifiedReturnBlock |