[llvm] r289322 - [AVR] Use the register scavenger when expanding 'LDDW' instructions
Dylan McKay via llvm-commits
llvm-commits at lists.llvm.org
Sat Dec 10 02:51:55 PST 2016
Author: dylanmckay
Date: Sat Dec 10 04:51:55 2016
New Revision: 289322
URL: http://llvm.org/viewvc/llvm-project?rev=289322&view=rev
Log:
[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
Modified:
llvm/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp
llvm/trunk/test/CodeGen/AVR/pseudo/expand-lddw-dst-src-same.mir
Modified: llvm/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp?rev=289322&r1=289321&r2=289322&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp (original)
+++ llvm/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp Sat Dec 10 04:51:55 2016
@@ -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::runOnMachineFuncti
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::LDDWRd
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::LDDWRd
//
// In this case, just use a temporary register.
if (DstReg == SrcReg) {
- TmpLoReg = SCRATCH_REGISTER;
- TmpHiReg = SCRATCH_REGISTER;
- }
-
- auto MIBLO = buildMI(MBB, MBBI, OpLo)
- .addReg(TmpLoReg, RegState::Define | getDeadRegState(DstIsDead))
- .addReg(SrcReg)
- .addImm(Imm);
-
- // Push the low part of the temporary register to the stack.
- if (TmpLoReg != DstLoReg)
- buildMI(MBB, MBBI, AVR::PUSHRr)
- .addReg(AVR::R0);
+ RegScavenger RS;
- auto MIBHI = buildMI(MBB, MBBI, OpHi)
- .addReg(TmpHiReg, RegState::Define | getDeadRegState(DstIsDead))
- .addReg(SrcReg, getKillRegState(SrcIsKill))
- .addImm(Imm + 1);
+ RS.enterBasicBlock(MBB);
+ RS.forward(MBBI);
- // 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);
-
- // Pop the lo result calculated previously and put it into
- // the lo destination.
- buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
+ BitVector Candidates =
+ TRI->getAllocatableSet
+ (*MBB.getParent(), &AVR::GPR8RegClass);
+
+ // 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());
+ }
+
+ 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);
+
+ 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());
Modified: llvm/trunk/test/CodeGen/AVR/pseudo/expand-lddw-dst-src-same.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AVR/pseudo/expand-lddw-dst-src-same.mir?rev=289322&r1=289321&r2=289322&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AVR/pseudo/expand-lddw-dst-src-same.mir (original)
+++ llvm/trunk/test/CodeGen/AVR/pseudo/expand-lddw-dst-src-same.mir Sat Dec 10 04:51:55 2016
@@ -1,4 +1,4 @@
-# RUN: llc -O0 -run-pass=avr-expand-pseudo %s -o - 2>&1 | FileCheck %s
+# RUN: llc -O0 %s -o - 2>&1 | FileCheck %s
# This test ensures that the pseudo expander can correctly handle the case
# where we are expanding a 16-bit LDD instruction where the source and
@@ -9,25 +9,26 @@
--- |
target triple = "avr--"
+
define void @test_lddw() {
entry:
ret void
}
-...
+...
---
name: test_lddw
-registers:
- - { id: 0, class: _ }
-body: |
- ; CHECK-LABEL: bb.0.entry
+stack:
+ - { id: 0, type: spill-slot, offset: -4, size: 1, alignment: 1, callee-saved-register: '%r28' }
+body: |
bb.0.entry:
+ liveins: %r28, %r29
- ; CHECK-NEXT: early-clobber %r0 = LDDRdPtrQ %r29r28, 1
- ; CHECK-NEXT: PUSHRr %r0, implicit-def %sp, implicit %sp
- ; CHECK-NEXT: early-clobber %r0 = LDDRdPtrQ %r29r28, 2
- ; CHECK-NEXT: MOVRdRr %r29, %r0
- ; CHECK-NEXT: POPRd %r28, implicit-def %sp, implicit %sp
+ ; CHECK-LABEL: test_lddw
- early-clobber %r29r28 = LDDWRdYQ %r29r28, 1
+ ; CHECK: ldd [[TMPREG:r[0-9]+]], Y+0
+ ; CHECK-NEXT: mov r28, [[TMPREG]]
+ ; CHECK-NEXT: ldd [[TMPREG]], Y+1
+ ; CHECK-NEXT: mov r29, [[TMPREG]]
+ dead early-clobber %r29r28 = LDDWRdYQ killed %r29r28, 0
...
More information about the llvm-commits
mailing list