diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 2c6080bd099..5aad99865c5 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -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 diff --git a/lib/CodeGen/LowerSubregs.cpp b/lib/CodeGen/LowerSubregs.cpp index 172e4b57950..4ba8adab12b 100644 --- a/lib/CodeGen/LowerSubregs.cpp +++ b/lib/CodeGen/LowerSubregs.cpp @@ -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({ diff --git a/lib/CodeGen/TargetInstrInfoImpl.cpp b/lib/CodeGen/TargetInstrInfoImpl.cpp index 5e145cf2de1..ff8d0ede827 100644 --- a/lib/CodeGen/TargetInstrInfoImpl.cpp +++ b/lib/CodeGen/TargetInstrInfoImpl.cpp @@ -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); +}