summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AVR
diff options
context:
space:
mode:
authorDylan McKay <dylanmckay34@gmail.com>2016-12-10 10:51:55 +0000
committerDylan McKay <dylanmckay34@gmail.com>2016-12-10 10:51:55 +0000
commit5c90b8cb4f3b922dd66c0fdb81193f9d91aa3fb4 (patch)
treed68e83b4ce108f9b91af998aec3bd1f6094a74b0 /llvm/lib/Target/AVR
parent5d0233bea22a103b5ecb5a9b5453f1206f2defe0 (diff)
downloadbcm5719-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.cpp70
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());
OpenPOWER on IntegriCloud