Add TargetInstrInfo::copyPhysReg hook and use it from LowerSubregs.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 8 Jul 2010 05:01:41 +0000 (05:01 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 8 Jul 2010 05:01:41 +0000 (05:01 +0000)
This target hook is intended to replace copyRegToReg entirely, but for now it
calls copyRegToReg.

Any remaining calls to copyRegToReg wil be replaced by COPY instructions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107854 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetInstrInfo.h
lib/CodeGen/LowerSubregs.cpp
lib/CodeGen/TargetInstrInfoImpl.cpp

index 2c6080bd0998330c21e777c59b3d15c3a216c7e5..5aad99865c5504e1822de45dcb34be560dcc5736 100644 (file)
@@ -369,7 +369,13 @@ public:
     assert(0 && "Target didn't implement TargetInstrInfo::copyRegToReg!");
     return false;
   }
-  
+
+  /// copyPhysReg - Emit instructions to copy a pair of physical registers.
+  virtual void copyPhysReg(MachineBasicBlock &MBB,
+                           MachineBasicBlock::iterator MI, DebugLoc DL,
+                           unsigned DestReg, unsigned SrcReg,
+                           bool KillSrc) const =0;
+
   /// storeRegToStackSlot - Store the specified register of the given register
   /// class to the specified stack frame index. The store instruction is to be
   /// added to the given machine basic block before the specified machine
@@ -661,6 +667,10 @@ public:
 
   virtual ScheduleHazardRecognizer *
   CreateTargetPostRAHazardRecognizer(const InstrItineraryData&) const;
+  virtual void copyPhysReg(MachineBasicBlock &MBB,
+                           MachineBasicBlock::iterator MI, DebugLoc DL,
+                           unsigned DestReg, unsigned SrcReg,
+                           bool KillSrc) const;
 };
 
 } // End llvm namespace
index 172e4b579505db76b85037bfa9ac953e6a86dfc6..4ba8adab12be55a8fe052c48456def5a6864b582 100644 (file)
@@ -85,7 +85,7 @@ LowerSubregsInstructionPass::TransferDeadFlag(MachineInstr *MI,
     if (MII->addRegisterDead(DstReg, TRI))
       break;
     assert(MII != MI->getParent()->begin() &&
-           "copyRegToReg output doesn't reference destination register!");
+           "copyPhysReg output doesn't reference destination register!");
   }
 }
 
@@ -102,7 +102,7 @@ LowerSubregsInstructionPass::TransferKillFlag(MachineInstr *MI,
     if (MII->addRegisterKilled(SrcReg, TRI, AddIfNotFound))
       break;
     assert(MII != MI->getParent()->begin() &&
-           "copyRegToReg output doesn't reference source register!");
+           "copyPhysReg output doesn't reference source register!");
   }
 }
 
@@ -155,13 +155,7 @@ bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) {
 
     DEBUG(dbgs() << "subreg: eliminated!");
   } else {
-    // Insert copy
-    const TargetRegisterClass *TRCS = TRI->getPhysicalRegisterRegClass(DstReg);
-    const TargetRegisterClass *TRCD = TRI->getPhysicalRegisterRegClass(SrcReg);
-    bool Emitted = TII->copyRegToReg(*MBB, MI, DstReg, SrcReg, TRCD, TRCS,
-                                     MI->getDebugLoc());
-    (void)Emitted;
-    assert(Emitted && "Subreg and Dst must be of compatible register class");
+    TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstReg, SrcReg, false);
     // Transfer the kill/dead flags, if needed.
     if (MI->getOperand(0).isDead())
       TransferDeadFlag(MI, DstReg, TRI);
@@ -215,18 +209,11 @@ bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) {
     }
     DEBUG(dbgs() << "subreg: eliminated!");
   } else {
-    // Insert sub-register copy
-    const TargetRegisterClass *TRC0= TRI->getPhysicalRegisterRegClass(DstSubReg);
-    const TargetRegisterClass *TRC1= TRI->getPhysicalRegisterRegClass(InsReg);
-    bool Emitted = TII->copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC0, TRC1,
-                                     MI->getDebugLoc());
-    (void)Emitted;
-    assert(Emitted && "Subreg and Dst must be of compatible register class");
+    TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstSubReg, InsReg,
+                     MI->getOperand(2).isKill());
     // Transfer the kill/dead flags, if needed.
     if (MI->getOperand(0).isDead())
       TransferDeadFlag(MI, DstSubReg, TRI);
