X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FLowerSubregs.cpp;h=6d7c5ccee6009657f43f9e5e2b5a18ff68687e0b;hb=253174bf50c932abaa680f465e2888c0e5272267;hp=232dc061e5851dcd334a6892711f334723d5eaae;hpb=6f0d024a534af18d9e60b3ea757376cd8a3a980e;p=oota-llvm.git diff --git a/lib/CodeGen/LowerSubregs.cpp b/lib/CodeGen/LowerSubregs.cpp index 232dc061e58..6d7c5ccee60 100644 --- a/lib/CodeGen/LowerSubregs.cpp +++ b/lib/CodeGen/LowerSubregs.cpp @@ -6,6 +6,13 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// This file defines a MachineFunction pass which runs after register +// allocation that turns subreg insert/extract instructions into register +// copies, as needed. This ensures correct codegen even if the coalescer +// isn't able to remove all subreg instructions. +// +//===----------------------------------------------------------------------===// #define DEBUG_TYPE "lowersubregs" #include "llvm/CodeGen/Passes.h" @@ -24,17 +31,24 @@ namespace { struct VISIBILITY_HIDDEN LowerSubregsInstructionPass : public MachineFunctionPass { static char ID; // Pass identification, replacement for typeid - LowerSubregsInstructionPass() : MachineFunctionPass((intptr_t)&ID) {} + LowerSubregsInstructionPass() : MachineFunctionPass(&ID) {} const char *getPassName() const { return "Subregister lowering instruction pass"; } + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addPreservedID(MachineLoopInfoID); + AU.addPreservedID(MachineDominatorsID); + MachineFunctionPass::getAnalysisUsage(AU); + } + /// runOnMachineFunction - pass entry point bool runOnMachineFunction(MachineFunction&); bool LowerExtract(MachineInstr *MI); bool LowerInsert(MachineInstr *MI); + bool LowerSubregToReg(MachineInstr *MI); }; char LowerSubregsInstructionPass::ID = 0; @@ -44,172 +58,125 @@ FunctionPass *llvm::createLowerSubregsPass() { return new LowerSubregsInstructionPass(); } -// Returns the Register Class of a physical register. -static const TargetRegisterClass *getPhysicalRegisterRegClass( - const TargetRegisterInfo &TRI, - unsigned reg) { - assert(TargetRegisterInfo::isPhysicalRegister(reg) && - "reg must be a physical register"); - // Pick the register class of the right type that contains this physreg. - for (TargetRegisterInfo::regclass_iterator I = TRI.regclass_begin(), - E = TRI.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"); + assert(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() && + MI->getOperand(1).isReg() && MI->getOperand(1).isUse() && + MI->getOperand(2).isImm() && "Malformed extract_subreg"); + unsigned DstReg = MI->getOperand(0).getReg(); unsigned SuperReg = MI->getOperand(1).getReg(); - unsigned SubIdx = MI->getOperand(2).getImm(); + unsigned SubIdx = MI->getOperand(2).getImm(); + unsigned SrcReg = TRI.getSubReg(SuperReg, SubIdx); assert(TargetRegisterInfo::isPhysicalRegister(SuperReg) && "Extract supperg source must be a physical register"); - unsigned SrcReg = TRI.getSubReg(SuperReg, SubIdx); - unsigned DstReg = MI->getOperand(0).getReg(); - + assert(TargetRegisterInfo::isPhysicalRegister(DstReg) && + "Insert destination must be in a physical register"); + DOUT << "subreg: CONVERTING: " << *MI; if (SrcReg != DstReg) { - const TargetRegisterClass *TRC = 0; - if (TargetRegisterInfo::isPhysicalRegister(DstReg)) { - TRC = getPhysicalRegisterRegClass(TRI, DstReg); - } else { - TRC = MF.getRegInfo().getRegClass(DstReg); - } - assert(TRC == getPhysicalRegisterRegClass(TRI, SrcReg) && + 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); + MBB->erase(MI); return true; } - -bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) { +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(); - 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).isImmediate() && "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).isImmediate() && "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"); + assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) && + MI->getOperand(1).isImm() && + (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) && + MI->getOperand(3).isImm() && "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(SrcReg) && - "Insert superreg source must be in a physical register"); + 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; - - // 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 = TRI.isSubRegister(DstReg, InsReg); - if (revCopyOrder && InsReg != DstSubReg) { - if (MI->getOperand(1).isKill()) { - DstSubReg = TRI.getSubReg(SrcReg, SubIdx); - // Insert sub-register copy - const TargetRegisterClass *TRC1 = 0; - if (TargetRegisterInfo::isPhysicalRegister(InsReg)) { - TRC1 = getPhysicalRegisterRegClass(TRI, InsReg); - } else { - TRC1 = MF.getRegInfo().getRegClass(InsReg); - } - TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1, TRC1); - -#ifndef NDEBUG - MachineBasicBlock::iterator dMI = MI; - DOUT << "subreg: " << *(--dMI); -#endif - } else { - assert(0 && "Don't know how to convert this insert"); - } - } -#ifndef NDEBUG - if (InsReg == DstSubReg) { - DOUT << "subreg: Eliminated subreg copy\n"; - } -#endif - if (SrcReg != DstReg) { - // Insert super-register copy - const TargetRegisterClass *TRC0 = 0; - if (TargetRegisterInfo::isPhysicalRegister(DstReg)) { - TRC0 = getPhysicalRegisterRegClass(TRI, DstReg); - } else { - TRC0 = MF.getRegInfo().getRegClass(DstReg); - } - assert(TRC0 == getPhysicalRegisterRegClass(TRI, SrcReg) && - "Insert superreg and Dst must be of same register class"); - - TII.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC0, TRC0); + 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->erase(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).isReg() && MI->getOperand(0).isDef()) && + (MI->getOperand(1).isReg() && MI->getOperand(1).isUse()) && + (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) && + MI->getOperand(3).isImm() && "Invalid insert_subreg"); + + unsigned DstReg = MI->getOperand(0).getReg(); #ifndef NDEBUG - if (SrcReg == DstReg) { - DOUT << "subreg: Eliminated superreg copy\n"; - } + unsigned SrcReg = MI->getOperand(1).getReg(); #endif + unsigned InsReg = MI->getOperand(2).getReg(); + unsigned SubIdx = MI->getOperand(3).getImm(); - if (!revCopyOrder && InsReg != DstSubReg) { - // Insert sub-register copy - const TargetRegisterClass *TRC1 = 0; - if (TargetRegisterInfo::isPhysicalRegister(InsReg)) { - TRC1 = getPhysicalRegisterRegClass(TRI, InsReg); - } else { - TRC1 = MF.getRegInfo().getRegClass(InsReg); - } - TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1, TRC1); + 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); @@ -217,7 +184,7 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) { } DOUT << "\n"; - MBB->remove(MI); + MBB->erase(MI); return true; } @@ -242,6 +209,8 @@ bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) { MadeChange |= LowerExtract(MI); } else if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) { MadeChange |= LowerInsert(MI); + } else if (MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) { + MadeChange |= LowerSubregToReg(MI); } } }