From d20d6586759fe7a53ec8b1dde80622cda49e31b8 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 1 Oct 2009 01:33:39 +0000 Subject: [PATCH] Change ld/st multiples to explicitly model the writeback to base register. This fixes most of the -ldstopti-before-sched2 regressions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83191 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrInfo.td | 15 ++++++-------- lib/Target/ARM/ARMInstrThumb.td | 20 +++++++++--------- lib/Target/ARM/ARMInstrThumb2.td | 12 +++++------ lib/Target/ARM/ARMInstrVFP.td | 20 +++++++++--------- lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 23 ++++++++++++++++++--- lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp | 5 +++-- 6 files changed, 55 insertions(+), 40 deletions(-) diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 29f1a0e3b5e..d54fb08bc97 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -627,13 +627,11 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1 in } // FIXME: remove when we have a way to marking a MI with these properties. -// FIXME: $dst1 should be a def. But the extra ops must be in the end of the -// operand list. // FIXME: Should pc be an implicit operand like PICADD, etc? let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1 in def LDM_RET : AXI4ld<(outs), - (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops), - LdStMulFrm, IIC_Br, "ldm${p}${addr:submode} $addr, $dst1", + (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), + LdStMulFrm, IIC_Br, "ldm${p}${addr:submode} $addr, $wb", []>; // On non-Darwin platforms R9 is callee-saved. @@ -900,17 +898,16 @@ def STRB_POST: AI2stbpo<(outs GPR:$base_wb), // Load / store multiple Instructions. // -// FIXME: $dst1 should be a def. let mayLoad = 1 in def LDM : AXI4ld<(outs), - (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops), - LdStMulFrm, IIC_iLoadm, "ldm${p}${addr:submode} $addr, $dst1", + (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), + LdStMulFrm, IIC_iLoadm, "ldm${p}${addr:submode} $addr, $wb", []>; let mayStore = 1 in def STM : AXI4st<(outs), - (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops), - LdStMulFrm, IIC_iStorem, "stm${p}${addr:submode} $addr, $src1", + (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), + LdStMulFrm, IIC_iStorem, "stm${p}${addr:submode} $addr, $wb", []>; //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 7ec4bdef263..b1a343c54dc 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -182,8 +182,8 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1 in { // FIXME: remove when we have a way to marking a MI with these properties. let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1 in -def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$dst1, variable_ops), IIC_Br, - "pop${p} $dst1", []>; +def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, + "pop${p} $wb", []>; let isCall = 1, Defs = [R0, R1, R2, R3, R12, LR, @@ -350,23 +350,23 @@ def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, // These requires base address to be written back or one of the loaded regs. let mayLoad = 1 in def tLDM : T1I<(outs), - (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops), + (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), IIC_iLoadm, - "ldm${addr:submode}${p} $addr, $dst1", []>; + "ldm${addr:submode}${p} $addr, $wb", []>; let mayStore = 1 in def tSTM : T1I<(outs), - (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops), + (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), IIC_iStorem, - "stm${addr:submode}${p} $addr, $src1", []>; + "stm${addr:submode}${p} $addr, $wb", []>; let mayLoad = 1, Uses = [SP], Defs = [SP] in -def tPOP : T1I<(outs), (ins pred:$p, reglist:$dst1, variable_ops), IIC_Br, - "pop${p} $dst1", []>; +def tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, + "pop${p} $wb", []>; let mayStore = 1, Uses = [SP], Defs = [SP] in -def tPUSH : T1I<(outs), (ins pred:$p, reglist:$src1, variable_ops), IIC_Br, - "push${p} $src1", []>; +def tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, + "push${p} $wb", []>; //===----------------------------------------------------------------------===// // Arithmetic Instructions. diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 9c60aaa45bc..db9abb3a49f 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -633,13 +633,13 @@ def t2STRB_POST : T2Iidxldst<(outs GPR:$base_wb), let mayLoad = 1 in def t2LDM : T2XI<(outs), - (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops), - IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide} $addr, $dst1", []>; + (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), + IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide} $addr, $wb", []>; let mayStore = 1 in def t2STM : T2XI<(outs), - (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops), - IIC_iStorem, "stm${addr:submode}${p}${addr:wide} $addr, $src1", []>; + (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), + IIC_iStorem, "stm${addr:submode}${p}${addr:wide} $addr, $wb", []>; //===----------------------------------------------------------------------===// // Move Instructions. @@ -1074,8 +1074,8 @@ let Defs = // FIXME: Should pc be an implicit operand like PICADD, etc? let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1 in def t2LDM_RET : T2XI<(outs), - (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops), - IIC_Br, "ldm${addr:submode}${p}${addr:wide} $addr, $dst1", + (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), + IIC_Br, "ldm${addr:submode}${p}${addr:wide} $addr, $wb", []>; let isBranch = 1, isTerminator = 1, isBarrier = 1 in { diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td index 4ecc79d7a11..8be3696b21b 100644 --- a/lib/Target/ARM/ARMInstrVFP.td +++ b/lib/Target/ARM/ARMInstrVFP.td @@ -57,32 +57,32 @@ def FSTS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr), // let mayLoad = 1 in { -def FLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1, +def FLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb, variable_ops), IIC_fpLoadm, - "fldm${addr:submode}d${p} ${addr:base}, $dst1", + "fldm${addr:submode}d${p} ${addr:base}, $wb", []> { let Inst{20} = 1; } -def FLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1, +def FLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb, variable_ops), IIC_fpLoadm, - "fldm${addr:submode}s${p} ${addr:base}, $dst1", + "fldm${addr:submode}s${p} ${addr:base}, $wb", []> { let Inst{20} = 1; } } let mayStore = 1 in { -def FSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1, +def FSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb, variable_ops), IIC_fpStorem, - "fstm${addr:submode}d${p} ${addr:base}, $src1", + "fstm${addr:submode}d${p} ${addr:base}, $wb", []> { let Inst{20} = 0; } -def FSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1, +def FSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb, variable_ops), IIC_fpStorem, - "fstm${addr:submode}s${p} ${addr:base}, $src1", + "fstm${addr:submode}s${p} ${addr:base}, $wb", []> { let Inst{20} = 0; } @@ -233,8 +233,8 @@ def FMSR : AVConv4I<0b11100000, 0b1010, (outs SPR:$dst), (ins GPR:$src), [(set SPR:$dst, (bitconvert GPR:$src))]>; def FMRRD : AVConv3I<0b11000101, 0b1011, - (outs GPR:$dst1, GPR:$dst2), (ins DPR:$src), - IIC_VMOVDI, "fmrrd", " $dst1, $dst2, $src", + (outs GPR:$wb, GPR:$dst2), (ins DPR:$src), + IIC_VMOVDI, "fmrrd", " $wb, $dst2, $src", [/* FIXME: Can't write pattern for multiple result instr*/]>; // FMDHR: GPR -> SPR diff --git a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp index 031f5b0da4c..d2ec9ee6cdf 100644 --- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp +++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp @@ -241,6 +241,7 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB, .addReg(Base, getKillRegState(BaseKill)) .addImm(ARM_AM::getAM5Opc(Mode, false, isDPR ? NumRegs<<1 : NumRegs)) .addImm(Pred).addReg(PredReg); + MIB.addReg(0); // Add optional writeback (0 for now). for (unsigned i = 0; i != NumRegs; ++i) MIB = MIB.addReg(Regs[i].first, getDefRegState(isDef) | getKillRegState(Regs[i].second)); @@ -383,7 +384,7 @@ static inline unsigned getLSMultipleTransferSize(MachineInstr *MI) { case ARM::STM: case ARM::t2LDM: case ARM::t2STM: - return (MI->getNumOperands() - 4) * 4; + return (MI->getNumOperands() - 5) * 4; case ARM::FLDMS: case ARM::FSTMS: case ARM::FLDMD: @@ -434,11 +435,15 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineBasicBlock &MBB, if (Mode == ARM_AM::ia && isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) { MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(ARM_AM::db, true)); + MI->getOperand(4).setReg(Base); + MI->getOperand(4).setIsDef(); MBB.erase(PrevMBBI); return true; } else if (Mode == ARM_AM::ib && isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) { MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(ARM_AM::da, true)); + MI->getOperand(4).setReg(Base); // WB to base + MI->getOperand(4).setIsDef(); MBB.erase(PrevMBBI); return true; } @@ -449,6 +454,8 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineBasicBlock &MBB, if ((Mode == ARM_AM::ia || Mode == ARM_AM::ib) && isMatchingIncrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) { MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(Mode, true)); + MI->getOperand(4).setReg(Base); // WB to base + MI->getOperand(4).setIsDef(); if (NextMBBI == I) { Advance = true; ++I; @@ -458,6 +465,8 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineBasicBlock &MBB, } else if ((Mode == ARM_AM::da || Mode == ARM_AM::db) && isMatchingDecrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) { MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(Mode, true)); + MI->getOperand(4).setReg(Base); // WB to base + MI->getOperand(4).setIsDef(); if (NextMBBI == I) { Advance = true; ++I; @@ -478,6 +487,8 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineBasicBlock &MBB, if (Mode == ARM_AM::ia && isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) { MI->getOperand(1).setImm(ARM_AM::getAM5Opc(ARM_AM::db, true, Offset)); + MI->getOperand(4).setReg(Base); // WB to base + MI->getOperand(4).setIsDef(); MBB.erase(PrevMBBI); return true; } @@ -488,6 +499,8 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineBasicBlock &MBB, if (Mode == ARM_AM::ia && isMatchingIncrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) { MI->getOperand(1).setImm(ARM_AM::getAM5Opc(ARM_AM::ia, true, Offset)); + MI->getOperand(4).setReg(Base); // WB to base + MI->getOperand(4).setIsDef(); if (NextMBBI == I) { Advance = true; ++I; @@ -630,6 +643,7 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineBasicBlock &MBB, BuildMI(MBB, MBBI, dl, TII->get(NewOpc)) .addReg(Base, getKillRegState(BaseKill)) .addImm(Offset).addImm(Pred).addReg(PredReg) + .addReg(Base, getDefRegState(true)) // WB base register .addReg(MI->getOperand(0).getReg(), RegState::Define); else if (isAM2) // LDR_PRE, LDR_POST, @@ -647,6 +661,7 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineBasicBlock &MBB, // FSTMS, FSTMD BuildMI(MBB, MBBI, dl, TII->get(NewOpc)).addReg(Base).addImm(Offset) .addImm(Pred).addReg(PredReg) + .addReg(Base, getDefRegState(true)) // WB base register .addReg(MO.getReg(), getKillRegState(MO.isKill())); else if (isAM2) // STR_PRE, STR_POST @@ -811,18 +826,20 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB, .addReg(BaseReg, getKillRegState(BaseKill)) .addImm(ARM_AM::getAM4ModeImm(ARM_AM::ia)) .addImm(Pred).addReg(PredReg) + .addReg(0) .addReg(EvenReg, getDefRegState(isLd) | getDeadRegState(EvenDeadKill)) - .addReg(OddReg, getDefRegState(isLd)| getDeadRegState(OddDeadKill)); + .addReg(OddReg, getDefRegState(isLd) | getDeadRegState(OddDeadKill)); ++NumLDRD2LDM; } else { BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(NewOpc)) .addReg(BaseReg, getKillRegState(BaseKill)) .addImm(ARM_AM::getAM4ModeImm(ARM_AM::ia)) .addImm(Pred).addReg(PredReg) + .addReg(0) .addReg(EvenReg, getKillRegState(EvenDeadKill) | getUndefRegState(EvenUndef)) .addReg(OddReg, - getKillRegState(OddDeadKill) | getUndefRegState(OddUndef)); + getKillRegState(OddDeadKill) | getUndefRegState(OddUndef)); ++NumSTRD2STM; } } else { diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp index bc0c0e75232..64d9f16e594 100644 --- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp @@ -838,10 +838,11 @@ void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int OpNum) { void ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int OpNum) { O << "{"; - for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) { + // Always skip the first operand, it's the optional (and implicit writeback). + for (unsigned i = OpNum+1, e = MI->getNumOperands(); i != e; ++i) { if (MI->getOperand(i).isImplicit()) continue; - if ((int)i != OpNum) O << ", "; + if ((int)i != OpNum+1) O << ", "; printOperand(MI, i); } O << "}";