X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FLowerSubregs.cpp;h=6d7c5ccee6009657f43f9e5e2b5a18ff68687e0b;hb=253174bf50c932abaa680f465e2888c0e5272267;hp=0710a3530068165bee671839f021a646d6698ace;hpb=c9298235251b014e86a7368d92b589d093acb64a;p=oota-llvm.git diff --git a/lib/CodeGen/LowerSubregs.cpp b/lib/CodeGen/LowerSubregs.cpp index 0710a353006..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,12 +31,18 @@ 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&); @@ -51,9 +64,9 @@ bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) { 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(); @@ -80,7 +93,7 @@ bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) { } DOUT << "\n"; - MBB->remove(MI); + MBB->erase(MI); return true; } @@ -89,10 +102,10 @@ bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) { 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"); + 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(); @@ -108,18 +121,23 @@ bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) { 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); + 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); + MachineBasicBlock::iterator dMI = MI; + DOUT << "subreg: " << *(--dMI); #endif + } DOUT << "\n"; - MBB->remove(MI); + MBB->erase(MI); return true; } @@ -128,13 +146,15 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) { 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"); + 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 unsigned SrcReg = MI->getOperand(1).getReg(); +#endif unsigned InsReg = MI->getOperand(2).getReg(); unsigned SubIdx = MI->getOperand(3).getImm(); @@ -149,18 +169,22 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) { 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); - + 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); + MachineBasicBlock::iterator dMI = MI; + DOUT << "subreg: " << *(--dMI); #endif + } DOUT << "\n"; - MBB->remove(MI); + MBB->erase(MI); return true; }