-    if (MI->getOperand(2).isKill())
-      TransferKillFlag(MI, InsReg, TRI);
     DEBUG({
         MachineBasicBlock::iterator dMI = MI;
         dbgs() << "subreg: " << *(--dMI);
@@ -280,18 +267,13 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) {
     }
   } else {
     // Insert sub-register copy
-    const TargetRegisterClass *TRC0= TRI->getPhysicalRegisterRegClass(DstSubReg);
-    const TargetRegisterClass *TRC1= TRI->getPhysicalRegisterRegClass(InsReg);
     if (MI->getOperand(2).isUndef())
       // If the source register being inserted is undef, then this becomes a
       // KILL.
       BuildMI(*MBB, MI, MI->getDebugLoc(),
               TII->get(TargetOpcode::KILL), DstSubReg);
     else {
-      bool Emitted = TII->copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC0, TRC1,
-                                       MI->getDebugLoc());
-      (void)Emitted;
-      assert(Emitted && "Subreg and Dst must be of compatible register class");
+      TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstSubReg, InsReg, false);
     }
     MachineBasicBlock::iterator CopyMI = MI;
     --CopyMI;
@@ -343,21 +325,11 @@ bool LowerSubregsInstructionPass::LowerCopy(MachineInstr *MI) {
   }
 
   DEBUG(dbgs() << "real copy:   " << *MI);
-  // Ask target for a lowered copy instruction.
-  const TargetRegisterClass *DstRC =
-    TRI->getPhysicalRegisterRegClass(DstMO.getReg());
-  const TargetRegisterClass *SrcRC =
-    TRI->getPhysicalRegisterRegClass(SrcMO.getReg());
-  bool Emitted = TII->copyRegToReg(*MI->getParent(), MI,
-                                   DstMO.getReg(), SrcMO.getReg(),
-                                   DstRC, SrcRC, MI->getDebugLoc());
-  (void)Emitted;
-  assert(Emitted && "Cannot emit copy");
+  TII->copyPhysReg(*MI->getParent(), MI, MI->getDebugLoc(),
+                   DstMO.getReg(), SrcMO.getReg(), SrcMO.isKill());
 
   if (DstMO.isDead())
     TransferDeadFlag(MI, DstMO.getReg(), TRI);
-  if (SrcMO.isKill())
-    TransferKillFlag(MI, SrcMO.getReg(), TRI, true);
   if (MI->getNumOperands() > 2)
     TransferImplicitDefs(MI);
   DEBUG({
index 5e145cf2de14911a856e14243b8a802bcc2895a9..ff8d0ede827dd81906c3fd776ebc8055219f507f 100644 (file)
@@ -365,3 +365,20 @@ ScheduleHazardRecognizer *TargetInstrInfoImpl::
 CreateTargetPostRAHazardRecognizer(const InstrItineraryData &II) const {
   return (ScheduleHazardRecognizer *)new PostRAHazardRecognizer(II);
 }
+
+// Default implementation of copyPhysReg using copyRegToReg.
+void TargetInstrInfoImpl::copyPhysReg(MachineBasicBlock &MBB,
+                                      MachineBasicBlock::iterator MI,
+                                      DebugLoc DL,
+                                      unsigned DestReg, unsigned SrcReg,
+                                      bool KillSrc) const {
+  assert(TargetRegisterInfo::isPhysicalRegister(DestReg));
+  assert(TargetRegisterInfo::isPhysicalRegister(SrcReg));
+  const TargetRegisterInfo *TRI = MBB.getParent()->getTarget().getRegisterInfo();
+  const TargetRegisterClass *DRC = TRI->getPhysicalRegisterRegClass(DestReg);
+  const TargetRegisterClass *SRC = TRI->getPhysicalRegisterRegClass(SrcReg);
+  if (!copyRegToReg(MBB, MI, DestReg, SrcReg, DRC, SRC, DL))
+    llvm_unreachable("Cannot emit physreg copy instruction");
+  if (KillSrc)
+    llvm::prior(MI)->addRegisterKilled(SrcReg, TRI, true);
+}