[MachineOutliner][NFC] Change getMachineOutlinerMBBFlags to isMBBSafeToOutlineFrom
authorJessica Paquette <jpaquette@apple.com>
Mon, 12 Nov 2018 23:51:32 +0000 (23:51 +0000)
committerJessica Paquette <jpaquette@apple.com>
Mon, 12 Nov 2018 23:51:32 +0000 (23:51 +0000)
Instead of returning Flags, return true if the MBB is safe to outline from.

This lets us check for unsafe situations, like say, in AArch64, X17 is live
across a MBB without being defined in that MBB. In that case, there's no point
in performing an instruction mapping.

llvm-svn: 346718

llvm/include/llvm/CodeGen/TargetInstrInfo.h
llvm/lib/CodeGen/MachineOutliner.cpp
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
llvm/lib/Target/AArch64/AArch64InstrInfo.h

index 1fa3de4..39146b5 100644 (file)
@@ -1635,10 +1635,11 @@ public:
         "Target didn't implement TargetInstrInfo::getOutliningType!");
   }
 
-  /// Returns target-defined flags defining properties of the MBB for
-  /// the outliner.
-  virtual unsigned getMachineOutlinerMBBFlags(MachineBasicBlock &MBB) const {
-    return 0x0;
+  /// Optional target hook that returns true if \p MBB is safe to outline from,
+  /// and returns any target-specific information in \p Flags.
+  virtual bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,
+                                      unsigned &Flags) const {
+    return true;
   }
 
   /// Insert a custom frame for outlined functions.
index 143310e..e6f3066 100644 (file)
@@ -742,7 +742,12 @@ struct InstructionMapper {
   /// \param TII \p TargetInstrInfo for the function.
   void convertToUnsignedVec(MachineBasicBlock &MBB,
                             const TargetInstrInfo &TII) {
-    unsigned Flags = TII.getMachineOutlinerMBBFlags(MBB);
+    unsigned Flags;
+
+    // Don't even map in this case.
+    if (!TII.isMBBSafeToOutlineFrom(MBB, Flags))
+      return;
+
     MachineBasicBlock::iterator It = MBB.begin();
 
     // The number of instructions in this block that will be considered for
index bcf278e..71cbffd 100644 (file)
@@ -5286,29 +5286,44 @@ bool AArch64InstrInfo::isFunctionSafeToOutlineFrom(
   return true;
 }
 
-unsigned
-AArch64InstrInfo::getMachineOutlinerMBBFlags(MachineBasicBlock &MBB) const {
-  unsigned Flags = 0x0;
-  // Check if there's a call inside this MachineBasicBlock. If there is, then
-  // set a flag.
-  if (any_of(MBB, [](MachineInstr &MI) { return MI.isCall(); }))
-    Flags |= MachineOutlinerMBBFlags::HasCalls;
-
+bool AArch64InstrInfo::isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,
+                                              unsigned &Flags) const {
   // Check if LR is available through all of the MBB. If it's not, then set
   // a flag.
   assert(MBB.getParent()->getRegInfo().tracksLiveness() &&
          "Suitable Machine Function for outlining must track liveness");
-  LiveRegUnits LRU(getRegisterInfo());
-  LRU.addLiveOuts(MBB);
+  LiveRegUnits ModifiedRegUnits(getRegisterInfo());
+  LiveRegUnits UsedRegUnits(getRegisterInfo());
+  ModifiedRegUnits.addLiveOuts(MBB);
+  UsedRegUnits.addLiveOuts(MBB);
+  const TargetRegisterInfo *TRI = &getRegisterInfo();
 
-  std::for_each(MBB.rbegin(),
-                MBB.rend(),
-                [&LRU](MachineInstr &MI) { LRU.accumulate(MI); });
+  std::for_each(MBB.rbegin(), MBB.rend(),
+                [&ModifiedRegUnits, &UsedRegUnits, &TRI](MachineInstr &MI) {
+                  LiveRegUnits::accumulateUsedDefed(MI, ModifiedRegUnits,
+                                                    UsedRegUnits, TRI);
+                });
+
+  // If one of these registers is live out of the MBB, but not modified in the
+  // MBB, then we can't outline.
+  if ((ModifiedRegUnits.available(AArch64::W16) &&
+       !UsedRegUnits.available(AArch64::W16)) ||
+      (ModifiedRegUnits.available(AArch64::W17) &&
+       !UsedRegUnits.available(AArch64::W17)) ||
+      (ModifiedRegUnits.available(AArch64::NZCV) &&
+       !UsedRegUnits.available(AArch64::NZCV)))
+    return false;
 
-  if (!LRU.available(AArch64::LR))
-      Flags |= MachineOutlinerMBBFlags::LRUnavailableSomewhere;
+  // Check if there's a call inside this MachineBasicBlock. If there is, then
+  // set a flag.
+  if (any_of(MBB, [](MachineInstr &MI) { return MI.isCall(); }))
+    Flags |= MachineOutlinerMBBFlags::HasCalls;
+
+  if (!ModifiedRegUnits.available(AArch64::LR) ||
+      !UsedRegUnits.available(AArch64::LR))
+    Flags |= MachineOutlinerMBBFlags::LRUnavailableSomewhere;
 
-  return Flags;
+  return true;
 }
 
 outliner::InstrType
index 43011dd..404d632 100644 (file)
@@ -246,7 +246,8 @@ public:
       std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override;
   outliner::InstrType
   getOutliningType(MachineBasicBlock::iterator &MIT, unsigned Flags) const override;
-  unsigned getMachineOutlinerMBBFlags(MachineBasicBlock &MBB) const override;
+  bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,
+                              unsigned &Flags) const override;
   void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF,
                           const outliner::OutlinedFunction &OF) const override;
   MachineBasicBlock::iterator