[LVI] Improve LazyValueInfo compile time performance
[oota-llvm.git] / lib / CodeGen / ShrinkWrap.cpp
index e1869b3034301ee721b7b03ab3b2dca1f76274c3..8af859f6bc7bf3e25304e346a28ab43336c8f6ca 100644 (file)
@@ -62,6 +62,8 @@
 // To know about callee-saved.
 #include "llvm/CodeGen/RegisterClassInfo.h"
 #include "llvm/Support/Debug.h"
+// To query the target about frame lowering.
+#include "llvm/Target/TargetFrameLowering.h"
 // To know about frame setup operation.
 #include "llvm/Target/TargetInstrInfo.h"
 // To access TargetInstrInfo.
@@ -288,12 +290,30 @@ void ShrinkWrap::updateSaveRestorePoints(MachineBasicBlock &MBB) {
     // Fix (C).
     if (Save && Restore && Save != Restore &&
         MLI->getLoopFor(Save) != MLI->getLoopFor(Restore)) {
-      if (MLI->getLoopDepth(Save) > MLI->getLoopDepth(Restore))
-        // Push Save outside of this loop.
-        Save = FindIDom<>(*Save, Save->predecessors(), *MDT);
-      else
-        // Push Restore outside of this loop.
-        Restore = FindIDom<>(*Restore, Restore->successors(), *MPDT);
+      if (MLI->getLoopDepth(Save) > MLI->getLoopDepth(Restore)) {
+        // Push Save outside of this loop if immediate dominator is different
+        // from save block. If immediate dominator is not different, bail out. 
+        MachineBasicBlock *IDom = FindIDom<>(*Save, Save->predecessors(), *MDT);
+        if (IDom != Save)
+          Save = IDom;
+        else {
+          Save = nullptr;
+          break;
+        }
+      }
+      else {
+        // Push Restore outside of this loop if immediate post-dominator is
+        // different from restore block. If immediate post-dominator is not
+        // different, bail out. 
+        MachineBasicBlock *IPdom =
+          FindIDom<>(*Restore, Restore->successors(), *MPDT);
+        if (IPdom != Restore)
+          Restore = IPdom; 
+        else {
+          Restore = nullptr;
+          break;
+        }
+      }      
     }
   }
 }
@@ -338,6 +358,7 @@ bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) {
   DEBUG(dbgs() << "\n ** Results **\nFrequency of the Entry: " << EntryFreq
                << '\n');
 
+  const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
   do {
     DEBUG(dbgs() << "Shrink wrap candidates (#, Name, Freq):\nSave: "
                  << Save->getNumber() << ' ' << Save->getName() << ' '
@@ -345,13 +366,15 @@ bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) {
                  << Restore->getNumber() << ' ' << Restore->getName() << ' '
                  << MBFI->getBlockFreq(Restore).getFrequency() << '\n');
 
-    bool IsSaveCheap;
-    if ((IsSaveCheap = EntryFreq >= MBFI->getBlockFreq(Save).getFrequency()) &&
-        EntryFreq >= MBFI->getBlockFreq(Restore).getFrequency())
+    bool IsSaveCheap, TargetCanUseSaveAsPrologue = false;
+    if (((IsSaveCheap = EntryFreq >= MBFI->getBlockFreq(Save).getFrequency()) &&
+         EntryFreq >= MBFI->getBlockFreq(Restore).getFrequency()) &&
+        ((TargetCanUseSaveAsPrologue = TFI->canUseAsPrologue(*Save)) &&
+         TFI->canUseAsEpilogue(*Restore)))
       break;
-    DEBUG(dbgs() << "New points are too expensive\n");
+    DEBUG(dbgs() << "New points are too expensive or invalid for the target\n");
     MachineBasicBlock *NewBB;
-    if (!IsSaveCheap) {
+    if (!IsSaveCheap || !TargetCanUseSaveAsPrologue) {
       Save = FindIDom<>(*Save, Save->predecessors(), *MDT);
       if (!Save)
         break;