[llvm] r318291 - [ARM] Split Arm jump table branch into i12 and rs suffixed versions
Momchil Velikov via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 15 04:02:55 PST 2017
Author: chill
Date: Wed Nov 15 04:02:55 2017
New Revision: 318291
URL: http://llvm.org/viewvc/llvm-project?rev=318291&view=rev
Log:
[ARM] Split Arm jump table branch into i12 and rs suffixed versions
This is a refactoring/cleanup of Arm `addrmode2` operand class. The patch
removes it completely.
Differential Revision: https://reviews.llvm.org/D39832
Modified:
llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h
llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp
llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=318291&r1=318290&r2=318291&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Wed Nov 15 04:02:55 2017
@@ -1542,7 +1542,6 @@ void ARMAsmPrinter::EmitInstruction(cons
EmitJumpTableTBInst(MI, MI->getOpcode() == ARM::JUMPTABLE_TBB ? 1 : 2);
return;
case ARM::t2BR_JT: {
- // Lower and emit the instruction itself, then the jump table following it.
EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVr)
.addReg(ARM::PC)
.addReg(MI->getOperand(0).getReg())
@@ -1651,7 +1650,6 @@ void ARMAsmPrinter::EmitInstruction(cons
}
case ARM::tBR_JTr:
case ARM::BR_JTr: {
- // Lower and emit the instruction itself, then the jump table following it.
// mov pc, target
MCInst TmpInst;
unsigned Opc = MI->getOpcode() == ARM::BR_JTr ?
@@ -1668,23 +1666,27 @@ void ARMAsmPrinter::EmitInstruction(cons
EmitToStreamer(*OutStreamer, TmpInst);
return;
}
- case ARM::BR_JTm: {
- // Lower and emit the instruction itself, then the jump table following it.
+ case ARM::BR_JTm_i12: {
// ldr pc, target
MCInst TmpInst;
- if (MI->getOperand(1).getReg() == 0) {
- // literal offset
- TmpInst.setOpcode(ARM::LDRi12);
- TmpInst.addOperand(MCOperand::createReg(ARM::PC));
- TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
- TmpInst.addOperand(MCOperand::createImm(MI->getOperand(2).getImm()));
- } else {
- TmpInst.setOpcode(ARM::LDRrs);
- TmpInst.addOperand(MCOperand::createReg(ARM::PC));
- TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
- TmpInst.addOperand(MCOperand::createReg(MI->getOperand(1).getReg()));
- TmpInst.addOperand(MCOperand::createImm(MI->getOperand(2).getImm()));
- }
+ TmpInst.setOpcode(ARM::LDRi12);
+ TmpInst.addOperand(MCOperand::createReg(ARM::PC));
+ TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
+ TmpInst.addOperand(MCOperand::createImm(MI->getOperand(2).getImm()));
+ // Add predicate operands.
+ TmpInst.addOperand(MCOperand::createImm(ARMCC::AL));
+ TmpInst.addOperand(MCOperand::createReg(0));
+ EmitToStreamer(*OutStreamer, TmpInst);
+ return;
+ }
+ case ARM::BR_JTm_rs: {
+ // ldr pc, target
+ MCInst TmpInst;
+ TmpInst.setOpcode(ARM::LDRrs);
+ TmpInst.addOperand(MCOperand::createReg(ARM::PC));
+ TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
+ TmpInst.addOperand(MCOperand::createReg(MI->getOperand(1).getReg()));
+ TmpInst.addOperand(MCOperand::createImm(MI->getOperand(2).getImm()));
// Add predicate operands.
TmpInst.addOperand(MCOperand::createImm(ARMCC::AL));
TmpInst.addOperand(MCOperand::createReg(0));
@@ -1692,7 +1694,6 @@ void ARMAsmPrinter::EmitInstruction(cons
return;
}
case ARM::BR_JTadd: {
- // Lower and emit the instruction itself, then the jump table following it.
// add pc, target, idx
EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::ADDrr)
.addReg(ARM::PC)
Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=318291&r1=318290&r2=318291&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Wed Nov 15 04:02:55 2017
@@ -468,10 +468,10 @@ bool isCondBranchOpcode(int Opc) {
return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc;
}
-static inline
-bool isJumpTableBranchOpcode(int Opc) {
- return Opc == ARM::BR_JTr || Opc == ARM::BR_JTm || Opc == ARM::BR_JTadd ||
- Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT;
+static inline bool isJumpTableBranchOpcode(int Opc) {
+ return Opc == ARM::BR_JTr || Opc == ARM::BR_JTm_i12 ||
+ Opc == ARM::BR_JTm_rs || Opc == ARM::BR_JTadd || Opc == ARM::tBR_JTr ||
+ Opc == ARM::t2BR_JT;
}
static inline
Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=318291&r1=318290&r2=318291&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Wed Nov 15 04:02:55 2017
@@ -564,7 +564,8 @@ void ARMConstantIslands::doInitialJumpTa
case ARM::BR_JTadd:
case ARM::BR_JTr:
case ARM::tBR_JTr:
- case ARM::BR_JTm:
+ case ARM::BR_JTm_i12:
+ case ARM::BR_JTm_rs:
JTOpcode = ARM::JUMPTABLE_ADDRS;
break;
case ARM::t2BR_JT:
Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=318291&r1=318290&r2=318291&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Wed Nov 15 04:02:55 2017
@@ -50,11 +50,6 @@ DisableShifterOp("disable-shifter-op", c
///
namespace {
-enum AddrMode2Type {
- AM2_BASE, // Simple AM2 (+-imm12)
- AM2_SHOP // Shifter-op AM2
-};
-
class ARMDAGToDAGISel : public SelectionDAGISel {
/// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
/// make the right decision when generating code for different targets.
@@ -105,26 +100,6 @@ public:
bool SelectAddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm);
bool SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc);
- AddrMode2Type SelectAddrMode2Worker(SDValue N, SDValue &Base,
- SDValue &Offset, SDValue &Opc);
- bool SelectAddrMode2Base(SDValue N, SDValue &Base, SDValue &Offset,
- SDValue &Opc) {
- return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_BASE;
- }
-
- bool SelectAddrMode2ShOp(SDValue N, SDValue &Base, SDValue &Offset,
- SDValue &Opc) {
- return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_SHOP;
- }
-
- bool SelectAddrMode2(SDValue N, SDValue &Base, SDValue &Offset,
- SDValue &Opc) {
- SelectAddrMode2Worker(N, Base, Offset, Opc);
-// return SelectAddrMode2ShOp(N, Base, Offset, Opc);
- // This always matches one way or another.
- return true;
- }
-
bool SelectCMOVPred(SDValue N, SDValue &Pred, SDValue &Reg) {
const ConstantSDNode *CN = cast<ConstantSDNode>(N);
Pred = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(N), MVT::i32);
@@ -754,148 +729,6 @@ bool ARMDAGToDAGISel::SelectLdStSOReg(SD
return true;
}
-
-//-----
-
-AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDValue N,
- SDValue &Base,
- SDValue &Offset,
- SDValue &Opc) {
- if (N.getOpcode() == ISD::MUL &&
- (!(Subtarget->isLikeA9() || Subtarget->isSwift()) || N.hasOneUse())) {
- if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
- // X * [3,5,9] -> X + X * [2,4,8] etc.
- int RHSC = (int)RHS->getZExtValue();
- if (RHSC & 1) {
- RHSC = RHSC & ~1;
- ARM_AM::AddrOpc AddSub = ARM_AM::add;
- if (RHSC < 0) {
- AddSub = ARM_AM::sub;
- RHSC = - RHSC;
- }
- if (isPowerOf2_32(RHSC)) {
- unsigned ShAmt = Log2_32(RHSC);
- Base = Offset = N.getOperand(0);
- Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt,
- ARM_AM::lsl),
- SDLoc(N), MVT::i32);
- return AM2_SHOP;
- }
- }
- }
- }
-
- if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB &&
- // ISD::OR that is equivalent to an ADD.
- !CurDAG->isBaseWithConstantOffset(N)) {
- Base = N;
- if (N.getOpcode() == ISD::FrameIndex) {
- int FI = cast<FrameIndexSDNode>(N)->getIndex();
- Base = CurDAG->getTargetFrameIndex(
- FI, TLI->getPointerTy(CurDAG->getDataLayout()));
- } else if (N.getOpcode() == ARMISD::Wrapper &&
- N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress &&
- N.getOperand(0).getOpcode() != ISD::TargetExternalSymbol &&
- N.getOperand(0).getOpcode() != ISD::TargetGlobalTLSAddress) {
- Base = N.getOperand(0);
- }
- Offset = CurDAG->getRegister(0, MVT::i32);
- Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0,
- ARM_AM::no_shift),
- SDLoc(N), MVT::i32);
- return AM2_BASE;
- }
-
- // Match simple R +/- imm12 operands.
- if (N.getOpcode() != ISD::SUB) {
- int RHSC;
- if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/1,
- -0x1000+1, 0x1000, RHSC)) { // 12 bits.
- Base = N.getOperand(0);
- if (Base.getOpcode() == ISD::FrameIndex) {
- int FI = cast<FrameIndexSDNode>(Base)->getIndex();
- Base = CurDAG->getTargetFrameIndex(
- FI, TLI->getPointerTy(CurDAG->getDataLayout()));
- }
- Offset = CurDAG->getRegister(0, MVT::i32);
-
- ARM_AM::AddrOpc AddSub = ARM_AM::add;
- if (RHSC < 0) {
- AddSub = ARM_AM::sub;
- RHSC = - RHSC;
- }
- Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC,
- ARM_AM::no_shift),
- SDLoc(N), MVT::i32);
- return AM2_BASE;
- }
- }
-
- if ((Subtarget->isLikeA9() || Subtarget->isSwift()) && !N.hasOneUse()) {
- // Compute R +/- (R << N) and reuse it.
- Base = N;
- Offset = CurDAG->getRegister(0, MVT::i32);
- Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0,
- ARM_AM::no_shift),
- SDLoc(N), MVT::i32);
- return AM2_BASE;
- }
-
- // Otherwise this is R +/- [possibly shifted] R.
- ARM_AM::AddrOpc AddSub = N.getOpcode() != ISD::SUB ? ARM_AM::add:ARM_AM::sub;
- ARM_AM::ShiftOpc ShOpcVal =
- ARM_AM::getShiftOpcForNode(N.getOperand(1).getOpcode());
- unsigned ShAmt = 0;
-
- Base = N.getOperand(0);
- Offset = N.getOperand(1);
-
- if (ShOpcVal != ARM_AM::no_shift) {
- // Check to see if the RHS of the shift is a constant, if not, we can't fold
- // it.
- if (ConstantSDNode *Sh =
- dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) {
- ShAmt = Sh->getZExtValue();
- if (isShifterOpProfitable(Offset, ShOpcVal, ShAmt))
- Offset = N.getOperand(1).getOperand(0);
- else {
- ShAmt = 0;
- ShOpcVal = ARM_AM::no_shift;
- }
- } else {
- ShOpcVal = ARM_AM::no_shift;
- }
- }
-
- // Try matching (R shl C) + (R).
- if (N.getOpcode() != ISD::SUB && ShOpcVal == ARM_AM::no_shift &&
- !(Subtarget->isLikeA9() || Subtarget->isSwift() ||
- N.getOperand(0).hasOneUse())) {
- ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0).getOpcode());
- if (ShOpcVal != ARM_AM::no_shift) {
- // Check to see if the RHS of the shift is a constant, if not, we can't
- // fold it.
- if (ConstantSDNode *Sh =
- dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) {
- ShAmt = Sh->getZExtValue();
- if (isShifterOpProfitable(N.getOperand(0), ShOpcVal, ShAmt)) {
- Offset = N.getOperand(0).getOperand(0);
- Base = N.getOperand(1);
- } else {
- ShAmt = 0;
- ShOpcVal = ARM_AM::no_shift;
- }
- } else {
- ShOpcVal = ARM_AM::no_shift;
- }
- }
- }
-
- Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
- SDLoc(N), MVT::i32);
- return AM2_SHOP;
-}
-
bool ARMDAGToDAGISel::SelectAddrMode2OffsetReg(SDNode *Op, SDValue N,
SDValue &Offset, SDValue &Opc) {
unsigned Opcode = Op->getOpcode();
Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=318291&r1=318290&r2=318291&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Wed Nov 15 04:02:55 2017
@@ -971,21 +971,6 @@ def postidx_reg : MemOperand {
let MIOperandInfo = (ops GPRnopc, i32imm);
}
-
-// addrmode2 := reg +/- imm12
-// := reg +/- reg shop imm
-//
-// FIXME: addrmode2 should be refactored the rest of the way to always
-// use explicit imm vs. reg versions above (addrmode_imm12 and ldst_so_reg).
-def AddrMode2AsmOperand : AsmOperandClass { let Name = "AddrMode2"; }
-def addrmode2 : MemOperand,
- ComplexPattern<i32, 3, "SelectAddrMode2", []> {
- let EncoderMethod = "getAddrMode2OpValue";
- let PrintMethod = "printAddrMode2Operand";
- let ParserMatchClass = AddrMode2AsmOperand;
- let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
-}
-
def PostIdxRegShiftedAsmOperand : AsmOperandClass {
let Name = "PostIdxRegShifted";
let ParserMethod = "parsePostIdxReg";
@@ -2380,12 +2365,15 @@ let isBranch = 1, isTerminator = 1 in {
0, IIC_Br,
[(ARMbrjt GPR:$target, tjumptable:$jt)]>,
Sched<[WriteBr]>;
- // FIXME: This shouldn't use the generic "addrmode2," but rather be split
- // into i12 and rs suffixed versions.
- def BR_JTm : ARMPseudoInst<(outs),
- (ins addrmode2:$target, i32imm:$jt),
+ def BR_JTm_i12 : ARMPseudoInst<(outs),
+ (ins addrmode_imm12:$target, i32imm:$jt),
+ 0, IIC_Br,
+ [(ARMbrjt (i32 (load addrmode_imm12:$target)),
+ tjumptable:$jt)]>, Sched<[WriteBrTbl]>;
+ def BR_JTm_rs : ARMPseudoInst<(outs),
+ (ins ldst_so_reg:$target, i32imm:$jt),
0, IIC_Br,
- [(ARMbrjt (i32 (load addrmode2:$target)),
+ [(ARMbrjt (i32 (load ldst_so_reg:$target)),
tjumptable:$jt)]>, Sched<[WriteBrTbl]>;
def BR_JTadd : ARMPseudoInst<(outs),
(ins GPR:$target, GPR:$idx, i32imm:$jt),
More information about the llvm-commits
mailing list