X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FLowerSubregs.cpp;h=e2e68d86713bd2f07aaa2f196c9bbe2a93054316;hb=5ac319ac7125b009adddcc49294d2e040c4a91e5;hp=01fa032a154a527afde4f3c3765fe6ef228a6b1d;hpb=bab2474b64e81be0ed4fc35d16cdfac65f283361;p=oota-llvm.git diff --git a/lib/CodeGen/LowerSubregs.cpp b/lib/CodeGen/LowerSubregs.cpp index 01fa032a154..e2e68d86713 100644 --- a/lib/CodeGen/LowerSubregs.cpp +++ b/lib/CodeGen/LowerSubregs.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Christopher Lamb and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// @@ -12,8 +12,8 @@ #include "llvm/Function.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/SSARegMap.h" -#include "llvm/Target/MRegisterInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/Debug.h" @@ -32,6 +32,10 @@ namespace { /// runOnMachineFunction - pass entry point bool runOnMachineFunction(MachineFunction&); + + bool LowerExtract(MachineInstr *MI); + bool LowerInsert(MachineInstr *MI); + bool LowerSubregToReg(MachineInstr *MI); }; char LowerSubregsInstructionPass::ID = 0; @@ -41,40 +45,134 @@ FunctionPass *llvm::createLowerSubregsPass() { return new LowerSubregsInstructionPass(); } -// Returns the Register Class of a physical register -static const TargetRegisterClass *getPhysicalRegisterRegClass( - const MRegisterInfo &MRI, - unsigned reg) { - assert(MRegisterInfo::isPhysicalRegister(reg) && - "reg must be a physical register"); - // Pick the register class of the right type that contains this physreg. - for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(), - E = MRI.regclass_end(); I != E; ++I) - if ((*I)->contains(reg)) - return *I; - assert(false && "Couldn't find the register class"); - return 0; +bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) { + MachineBasicBlock *MBB = MI->getParent(); + MachineFunction &MF = *MBB->getParent(); + const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo(); + const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); + + assert(MI->getOperand(0).isRegister() && MI->getOperand(0).isDef() && + MI->getOperand(1).isRegister() && MI->getOperand(1).isUse() && + MI->getOperand(2).isImmediate() && "Malformed extract_subreg"); + + unsigned DstReg = MI->getOperand(0).getReg(); + unsigned SuperReg = MI->getOperand(1).getReg(); + unsigned SubIdx = MI->getOperand(2).getImm(); + unsigned SrcReg = TRI.getSubReg(SuperReg, SubIdx); + + assert(TargetRegisterInfo::isPhysicalRegister(SuperReg) && + "Extract supperg source must be a physical register"); + assert(TargetRegisterInfo::isPhysicalRegister(DstReg) && + "Insert destination must be in a physical register"); + + DOUT << "subreg: CONVERTING: " << *MI; + + if (SrcReg != DstReg) { + const TargetRegisterClass *TRC = TRI.getPhysicalRegisterRegClass(DstReg); + assert(TRC == TRI.getPhysicalRegisterRegClass(SrcReg) && + "Extract subreg and Dst must be of same register class"); + TII.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC, TRC); + +#ifndef NDEBUG + MachineBasicBlock::iterator dMI = MI; + DOUT << "subreg: " << *(--dMI); +#endif + } + + DOUT << "\n"; + MBB->remove(MI); + return true; } -static bool isSubRegOf(const MRegisterInfo &MRI, - unsigned SubReg, - unsigned SupReg) { - const TargetRegisterDesc &RD = MRI[SubReg]; - for (const unsigned *reg = RD.SuperRegs; *reg != 0; ++reg) - if (*reg == SupReg) - return true; - - return false; +bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) { + MachineBasicBlock *MBB = MI->getParent(); + MachineFunction &MF = *MBB->getParent(); + const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo(); + const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); + assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) && + MI->getOperand(1).isImmediate() && + (MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) && + MI->getOperand(3).isImmediate() && "Invalid subreg_to_reg"); + + unsigned DstReg = MI->getOperand(0).getReg(); + unsigned InsReg = MI->getOperand(2).getReg(); + unsigned SubIdx = MI->getOperand(3).getImm(); + + assert(SubIdx != 0 && "Invalid index for insert_subreg"); + unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx); + + assert(TargetRegisterInfo::isPhysicalRegister(DstReg) && + "Insert destination must be in a physical register"); + assert(TargetRegisterInfo::isPhysicalRegister(InsReg) && + "Inserted value must be in a physical register"); + + DOUT << "subreg: CONVERTING: " << *MI; + + // Insert sub-register copy + const TargetRegisterClass *TRC0= TRI.getPhysicalRegisterRegClass(DstSubReg); + const TargetRegisterClass *TRC1= TRI.getPhysicalRegisterRegClass(InsReg); + TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC0, TRC1); + +#ifndef NDEBUG + MachineBasicBlock::iterator dMI = MI; + DOUT << "subreg: " << *(--dMI); +#endif + + DOUT << "\n"; + MBB->remove(MI); + return true; } +bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) { + MachineBasicBlock *MBB = MI->getParent(); + MachineFunction &MF = *MBB->getParent(); + const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo(); + const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); + 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).isImmediate() && "Invalid insert_subreg"); + + unsigned DstReg = MI->getOperand(0).getReg(); + unsigned SrcReg = MI->getOperand(1).getReg(); + unsigned InsReg = MI->getOperand(2).getReg(); + unsigned SubIdx = MI->getOperand(3).getImm(); + + assert(DstReg == SrcReg && "insert_subreg not a two-address instruction?"); + assert(SubIdx != 0 && "Invalid index for insert_subreg"); + unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx); + + assert(TargetRegisterInfo::isPhysicalRegister(SrcReg) && + "Insert superreg source must be in a physical register"); + assert(TargetRegisterInfo::isPhysicalRegister(InsReg) && + "Inserted value must be in a physical register"); + + DOUT << "subreg: CONVERTING: " << *MI; + + if (DstSubReg == InsReg) { + // No need to insert an identify copy instruction. + DOUT << "subreg: eliminated!"; + } else { + // Insert sub-register copy + const TargetRegisterClass *TRC0= TRI.getPhysicalRegisterRegClass(DstSubReg); + const TargetRegisterClass *TRC1= TRI.getPhysicalRegisterRegClass(InsReg); + TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC0, TRC1); +#ifndef NDEBUG + MachineBasicBlock::iterator dMI = MI; + DOUT << "subreg: " << *(--dMI); +#endif + } + + DOUT << "\n"; + MBB->remove(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 +182,15 @@ 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); + } else if (MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) { + MadeChange |= LowerSubregToReg(MI); } } }