Move -widen-vmovs to ARMBaseInstrInfo::expandPostRAPseudo().
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 11 Oct 2011 00:59:06 +0000 (00:59 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 11 Oct 2011 00:59:06 +0000 (00:59 +0000)
The VMOVS widening needs to look at the implicit COPY operands.  Trying
to dig out the COPY instruction from an iterator in copyPhysReg() is the
wrong approach.

The expandPostRAPseudo() hook gets to look at COPY instructions before
they are converted to copyPhysReg() calls.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141619 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMBaseInstrInfo.cpp
lib/Target/ARM/ARMBaseInstrInfo.h

index e4f4ab1a2a91fee607a0c00961adbc290e6072dc..a696e1641f2791fc62f8e319f90babfe1d9bc80c 100644 (file)
@@ -640,37 +640,9 @@ void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
   bool SPRSrc  = ARM::SPRRegClass.contains(SrcReg);
 
   unsigned Opc = 0;
-  if (SPRDest && SPRSrc) {
+  if (SPRDest && SPRSrc)
     Opc = ARM::VMOVS;
-
-    // An even S-S copy may be feeding a NEON v2f32 instruction being used for
-    // f32 operations.  In that case, it is better to copy the full D-regs with
-    // a VMOVD since that can be converted to a NEON-domain move by
-    // NEONMoveFix.cpp.  Check that MI is the original COPY instruction, and
-    // that it really defines the whole D-register.
-    if (WidenVMOVS &&
-        (DestReg - ARM::S0) % 2 == 0 && (SrcReg - ARM::S0) % 2 == 0 &&
-        I != MBB.end() && I->isCopy() &&
-        I->getOperand(0).getReg() == DestReg &&
-        I->getOperand(1).getReg() == SrcReg) {
-      // I is pointing to the ortiginal COPY instruction.
-      // Find the parent D-registers.
-      const TargetRegisterInfo *TRI = &getRegisterInfo();
-      unsigned SrcD = TRI->getMatchingSuperReg(SrcReg, ARM::ssub_0,
-                                               &ARM::DPRRegClass);
-      unsigned DestD = TRI->getMatchingSuperReg(DestReg, ARM::ssub_0,
-                                                &ARM::DPRRegClass);
-      // Be careful to not clobber an INSERT_SUBREG that reads and redefines a
-      // D-register.  There must be an <imp-def> of destD, and no <imp-use>.
-      if (I->definesRegister(DestD, TRI) && !I->readsRegister(DestD, TRI)) {
-        Opc = ARM::VMOVD;
-        SrcReg = SrcD;
-        DestReg = DestD;
-        if (KillSrc)
-          KillSrc = I->killsRegister(SrcReg, TRI);
-      }
-    }
-  } else if (GPRDest && SPRSrc)
+  else if (GPRDest && SPRSrc)
     Opc = ARM::VMOVRS;
   else if (SPRDest && GPRSrc)
     Opc = ARM::VMOVSR;
@@ -1024,6 +996,46 @@ unsigned ARMBaseInstrInfo::isLoadFromStackSlotPostFE(const MachineInstr *MI,
   return MI->getDesc().mayLoad() && hasLoadFromStackSlot(MI, Dummy, FrameIndex);
 }
 
+bool ARMBaseInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const{
+  // This hook gets to expand COPY instructions before they become
+  // copyPhysReg() calls.  Look for VMOVS instructions that can legally be
+  // widened to VMOVD.  We prefer the VMOVD when possible because it may be
+  // changed into a VORR that can go down the NEON pipeline.
+  if (!WidenVMOVS || !MI->isCopy())
+    return false;
+
+  // Look for a copy between even S-registers.  That is where we keep floats
+  // when using NEON v2f32 instructions for f32 arithmetic.
+  unsigned DstRegS = MI->getOperand(0).getReg();
+  unsigned SrcRegS = MI->getOperand(1).getReg();
+  if (!ARM::SPRRegClass.contains(DstRegS, SrcRegS))
+    return false;
+
+  const TargetRegisterInfo *TRI = &getRegisterInfo();
+  unsigned DstRegD = TRI->getMatchingSuperReg(DstRegS, ARM::ssub_0,
+                                              &ARM::DPRRegClass);
+  unsigned SrcRegD = TRI->getMatchingSuperReg(SrcRegS, ARM::ssub_0,
+                                              &ARM::DPRRegClass);
+  if (!DstRegD || !SrcRegD)
+    return false;
+
+  // We want to widen this into a DstRegD = VMOVD SrcRegD copy.  This is only
+  // legal if the COPY already defines the full DstRegD, and it isn't a
+  // sub-register insertion.
+  if (!MI->definesRegister(DstRegD, TRI) || MI->readsRegister(DstRegD, TRI))
+    return false;
+
+  // All clear, widen the COPY.  Preserve the implicit operands, even if they
+  // may be superfluous now.
+  DEBUG(dbgs() << "widening:    " << *MI);
+  MI->setDesc(get(ARM::VMOVD));
+  MI->getOperand(0).setReg(DstRegD);
+  MI->getOperand(1).setReg(SrcRegD);
+  AddDefaultPred(MachineInstrBuilder(MI));
+  DEBUG(dbgs() << "replaced by: " << *MI);
+  return true;
+}
+
 MachineInstr*
 ARMBaseInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF,
                                            int FrameIx, uint64_t Offset,
index 30dd6973fdae560d17a49c93ed7919ed4b260069..0f9f32179a310b676823e97ad66a8bfcf1e460a5 100644 (file)
@@ -123,6 +123,8 @@ public:
                                     const TargetRegisterClass *RC,
                                     const TargetRegisterInfo *TRI) const;
 
+  virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const;
+
   virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF,
                                                  int FrameIx,
                                                  uint64_t Offset,