diff options
| author | Dylan McKay <dylanmckay34@gmail.com> | 2016-12-10 10:51:55 +0000 |
|---|---|---|
| committer | Dylan McKay <dylanmckay34@gmail.com> | 2016-12-10 10:51:55 +0000 |
| commit | 5c90b8cb4f3b922dd66c0fdb81193f9d91aa3fb4 (patch) | |
| tree | d68e83b4ce108f9b91af998aec3bd1f6094a74b0 /llvm/lib/Target/AVR | |
| parent | 5d0233bea22a103b5ecb5a9b5453f1206f2defe0 (diff) | |
| download | bcm5719-llvm-5c90b8cb4f3b922dd66c0fdb81193f9d91aa3fb4.tar.gz bcm5719-llvm-5c90b8cb4f3b922dd66c0fdb81193f9d91aa3fb4.zip | |
[AVR] Use the register scavenger when expanding 'LDDW' instructions
Summary: This gets rid of the hardcoded 'r0' that was used previously.
Reviewers: asl
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D27567
llvm-svn: 289322
Diffstat (limited to 'llvm/lib/Target/AVR')
| -rw-r--r-- | llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 70 |
1 files changed, 45 insertions, 25 deletions
diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp index c19eac64aa3..bb952e27dc9 100644 --- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp +++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp @@ -21,6 +21,7 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; @@ -110,6 +111,9 @@ bool AVRExpandPseudo::runOnMachineFunction(MachineFunction &MF) { TRI = STI.getRegisterInfo(); TII = STI.getInstrInfo(); + // We need to track liveness in order to use register scavenging. + MF.getProperties().set(MachineFunctionProperties::Property::TracksLiveness); + for (Block &MBB : MF) { bool ContinueExpanding = true; unsigned ExpandCount = 0; @@ -656,8 +660,7 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) { assert(Imm <= 63 && "Offset is out of range"); - unsigned TmpLoReg = DstLoReg; - unsigned TmpHiReg = DstHiReg; + MachineInstr *MIBLO, *MIBHI; // HACK: We shouldn't have instances of this instruction // where src==dest because the instruction itself is @@ -666,34 +669,51 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) { // // In this case, just use a temporary register. if (DstReg == SrcReg) { - TmpLoReg = SCRATCH_REGISTER; - TmpHiReg = SCRATCH_REGISTER; - } + RegScavenger RS; - auto MIBLO = buildMI(MBB, MBBI, OpLo) - .addReg(TmpLoReg, RegState::Define | getDeadRegState(DstIsDead)) - .addReg(SrcReg) - .addImm(Imm); + RS.enterBasicBlock(MBB); + RS.forward(MBBI); - // Push the low part of the temporary register to the stack. - if (TmpLoReg != DstLoReg) - buildMI(MBB, MBBI, AVR::PUSHRr) - .addReg(AVR::R0); + BitVector Candidates = + TRI->getAllocatableSet + (*MBB.getParent(), &AVR::GPR8RegClass); - auto MIBHI = buildMI(MBB, MBBI, OpHi) - .addReg(TmpHiReg, RegState::Define | getDeadRegState(DstIsDead)) - .addReg(SrcReg, getKillRegState(SrcIsKill)) - .addImm(Imm + 1); + // Exclude all the registers being used by the instruction. + for (MachineOperand &MO : MI.operands()) { + if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() && + !TargetRegisterInfo::isVirtualRegister(MO.getReg())) + Candidates.reset(MO.getReg()); + } - // If we need to use a temporary register. - if (TmpHiReg != DstHiReg) { - // Move the hi result from the tmp register to the destination. - buildMI(MBB, MBBI, AVR::MOVRdRr) - .addReg(DstHiReg).addReg(SCRATCH_REGISTER); + BitVector Available = RS.getRegsAvailable(&AVR::GPR8RegClass); + Available &= Candidates; + + unsigned TmpReg = Available.find_first(); + assert(TmpReg != -1 && "ran out of registers"); + + MIBLO = buildMI(MBB, MBBI, OpLo) + .addReg(TmpReg, RegState::Define) + .addReg(SrcReg) + .addImm(Imm); + + buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstLoReg).addReg(TmpReg); + + MIBHI = buildMI(MBB, MBBI, OpHi) + .addReg(TmpReg, RegState::Define) + .addReg(SrcReg, getKillRegState(SrcIsKill)) + .addImm(Imm + 1); + + buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg); + } else { + MIBLO = buildMI(MBB, MBBI, OpLo) + .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) + .addReg(SrcReg) + .addImm(Imm); - // Pop the lo result calculated previously and put it into - // the lo destination. - buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg); + MIBHI = buildMI(MBB, MBBI, OpHi) + .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) + .addReg(SrcReg, getKillRegState(SrcIsKill)) + .addImm(Imm + 1); } MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); |

