diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/CodeGen/LowerSubregs.cpp | 35 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp | 30 | ||||
| -rw-r--r-- | llvm/lib/Target/Target.td | 12 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 13 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.h | 8 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.td | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86RegisterInfo.h | 9 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86RegisterInfo.td | 4 | 
8 files changed, 68 insertions, 47 deletions
diff --git a/llvm/lib/CodeGen/LowerSubregs.cpp b/llvm/lib/CodeGen/LowerSubregs.cpp index 61601d50d05..531713e47fb 100644 --- a/llvm/lib/CodeGen/LowerSubregs.cpp +++ b/llvm/lib/CodeGen/LowerSubregs.cpp @@ -90,32 +90,21 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) {    MachineFunction &MF = *MBB->getParent();    const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo();     const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); -  unsigned DstReg = 0; +  assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) && +         ((MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) ||  +            MI->getOperand(1).isImmediate()) && +         (MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) && +          MI->getOperand(3).isImmediate() && "Invalid insert_subreg"); +           +  unsigned DstReg = MI->getOperand(0).getReg();    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(); +  // Check if we're inserting into an implicit value. +  if (MI->getOperand(1).isImmediate())      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(); +  else      SrcReg = MI->getOperand(1).getReg(); -    InsReg = MI->getOperand(2).getReg(); -    SubIdx = MI->getOperand(3).getImm();      -  } else  -    assert(0 && "Malformed extract_subreg"); +  unsigned InsReg = MI->getOperand(2).getReg(); +  unsigned SubIdx = MI->getOperand(3).getImm();         assert(SubIdx != 0 && "Invalid index for extract_subreg");    unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx); diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index c042acb4dd9..5b0d48df467 100644 --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -695,19 +695,11 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node,      MI->addOperand(MachineOperand::CreateImm(SubIdx));    } else if (Opc == TargetInstrInfo::INSERT_SUBREG) { -    assert((Node->getNumOperands() == 2 || Node->getNumOperands() == 3) && -            "Malformed insert_subreg node"); -    bool isUndefInput = (Node->getNumOperands() == 2); -    unsigned SubReg = 0; -    unsigned SubIdx = 0; -     -    if (isUndefInput) { -      SubReg = getVR(Node->getOperand(0), VRBaseMap); -      SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getValue(); -    } else { -      SubReg = getVR(Node->getOperand(1), VRBaseMap); -      SubIdx = cast<ConstantSDNode>(Node->getOperand(2))->getValue(); -    } +    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 @@ -745,9 +737,15 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node,      }      MI->addOperand(MachineOperand::CreateReg(VRBase, true)); -    AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap); -    if (!isUndefInput) -      AddOperand(MI, Node->getOperand(1), 0, 0, VRBaseMap); +     +    // 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)) +      MI->addOperand(MachineOperand::CreateImm(SD->getValue())); +    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"); diff --git a/llvm/lib/Target/Target.td b/llvm/lib/Target/Target.td index cebac7a2636..ea8f6ec3a15 100644 --- a/llvm/lib/Target/Target.td +++ b/llvm/lib/Target/Target.td @@ -263,6 +263,10 @@ def variable_ops;  /// flags. But currently we have but one flag.  def ptr_rc; +/// unknown definition - Mark this operand as being of unknown type, causing +/// it to be resolved by inference in the context it is used. +def unknown; +  /// Operand Types - These provide the built-in operand types that may be used  /// by a target.  Targets can optionally provide their own operand types as  /// needed, though this should not be needed for RISC targets. @@ -351,15 +355,15 @@ def DECLARE : Instruction {    let hasCtrlDep = 1;  }  def EXTRACT_SUBREG : Instruction { -  let OutOperandList = (ops variable_ops); -  let InOperandList = (ops variable_ops); +  let OutOperandList = (ops unknown:$dst); +  let InOperandList = (ops unknown:$supersrc, i32imm:$subidx);    let AsmString = "";    let Namespace = "TargetInstrInfo";    let neverHasSideEffects = 1;  }  def INSERT_SUBREG : Instruction { -        let OutOperandList = (ops variable_ops); -  let InOperandList = (ops variable_ops); +  let OutOperandList = (ops unknown:$dst); +  let InOperandList = (ops unknown:$supersrc, unknown:$subsrc, i32imm:$subidx);    let AsmString = "";    let Namespace = "TargetInstrInfo";    let neverHasSideEffects = 1; diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index ea1bed19ce8..d5601b74eab 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -1533,22 +1533,27 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {        AddToISelQueue(N0);        if (NVT == MVT::i64 || NVT == MVT::i32 || NVT == MVT::i16) {          SDOperand SRIdx; +        SDOperand ImplVal = CurDAG->getTargetConstant(X86::IMPL_VAL_UNDEF,  +                                                      MVT::i32);          switch(N0.getValueType()) {          case MVT::i32: -          SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3 +          SRIdx = CurDAG->getTargetConstant(X86::SUBREG_32BIT, MVT::i32); +          // x86-64 zero extends 32-bit inserts int 64-bit registers +          if (Subtarget->is64Bit()) +            ImplVal = CurDAG->getTargetConstant(X86::IMPL_VAL_ZERO, MVT::i32);            break;          case MVT::i16: -          SRIdx = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2 +          SRIdx = CurDAG->getTargetConstant(X86::SUBREG_16BIT, MVT::i32);            break;          case MVT::i8:            if (Subtarget->is64Bit()) -            SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1 +            SRIdx = CurDAG->getTargetConstant(X86::SUBREG_8BIT, MVT::i32);            break;          default: assert(0 && "Unknown any_extend!");          }          if (SRIdx.Val) {            SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG, -                                                  NVT, N0, SRIdx); +                                                  NVT, ImplVal, N0, SRIdx);  #ifndef NDEBUG            DOUT << std::string(Indent-2, ' ') << "=> "; diff --git a/llvm/lib/Target/X86/X86InstrInfo.h b/llvm/lib/Target/X86/X86InstrInfo.h index 839a0f248b6..e0d0342ae6d 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.h +++ b/llvm/lib/Target/X86/X86InstrInfo.h @@ -46,6 +46,14 @@ namespace X86 {      COND_INVALID    }; +  // X86 specific implict values used for subregister inserts.  +  // This can be used to model the fact that x86-64 by default +  // inserts 32-bit values into 64-bit registers implicitly containing zeros. +  enum ImplicitVal { +    IMPL_VAL_UNDEF = 0, +    IMPL_VAL_ZERO  = 1 +  }; +      // Turn condition code into conditional branch opcode.    unsigned GetCondBranchFromCond(CondCode CC); diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index e32fb9c4b53..4d03dba32dc 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -161,6 +161,10 @@ def i32i8imm  : Operand<i32>;  // Branch targets have OtherVT type.  def brtarget : Operand<OtherVT>; +// These should match the enum X86::ImplicitVal +def x86_impl_val_undef : PatLeaf<(i32 0)>; +def x86_impl_val_zero  : PatLeaf<(i32 1)>; +  //===----------------------------------------------------------------------===//  // X86 Complex Pattern Definitions.  // diff --git a/llvm/lib/Target/X86/X86RegisterInfo.h b/llvm/lib/Target/X86/X86RegisterInfo.h index 8b010a92404..1c8f5e28b99 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.h +++ b/llvm/lib/Target/X86/X86RegisterInfo.h @@ -32,6 +32,15 @@ namespace N86 {    };  } +namespace X86 { +  /// SubregIndex - The index of various sized subregister classes. Note that  +  /// these indices must be kept in sync with the class indices in the  +  /// X86RegisterInfo.td file. +  enum SubregIndex { +    SUBREG_8BIT = 1, SUBREG_16BIT = 2, SUBREG_32BIT = 3 +  }; +} +  /// DWARFFlavour - Flavour of dwarf regnumbers  ///  namespace DWARFFlavour { diff --git a/llvm/lib/Target/X86/X86RegisterInfo.td b/llvm/lib/Target/X86/X86RegisterInfo.td index 24402386c8e..b713c892ba1 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.td +++ b/llvm/lib/Target/X86/X86RegisterInfo.td @@ -176,6 +176,10 @@ let Namespace = "X86" in {  // sub registers for each register.  // +def x86_subreg_8bit    : PatLeaf<(i32 1)>; +def x86_subreg_16bit   : PatLeaf<(i32 2)>; +def x86_subreg_32bit   : PatLeaf<(i32 3)>; +  def : SubRegSet<1, [AX, CX, DX, BX, SP,  BP,  SI,  DI,                        R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W],                     [AL, CL, DL, BL, SPL, BPL, SIL, DIL,   | 

