Hoist back-copies to the least busy dominator.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 14 Sep 2011 16:45:39 +0000 (16:45 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 14 Sep 2011 16:45:39 +0000 (16:45 +0000)
When a back-copy is hoisted to the nearest common dominator, keep
looking up the dominator tree for a less loopy dominator, and place the
back-copy there instead.

Don't do this when a single existing back-copy dominates all the others.
Assume the client knows what he is doing, and keep the dominating
back-copy.

This prevents us from hoisting back-copies into loops in most cases.  If
a value is defined in a loop with multiple exits, we may still hoist
back-copies into that loop.  That is the speed/size tradeoff.

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

lib/CodeGen/SplitKit.cpp
lib/CodeGen/SplitKit.h

index 149def33bdcb6ced70738ccee4f5282b144d67a5..5f7fdccfb6a054c6b8c66c312a24f9fdf33f2947 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
 #include "llvm/CodeGen/MachineDominators.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineLoopInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
@@ -635,6 +636,60 @@ void SplitEditor::removeBackCopies(SmallVectorImpl<VNInfo*> &Copies) {
   }
 }
 
+MachineBasicBlock*
+SplitEditor::findShallowDominator(MachineBasicBlock *MBB,
+                                  MachineBasicBlock *DefMBB) {
+  if (MBB == DefMBB)
+    return MBB;
+  assert(MDT.dominates(DefMBB, MBB) && "MBB must be dominated by the def.");
+
+  const MachineLoopInfo &Loops = SA.Loops;
+  const MachineLoop *DefLoop = Loops.getLoopFor(DefMBB);
+  MachineDomTreeNode *DefDomNode = MDT[DefMBB];
+
+  // Best candidate so far.
+  MachineBasicBlock *BestMBB = MBB;
+  unsigned BestDepth = UINT_MAX;
+
+  for (;;) {
+    const MachineLoop *Loop = Loops.getLoopFor(MBB);
+
+    // MBB isn't in a loop, it doesn't get any better.  All dominators have a
+    // higher frequency by definition.
+    if (!Loop) {
+      DEBUG(dbgs() << "Def in BB#" << DefMBB->getNumber() << " dominates BB#"
+                   << MBB->getNumber() << " at depth 0\n");
+      return MBB;
+    }
+
+    // We'll never be able to exit the DefLoop.
+    if (Loop == DefLoop) {
+      DEBUG(dbgs() << "Def in BB#" << DefMBB->getNumber() << " dominates BB#"
+                   << MBB->getNumber() << " in the same loop\n");
+      return MBB;
+    }
+
+    // Least busy dominator seen so far.
+    unsigned Depth = Loop->getLoopDepth();
+    if (Depth < BestDepth) {
+      BestMBB = MBB;
+      BestDepth = Depth;
+      DEBUG(dbgs() << "Def in BB#" << DefMBB->getNumber() << " dominates BB#"
+                   << MBB->getNumber() << " at depth " << Depth << '\n');
+    }
+
+    // Leave loop by going to the immediate dominator of the loop header.
+    // This is a bigger stride than simply walking up the dominator tree.
+    MachineDomTreeNode *IDom = MDT[Loop->getHeader()]->getIDom();
+
+    // Too far up the dominator tree?
+    if (!IDom || !MDT.dominates(DefDomNode, IDom))
+      return BestMBB;
+
+    MBB = IDom->getBlock();
+  }
+}
+
 void SplitEditor::hoistCopiesForSize() {
   // Get the complement interval, always RegIdx 0.
   LiveInterval *LI = Edit->get(0);
@@ -706,10 +761,14 @@ void SplitEditor::hoistCopiesForSize() {
     DomPair &Dom = NearestDom[i];
     if (!Dom.first || Dom.second.isValid())
       continue;
-    // This value needs a hoisted copy inserted at the end of Dom.second.
+    // This value needs a hoisted copy inserted at the end of Dom.first.
+    VNInfo *ParentVNI = Parent->getValNumInfo(i);
+    MachineBasicBlock *DefMBB = LIS.getMBBFromIndex(ParentVNI->def);
+    // Get a less loopy dominator than Dom.first.
+    Dom.first = findShallowDominator(Dom.first, DefMBB);
     SlotIndex Last = LIS.getMBBEndIdx(Dom.first).getPrevSlot();
     Dom.second =
-      defFromParent(0, Parent->getValNumInfo(i), Last, *Dom.first,
+      defFromParent(0, ParentVNI, Last, *Dom.first,
                     LIS.getLastSplitPoint(Edit->getParent(), Dom.first))->def;
   }
 
index 5a294e505541b10725615d563e8b9cb32532a095..d8fc2122a3c7545d28a3b3cfe5b3ab20072ae095 100644 (file)
@@ -315,6 +315,11 @@ private:
   /// in the vector in the complement interval.
   void removeBackCopies(SmallVectorImpl<VNInfo*> &Copies);
 
+  /// getShallowDominator - Returns the least busy dominator of MBB that is
+  /// also dominated by DefMBB.  Busy is measured by loop depth.
+  MachineBasicBlock *findShallowDominator(MachineBasicBlock *MBB,
+                                          MachineBasicBlock *DefMBB);
+
   /// hoistCopiesForSize - Hoist back-copies to the complement interval in a
   /// way that minimizes code size. This implements the SM_Size spill mode.
   void hoistCopiesForSize();