diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h index 290e86f37ec7..45129829038e 100644 --- a/llvm/include/llvm/CodeGen/Passes.h +++ b/llvm/include/llvm/CodeGen/Passes.h @@ -90,7 +90,7 @@ namespace llvm { FunctionPass *createPrologEpilogCodeInserter(); /// LowerSubregs Pass - This pass lowers subregs to register-register copies - /// which yields suboptimial, but correct code if the register allocator + /// which yields suboptimal, but correct code if the register allocator /// cannot coalesce all subreg operations during allocation. /// FunctionPass *createLowerSubregsPass(); diff --git a/llvm/lib/CodeGen/LowerSubregs.cpp b/llvm/lib/CodeGen/LowerSubregs.cpp index 01fa032a154a..830384427dea 100644 --- a/llvm/lib/CodeGen/LowerSubregs.cpp +++ b/llvm/lib/CodeGen/LowerSubregs.cpp @@ -32,6 +32,9 @@ namespace { /// runOnMachineFunction - pass entry point bool runOnMachineFunction(MachineFunction&); + + bool LowerExtract(MachineInstr *MI); + bool LowerInsert(MachineInstr *MI); }; char LowerSubregsInstructionPass::ID = 0; @@ -41,7 +44,7 @@ FunctionPass *llvm::createLowerSubregsPass() { return new LowerSubregsInstructionPass(); } -// Returns the Register Class of a physical register +// Returns the Register Class of a physical register. static const TargetRegisterClass *getPhysicalRegisterRegClass( const MRegisterInfo &MRI, unsigned reg) { @@ -67,14 +70,153 @@ static bool isSubRegOf(const MRegisterInfo &MRI, return false; } +bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) { + MachineBasicBlock *MBB = MI->getParent(); + MachineFunction &MF = *MBB->getParent(); + const MRegisterInfo &MRI = *MF.getTarget().getRegisterInfo(); + + assert(MI->getOperand(0).isRegister() && MI->getOperand(0).isDef() && + MI->getOperand(1).isRegister() && MI->getOperand(1).isUse() && + MI->getOperand(2).isImm() && "Malformed extract_subreg"); + + unsigned SuperReg = MI->getOperand(1).getReg(); + unsigned SubIdx = MI->getOperand(2).getImm(); + + assert(MRegisterInfo::isPhysicalRegister(SuperReg) && + "Extract supperg source must be a physical register"); + unsigned SrcReg = MRI.getSubReg(SuperReg, SubIdx); + unsigned DstReg = MI->getOperand(0).getReg(); + + DOUT << "subreg: CONVERTING: " << *MI; + + if (SrcReg != DstReg) { + const TargetRegisterClass *TRC = 0; + if (MRegisterInfo::isPhysicalRegister(DstReg)) { + TRC = getPhysicalRegisterRegClass(MRI, DstReg); + } else { + TRC = MF.getSSARegMap()->getRegClass(DstReg); + } + assert(TRC == getPhysicalRegisterRegClass(MRI, SrcReg) && + "Extract subreg and Dst must be of same register class"); + + MRI.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC); + MachineBasicBlock::iterator dMI = MI; + DOUT << "subreg: " << *(--dMI); + } + + DOUT << "\n"; + MBB->erase(MI); + return true; +} + + +bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) { + MachineBasicBlock *MBB = MI->getParent(); + MachineFunction &MF = *MBB->getParent(); + const MRegisterInfo &MRI = *MF.getTarget().getRegisterInfo(); + unsigned DstReg = 0; + unsigned SrcReg = 0; + unsigned InsReg = 0; + unsigned SubIdx = 0; + + // If only have 3 operands, then the source superreg is undef + // and we can supress the copy from the undef value + if (MI->getNumOperands() == 3) { + assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) && + (MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) && + MI->getOperand(2).isImm() && "Invalid extract_subreg"); + DstReg = MI->getOperand(0).getReg(); + SrcReg = DstReg; + InsReg = MI->getOperand(1).getReg(); + SubIdx = MI->getOperand(2).getImm(); + } else if (MI->getNumOperands() == 4) { + assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) && + (MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) && + (MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) && + MI->getOperand(3).isImm() && "Invalid extract_subreg"); + DstReg = MI->getOperand(0).getReg(); + SrcReg = MI->getOperand(1).getReg(); + InsReg = MI->getOperand(2).getReg(); + SubIdx = MI->getOperand(3).getImm(); + } else + assert(0 && "Malformed extract_subreg"); + + assert(SubIdx != 0 && "Invalid index for extract_subreg"); + unsigned DstSubReg = MRI.getSubReg(DstReg, SubIdx); + + assert(MRegisterInfo::isPhysicalRegister(SrcReg) && + "Insert superreg source must be in a physical register"); + assert(MRegisterInfo::isPhysicalRegister(DstReg) && + "Insert destination must be in a physical register"); + assert(MRegisterInfo::isPhysicalRegister(InsReg) && + "Inserted value must be in a physical register"); + + DOUT << "subreg: CONVERTING: " << *MI; + + // If the inserted register is already allocated into a subregister + // of the destination, we copy the subreg into the source + // However, this is only safe if the insert instruction is the kill + // of the source register + bool revCopyOrder = isSubRegOf(MRI, InsReg, DstReg); + if (revCopyOrder) { + if (MI->getOperand(1).isKill()) { + DstSubReg = MRI.getSubReg(SrcReg, SubIdx); + // Insert sub-register copy + const TargetRegisterClass *TRC1 = 0; + if (MRegisterInfo::isPhysicalRegister(InsReg)) { + TRC1 = getPhysicalRegisterRegClass(MRI, InsReg); + } else { + TRC1 = MF.getSSARegMap()->getRegClass(InsReg); + } + + MRI.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1); + MachineBasicBlock::iterator dMI = MI; + DOUT << "subreg: " << *(--dMI); + } else { + assert(0 && "Don't know how to convert this insert"); + } + } + + if (SrcReg != DstReg) { + // Insert super-register copy + const TargetRegisterClass *TRC0 = 0; + if (MRegisterInfo::isPhysicalRegister(DstReg)) { + TRC0 = getPhysicalRegisterRegClass(MRI, DstReg); + } else { + TRC0 = MF.getSSARegMap()->getRegClass(DstReg); + } + assert(TRC0 == getPhysicalRegisterRegClass(MRI, SrcReg) && + "Insert superreg and Dst must be of same register class"); + + MRI.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC0); + MachineBasicBlock::iterator dMI = MI; + DOUT << "subreg: " << *(--dMI); + } + + if (!revCopyOrder && InsReg != DstSubReg) { + // Insert sub-register copy + const TargetRegisterClass *TRC1 = 0; + if (MRegisterInfo::isPhysicalRegister(InsReg)) { + TRC1 = getPhysicalRegisterRegClass(MRI, InsReg); + } else { + TRC1 = MF.getSSARegMap()->getRegClass(InsReg); + } + + MRI.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1); + MachineBasicBlock::iterator dMI = MI; + DOUT << "subreg: " << *(--dMI); + } + + DOUT << "\n"; + MBB->erase(MI); + return true; +} /// runOnMachineFunction - Reduce subregister inserts and extracts to register /// copies. /// bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) { DOUT << "Machine Function\n"; - const TargetMachine &TM = MF.getTarget(); - const MRegisterInfo &MRI = *TM.getRegisterInfo(); bool MadeChange = false; @@ -84,140 +226,13 @@ bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) { for (MachineFunction::iterator mbbi = MF.begin(), mbbe = MF.end(); mbbi != mbbe; ++mbbi) { for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end(); - mi != me; ++mi) { - - if (mi->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) { - assert(mi->getOperand(0).isRegister() && mi->getOperand(0).isDef() && - mi->getOperand(1).isRegister() && mi->getOperand(1).isUse() && - mi->getOperand(2).isImm() && "Malformed extract_subreg"); - - unsigned SuperReg = mi->getOperand(1).getReg(); - unsigned SubIdx = mi->getOperand(2).getImm(); - - assert(MRegisterInfo::isPhysicalRegister(SuperReg) && - "Extract supperg source must be a physical register"); - unsigned SrcReg = MRI.getSubReg(SuperReg, SubIdx); - unsigned DstReg = mi->getOperand(0).getReg(); - - DOUT << "subreg: CONVERTING: " << *mi; - - if (SrcReg != DstReg) { - const TargetRegisterClass *TRC = 0; - if (MRegisterInfo::isPhysicalRegister(DstReg)) { - TRC = getPhysicalRegisterRegClass(MRI, DstReg); - } else { - TRC = MF.getSSARegMap()->getRegClass(DstReg); - } - assert(TRC == getPhysicalRegisterRegClass(MRI, SrcReg) && - "Extract subreg and Dst must be of same register class"); - - MRI.copyRegToReg(*mbbi, mi, DstReg, SrcReg, TRC); - MachineBasicBlock::iterator dmi = mi; - DOUT << "subreg: " << *(--dmi); - } - - DOUT << "\n"; - mbbi->erase(mi); - MadeChange = true; - - } else if (mi->getOpcode() == TargetInstrInfo::INSERT_SUBREG) { - - unsigned DstReg = 0; - unsigned SrcReg = 0; - unsigned InsReg = 0; - unsigned SubIdx = 0; - - // If only have 3 operands, then the source superreg is undef - // and we can supress the copy from the undef value - if (mi->getNumOperands() == 3) { - assert((mi->getOperand(0).isRegister() && mi->getOperand(0).isDef()) && - (mi->getOperand(1).isRegister() && mi->getOperand(1).isUse()) && - mi->getOperand(2).isImm() && "Invalid extract_subreg"); - DstReg = mi->getOperand(0).getReg(); - SrcReg = DstReg; - InsReg = mi->getOperand(1).getReg(); - SubIdx = mi->getOperand(2).getImm(); - } else if (mi->getNumOperands() == 4) { - assert((mi->getOperand(0).isRegister() && mi->getOperand(0).isDef()) && - (mi->getOperand(1).isRegister() && mi->getOperand(1).isUse()) && - (mi->getOperand(2).isRegister() && mi->getOperand(2).isUse()) && - mi->getOperand(3).isImm() && "Invalid extract_subreg"); - DstReg = mi->getOperand(0).getReg(); - SrcReg = mi->getOperand(1).getReg(); - InsReg = mi->getOperand(2).getReg(); - SubIdx = mi->getOperand(3).getImm(); - } else - assert(0 && "Malformed extract_subreg"); - - assert(SubIdx != 0 && "Invalid index for extract_subreg"); - unsigned DstSubReg = MRI.getSubReg(DstReg, SubIdx); - - assert(MRegisterInfo::isPhysicalRegister(SrcReg) && - "Insert superreg source must be in a physical register"); - assert(MRegisterInfo::isPhysicalRegister(DstReg) && - "Insert destination must be in a physical register"); - assert(MRegisterInfo::isPhysicalRegister(InsReg) && - "Inserted value must be in a physical register"); - - DOUT << "subreg: CONVERTING: " << *mi; - - // If the inserted register is already allocated into a subregister - // of the destination, we copy the subreg into the source - // However, this is only safe if the insert instruction is the kill - // of the source register - bool revCopyOrder = isSubRegOf(MRI, InsReg, DstReg); - if (revCopyOrder) { - if (mi->getOperand(1).isKill()) { - DstSubReg = MRI.getSubReg(SrcReg, SubIdx); - // Insert sub-register copy - const TargetRegisterClass *TRC1 = 0; - if (MRegisterInfo::isPhysicalRegister(InsReg)) { - TRC1 = getPhysicalRegisterRegClass(MRI, InsReg); - } else { - TRC1 = MF.getSSARegMap()->getRegClass(InsReg); - } - - MRI.copyRegToReg(*mbbi, mi, DstSubReg, InsReg, TRC1); - MachineBasicBlock::iterator dmi = mi; - DOUT << "subreg: " << *(--dmi); - } else { - assert(0 && "Don't know how to convert this insert"); - } - } - - if (SrcReg != DstReg) { - // Insert super-register copy - const TargetRegisterClass *TRC0 = 0; - if (MRegisterInfo::isPhysicalRegister(DstReg)) { - TRC0 = getPhysicalRegisterRegClass(MRI, DstReg); - } else { - TRC0 = MF.getSSARegMap()->getRegClass(DstReg); - } - assert(TRC0 == getPhysicalRegisterRegClass(MRI, SrcReg) && - "Insert superreg and Dst must be of same register class"); - - MRI.copyRegToReg(*mbbi, mi, DstReg, SrcReg, TRC0); - MachineBasicBlock::iterator dmi = mi; - DOUT << "subreg: " << *(--dmi); - } - - if (!revCopyOrder && InsReg != DstSubReg) { - // Insert sub-register copy - const TargetRegisterClass *TRC1 = 0; - if (MRegisterInfo::isPhysicalRegister(InsReg)) { - TRC1 = getPhysicalRegisterRegClass(MRI, InsReg); - } else { - TRC1 = MF.getSSARegMap()->getRegClass(InsReg); - } - - MRI.copyRegToReg(*mbbi, mi, DstSubReg, InsReg, TRC1); - MachineBasicBlock::iterator dmi = mi; - DOUT << "subreg: " << *(--dmi); - } - - DOUT << "\n"; - mbbi->erase(mi); - MadeChange = true; + mi != me;) { + MachineInstr *MI = mi++; + + if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) { + MadeChange |= LowerExtract(MI); + } else if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) { + MadeChange |= LowerInsert(MI); } } }