[llvm-commits] [llvm] r146583 - in /llvm/trunk: include/llvm/Target/TargetInstrInfo.h lib/CodeGen/ScheduleDAGInstrs.cpp lib/Target/ARM/ARMBaseInstrInfo.cpp lib/Target/ARM/ARMBaseInstrInfo.h

Evan Cheng evan.cheng at apple.com
Wed Dec 14 12:00:09 PST 2011


Author: evancheng
Date: Wed Dec 14 14:00:08 2011
New Revision: 146583

URL: http://llvm.org/viewvc/llvm-project?rev=146583&view=rev
Log:
Model ARM predicated write as read-mod-write. e.g.
r0 = mov #0
r0 = moveq #1

Then the second instruction has an implicit data dependency on the first
instruction. Sadly I have yet to come up with a small test case that
demonstrate the post-ra scheduler taking advantage of this.

Modified:
    llvm/trunk/include/llvm/Target/TargetInstrInfo.h
    llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp
    llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp
    llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h

Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=146583&r1=146582&r2=146583&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Wed Dec 14 14:00:08 2011
@@ -652,9 +652,8 @@
   /// a given pair of defs which both target the same register. This is usually
   /// one.
   virtual unsigned getOutputLatency(const InstrItineraryData *ItinData,
-                                    const MachineInstr *DefMI1,
-                                    const MachineInstr *DefMI2,
-                                    unsigned Reg) const {
+                                    const MachineInstr *DefMI, unsigned DefIdx,
+                                    const MachineInstr *DepMI) const {
     return 1;
   }
 

Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=146583&r1=146582&r2=146583&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original)
+++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Wed Dec 14 14:00:08 2011
@@ -281,8 +281,8 @@
           if (Kind == SDep::Anti)
             DefSU->addPred(SDep(SU, Kind, 0, /*Reg=*/Reg));
           else {
-            unsigned AOLat = TII->getOutputLatency(InstrItins, MI,
-                                                   DefSU->getInstr(), Reg);
+            unsigned AOLat = TII->getOutputLatency(InstrItins, MI, j,
+                                                   DefSU->getInstr());
             DefSU->addPred(SDep(SU, Kind, AOLat, /*Reg=*/Reg));
           }
         }

Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=146583&r1=146582&r2=146583&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Wed Dec 14 14:00:08 2011
@@ -2360,7 +2360,7 @@
 }
 
 static const MachineInstr *getBundledDefMI(const TargetRegisterInfo *TRI,
-                                           const MachineInstr *MI,
+                                           const MachineInstr *MI, unsigned Reg,
                                            unsigned &DefIdx, unsigned &Dist) {
   Dist = 0;
 
@@ -2370,7 +2370,6 @@
   assert(II->isInsideBundle() && "Empty bundle?");
 
   int Idx = -1;
-  unsigned Reg = MI->getOperand(DefIdx).getReg();
   while (II->isInsideBundle()) {
     Idx = II->findRegisterDefOperandIdx(Reg, false, true, TRI);
     if (Idx != -1)
@@ -2385,7 +2384,7 @@
 }
 
 static const MachineInstr *getBundledUseMI(const TargetRegisterInfo *TRI,
-                                           const MachineInstr *MI,
+                                           const MachineInstr *MI, unsigned Reg,
                                            unsigned &UseIdx, unsigned &Dist) {
   Dist = 0;
 
@@ -2395,7 +2394,6 @@
 
   // FIXME: This doesn't properly handle multiple uses.
   int Idx = -1;
-  unsigned Reg = MI->getOperand(UseIdx).getReg();
   while (II != E && II->isInsideBundle()) {
     Idx = II->findRegisterUseOperandIdx(Reg, false, TRI);
     if (Idx != -1)
@@ -2405,7 +2403,11 @@
     ++II;
   }
 
-  assert(Idx != -1 && "Cannot find bundled definition!");
+  if (Idx == -1) {
+    Dist = 0;
+    return 0;
+  }
+
   UseIdx = Idx;
   return II;
 }
@@ -2424,7 +2426,8 @@
   const MCInstrDesc *DefMCID = &DefMI->getDesc();
   const MCInstrDesc *UseMCID = &UseMI->getDesc();
   const MachineOperand &DefMO = DefMI->getOperand(DefIdx);
-  if (DefMO.getReg() == ARM::CPSR) {
+  unsigned Reg = DefMO.getReg();
+  if (Reg == ARM::CPSR) {
     if (DefMI->getOpcode() == ARM::FMSTAT) {
       // fpscr -> cpsr stalls over 20 cycles on A8 (and earlier?)
       return Subtarget.isCortexA9() ? 1 : 20;
@@ -2436,11 +2439,16 @@
 
     // Otherwise it takes the instruction latency (generally one).
     int Latency = getInstrLatency(ItinData, DefMI);
-    // For Thumb2, prefer scheduling CPSR setting instruction close to its uses.
-    // Instructions which are otherwise scheduled between them may incur a code
-    // size penalty (not able to use the CPSR setting 16-bit instructions).
-    if (Latency > 0 && Subtarget.isThumb2())
-      --Latency;
+
+    // For Thumb2 and -Os, prefer scheduling CPSR setting instruction close to
+    // its uses. Instructions which are otherwise scheduled between them may
+    // incur a code size penalty (not able to use the CPSR setting 16-bit
+    // instructions).
+    if (Latency > 0 && Subtarget.isThumb2()) {
+      const MachineFunction *MF = DefMI->getParent()->getParent();
+      if (MF->getFunction()->hasFnAttr(Attribute::OptimizeForSize))
+        --Latency;
+    }
     return Latency;
   }
 
@@ -2451,7 +2459,7 @@
 
   unsigned DefAdj = 0;
   if (DefMI->isBundle()) {
-    DefMI = getBundledDefMI(&getRegisterInfo(), DefMI, DefIdx, DefAdj);
+    DefMI = getBundledDefMI(&getRegisterInfo(), DefMI, Reg, DefIdx, DefAdj);
     if (DefMI->isCopyLike() || DefMI->isInsertSubreg() ||
         DefMI->isRegSequence() || DefMI->isImplicitDef())
       return 1;
@@ -2459,8 +2467,14 @@
   }
   unsigned UseAdj = 0;
   if (UseMI->isBundle()) {
-    UseMI = getBundledUseMI(&getRegisterInfo(), UseMI, UseIdx, UseAdj);
-    UseMCID = &UseMI->getDesc();
+    unsigned NewUseIdx;
+    const MachineInstr *NewUseMI = getBundledUseMI(&getRegisterInfo(), UseMI,
+                                                   Reg, NewUseIdx, UseAdj);
+    if (NewUseMI) {
+      UseMI = NewUseMI;
+      UseIdx = NewUseIdx;
+      UseMCID = &UseMI->getDesc();
+    }
   }
 
   int Latency = getOperandLatency(ItinData, *DefMCID, DefIdx, DefAlign,
@@ -2797,6 +2811,19 @@
   return Latency;
 }
 
+unsigned
+ARMBaseInstrInfo::getOutputLatency(const InstrItineraryData *ItinData,
+                                   const MachineInstr *DefMI, unsigned DefIdx,
+                                   const MachineInstr *DepMI) const {
+  unsigned Reg = DefMI->getOperand(DefIdx).getReg();
+  if (DepMI->readsRegister(Reg, &getRegisterInfo()) || !isPredicated(DepMI))
+    return 1;
+
+  // If the second MI is predicated, then there is an implicit use dependency.
+  return getOperandLatency(ItinData, DefMI, DefIdx, DepMI,
+                           DepMI->getNumOperands());
+}
+
 int ARMBaseInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
                                       const MachineInstr *MI,
                                       unsigned *PredCost) const {

Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=146583&r1=146582&r2=146583&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Wed Dec 14 14:00:08 2011
@@ -210,6 +210,10 @@
                         SDNode *DefNode, unsigned DefIdx,
                         SDNode *UseNode, unsigned UseIdx) const;
 
+  virtual unsigned getOutputLatency(const InstrItineraryData *ItinData,
+                                    const MachineInstr *DefMI, unsigned DefIdx,
+                                    const MachineInstr *DepMI) const;
+
   /// VFP/NEON execution domains.
   std::pair<uint16_t, uint16_t>
   getExecutionDomain(const MachineInstr *MI) const;





More information about the llvm-commits mailing list