[llvm-branch-commits] [llvm-branch] r105446 - in /llvm/branches/Apple/Troughton: ./ lib/CodeGen/TwoAddressInstructionPass.cpp lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h

Bob Wilson bob.wilson at apple.com
Thu Jun 3 17:39:50 PDT 2010


Author: bwilson
Date: Thu Jun  3 19:39:49 2010
New Revision: 105446

URL: http://llvm.org/viewvc/llvm-project?rev=105446&view=rev
Log:
--- Merging r105437 into '.':
U    lib/CodeGen/TwoAddressInstructionPass.cpp
--- Merging r105439 into '.':
U    lib/Target/ARM/ARMISelLowering.h
U    lib/Target/ARM/ARMISelLowering.cpp
U    lib/Target/ARM/ARMISelDAGToDAG.cpp

Modified:
    llvm/branches/Apple/Troughton/   (props changed)
    llvm/branches/Apple/Troughton/lib/CodeGen/TwoAddressInstructionPass.cpp
    llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelDAGToDAG.cpp
    llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelLowering.cpp
    llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelLowering.h

Propchange: llvm/branches/Apple/Troughton/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Jun  3 19:39:49 2010
@@ -1 +1 @@
-/llvm/trunk:105358,105361,105369,105372,105399,105427
+/llvm/trunk:105358,105361,105369,105372,105399,105427,105437,105439

Modified: llvm/branches/Apple/Troughton/lib/CodeGen/TwoAddressInstructionPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Troughton/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=105446&r1=105445&r2=105446&view=diff
==============================================================================
--- llvm/branches/Apple/Troughton/lib/CodeGen/TwoAddressInstructionPass.cpp (original)
+++ llvm/branches/Apple/Troughton/lib/CodeGen/TwoAddressInstructionPass.cpp Thu Jun  3 19:39:49 2010
@@ -1164,6 +1164,12 @@
     if (!Seen.insert(SrcReg))
       continue;
 
+    // Check that the instructions are all in the same basic block.
+    MachineInstr *SrcDefMI = MRI->getVRegDef(SrcReg);
+    MachineInstr *DstDefMI = MRI->getVRegDef(DstReg);
+    if (SrcDefMI->getParent() != DstDefMI->getParent())
+      continue;
+
     // If there are no other uses than extract_subreg which feed into
     // the reg_sequence, then we might be able to coalesce them.
     bool CanCoalesce = true;
@@ -1172,25 +1178,36 @@
            UI = MRI->use_nodbg_begin(SrcReg),
            UE = MRI->use_nodbg_end(); UI != UE; ++UI) {
       MachineInstr *UseMI = &*UI;
+      unsigned SubRegIdx = UseMI->getOperand(2).getImm();
+      // FIXME: For now require that the destination subregs match the subregs
+      // being extracted.
       if (!UseMI->isExtractSubreg() ||
-          UseMI->getOperand(0).getReg() != DstReg) {
+          UseMI->getOperand(0).getReg() != DstReg ||
+          UseMI->getOperand(0).getSubReg() != SubRegIdx ||
+          UseMI->getOperand(1).getSubReg() != 0) {
         CanCoalesce = false;
         break;
       }
-      SubIndices.push_back(UseMI->getOperand(2).getImm());
+      SubIndices.push_back(SubRegIdx);
     }
 
     if (!CanCoalesce || SubIndices.size() < 2)
       continue;
 
