Add support for folding loads / stores into 16-bit moves used by Thumb2.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78558 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2009-08-10 06:32:05 +00:00
parent 2294645642
commit 19068ba71a

View File

@ -698,45 +698,65 @@ foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
unsigned OpNum = Ops[0]; unsigned OpNum = Ops[0];
unsigned Opc = MI->getOpcode(); unsigned Opc = MI->getOpcode();
MachineInstr *NewMI = NULL; MachineInstr *NewMI = NULL;
if (Opc == ARM::MOVr || Opc == ARM::t2MOVr) { // FIXME: tMOVgpr2gpr etc.? if (Opc == ARM::MOVr || Opc == ARM::t2MOVr) {
// If it is updating CPSR, then it cannot be folded. // If it is updating CPSR, then it cannot be folded.
if (MI->getOperand(4).getReg() != ARM::CPSR || MI->getOperand(4).isDead()) { if (MI->getOperand(4).getReg() == ARM::CPSR && !MI->getOperand(4).isDead())
unsigned Pred = MI->getOperand(2).getImm(); return NULL;
unsigned PredReg = MI->getOperand(3).getReg(); unsigned Pred = MI->getOperand(2).getImm();
if (OpNum == 0) { // move -> store unsigned PredReg = MI->getOperand(3).getReg();
unsigned SrcReg = MI->getOperand(1).getReg(); if (OpNum == 0) { // move -> store
bool isKill = MI->getOperand(1).isKill(); unsigned SrcReg = MI->getOperand(1).getReg();
bool isUndef = MI->getOperand(1).isUndef(); bool isKill = MI->getOperand(1).isKill();
if (Opc == ARM::MOVr) bool isUndef = MI->getOperand(1).isUndef();
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::STR)) if (Opc == ARM::MOVr)
.addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::STR))
.addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg); .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
else // ARM::t2MOVr .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2STRi12)) else // ARM::t2MOVr
.addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2STRi12))
.addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
} else { // move -> load .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
unsigned DstReg = MI->getOperand(0).getReg(); } else { // move -> load
bool isDead = MI->getOperand(0).isDead(); unsigned DstReg = MI->getOperand(0).getReg();
bool isUndef = MI->getOperand(0).isUndef(); bool isDead = MI->getOperand(0).isDead();
if (Opc == ARM::MOVr) bool isUndef = MI->getOperand(0).isUndef();
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::LDR)) if (Opc == ARM::MOVr)
.addReg(DstReg, NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::LDR))
RegState::Define | .addReg(DstReg,
getDeadRegState(isDead) | RegState::Define |
getUndefRegState(isUndef)) getDeadRegState(isDead) |
.addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg); getUndefRegState(isUndef))
else // ARM::t2MOVr .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2LDRi12)) else // ARM::t2MOVr
.addReg(DstReg, NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2LDRi12))
RegState::Define | .addReg(DstReg,
getDeadRegState(isDead) | RegState::Define |
getUndefRegState(isUndef)) getDeadRegState(isDead) |
.addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); getUndefRegState(isUndef))
} .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
} }
} } else if (Opc == ARM::tMOVgpr2gpr ||
else if (Opc == ARM::FCPYS) { Opc == ARM::tMOVtgpr2gpr ||
Opc == ARM::tMOVgpr2tgpr) {
if (OpNum == 0) { // move -> store
unsigned SrcReg = MI->getOperand(1).getReg();
bool isKill = MI->getOperand(1).isKill();
bool isUndef = MI->getOperand(1).isUndef();
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2STRi12))
.addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
.addFrameIndex(FI).addImm(0).addImm(ARMCC::AL).addReg(0);
} else { // move -> load
unsigned DstReg = MI->getOperand(0).getReg();
bool isDead = MI->getOperand(0).isDead();
bool isUndef = MI->getOperand(0).isUndef();
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2LDRi12))
.addReg(DstReg,
RegState::Define |
getDeadRegState(isDead) |
getUndefRegState(isUndef))
.addFrameIndex(FI).addImm(0).addImm(ARMCC::AL).addReg(0);
}
} else if (Opc == ARM::FCPYS) {
unsigned Pred = MI->getOperand(2).getImm(); unsigned Pred = MI->getOperand(2).getImm();
unsigned PredReg = MI->getOperand(3).getReg(); unsigned PredReg = MI->getOperand(3).getReg();
if (OpNum == 0) { // move -> store if (OpNum == 0) { // move -> store
@ -804,6 +824,10 @@ ARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
// If it is updating CPSR, then it cannot be folded. // If it is updating CPSR, then it cannot be folded.
return MI->getOperand(4).getReg() != ARM::CPSR || return MI->getOperand(4).getReg() != ARM::CPSR ||
MI->getOperand(4).isDead(); MI->getOperand(4).isDead();
} else if (Opc == ARM::tMOVgpr2gpr ||
Opc == ARM::tMOVtgpr2gpr ||
Opc == ARM::tMOVgpr2tgpr) {
return true;
} else if (Opc == ARM::FCPYS || Opc == ARM::FCPYD) { } else if (Opc == ARM::FCPYS || Opc == ARM::FCPYD) {
return true; return true;
} else if (Opc == ARM::VMOVD || Opc == ARM::VMOVQ) { } else if (Opc == ARM::VMOVD || Opc == ARM::VMOVQ) {