[llvm-commits] [llvm] r103437 - in /llvm/trunk/lib/Target/ARM: ARMISelDAGToDAG.cpp NEONPreAllocPass.cpp

Evan Cheng evan.cheng at apple.com
Mon May 10 14:26:25 PDT 2010


Author: evancheng
Date: Mon May 10 16:26:24 2010
New Revision: 103437

URL: http://llvm.org/viewvc/llvm-project?rev=103437&view=rev
Log:
Model some vld3 instructions with REG_SEQUENCE.

Modified:
    llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
    llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=103437&r1=103436&r2=103437&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Mon May 10 16:26:24 2010
@@ -1044,7 +1044,40 @@
     const SDValue Ops[] = { MemAddr, Align, Pred, Reg0, Chain };
     std::vector<EVT> ResTys(NumVecs, VT);
     ResTys.push_back(MVT::Other);
-    return CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5);
+    SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5);
+    if (!llvm::ModelWithRegSequence() || NumVecs < 2)
+      return VLd;
+
+    assert(NumVecs <= 4);
+    SDValue V0 = SDValue(VLd, 0);
+    SDValue V1 = SDValue(VLd, 1);
+    SDValue RegSeq;
+
+    if (NumVecs == 2)
+      RegSeq = SDValue(PairDRegs(MVT::v2i64, V0, V1), 0);
+    else {
+      SDValue V2 = SDValue(VLd, 2);
+      SDValue V3 = (NumVecs == 3)
+          ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0)
+          : SDValue(VLd, 3);
+      RegSeq = SDValue(QuadDRegs(MVT::v4i64, V0, V1, V2, V3), 0);
+    }
+
+    SDValue D0 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, VT, RegSeq);
+    ReplaceUses(SDValue(N, 0), D0);
+    SDValue D1 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, VT, RegSeq);
+    ReplaceUses(SDValue(N, 1), D1);
+
+    if (NumVecs > 2) {
+      SDValue D2 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_2, dl, VT, RegSeq);
+      ReplaceUses(SDValue(N, 2), D2);
+    }
+    if (NumVecs > 3) {
+      SDValue D3 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_3, dl, VT, RegSeq);
+      ReplaceUses(SDValue(N, 3), D3);
+    }
+    ReplaceUses(SDValue(N, NumVecs), SDValue(VLd, NumVecs));
+    return NULL;
   }
 
   EVT RegVT = GetNEONSubregVT(VT);

Modified: llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp?rev=103437&r1=103436&r2=103437&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp (original)
+++ llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp Mon May 10 16:26:24 2010
@@ -33,7 +33,7 @@
 
   private:
     bool FormsRegSequence(MachineInstr *MI,
-                          unsigned FirstOpnd, unsigned NumRegs);
+                          unsigned FirstOpnd, unsigned NumRegs) const;
     bool PreAllocNEONRegisters(MachineBasicBlock &MBB);
   };
 
@@ -338,18 +338,22 @@
   return false;
 }
 
-bool NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
-                                        unsigned FirstOpnd, unsigned NumRegs) {
-  MachineInstr *RegSeq = 0;
-  unsigned LastSrcReg = 0;
-  unsigned LastSubIdx = 0;
-  for (unsigned R = 0; R < NumRegs; ++R) {
-    MachineOperand &MO = MI->getOperand(FirstOpnd + R);
-    assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
-    unsigned VirtReg = MO.getReg();
-    assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
-           "expected a virtual register");
-    if (MO.isDef()) {
+bool
+NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
+                                   unsigned FirstOpnd, unsigned NumRegs) const {
+  MachineOperand &FMO = MI->getOperand(FirstOpnd);
+  assert(FMO.isReg() && FMO.getSubReg() == 0 && "unexpected operand");
+  unsigned VirtReg = FMO.getReg();
+  assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
+         "expected a virtual register");
+  if (FMO.isDef()) {
+    MachineInstr *RegSeq = 0;
+    for (unsigned R = 0; R < NumRegs; ++R) {
+      const MachineOperand &MO = MI->getOperand(FirstOpnd + R);
+      assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
+      unsigned VirtReg = MO.getReg();
+      assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
+             "expected a virtual register");
       // Feeding into a REG_SEQUENCE.
       if (!MRI->hasOneNonDBGUse(VirtReg))
         return false;
@@ -359,25 +363,45 @@
       if (RegSeq && RegSeq != UseMI)
         return false;
       RegSeq = UseMI;
-    } else {
-      // Extracting from a Q or QQ register.
+    }
+
+    // Make sure trailing operands of REG_SEQUENCE are undef.
+    unsigned NumExps = (RegSeq->getNumOperands() - 1) / 2;
+    for (unsigned i = NumRegs * 2 + 1; i < NumExps; i += 2) {
+      const MachineOperand &MO = RegSeq->getOperand(i);
+      unsigned VirtReg = MO.getReg();
       MachineInstr *DefMI = MRI->getVRegDef(VirtReg);
-      if (!DefMI || !DefMI->isExtractSubreg())
-        return false;
-      VirtReg = DefMI->getOperand(1).getReg();
-      if (LastSrcReg && LastSrcReg != VirtReg)
+      if (!DefMI || !DefMI->isImplicitDef())
         return false;
-      const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
-      if (NumRegs == 2) {
-        if (RC != ARM::QPRRegisterClass)
-          return false;
-      } else if (RC != ARM::QQPRRegisterClass)
-          return false;
-      unsigned SubIdx = DefMI->getOperand(2).getImm();
-      if (LastSubIdx && LastSubIdx != SubIdx-1)
-        return false;
-      LastSubIdx = SubIdx;
     }
+    return true;
+  }
+
+  unsigned LastSrcReg = 0;
+  unsigned LastSubIdx = 0;
+  for (unsigned R = 0; R < NumRegs; ++R) {
+    const MachineOperand &MO = MI->getOperand(FirstOpnd + R);
+    assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
+    unsigned VirtReg = MO.getReg();
+    assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
+           "expected a virtual register");
+    // Extracting from a Q or QQ register.
+    MachineInstr *DefMI = MRI->getVRegDef(VirtReg);
+    if (!DefMI || !DefMI->isExtractSubreg())
+      return false;
+    VirtReg = DefMI->getOperand(1).getReg();
+    if (LastSrcReg && LastSrcReg != VirtReg)
+      return false;
+    const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
+    if (NumRegs == 2) {
+      if (RC != ARM::QPRRegisterClass)
+        return false;
+    } else if (RC != ARM::QQPRRegisterClass)
+      return false;
+    unsigned SubIdx = DefMI->getOperand(2).getImm();
+    if (LastSubIdx && LastSubIdx != SubIdx-1)
+      return false;
+    LastSubIdx = SubIdx;
   }
   return true;
 }





More information about the llvm-commits mailing list