diff --git a/include/llvm/Target/MRegisterInfo.h b/include/llvm/Target/MRegisterInfo.h index 8c74c3235a6..23472f548dc 100644 --- a/include/llvm/Target/MRegisterInfo.h +++ b/include/llvm/Target/MRegisterInfo.h @@ -374,6 +374,13 @@ public: unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const = 0; + /// reMaterialize - Re-issue the specified 'original' instruction at the + /// specific location targeting a new destination register. + virtual void reMaterialize(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, + const MachineInstr *Orig) const = 0; + /// foldMemoryOperand - Attempt to fold a load or store of the /// specified stack slot into the specified machine instruction for /// the specified operand. If this is possible, a new instruction diff --git a/lib/Target/ARM/ARMRegisterInfo.cpp b/lib/Target/ARM/ARMRegisterInfo.cpp index 2cc9da6967e..abc0ad82743 100644 --- a/lib/Target/ARM/ARMRegisterInfo.cpp +++ b/lib/Target/ARM/ARMRegisterInfo.cpp @@ -195,6 +195,38 @@ void ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, abort(); } +/// emitLoadConstPool - Emits a load from constpool to materialize the +/// specified immediate. +static void emitLoadConstPool(MachineBasicBlock &MBB, + MachineBasicBlock::iterator &MBBI, + unsigned DestReg, int Val, + const TargetInstrInfo &TII, bool isThumb) { + MachineFunction &MF = *MBB.getParent(); + MachineConstantPool *ConstantPool = MF.getConstantPool(); + Constant *C = ConstantInt::get(Type::Int32Ty, Val); + unsigned Idx = ConstantPool->getConstantPoolIndex(C, 2); + if (isThumb) + BuildMI(MBB, MBBI, TII.get(ARM::tLDRcp), DestReg).addConstantPoolIndex(Idx); + else + BuildMI(MBB, MBBI, TII.get(ARM::LDRcp), DestReg).addConstantPoolIndex(Idx) + .addReg(0).addImm(0); +} + +void ARMRegisterInfo::reMaterialize(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned DestReg, + const MachineInstr *Orig) const { + if (Orig->getOpcode() == ARM::MOVi2pieces) { + emitLoadConstPool(MBB, I, DestReg, Orig->getOperand(1).getImmedValue(), + TII, false); + return; + } + + MachineInstr *MI = Orig->clone(); + MI->getOperand(0).setReg(DestReg); + MBB.insert(I, MI); +} + /// isLowRegister - Returns true if the register is low register r0-r7. /// static bool isLowRegister(unsigned Reg) { @@ -410,19 +442,6 @@ static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes, return NumMIs; } -/// emitLoadConstPool - Emits a load from constpool to materialize NumBytes -/// immediate. -static void emitLoadConstPool(MachineBasicBlock &MBB, - MachineBasicBlock::iterator &MBBI, - unsigned DestReg, int NumBytes, - const TargetInstrInfo &TII) { - MachineFunction &MF = *MBB.getParent(); - MachineConstantPool *ConstantPool = MF.getConstantPool(); - Constant *C = ConstantInt::get(Type::Int32Ty, NumBytes); - unsigned Idx = ConstantPool->getConstantPoolIndex(C, 2); - BuildMI(MBB, MBBI, TII.get(ARM::tLDRpci), DestReg).addConstantPoolIndex(Idx); -} - /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize /// a destreg = basereg + immediate in Thumb code. Materialize the immediate /// in a register using mov / mvn sequences or load the immediate from a @@ -459,7 +478,7 @@ void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, BuildMI(MBB, MBBI, TII.get(ARM::tNEG), LdReg) .addReg(LdReg, false, false, true); } else - emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, TII); + emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, TII, true); // Emit add / sub. int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr); @@ -885,7 +904,7 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, if (FrameReg == ARM::SP) emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,Offset,false,TII); else { - emitLoadConstPool(MBB, II, TmpReg, Offset, TII); + emitLoadConstPool(MBB, II, TmpReg, Offset, TII, true); UseRR = true; } } else @@ -920,7 +939,7 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, if (FrameReg == ARM::SP) emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,Offset,false,TII); else { - emitLoadConstPool(MBB, II, TmpReg, Offset, TII); + emitLoadConstPool(MBB, II, TmpReg, Offset, TII, true); UseRR = true; } } else diff --git a/lib/Target/ARM/ARMRegisterInfo.h b/lib/Target/ARM/ARMRegisterInfo.h index 3187db8c361..450f2f0d971 100644 --- a/lib/Target/ARM/ARMRegisterInfo.h +++ b/lib/Target/ARM/ARMRegisterInfo.h @@ -60,6 +60,9 @@ public: unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const; + void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, + unsigned DestReg, const MachineInstr *Orig) const; + MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum, int FrameIndex) const; diff --git a/lib/Target/Alpha/AlphaRegisterInfo.cpp b/lib/Target/Alpha/AlphaRegisterInfo.cpp index aea7c6da514..8dd8b1769a7 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.cpp +++ b/lib/Target/Alpha/AlphaRegisterInfo.cpp @@ -155,6 +155,15 @@ void AlphaRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, } } +void AlphaRegisterInfo::reMaterialize(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned DestReg, + const MachineInstr *Orig) const { + MachineInstr *MI = Orig->clone(); + MI->getOperand(0).setReg(DestReg); + MBB.insert(I, MI); +} + const unsigned* AlphaRegisterInfo::getCalleeSavedRegs() const { static const unsigned CalleeSavedRegs[] = { Alpha::R9, Alpha::R10, diff --git a/lib/Target/Alpha/AlphaRegisterInfo.h b/lib/Target/Alpha/AlphaRegisterInfo.h index 1ef6ac0980e..0fd82dd864f 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.h +++ b/lib/Target/Alpha/AlphaRegisterInfo.h @@ -45,6 +45,9 @@ struct AlphaRegisterInfo : public AlphaGenRegisterInfo { unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const; + void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, + unsigned DestReg, const MachineInstr *Orig) const; + const unsigned *getCalleeSavedRegs() const; const TargetRegisterClass* const* getCalleeSavedRegClasses() const; diff --git a/lib/Target/IA64/IA64RegisterInfo.cpp b/lib/Target/IA64/IA64RegisterInfo.cpp index ebdf1dc4193..e7e14412103 100644 --- a/lib/Target/IA64/IA64RegisterInfo.cpp +++ b/lib/Target/IA64/IA64RegisterInfo.cpp @@ -93,6 +93,15 @@ void IA64RegisterInfo::copyRegToReg(MachineBasicBlock &MBB, BuildMI(MBB, MI, TII.get(IA64::MOV), DestReg).addReg(SrcReg); } +void IA64RegisterInfo::reMaterialize(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned DestReg, + const MachineInstr *Orig) const { + MachineInstr *MI = Orig->clone(); + MI->getOperand(0).setReg(DestReg); + MBB.insert(I, MI); +} + const unsigned* IA64RegisterInfo::getCalleeSavedRegs() const { static const unsigned CalleeSavedRegs[] = { IA64::r5, 0 diff --git a/lib/Target/IA64/IA64RegisterInfo.h b/lib/Target/IA64/IA64RegisterInfo.h index 446d629aaf5..89d9c5e0fce 100644 --- a/lib/Target/IA64/IA64RegisterInfo.h +++ b/lib/Target/IA64/IA64RegisterInfo.h @@ -44,6 +44,9 @@ struct IA64RegisterInfo : public IA64GenRegisterInfo { unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const; + void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, + unsigned DestReg, const MachineInstr *Orig) const; + const unsigned *getCalleeSavedRegs() const; const TargetRegisterClass* const* getCalleeSavedRegClasses() const; diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 1029babe99e..0b9602be36e 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -239,6 +239,15 @@ void PPCRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, } } +void PPCRegisterInfo::reMaterialize(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned DestReg, + const MachineInstr *Orig) const { + MachineInstr *MI = Orig->clone(); + MI->getOperand(0).setReg(DestReg); + MBB.insert(I, MI); +} + const unsigned* PPCRegisterInfo::getCalleeSavedRegs() const { // 32-bit Darwin calling convention. static const unsigned Darwin32_CalleeSavedRegs[] = { diff --git a/lib/Target/PowerPC/PPCRegisterInfo.h b/lib/Target/PowerPC/PPCRegisterInfo.h index e23ab336f05..d8e80250918 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.h +++ b/lib/Target/PowerPC/PPCRegisterInfo.h @@ -49,6 +49,9 @@ public: unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const; + void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, + unsigned DestReg, const MachineInstr *Orig) const; + /// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into /// copy instructions, turning them into load/store instructions. virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum, diff --git a/lib/Target/Sparc/SparcRegisterInfo.cpp b/lib/Target/Sparc/SparcRegisterInfo.cpp index bd784a93f63..521e9b964ec 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.cpp +++ b/lib/Target/Sparc/SparcRegisterInfo.cpp @@ -77,6 +77,15 @@ void SparcRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, assert (0 && "Can't copy this register"); } +void SparcRegisterInfo::reMaterialize(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned DestReg, + const MachineInstr *Orig) const { + MachineInstr *MI = Orig->clone(); + MI->getOperand(0).setReg(DestReg); + MBB.insert(I, MI); +} + MachineInstr *SparcRegisterInfo::foldMemoryOperand(MachineInstr* MI, unsigned OpNum, int FI) const { diff --git a/lib/Target/Sparc/SparcRegisterInfo.h b/lib/Target/Sparc/SparcRegisterInfo.h index 411ce5e054a..520836e9dee 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.h +++ b/lib/Target/Sparc/SparcRegisterInfo.h @@ -44,6 +44,9 @@ struct SparcRegisterInfo : public SparcGenRegisterInfo { unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const; + void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, + unsigned DestReg, const MachineInstr *Orig) const; + virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum, int FrameIndex) const; diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 749bb1f3edc..fd869072154 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -167,6 +167,16 @@ void X86RegisterInfo::copyRegToReg(MachineBasicBlock &MBB, BuildMI(MBB, MI, TII.get(Opc), DestReg).addReg(SrcReg); } + +void X86RegisterInfo::reMaterialize(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned DestReg, + const MachineInstr *Orig) const { + MachineInstr *MI = Orig->clone(); + MI->getOperand(0).setReg(DestReg); + MBB.insert(I, MI); +} + static MachineInstr *FuseTwoAddrInst(unsigned Opcode, unsigned FrameIndex, MachineInstr *MI, const TargetInstrInfo &TII) { diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h index e1aafab1783..dbf7bf03d20 100644 --- a/lib/Target/X86/X86RegisterInfo.h +++ b/lib/Target/X86/X86RegisterInfo.h @@ -58,6 +58,9 @@ public: MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const; + + void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, + unsigned DestReg, const MachineInstr *Orig) const; /// foldMemoryOperand - If this target supports it, fold a load or store of /// the specified stack slot into the specified machine instruction for the