+    // FIXME: For now require that the src and dst registers are in the
+    // same regclass.
+    if (MRI->getRegClass(SrcReg) != MRI->getRegClass(DstReg))
+      continue;
+
     std::sort(SubIndices.begin(), SubIndices.end());
     unsigned NewSubIdx = 0;
     if (TRI->canCombineSubRegIndices(MRI->getRegClass(SrcReg), SubIndices,
                                      NewSubIdx)) {
       bool Proceed = true;
       if (NewSubIdx)
-        for (MachineRegisterInfo::reg_iterator RI = MRI->reg_begin(SrcReg),
-               RE = MRI->reg_end(); RI != RE; ) {
+        for (MachineRegisterInfo::reg_nodbg_iterator
+               RI = MRI->reg_nodbg_begin(SrcReg), RE = MRI->reg_nodbg_end();
+             RI != RE; ) {
           MachineOperand &MO = RI.getOperand();
           ++RI;
           // FIXME: If the sub-registers do not combine to the whole

Modified: llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=105446&r1=105445&r2=105446&view=diff
==============================================================================
--- llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
+++ llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelDAGToDAG.cpp Thu Jun  3 19:39:49 2010
@@ -173,24 +173,17 @@
                                             char ConstraintCode,
                                             std::vector<SDValue> &OutOps);
 
-  /// PairDRegs - Form a quad register from a pair of D registers.
-  ///
+  // Form pairs of consecutive S, D, or Q registers.
+  SDNode *PairSRegs(EVT VT, SDValue V0, SDValue V1);
   SDNode *PairDRegs(EVT VT, SDValue V0, SDValue V1);
-
-  /// PairDRegs - Form a quad register pair from a pair of Q registers.
-  ///
   SDNode *PairQRegs(EVT VT, SDValue V0, SDValue V1);
 
-  /// QuadDRegs - Form a quad register pair from a quad of D registers.
-  ///
+  // Form sequences of 4 consecutive S, D, or Q registers.
+  SDNode *QuadSRegs(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3);
   SDNode *QuadDRegs(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3);
-
-  /// QuadQRegs - Form 4 consecutive Q registers.
-  ///
   SDNode *QuadQRegs(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3);
 
-  /// OctoDRegs - Form 8 consecutive D registers.
-  ///
+  // Form sequences of 8 consecutive D registers.
   SDNode *OctoDRegs(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3,
                     SDValue V4, SDValue V5, SDValue V6, SDValue V7);
 };
@@ -962,6 +955,24 @@
   return NULL;
 }
 
+/// PairSRegs - Form a D register from a pair of S registers.
+///
+SDNode *ARMDAGToDAGISel::PairSRegs(EVT VT, SDValue V0, SDValue V1) {
+  DebugLoc dl = V0.getNode()->getDebugLoc();
+  SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, MVT::i32);
+  SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, MVT::i32);
+  if (llvm::ModelWithRegSequence()) {
+    const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 };
+    return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4);
+  }
+  SDValue Undef =
+    SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0);
+  SDNode *Pair = CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl,
+                                        VT, Undef, V0, SubReg0);
+  return CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl,
+                                VT, SDValue(Pair, 0), V1, SubReg1);
+}
+
 /// PairDRegs - Form a quad register from a pair of D registers.
 ///
 SDNode *ARMDAGToDAGISel::PairDRegs(EVT VT, SDValue V0, SDValue V1) {
@@ -990,6 +1001,19 @@
   return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4);
 }
 
+/// QuadSRegs - Form 4 consecutive S registers.
+///
+SDNode *ARMDAGToDAGISel::QuadSRegs(EVT VT, SDValue V0, SDValue V1,
+                                   SDValue V2, SDValue V3) {
+  DebugLoc dl = V0.getNode()->getDebugLoc();
+  SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, MVT::i32);
+  SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, MVT::i32);
+  SDValue SubReg2 = CurDAG->getTargetConstant(ARM::ssub_2, MVT::i32);
+  SDValue SubReg3 = CurDAG->getTargetConstant(ARM::ssub_3, MVT::i32);
+  const SDValue Ops[] = { V0, SubReg0, V1, SubReg1, V2, SubReg2, V3, SubReg3 };
+  return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 8);
+}
+
 /// QuadDRegs - Form 4 consecutive D registers.
 ///
 SDNode *ARMDAGToDAGISel::QuadDRegs(EVT VT, SDValue V0, SDValue V1,
@@ -2213,6 +2237,22 @@
     SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg };
     return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops, 4);
   }
+  case ARMISD::BUILD_VECTOR: {
+    EVT VecVT = N->getValueType(0);
+    EVT EltVT = VecVT.getVectorElementType();
+    unsigned NumElts = VecVT.getVectorNumElements();
+    if (EltVT.getSimpleVT() == MVT::f64) {
+      assert(NumElts == 2 && "unexpected type for BUILD_VECTOR");
+      return PairDRegs(VecVT, N->getOperand(0), N->getOperand(1));
+    }
+    assert(EltVT.getSimpleVT() == MVT::f32 &&
+           "unexpected type for BUILD_VECTOR");
+    if (NumElts == 2)
+      return PairSRegs(VecVT, N->getOperand(0), N->getOperand(1));
+    assert(NumElts == 4 && "unexpected type for BUILD_VECTOR");
+    return QuadSRegs(VecVT, N->getOperand(0), N->getOperand(1),
+                     N->getOperand(2), N->getOperand(3));
+  }
 
   case ISD::INTRINSIC_VOID:
   case ISD::INTRINSIC_W_CHAIN: {

Modified: llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelLowering.cpp?rev=105446&r1=105445&r2=105446&view=diff
==============================================================================
--- llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelLowering.cpp Thu Jun  3 19:39:49 2010
@@ -579,6 +579,7 @@
   case ARMISD::VZIP:          return "ARMISD::VZIP";
   case ARMISD::VUZP:          return "ARMISD::VUZP";
   case ARMISD::VTRN:          return "ARMISD::VTRN";
+  case ARMISD::BUILD_VECTOR:  return "ARMISD::BUILD_VECTOR";
   case ARMISD::FMAX:          return "ARMISD::FMAX";
   case ARMISD::FMIN:          return "ARMISD::FMIN";
   }
