diff options
-rw-r--r-- | include/llvm/Target/TargetInstrInfo.h | 12 | ||||
-rw-r--r-- | lib/CodeGen/LowerSubregs.cpp | 155 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAG.cpp | 75 | ||||
-rw-r--r-- | lib/Target/Target.td | 8 | ||||
-rw-r--r-- | lib/Target/TargetSelectionDAG.td | 8 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelDAGToDAG.cpp | 53 | ||||
-rw-r--r-- | lib/Target/X86/X86Instr64bit.td | 28 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.cpp | 6 | ||||
-rw-r--r-- | utils/TableGen/CodeEmitterGen.cpp | 9 | ||||
-rw-r--r-- | utils/TableGen/CodeGenTarget.cpp | 9 | ||||
-rw-r--r-- | utils/TableGen/InstrInfoEmitter.cpp | 3 |
11 files changed, 158 insertions, 208 deletions
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index d6acc63..05ca9e6 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -50,16 +50,8 @@ public: DECLARE = 3, EXTRACT_SUBREG = 4, INSERT_SUBREG = 5, - IMPLICIT_DEF = 6 - }; - - // Target independent implict values for use with subreg insert. All targets - // that support insert_subreg support IMPL_VAL_UNDEF. Support for the other - // values is target dependent. - enum ImplictVal { - IMPL_VAL_UNDEF = 0, - IMPL_VAL_ZERO = 1, - LAST_IMPL_VAL = 3 + IMPLICIT_DEF = 6, + SUBREG_TO_REG = 7 }; unsigned getNumOpcodes() const { return NumOpcodes; } diff --git a/lib/CodeGen/LowerSubregs.cpp b/lib/CodeGen/LowerSubregs.cpp index 8945dd5..0710a35 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 d0d078a..94d3a6d 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; } diff --git a/lib/Target/Target.td b/lib/Target/Target.td index 9d49bd2..6e2ba91 100644 --- a/lib/Target/Target.td +++ b/lib/Target/Target.td @@ -366,6 +366,7 @@ def INSERT_SUBREG : Instruction { let AsmString = ""; let Namespace = "TargetInstrInfo"; let neverHasSideEffects = 1; + let Constraints = "$supersrc = $dst"; } def IMPLICIT_DEF : Instruction { let OutOperandList = (ops unknown:$dst); @@ -374,6 +375,13 @@ def IMPLICIT_DEF : Instruction { let Namespace = "TargetInstrInfo"; let neverHasSideEffects = 1; } +def SUBREG_TO_REG : Instruction { + let OutOperandList = (ops unknown:$dst); + let InOperandList = (ops unknown:$implsrc, unknown:$subsrc, i32imm:$subidx); + let AsmString = ""; + let Namespace = "TargetInstrInfo"; + let neverHasSideEffects = 1; +} //===----------------------------------------------------------------------===// // AsmWriter - This class can be implemented by targets that need to customize diff --git a/lib/Target/TargetSelectionDAG.td b/lib/Target/TargetSelectionDAG.td index 73280f3..d70cc75 100644 --- a/lib/Target/TargetSelectionDAG.td +++ b/lib/Target/TargetSelectionDAG.td @@ -918,11 +918,3 @@ class ComplexPattern<ValueType ty, int numops, string fn, def SDT_dwarf_loc : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>; def dwarf_loc : SDNode<"ISD::DEBUG_LOC", SDT_dwarf_loc,[SDNPHasChain]>; - -//===----------------------------------------------------------------------===// -// Implict value insert subreg support. -// -// These should match the enum TargetInstrInfo::ImplictVal. -def tii_impl_val_undef : PatLeaf<(i32 0)>; -def tii_impl_val_zero : PatLeaf<(i32 1)>; - diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index bf233bf..7a55d9d 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -1529,39 +1529,36 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) { } case ISD::ANY_EXTEND: { + // Check if the type extended to supports subregs. + if (NVT == MVT::i8) + break; + SDOperand N0 = Node->getOperand(0); + // Get the subregsiter index for the type to extend. + MVT::ValueType N0VT = N0.getValueType(); + unsigned Idx = (N0VT == MVT::i32) ? X86::SUBREG_32BIT : + (N0VT == MVT::i16) ? X86::SUBREG_16BIT : + (Subtarget->is64Bit()) ? X86::SUBREG_8BIT : 0; + + // If we don't have a subreg Idx, let generated ISel have a try. + if (Idx == 0) + break; + + // If we have an index, generate an insert_subreg into undef. AddToISelQueue(N0); - if (NVT == MVT::i64 || NVT == MVT::i32 || NVT == MVT::i16) { - SDOperand SRIdx; - switch(N0.getValueType()) { - case MVT::i32: - SRIdx = CurDAG->getTargetConstant(X86::SUBREG_32BIT, MVT::i32); - break; - case MVT::i16: - SRIdx = CurDAG->getTargetConstant(X86::SUBREG_16BIT, MVT::i32); - break; - case MVT::i8: - if (Subtarget->is64Bit()) - SRIdx = CurDAG->getTargetConstant(X86::SUBREG_8BIT, MVT::i32); - break; - default: assert(0 && "Unknown any_extend!"); - } - if (SRIdx.Val) { - SDOperand ImplVal = - CurDAG->getTargetConstant(X86InstrInfo::IMPL_VAL_UNDEF, MVT::i32); - SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG, - NVT, ImplVal, N0, SRIdx); + SDOperand Undef = + SDOperand(CurDAG->getTargetNode(X86::IMPLICIT_DEF, NVT), 0); + SDOperand SRIdx = CurDAG->getTargetConstant(Idx, MVT::i32); + SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG, + NVT, Undef, N0, SRIdx); #ifndef NDEBUG - DOUT << std::string(Indent-2, ' ') << "=> "; - DEBUG(ResNode->dump(CurDAG)); - DOUT << "\n"; - Indent -= 2; + DOUT << std::string(Indent-2, ' ') << "=> "; + DEBUG(ResNode->dump(CurDAG)); + DOUT << "\n"; + Indent -= 2; #endif - return ResNode; - } // Otherwise let generated ISel handle it. - } - break; + return ResNode; } case ISD::SIGN_EXTEND_INREG: { diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td index 730f393..59d7afc 100644 --- a/lib/Target/X86/X86Instr64bit.td +++ b/lib/Target/X86/X86Instr64bit.td @@ -1202,43 +1202,43 @@ def : Pat<(parallel (X86cmp GR64:$src1, 0), (implicit EFLAGS)), // Zero-extension -def : Pat<(i64 (zext GR32:$src)), (INSERT_SUBREG tii_impl_val_zero, - GR32:$src, x86_subreg_32bit)>; +def : Pat<(i64 (zext GR32:$src)), + (SUBREG_TO_REG (i64 0), GR32:$src, x86_subreg_32bit)>; // zextload bool -> zextload byte def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>; -def : Pat<(zextloadi64i32 addr:$src), (INSERT_SUBREG tii_impl_val_zero, - (MOV32rm addr:$src), x86_subreg_32bit)>; +def : Pat<(zextloadi64i32 addr:$src), + (SUBREG_TO_REG (i64 0), (MOV32rm addr:$src), x86_subreg_32bit)>; // extload def : Pat<(extloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>; def : Pat<(extloadi64i8 addr:$src), (MOVZX64rm8 addr:$src)>; def : Pat<(extloadi64i16 addr:$src), (MOVZX64rm16 addr:$src)>; -def : Pat<(extloadi64i32 addr:$src), (INSERT_SUBREG tii_impl_val_undef, - (MOV32rm addr:$src), x86_subreg_32bit)>; +def : Pat<(extloadi64i32 addr:$src), + (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src), + x86_subreg_32bit)>; // anyext -> zext def : Pat<(i64 (anyext GR8 :$src)), (MOVZX64rr8 GR8 :$src)>; def : Pat<(i64 (anyext GR16:$src)), (MOVZX64rr16 GR16:$src)>; -def : Pat<(i64 (anyext GR32:$src)), (INSERT_SUBREG tii_impl_val_undef, - GR32:$src, x86_subreg_32bit)>; +def : Pat<(i64 (anyext GR32:$src)), + (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, x86_subreg_32bit)>; def : Pat<(i64 (anyext (loadi8 addr:$src))), (MOVZX64rm8 addr:$src)>; def : Pat<(i64 (anyext (loadi16 addr:$src))), (MOVZX64rm16 addr:$src)>; -def : Pat<(i64 (anyext (loadi32 addr:$src))), (INSERT_SUBREG tii_impl_val_undef, - (MOV32rm addr:$src), - x86_subreg_32bit)>; +def : Pat<(i64 (anyext (loadi32 addr:$src))), + (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src), + x86_subreg_32bit)>; //===----------------------------------------------------------------------===// // Some peepholes //===----------------------------------------------------------------------===// - // r & (2^32-1) ==> mov32 + implicit zext def : Pat<(and GR64:$src, i64immFFFFFFFF), - (INSERT_SUBREG tii_impl_val_zero, - (MOV32rr (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)), + (SUBREG_TO_REG (i64 0), + (i32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)), x86_subreg_32bit)>; // (shl x, 1) ==> (add x, x) diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index ff666ff..650ab41 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -920,10 +920,11 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, // Build and insert into an implicit UNDEF value. This is OK because // well be shifting and then extracting the lower 16-bits. + MachineInstr *Undef = BuildMI(get(X86::IMPLICIT_DEF), leaInReg); + MachineInstr *Ins = BuildMI(get(X86::INSERT_SUBREG),leaInReg) - .addImm(X86InstrInfo::IMPL_VAL_UNDEF) - .addReg(Src).addImm(X86::SUBREG_16BIT); + .addReg(leaInReg).addReg(Src).addImm(X86::SUBREG_16BIT); NewMI = BuildMI(get(Opc), leaOutReg) .addReg(0).addImm(1 << ShAmt).addReg(leaInReg).addImm(0); @@ -933,6 +934,7 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, .addReg(leaOutReg).addImm(X86::SUBREG_16BIT); Ext->copyKillDeadInfo(MI); + MFI->insert(MBBI, Undef); MFI->insert(MBBI, Ins); // Insert the insert_subreg LV.instructionChanged(MI, NewMI); // Update live variables LV.addVirtualRegisterKilled(leaInReg, NewMI); diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp index bebf1fd..a21a31c 100644 --- a/utils/TableGen/CodeEmitterGen.cpp +++ b/utils/TableGen/CodeEmitterGen.cpp @@ -30,7 +30,8 @@ void CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) { R->getName() == "DECLARE" || R->getName() == "EXTRACT_SUBREG" || R->getName() == "INSERT_SUBREG" || - R->getName() == "IMPLICIT_DEF") continue; + R->getName() == "IMPLICIT_DEF" || + R->getName() == "SUBREG_TO_REG") continue; BitsInit *BI = R->getValueAsBitsInit("Inst"); @@ -105,7 +106,8 @@ void CodeEmitterGen::run(std::ostream &o) { R->getName() == "DECLARE" || R->getName() == "EXTRACT_SUBREG" || R->getName() == "INSERT_SUBREG" || - R->getName() == "IMPLICIT_DEF") { + R->getName() == "IMPLICIT_DEF" || + R->getName() == "SUBREG_TO_REG") { o << " 0U"; continue; } @@ -139,7 +141,8 @@ void CodeEmitterGen::run(std::ostream &o) { InstName == "DECLARE"|| InstName == "EXTRACT_SUBREG" || InstName == "INSERT_SUBREG" || - InstName == "IMPLICIT_DEF") continue; + InstName == "IMPLICIT_DEF" || + InstName == "SUBREG_TO_REG") continue; BitsInit *BI = R->getValueAsBitsInit("Inst"); const std::vector<RecordVal> &Vals = R->getValues(); diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index e41f75a..da34ebf 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -309,6 +309,11 @@ getInstructionsByEnumValue(std::vector<const CodeGenInstruction*> throw "Could not find 'IMPLICIT_DEF' instruction!"; const CodeGenInstruction *IMPLICIT_DEF = &I->second; + I = getInstructions().find("SUBREG_TO_REG"); + if (I == Instructions.end()) + throw "Could not find 'SUBREG_TO_REG' instruction!"; + const CodeGenInstruction *SUBREG_TO_REG = &I->second; + // Print out the rest of the instructions now. NumberedInstructions.push_back(PHI); NumberedInstructions.push_back(INLINEASM); @@ -317,6 +322,7 @@ getInstructionsByEnumValue(std::vector<const CodeGenInstruction*> NumberedInstructions.push_back(EXTRACT_SUBREG); NumberedInstructions.push_back(INSERT_SUBREG); NumberedInstructions.push_back(IMPLICIT_DEF); + NumberedInstructions.push_back(SUBREG_TO_REG); for (inst_iterator II = inst_begin(), E = inst_end(); II != E; ++II) if (&II->second != PHI && &II->second != INLINEASM && @@ -324,7 +330,8 @@ getInstructionsByEnumValue(std::vector<const CodeGenInstruction*> &II->second != DECLARE && &II->second != EXTRACT_SUBREG && &II->second != INSERT_SUBREG && - &II->second != IMPLICIT_DEF) + &II->second != IMPLICIT_DEF && + &II->second != SUBREG_TO_REG) NumberedInstructions.push_back(&II->second); } diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index d765152..cc03c6a 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -411,7 +411,8 @@ void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val, R->getName() != "DECLARE" && R->getName() != "EXTRACT_SUBREG" && R->getName() != "INSERT_SUBREG" && - R->getName() != "IMPLICIT_DEF") + R->getName() != "IMPLICIT_DEF" && + R->getName() != "SUBREG_TO_REG") throw R->getName() + " doesn't have a field named '" + Val->getValue() + "'!"; return; |