forked from OSchip/llvm-project
[ARM] Place jump table as the first operand in additions
When generating table jump code for switch statements, place the jump table label as the first operand in the various addition instructions in order to enable addressing mode selectors to better match index computation and possibly fold them into the addressing mode of the table entry load instruction. Differential revision: https://reviews.llvm.org/D39752 llvm-svn: 318033
This commit is contained in:
parent
8e2a5bd235
commit
842aa90192
|
@ -1683,7 +1683,7 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||
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(0));
|
||||
TmpInst.addOperand(MCOperand::createImm(MI->getOperand(2).getImm()));
|
||||
}
|
||||
// Add predicate operands.
|
||||
TmpInst.addOperand(MCOperand::createImm(ARMCC::AL));
|
||||
|
|
|
@ -2124,7 +2124,7 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
|
|||
// We're in thumb-1 mode, so we must have something like:
|
||||
// %idx = tLSLri %idx, 2
|
||||
// %base = tLEApcrelJT
|
||||
// %t = tLDRr %idx, %base
|
||||
// %t = tLDRr %base, %idx
|
||||
unsigned BaseReg = User.MI->getOperand(0).getReg();
|
||||
|
||||
if (User.MI->getIterator() == User.MI->getParent()->begin())
|
||||
|
@ -2146,9 +2146,9 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
|
|||
MachineInstr *Load = User.MI->getNextNode();
|
||||
if (Load->getOpcode() != ARM::tLDRr)
|
||||
continue;
|
||||
if (Load->getOperand(1).getReg() != ShiftedIdxReg ||
|
||||
Load->getOperand(2).getReg() != BaseReg ||
|
||||
!Load->getOperand(1).isKill())
|
||||
if (Load->getOperand(1).getReg() != BaseReg ||
|
||||
Load->getOperand(2).getReg() != ShiftedIdxReg ||
|
||||
!Load->getOperand(2).isKill())
|
||||
continue;
|
||||
|
||||
// If we're in PIC mode, there should be another ADD following.
|
||||
|
@ -2165,9 +2165,9 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
|
|||
if (isPositionIndependentOrROPI) {
|
||||
MachineInstr *Add = Load->getNextNode();
|
||||
if (Add->getOpcode() != ARM::tADDrr ||
|
||||
Add->getOperand(2).getReg() != Load->getOperand(0).getReg() ||
|
||||
Add->getOperand(3).getReg() != BaseReg ||
|
||||
!Add->getOperand(2).isKill())
|
||||
Add->getOperand(2).getReg() != BaseReg ||
|
||||
Add->getOperand(3).getReg() != Load->getOperand(0).getReg() ||
|
||||
!Add->getOperand(3).isKill())
|
||||
continue;
|
||||
if (Add->getOperand(0).getReg() != MI->getOperand(0).getReg())
|
||||
continue;
|
||||
|
|
|
@ -4517,7 +4517,7 @@ SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
|
|||
SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy);
|
||||
Table = DAG.getNode(ARMISD::WrapperJT, dl, MVT::i32, JTI);
|
||||
Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(4, dl, PTy));
|
||||
SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table);
|
||||
SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Table, Index);
|
||||
if (Subtarget->isThumb2() || (Subtarget->hasV8MBaselineOps() && Subtarget->isThumb())) {
|
||||
// Thumb2 and ARMv8-M use a two-level jump. That is, it jumps into the jump table
|
||||
// which does another jump to the destination. This also makes it easier
|
||||
|
@ -4531,7 +4531,7 @@ SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
|
|||
DAG.getLoad((EVT)MVT::i32, dl, Chain, Addr,
|
||||
MachinePointerInfo::getJumpTable(DAG.getMachineFunction()));
|
||||
Chain = Addr.getValue(1);
|
||||
Addr = DAG.getNode(ISD::ADD, dl, PTy, Addr, Table);
|
||||
Addr = DAG.getNode(ISD::ADD, dl, PTy, Table, Addr);
|
||||
return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI);
|
||||
} else {
|
||||
Addr =
|
||||
|
|
|
@ -48,10 +48,9 @@ lab4:
|
|||
; CHECK-LABEL: jump_table:
|
||||
|
||||
; ARM: adr r[[R_TAB_BASE:[0-9]+]], [[LJTI:\.LJTI[0-9]+_[0-9]+]]
|
||||
; ARM: lsl r[[R_TAB_IDX:[0-9]+]], r{{[0-9]+}}, #2
|
||||
; ARM_ABS: ldr pc, [r[[R_TAB_IDX]], r[[R_TAB_BASE]]]
|
||||
; ARM_PC: ldr r[[R_OFFSET:[0-9]+]], [r[[R_TAB_IDX]], r[[R_TAB_BASE]]]
|
||||
; ARM_PC: add pc, r[[R_OFFSET]], r[[R_TAB_BASE]]
|
||||
; ARM_ABS: ldr pc, [r[[R_TAB_BASE]], r{{[0-9]+}}, lsl #2]
|
||||
; ARM_PC: ldr r[[R_OFFSET:[0-9]+]], [r[[R_TAB_BASE]], r{{[0-9]+}}, lsl #2]
|
||||
; ARM_PC: add pc, r[[R_TAB_BASE]], r[[R_OFFSET]]
|
||||
; ARM: [[LJTI]]
|
||||
; ARM_ABS: .long [[LBB1:\.LBB[0-9]+_[0-9]+]]
|
||||
; ARM_ABS: .long [[LBB2:\.LBB[0-9]+_[0-9]+]]
|
||||
|
|
|
@ -21,7 +21,7 @@ define i32 @jump_table(i32 %c, i32 %a, i32 %b) #0 {
|
|||
|
||||
; CHECK-T2BASE: lsls [[REG_OFFSET:r[0-9]+]], {{r[0-9]+}}, #2
|
||||
; CHECK-T2BASE: adr [[REG_JT:r[0-9]+]], .LJTI1_0
|
||||
; CHECK-T2BASE: adds [[REG_ENTRY:r[0-9]+]], [[REG_OFFSET]], [[REG_JT]]
|
||||
; CHECK-T2BASE: adds [[REG_ENTRY:r[0-9]+]], [[REG_JT]], [[REG_OFFSET]]
|
||||
; CHECK-T2BASE: mov pc, [[REG_ENTRY]]
|
||||
|
||||
; CHECK-LABEL: .LJTI1_0:
|
||||
|
|
|
@ -245,7 +245,7 @@ body: |
|
|||
|
||||
%r0, dead %cpsr = tLSLri killed %r1, 2, 14, _
|
||||
%r1 = tLEApcrelJT %jump-table.0, 14, _
|
||||
%r0 = tLDRr killed %r0, killed %r1, 14, _ :: (load 4 from jump-table)
|
||||
%r0 = tLDRr killed %r1, killed %r0, 14, _ :: (load 4 from jump-table)
|
||||
tBR_JTr killed %r0, %jump-table.0
|
||||
|
||||
bb.3.d2:
|
||||
|
@ -342,7 +342,7 @@ body: |
|
|||
|
||||
%r0, dead %cpsr = tLSLri killed %r1, 2, 14, _
|
||||
%r1 = tLEApcrelJT %jump-table.0, 14, _
|
||||
%r0 = tLDRr killed %r0, killed %r1, 14, _ :: (load 4 from jump-table)
|
||||
%r0 = tLDRr killed %r1, killed %r0, 14, _ :: (load 4 from jump-table)
|
||||
tBR_JTr killed %r0, %jump-table.0
|
||||
|
||||
bb.3.d2:
|
||||
|
|
Loading…
Reference in New Issue