diff options
author | Christopher Lamb <christopher.lamb@gmail.com> | 2008-03-16 03:12:01 +0000 |
---|---|---|
committer | Christopher Lamb <christopher.lamb@gmail.com> | 2008-03-16 03:12:01 +0000 |
commit | c9298235251b014e86a7368d92b589d093acb64a (patch) | |
tree | 11c2e0c245fb52c02a65e3e9469f5f83e94abaee /lib/CodeGen | |
parent | 606c5aa084041eb5ad60710728098eaf9c997315 (diff) |
Make insert_subreg a two-address instruction, vastly simplifying LowerSubregs pass. Add a new TII, subreg_to_reg, which is like insert_subreg except that it takes an immediate implicit value to insert into rather than a register.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48412 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/LowerSubregs.cpp | 155 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAG.cpp | 75 |
2 files changed, 89 insertions, 141 deletions
diff --git a/lib/CodeGen/LowerSubregs.cpp b/lib/CodeGen/LowerSubregs.cpp index 8945dd57b1..0710a35300 100644 --- a/lib/CodeGen/LowerSubregs.cpp +++ b/lib/CodeGen/LowerSubregs.cpp @@ -35,6 +35,7 @@ namespace { bool LowerExtract(MachineInstr *MI); bool LowerInsert(MachineInstr *MI); + bool LowerSubregToReg(MachineInstr *MI); }; char LowerSubregsInstructionPass::ID = 0; @@ -54,29 +55,28 @@ bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) { 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 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 = TRI.getPhysicalRegisterRegClass(DstReg); - } else { - TRC = MF.getRegInfo().getRegClass(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"; @@ -84,115 +84,80 @@ bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *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(); assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) && - ((MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) || - MI->getOperand(1).isImmediate()) && + MI->getOperand(1).isImmediate() && (MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) && - MI->getOperand(3).isImmediate() && "Invalid insert_subreg"); + MI->getOperand(3).isImmediate() && "Invalid subreg_to_reg"); - // Check if we're inserting into an implicit undef value. - bool isImplicit = MI->getOperand(1).isImmediate(); - unsigned DstReg = MI->getOperand(0).getReg(); - unsigned SrcReg = isImplicit ? DstReg : MI->getOperand(1).getReg(); - unsigned InsReg = MI->getOperand(2).getReg(); - unsigned SubIdx = MI->getOperand(3).getImm(); + unsigned DstReg = MI->getOperand(0).getReg(); + unsigned InsReg = MI->getOperand(2).getReg(); + unsigned SubIdx = MI->getOperand(3).getImm(); - assert(SubIdx != 0 && "Invalid index for extract_subreg"); + 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; - - // Check whether the implict subreg copy has side affects or not. Only copies - // into an undef value have no side affects, that is they can be eliminated - // without changing the semantics of the program. - bool copyHasSideAffects = isImplicit? - MI->getOperand(1).getImm() != TargetInstrInfo::IMPL_VAL_UNDEF - : false; - - // 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 || copyHasSideAffects)) { - if (isImplicit || MI->getOperand(1).isKill()) { - DstSubReg = TRI.getSubReg(SrcReg, SubIdx); - // Insert sub-register copy - const TargetRegisterClass *TRC1 = 0; - if (TargetRegisterInfo::isPhysicalRegister(InsReg)) { - TRC1 = TRI.getPhysicalRegisterRegClass(InsReg); - } else { - TRC1 = MF.getRegInfo().getRegClass(InsReg); - } - TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1, TRC1); + + // 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 - } else { - assert(0 && "Don't know how to convert this insert"); - } - } -#ifndef NDEBUG - if (InsReg == DstSubReg && !copyHasSideAffects) { - DOUT << "subreg: Eliminated subreg copy\n"; - } + MachineBasicBlock::iterator dMI = MI; + DOUT << "subreg: " << *(--dMI); #endif - if (SrcReg != DstReg) { - // Insert super-register copy - const TargetRegisterClass *TRC0 = 0; - if (TargetRegisterInfo::isPhysicalRegister(DstReg)) { - TRC0 = TRI.getPhysicalRegisterRegClass(DstReg); - } else { - TRC0 = MF.getRegInfo().getRegClass(DstReg); - } - assert(TRC0 == TRI.getPhysicalRegisterRegClass(SrcReg) && - "Insert superreg and Dst must be of same register class"); + DOUT << "\n"; + MBB->remove(MI); + return true; +} - TII.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC0, TRC0); +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(); -#ifndef NDEBUG - MachineBasicBlock::iterator dMI = MI; - DOUT << "subreg: " << *(--dMI); -#endif - } + assert(DstReg == SrcReg && "insert_subreg not a two-address instruction?"); + assert(SubIdx != 0 && "Invalid index for insert_subreg"); + unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx); -#ifndef NDEBUG - if (SrcReg == DstReg) { - DOUT << "subreg: Eliminated superreg copy\n"; - } -#endif + 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"); - if (!revCopyOrder && (InsReg != DstSubReg || copyHasSideAffects)) { - // Insert sub-register copy - const TargetRegisterClass *TRC1 = 0; - if (TargetRegisterInfo::isPhysicalRegister(InsReg)) { - TRC1 = TRI.getPhysicalRegisterRegClass(InsReg); - } else { - TRC1 = MF.getRegInfo().getRegClass(InsReg); - } - TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1, TRC1); + 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); + MachineBasicBlock::iterator dMI = MI; + DOUT << "subreg: " << *(--dMI); #endif - } DOUT << "\n"; MBB->remove(MI); @@ -220,6 +185,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); } } } diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index d0d078ab13..94d3a6dbfc 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -661,26 +661,24 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node, DenseMap<SDOperand, unsigned> &VRBaseMap) { unsigned VRBase = 0; unsigned Opc = Node->getTargetOpcode(); - if (Opc == TargetInstrInfo::EXTRACT_SUBREG) { - // If the node is only used by a CopyToReg and the dest reg is a vreg, use - // the CopyToReg'd destination register instead of creating a new vreg. - for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); - UI != E; ++UI) { - SDNode *Use = *UI; - if (Use->getOpcode() == ISD::CopyToReg && - Use->getOperand(2).Val == Node) { - unsigned DestReg = cast<RegisterSDNode>(Use->getOperand(1))->getReg(); - if (TargetRegisterInfo::isVirtualRegister(DestReg)) { - VRBase = DestReg; - break; - } + + // If the node is only used by a CopyToReg and the dest reg is a vreg, use + // the CopyToReg'd destination register instead of creating a new vreg. + for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); + UI != E; ++UI) { + SDNode *Use = *UI; + if (Use->getOpcode() == ISD::CopyToReg && + Use->getOperand(2).Val == Node) { + unsigned DestReg = cast<RegisterSDNode>(Use->getOperand(1))->getReg(); + if (TargetRegisterInfo::isVirtualRegister(DestReg)) { + VRBase = DestReg; + break; } } - + } + + if (Opc == TargetInstrInfo::EXTRACT_SUBREG) { unsigned SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getValue(); - - // TODO: If the node is a use of a CopyFromReg from a physical register - // fold the extract into the copy now // Create the extract_subreg machine instruction. MachineInstr *MI = @@ -707,36 +705,14 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node, AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap); MI->addOperand(MachineOperand::CreateImm(SubIdx)); - } else if (Opc == TargetInstrInfo::INSERT_SUBREG) { + } else if (Opc == TargetInstrInfo::INSERT_SUBREG || + Opc == TargetInstrInfo::SUBREG_TO_REG) { SDOperand N0 = Node->getOperand(0); SDOperand N1 = Node->getOperand(1); SDOperand N2 = Node->getOperand(2); unsigned SubReg = getVR(N1, VRBaseMap); unsigned SubIdx = cast<ConstantSDNode>(N2)->getValue(); - // TODO: Add tracking info to MachineRegisterInfo of which vregs are subregs - // to allow coalescing in the allocator - - // If the node is only used by a CopyToReg and the dest reg is a vreg, use - // the CopyToReg'd destination register instead of creating a new vreg. - // If the CopyToReg'd destination register is physical, then fold the - // insert into the copy - for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); - UI != E; ++UI) { - SDNode *Use = *UI; - if (Use->getOpcode() == ISD::CopyToReg && - Use->getOperand(2).Val == Node) { - unsigned DestReg = cast<RegisterSDNode>(Use->getOperand(1))->getReg(); - if (TargetRegisterInfo::isVirtualRegister(DestReg)) { - VRBase = DestReg; - break; - } - } - } - - // Create the insert_subreg machine instruction. - MachineInstr *MI = - new MachineInstr(BB, TII->get(TargetInstrInfo::INSERT_SUBREG)); // Figure out the register class to create for the destreg. const TargetRegisterClass *TRC = 0; @@ -749,19 +725,23 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node, VRBase = MRI.createVirtualRegister(TRC); // Create the reg } + // Create the insert_subreg or subreg_to_reg machine instruction. + MachineInstr *MI = + new MachineInstr(BB, TII->get(Opc)); MI->addOperand(MachineOperand::CreateReg(VRBase, true)); - // If N0 is a constant then it indicates the insert is being done - // into a target specific constant value, not a register. - if (const ConstantSDNode *SD = dyn_cast<ConstantSDNode>(N0)) + // If creating a subreg_to_reg, then the first input operand + // is an implicit value immediate, otherwise it's a register + if (Opc == TargetInstrInfo::SUBREG_TO_REG) { + const ConstantSDNode *SD = cast<ConstantSDNode>(N0); MI->addOperand(MachineOperand::CreateImm(SD->getValue())); - else + } else AddOperand(MI, N0, 0, 0, VRBaseMap); // Add the subregster being inserted AddOperand(MI, N1, 0, 0, VRBaseMap); MI->addOperand(MachineOperand::CreateImm(SubIdx)); } else - assert(0 && "Node is not a subreg insert or extract"); + assert(0 && "Node is not insert_subreg, extract_subreg, or subreg_to_reg"); bool isNew = VRBaseMap.insert(std::make_pair(SDOperand(Node,0), VRBase)); assert(isNew && "Node emitted out of order - early"); @@ -777,7 +757,8 @@ void ScheduleDAG::EmitNode(SDNode *Node, unsigned InstanceNo, // Handle subreg insert/extract specially if (Opc == TargetInstrInfo::EXTRACT_SUBREG || - Opc == TargetInstrInfo::INSERT_SUBREG) { + Opc == TargetInstrInfo::INSERT_SUBREG || + Opc == TargetInstrInfo::SUBREG_TO_REG) { EmitSubregNode(Node, VRBaseMap); return; } |