[ShrinkWrap] Add a target hook to check whether or not
authorQuentin Colombet <qcolombet@apple.com>
Wed, 27 May 2015 06:25:48 +0000 (06:25 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Wed, 27 May 2015 06:25:48 +0000 (06:25 +0000)
the target can handle a given basic block as prologue
or epilogue.

Related to <rdar://problem/20821487>

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

include/llvm/Target/TargetFrameLowering.h
lib/CodeGen/ShrinkWrap.cpp

index 25d43c82cd74e7de00c5ce2ece60020255da73db..0e317247a59f26f73dc6eb2159a359ca9d1d0cf1 100644 (file)
@@ -257,6 +257,30 @@ public:
     llvm_unreachable("Call Frame Pseudo Instructions do not exist on this "
                      "target!");
   }
+
+  /// Check whether or not the given \p MBB can be used as a prologue
+  /// for the target.
+  /// The prologue will be inserted first in this basic block.
+  /// This method is used by the shrink-wrapping pass to decide if
+  /// \p MBB will be correctly handled by the target.
+  /// As soon as the target enable shrink-wrapping without overriding
+  /// this method, we assume that each basic block is a valid
+  /// prologue.
+  virtual bool canUseAsPrologue(const MachineBasicBlock &MBB) const {
+    return true;
+  }
+
+  /// Check whether or not the given \p MBB can be used as a epilogue
+  /// for the target.
+  /// The epilogue will be inserted before the first terminator of that block.
+  /// This method is used by the shrink-wrapping pass to decide if
+  /// \p MBB will be correctly handled by the target.
+  /// As soon as the target enable shrink-wrapping without overriding
+  /// this method, we assume that each basic block is a valid
+  /// epilogue.
+  virtual bool canUseAsEpilogue(const MachineBasicBlock &MBB) const {
+    return true;
+  }
 };
 
 } // End llvm namespace
index e1869b3034301ee721b7b03ab3b2dca1f76274c3..4463cc7d3c51281dfcdebee9032144cb208237c4 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.
@@ -338,6 +340,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 +348,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;