@@ -2897,21 +2898,17 @@
     return DAG.getNode(ARMISD::VDUP, dl, VT, Value);
 
   // Vectors with 32- or 64-bit elements can be built by directly assigning
-  // the subregisters.
+  // the subregisters.  Lower it to an ARMISD::BUILD_VECTOR so the operands
+  // will be legalized.
   if (EltSize >= 32) {
     // Do the expansion with floating-point types, since that is what the VFP
     // registers are defined to use, and since i64 is not legal.
     EVT EltVT = EVT::getFloatingPointVT(EltSize);
     EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts);
-    SDValue Val = DAG.getUNDEF(VecVT);
-    for (unsigned i = 0; i < NumElts; ++i) {
-      SDValue Elt = Op.getOperand(i);
-      if (Elt.getOpcode() == ISD::UNDEF)
-        continue;
-      Elt = DAG.getNode(ISD::BIT_CONVERT, dl, EltVT, Elt);
-      Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VecVT, Val, Elt,
-                        DAG.getConstant(i, MVT::i32));
-    }
+    SmallVector<SDValue, 8> Ops;
+    for (unsigned i = 0; i < NumElts; ++i)
+      Ops.push_back(DAG.getNode(ISD::BIT_CONVERT, dl, EltVT, Op.getOperand(i)));
+    SDValue Val = DAG.getNode(ARMISD::BUILD_VECTOR, dl, VecVT, &Ops[0],NumElts);
     return DAG.getNode(ISD::BIT_CONVERT, dl, VT, Val);
   }
 
@@ -3122,7 +3119,7 @@
       return GeneratePerfectShuffle(PFEntry, V1, V2, DAG, dl);
   }
 
-  // Implement shuffles with 32- or 64-bit elements as subreg copies.
+  // Implement shuffles with 32- or 64-bit elements as ARMISD::BUILD_VECTORs.
   unsigned EltSize = VT.getVectorElementType().getSizeInBits();
   if (EltSize >= 32) {
     // Do the expansion with floating-point types, since that is what the VFP
@@ -3131,17 +3128,17 @@
     EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts);
     V1 = DAG.getNode(ISD::BIT_CONVERT, dl, VecVT, V1);
     V2 = DAG.getNode(ISD::BIT_CONVERT, dl, VecVT, V2);
-    SDValue Val = DAG.getUNDEF(VecVT);
+    SmallVector<SDValue, 8> Ops;
     for (unsigned i = 0; i < NumElts; ++i) {
       if (ShuffleMask[i] < 0)
-        continue;
-      SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT,
-                                ShuffleMask[i] < (int)NumElts ? V1 : V2,
-                                DAG.getConstant(ShuffleMask[i] & (NumElts-1),
-                                                MVT::i32));
-      Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VecVT, Val,
-                        Elt, DAG.getConstant(i, MVT::i32));
+        Ops.push_back(DAG.getUNDEF(EltVT));
+      else
+        Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT,
+                                  ShuffleMask[i] < (int)NumElts ? V1 : V2,
+                                  DAG.getConstant(ShuffleMask[i] & (NumElts-1),
+                                                  MVT::i32)));
     }
+    SDValue Val = DAG.getNode(ARMISD::BUILD_VECTOR, dl, VecVT, &Ops[0],NumElts);
     return DAG.getNode(ISD::BIT_CONVERT, dl, VT, Val);
   }
 

Modified: llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelLowering.h?rev=105446&r1=105445&r2=105446&view=diff
==============================================================================
--- llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelLowering.h (original)
+++ llvm/branches/Apple/Troughton/lib/Target/ARM/ARMISelLowering.h Thu Jun  3 19:39:49 2010
@@ -133,6 +133,13 @@
       VUZP,         // unzip (deinterleave)
       VTRN,         // transpose
 
+      // Operands of the standard BUILD_VECTOR node are not legalized, which
+      // is fine if BUILD_VECTORs are always lowered to shuffles or other
+      // operations, but for ARM some BUILD_VECTORs are legal as-is and their
+      // operands need to be legalized.  Define an ARM-specific version of
+      // BUILD_VECTOR for this purpose.
+      BUILD_VECTOR,
+
       // Floating-point max and min:
       FMAX,
       FMIN





More information about the llvm-branch-commits mailing list