[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