From f16936e5923156863906c915de657b134db4fb16 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 6 Apr 2012 00:04:58 +0000 Subject: Deduplicate ARM call-related instructions. We had special instructions for iOS because r9 is call-clobbered, but that is represented dynamically by the register mask operands now, so there is no need for the pseudo-instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154144 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMAsmPrinter.cpp | 5 --- lib/Target/ARM/ARMCodeEmitter.cpp | 4 +-- lib/Target/ARM/ARMFastISel.cpp | 13 +++---- lib/Target/ARM/ARMInstrInfo.td | 72 +++++---------------------------------- lib/Target/ARM/ARMInstrThumb.td | 51 ++++----------------------- lib/Target/ARM/ARMInstrThumb2.td | 24 ++----------- 6 files changed, 24 insertions(+), 145 deletions(-) diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index ee31c0c027..18ff37332a 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -1266,7 +1266,6 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { } // Darwin call instructions are just normal call instructions with different // clobber semantics (they clobber R9). - case ARM::BXr9_CALL: case ARM::BX_CALL: { { MCInst TmpInst; @@ -1288,7 +1287,6 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { } return; } - case ARM::tBXr9_CALL: case ARM::tBX_CALL: { { MCInst TmpInst; @@ -1311,7 +1309,6 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { } return; } - case ARM::BMOVPCRXr9_CALL: case ARM::BMOVPCRX_CALL: { { MCInst TmpInst; @@ -1339,7 +1336,6 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { } return; } - case ARM::BMOVPCBr9_CALL: case ARM::BMOVPCB_CALL: { { MCInst TmpInst; @@ -1367,7 +1363,6 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { } return; } - case ARM::t2BMOVPCBr9_CALL: case ARM::t2BMOVPCB_CALL: { { MCInst TmpInst; diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index e1e62e6de3..32ef345c05 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -836,9 +836,7 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) { default: llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction"); case ARM::BX_CALL: - case ARM::BMOVPCRX_CALL: - case ARM::BXr9_CALL: - case ARM::BMOVPCRXr9_CALL: { + case ARM::BMOVPCRX_CALL: { // First emit mov lr, pc unsigned Binary = 0x01a0e00f; Binary |= II->getPredicate(&MI) << ARMII::CondShift; diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index 2f08b148e1..3dc79c1625 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -2111,13 +2111,10 @@ bool ARMFastISel::SelectRet(const Instruction *I) { } unsigned ARMFastISel::ARMSelectCallOp(const GlobalValue *GV) { - - // iOS needs the r9 versions of the opcodes. - bool isiOS = Subtarget->isTargetIOS(); if (isThumb2) { - return isiOS ? ARM::tBLr9 : ARM::tBL; + return ARM::tBL; } else { - return isiOS ? ARM::BLr9 : ARM::BL; + return ARM::BL; } } @@ -2176,8 +2173,7 @@ bool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) { if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, RegArgs, CC, NumBytes)) return false; - // Issue the call, BLr9 for iOS, BL otherwise. - // TODO: Turn this into the table of arm call ops. + // Issue the call. MachineInstrBuilder MIB; unsigned CallOpc = ARMSelectCallOp(NULL); if (isThumb2) @@ -2302,8 +2298,7 @@ bool ARMFastISel::SelectCall(const Instruction *I, if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, RegArgs, CC, NumBytes)) return false; - // Issue the call, BLr9 for iOS, BL otherwise. - // TODO: Turn this into the table of arm call ops. + // Issue the call. MachineInstrBuilder MIB; unsigned CallOpc = ARMSelectCallOp(GV); // Explicitly adding the predicate here. diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 65628544ff..e771693590 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -1908,7 +1908,7 @@ let isCall = 1, def BL : ABXI<0b1011, (outs), (ins bl_target:$func, variable_ops), IIC_Br, "bl\t$func", [(ARMcall tglobaladdr:$func)]>, - Requires<[IsARM, IsNotIOS]> { + Requires<[IsARM]> { let Inst{31-28} = 0b1110; bits<24> func; let Inst{23-0} = func; @@ -1918,7 +1918,7 @@ let isCall = 1, def BL_pred : ABI<0b1011, (outs), (ins bl_target:$func, variable_ops), IIC_Br, "bl", "\t$func", [(ARMcall_pred tglobaladdr:$func)]>, - Requires<[IsARM, IsNotIOS]> { + Requires<[IsARM]> { bits<24> func; let Inst{23-0} = func; let DecoderMethod = "DecodeBranchImmInstruction"; @@ -1928,7 +1928,7 @@ let isCall = 1, def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm, IIC_Br, "blx\t$func", [(ARMcall GPR:$func)]>, - Requires<[IsARM, HasV5T, IsNotIOS]> { + Requires<[IsARM, HasV5T]> { bits<4> func; let Inst{31-4} = 0b1110000100101111111111110011; let Inst{3-0} = func; @@ -1937,7 +1937,7 @@ let isCall = 1, def BLX_pred : AI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm, IIC_Br, "blx", "\t$func", [(ARMcall_pred GPR:$func)]>, - Requires<[IsARM, HasV5T, IsNotIOS]> { + Requires<[IsARM, HasV5T]> { bits<4> func; let Inst{27-4} = 0b000100101111111111110011; let Inst{3-0} = func; @@ -1947,67 +1947,19 @@ let isCall = 1, // Note: Restrict $func to the tGPR regclass to prevent it being in LR. def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops), 8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, - Requires<[IsARM, HasV4T, IsNotIOS]>; + Requires<[IsARM, HasV4T]>; // ARMv4 def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops), 8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, - Requires<[IsARM, NoV4T, IsNotIOS]>; + Requires<[IsARM, NoV4T]>; // mov lr, pc; b if callee is marked noreturn to avoid confusing the // return stack predictor. def BMOVPCB_CALL : ARMPseudoInst<(outs), (ins bl_target:$func, variable_ops), 8, IIC_Br, [(ARMcall_nolink tglobaladdr:$func)]>, - Requires<[IsARM, IsNotIOS]>; -} - -let isCall = 1, - // On IOS R9 is call-clobbered. - // R7 is marked as a use to prevent frame-pointer assignments from being - // moved above / below calls. - Defs = [LR], Uses = [R7, SP] in { - def BLr9 : ARMPseudoExpand<(outs), (ins bl_target:$func, variable_ops), - 4, IIC_Br, - [(ARMcall tglobaladdr:$func)], (BL bl_target:$func)>, - Requires<[IsARM, IsIOS]>; - - def BLr9_pred : ARMPseudoExpand<(outs), - (ins bl_target:$func, pred:$p, variable_ops), - 4, IIC_Br, - [(ARMcall_pred tglobaladdr:$func)], - (BL_pred bl_target:$func, pred:$p)>, - Requires<[IsARM, IsIOS]>; - - // ARMv5T and above - def BLXr9 : ARMPseudoExpand<(outs), (ins GPR:$func, variable_ops), - 4, IIC_Br, - [(ARMcall GPR:$func)], - (BLX GPR:$func)>, - Requires<[IsARM, HasV5T, IsIOS]>; - - def BLXr9_pred: ARMPseudoExpand<(outs), (ins GPR:$func, pred:$p,variable_ops), - 4, IIC_Br, - [(ARMcall_pred GPR:$func)], - (BLX_pred GPR:$func, pred:$p)>, - Requires<[IsARM, HasV5T, IsIOS]>; - - // ARMv4T - // Note: Restrict $func to the tGPR regclass to prevent it being in LR. - def BXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops), - 8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, - Requires<[IsARM, HasV4T, IsIOS]>; - - // ARMv4 - def BMOVPCRXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops), - 8, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, - Requires<[IsARM, NoV4T, IsIOS]>; - - // mov lr, pc; b if callee is marked noreturn to avoid confusing the - // return stack predictor. - def BMOVPCBr9_CALL : ARMPseudoInst<(outs),(ins bl_target:$func, variable_ops), - 8, IIC_Br, [(ARMcall_nolink tglobaladdr:$func)]>, - Requires<[IsARM, IsIOS]>; + Requires<[IsARM]>; } let isBranch = 1, isTerminator = 1 in { @@ -4898,15 +4850,9 @@ def : ARMPat<(ARMtcret (i32 texternalsym:$dst)), // Direct calls def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>, - Requires<[IsARM, IsNotIOS]>; -def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>, - Requires<[IsARM, IsIOS]>; -def : ARMPat<(ARMcall_nolink texternalsym:$func), - (BMOVPCB_CALL texternalsym:$func)>, - Requires<[IsARM, IsNotIOS]>; + Requires<[IsARM]>; def : ARMPat<(ARMcall_nolink texternalsym:$func), - (BMOVPCBr9_CALL texternalsym:$func)>, - Requires<[IsARM, IsIOS]>; + (BMOVPCB_CALL texternalsym:$func)>, Requires<[IsARM]>; // zextload i1 -> zextload i8 def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 6c9a55cf64..6c45ccc5ae 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -416,14 +416,13 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1 in { // prevent stack-pointer assignments that appear immediately before calls from // potentially appearing dead. let isCall = 1, - // On non-IOS platforms R9 is callee-saved. Defs = [LR], Uses = [SP] in { // Also used for Thumb2 def tBL : TIx2<0b11110, 0b11, 1, (outs), (ins pred:$p, t_bltarget:$func, variable_ops), IIC_Br, "bl${p}\t$func", [(ARMtcall tglobaladdr:$func)]>, - Requires<[IsThumb, IsNotIOS]> { + Requires<[IsThumb]> { bits<22> func; let Inst{26} = func{21}; let Inst{25-16} = func{20-11}; @@ -437,7 +436,7 @@ let isCall = 1, (outs), (ins pred:$p, t_blxtarget:$func, variable_ops), IIC_Br, "blx${p}\t$func", [(ARMcall tglobaladdr:$func)]>, - Requires<[IsThumb, HasV5T, IsNotIOS]> { + Requires<[IsThumb, HasV5T]> { bits<21> func; let Inst{25-16} = func{20-11}; let Inst{13} = 1; @@ -450,7 +449,7 @@ let isCall = 1, def tBLXr : TI<(outs), (ins pred:$p, GPR:$func, variable_ops), IIC_Br, "blx${p}\t$func", [(ARMtcall GPR:$func)]>, - Requires<[IsThumb, HasV5T, IsNotIOS]>, + Requires<[IsThumb, HasV5T]>, T1Special<{1,1,1,?}> { // A6.2.3 & A8.6.24; bits<4> func; let Inst{6-3} = func; @@ -461,37 +460,7 @@ let isCall = 1, def tBX_CALL : tPseudoInst<(outs), (ins tGPR:$func, variable_ops), 4, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, - Requires<[IsThumb, IsThumb1Only, IsNotIOS]>; -} - -let isCall = 1, - // On IOS R9 is call-clobbered. - // R7 is marked as a use to prevent frame-pointer assignments from being - // moved above / below calls. - Defs = [LR], Uses = [R7, SP] in { - // Also used for Thumb2 - def tBLr9 : tPseudoExpand<(outs), (ins pred:$p, t_bltarget:$func, variable_ops), - 4, IIC_Br, [(ARMtcall tglobaladdr:$func)], - (tBL pred:$p, t_bltarget:$func)>, - Requires<[IsThumb, IsIOS]>; - - // ARMv5T and above, also used for Thumb2 - def tBLXi_r9 : tPseudoExpand<(outs), (ins pred:$p, t_blxtarget:$func, variable_ops), - 4, IIC_Br, [(ARMcall tglobaladdr:$func)], - (tBLXi pred:$p, t_blxtarget:$func)>, - Requires<[IsThumb, HasV5T, IsIOS]>; - - // Also used for Thumb2 - def tBLXr_r9 : tPseudoExpand<(outs), (ins pred:$p, GPR:$func, variable_ops), - 2, IIC_Br, [(ARMtcall GPR:$func)], - (tBLXr pred:$p, GPR:$func)>, - Requires<[IsThumb, HasV5T, IsIOS]>; - - // ARMv4T - def tBXr9_CALL : tPseudoInst<(outs), (ins tGPR:$func, variable_ops), - 4, IIC_Br, - [(ARMcall_nolink tGPR:$func)]>, - Requires<[IsThumb, IsThumb1Only, IsIOS]>; + Requires<[IsThumb, IsThumb1Only]>; } let isBranch = 1, isTerminator = 1, isBarrier = 1 in { @@ -1318,20 +1287,14 @@ def : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), // Direct calls def : T1Pat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>, - Requires<[IsThumb, IsNotIOS]>; -def : T1Pat<(ARMtcall texternalsym:$func), (tBLr9 texternalsym:$func)>, - Requires<[IsThumb, IsIOS]>; + Requires<[IsThumb]>; def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>, - Requires<[IsThumb, HasV5T, IsNotIOS]>; -def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi_r9 texternalsym:$func)>, - Requires<[IsThumb, HasV5T, IsIOS]>; + Requires<[IsThumb, HasV5T]>; // Indirect calls to ARM routines def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>, - Requires<[IsThumb, HasV5T, IsNotIOS]>; -def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr_r9 GPR:$dst)>, - Requires<[IsThumb, HasV5T, IsIOS]>; + Requires<[IsThumb, HasV5T]>; // zextload i1 -> zextload i8 def : T1Pat<(zextloadi1 t_addrmode_rrs1:$addr), diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index cf1fbfa1ab..424c9324e3 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -3276,37 +3276,19 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { Requires<[IsThumb2, IsIOS]>; } -let isCall = 1, - // On non-IOS platforms R9 is callee-saved. - Defs = [LR], Uses = [SP] in { +let isCall = 1, Defs = [LR], Uses = [SP] in { // mov lr, pc; b if callee is marked noreturn to avoid confusing the // return stack predictor. def t2BMOVPCB_CALL : tPseudoInst<(outs), (ins t_bltarget:$func, variable_ops), 6, IIC_Br, [(ARMcall_nolink tglobaladdr:$func)]>, - Requires<[IsThumb, IsNotIOS]>; -} - -let isCall = 1, - // On IOS R9 is call-clobbered. - // R7 is marked as a use to prevent frame-pointer assignments from being - // moved above / below calls. - Defs = [LR], Uses = [R7, SP] in { - // mov lr, pc; b if callee is marked noreturn to avoid confusing the - // return stack predictor. - def t2BMOVPCBr9_CALL : tPseudoInst<(outs), - (ins t_bltarget:$func, variable_ops), - 6, IIC_Br, [(ARMcall_nolink tglobaladdr:$func)]>, - Requires<[IsThumb, IsIOS]>; + Requires<[IsThumb]>; } // Direct calls def : T2Pat<(ARMcall_nolink texternalsym:$func), (t2BMOVPCB_CALL texternalsym:$func)>, - Requires<[IsThumb, IsNotIOS]>; -def : T2Pat<(ARMcall_nolink texternalsym:$func), - (t2BMOVPCBr9_CALL texternalsym:$func)>, - Requires<[IsThumb, IsIOS]>; + Requires<[IsThumb]>; // IT block let Defs = [ITSTATE] in -- cgit v1.2.3-18-g5258