[llvm] r346901 - [MachineOutliner][NFC] Don't compute liveness if X16/X17/NZCV are unused

Jessica Paquette via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 14 14:23:39 PST 2018


Author: paquette
Date: Wed Nov 14 14:23:38 2018
New Revision: 346901

URL: http://llvm.org/viewvc/llvm-project?rev=346901&view=rev
Log:
[MachineOutliner][NFC] Don't compute liveness if X16/X17/NZCV are unused

Using the MBB flags, we can tell if X16/X17/NZCV are unused in a block,
and also not live out.

If this holds for all MBBs, then we can avoid checking for liveness on
that candidate. Furthermore, if it holds for an individual candidate's
MBB, then we can avoid checking for liveness on that candidate.

Modified:
    llvm/trunk/include/llvm/CodeGen/MachineOutliner.h
    llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp

Modified: llvm/trunk/include/llvm/CodeGen/MachineOutliner.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineOutliner.h?rev=346901&r1=346900&r2=346901&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineOutliner.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineOutliner.h Wed Nov 14 14:23:38 2018
@@ -85,6 +85,9 @@ public:
   /// Target-specific flags for this Candidate's MBB.
   unsigned Flags = 0x0;
 
+  /// True if initLRU has been called on this Candidate.
+  bool LRUWasSet = false;
+
   /// Return the number of instructions in this Candidate.
   unsigned getLength() const { return Len; }
 
@@ -141,6 +144,10 @@ public:
   void initLRU(const TargetRegisterInfo &TRI) {
     assert(MBB->getParent()->getRegInfo().tracksLiveness() &&
            "Candidate's Machine Function must track liveness");
+    // Only initialize once.
+    if (LRUWasSet)
+      return;
+    LRUWasSet = true;
     LRU.init(TRI);
     LRU.addLiveOuts(*MBB);
 

Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp?rev=346901&r1=346900&r2=346901&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp Wed Nov 14 14:23:38 2018
@@ -5101,11 +5101,13 @@ enum MachineOutlinerClass {
 
 enum MachineOutlinerMBBFlags {
   LRUnavailableSomewhere = 0x2,
-  HasCalls = 0x4
+  HasCalls = 0x4,
+  UnsafeRegsDead = 0x8
 };
 
 unsigned
 AArch64InstrInfo::findRegisterToSaveLRTo(const outliner::Candidate &C) const {
+  assert(C.LRUWasSet && "LRU wasn't set?");
   MachineFunction *MF = C.getMF();
   const AArch64RegisterInfo *ARI = static_cast<const AArch64RegisterInfo *>(
       MF->getSubtarget().getRegisterInfo());
@@ -5141,9 +5143,8 @@ AArch64InstrInfo::getOutliningCandidateI
   // Compute liveness information for each candidate, and set FlagsSetInAll.
   const TargetRegisterInfo &TRI = getRegisterInfo();
   std::for_each(RepeatedSequenceLocs.begin(), RepeatedSequenceLocs.end(),
-                [&TRI, &FlagsSetInAll](outliner::Candidate &C) {
+                [&FlagsSetInAll](outliner::Candidate &C) {
                   FlagsSetInAll &= C.Flags;
-                  C.initLRU(TRI);
                 });
 
   // According to the AArch64 Procedure Call Standard, the following are
@@ -5157,23 +5158,31 @@ AArch64InstrInfo::getOutliningCandidateI
   // of these registers is live into/across it. Thus, we need to delete
   // those
   // candidates.
-  auto CantGuaranteeValueAcrossCall = [](outliner::Candidate &C) {
+  auto CantGuaranteeValueAcrossCall = [&TRI](outliner::Candidate &C) {
+    // If the unsafe registers in this block are all dead, then we don't need
+    // to compute liveness here.
+    if (C.Flags & UnsafeRegsDead)
+      return false;
+    C.initLRU(TRI);
     LiveRegUnits LRU = C.LRU;
     return (!LRU.available(AArch64::W16) || !LRU.available(AArch64::W17) ||
             !LRU.available(AArch64::NZCV));
   };
 
-  // Erase every candidate that violates the restrictions above. (It could be
-  // true that we have viable candidates, so it's not worth bailing out in
-  // the case that, say, 1 out of 20 candidates violate the restructions.)
-  RepeatedSequenceLocs.erase(std::remove_if(RepeatedSequenceLocs.begin(),
-                                            RepeatedSequenceLocs.end(),
-                                            CantGuaranteeValueAcrossCall),
-                             RepeatedSequenceLocs.end());
-
-  // If the sequence doesn't have enough candidates left, then we're done.
-  if (RepeatedSequenceLocs.size() < 2)
-    return outliner::OutlinedFunction();
+  // Are there any candidates where those registers are live?
+  if (!(FlagsSetInAll & UnsafeRegsDead)) {
+    // Erase every candidate that violates the restrictions above. (It could be
+    // true that we have viable candidates, so it's not worth bailing out in
+    // the case that, say, 1 out of 20 candidates violate the restructions.)
+    RepeatedSequenceLocs.erase(std::remove_if(RepeatedSequenceLocs.begin(),
+                                              RepeatedSequenceLocs.end(),
+                                              CantGuaranteeValueAcrossCall),
+                               RepeatedSequenceLocs.end());
+
+    // If the sequence doesn't have enough candidates left, then we're done.
+    if (RepeatedSequenceLocs.size() < 2)
+      return outliner::OutlinedFunction();
+  }
 
   // At this point, we have only "safe" candidates to outline. Figure out
   // frame + call instruction information.
@@ -5216,7 +5225,8 @@ AArch64InstrInfo::getOutliningCandidateI
   // to (or exit from) some candidate.
   else if (std::all_of(RepeatedSequenceLocs.begin(),
                        RepeatedSequenceLocs.end(),
-                       [](outliner::Candidate &C) {
+                       [&TRI](outliner::Candidate &C) {
+                         C.initLRU(TRI);
                          return C.LRU.available(AArch64::LR);
                          })) {
     FrameID = MachineOutlinerNoLRSave;
@@ -5227,7 +5237,8 @@ AArch64InstrInfo::getOutliningCandidateI
   // LR is live, so we need to save it. Decide whether it should be saved to
   // the stack, or if it can be saved to a register.
   else {
-    if (all_of(RepeatedSequenceLocs, [this](outliner::Candidate &C) {
+    if (all_of(RepeatedSequenceLocs, [this, &TRI](outliner::Candidate &C) {
+          C.initLRU(TRI);
           return findRegisterToSaveLRTo(C);
         })) {
       // Every candidate has an available callee-saved register for the save.
@@ -5311,6 +5322,11 @@ bool AArch64InstrInfo::isMBBSafeToOutlin
   bool W17AvailableInBlock = LRU.available(AArch64::W17);
   bool NZCVAvailableInBlock = LRU.available(AArch64::NZCV);
 
+  // If all of these are dead (and not live out), we know we don't have to check
+  // them later.
+  if (W16AvailableInBlock && W17AvailableInBlock && NZCVAvailableInBlock)
+    Flags |= MachineOutlinerMBBFlags::UnsafeRegsDead;
+
   // Now, add the live outs to the set.
   LRU.addLiveOuts(MBB);
 




More information about the llvm-commits mailing list