[llvm-commits] [llvm] r141619 - in /llvm/trunk/lib/Target/ARM: ARMBaseInstrInfo.cpp ARMBaseInstrInfo.h

Jakob Stoklund Olesen stoklund at 2pi.dk
Mon Oct 10 17:59:06 PDT 2011


Author: stoklund
Date: Mon Oct 10 19:59:06 2011
New Revision: 141619

URL: http://llvm.org/viewvc/llvm-project?rev=141619&view=rev
Log:
Move -widen-vmovs to ARMBaseInstrInfo::expandPostRAPseudo().

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.

Modified:
    llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp
    llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h

Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=141619&r1=141618&r2=141619&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Mon Oct 10 19:59:06 2011
@@ -640,37 +640,9 @@
   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 @@
   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,

Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=141619&r1=141618&r2=141619&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Mon Oct 10 19:59:06 2011
@@ -123,6 +123,8 @@
                                     const TargetRegisterClass *RC,
                                     const TargetRegisterInfo *TRI) const;
 
+  virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const;
+
   virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF,
                                                  int FrameIx,
                                                  uint64_t Offset,





More information about the llvm-commits mailing list