X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FLowerSubregs.cpp;h=6d7c5ccee6009657f43f9e5e2b5a18ff68687e0b;hb=253174bf50c932abaa680f465e2888c0e5272267;hp=1cdd34b77f456eeb21f6afe6dc1447b401a9c12f;hpb=2c3f7ae3843bdc9dcfe85393e178211976c1f9bd;p=oota-llvm.git diff --git a/lib/CodeGen/LowerSubregs.cpp b/lib/CodeGen/LowerSubregs.cpp index 1cdd34b77f4..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(); @@ -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,15 +121,20 @@ 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->erase(MI); @@ -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();