[llvm] r313268 - [IfConversion] More simple, correct dead/kill liveness handling

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 14 08:53:11 PDT 2017


Author: kparzysz
Date: Thu Sep 14 08:53:11 2017
New Revision: 313268

URL: http://llvm.org/viewvc/llvm-project?rev=313268&view=rev
Log:
[IfConversion] More simple, correct dead/kill liveness handling

Patch by Jesper Antonsson.

Differential Revision: https://reviews.llvm.org/D37611

Modified:
    llvm/trunk/include/llvm/CodeGen/LivePhysRegs.h
    llvm/trunk/lib/CodeGen/IfConversion.cpp
    llvm/trunk/lib/CodeGen/LivePhysRegs.cpp
    llvm/trunk/test/CodeGen/Hexagon/branch-folder-hoist-kills.mir
    llvm/trunk/test/CodeGen/Hexagon/ifcvt-impuse-livein.mir
    llvm/trunk/test/CodeGen/Hexagon/ifcvt-live-subreg.mir
    llvm/trunk/test/CodeGen/Hexagon/livephysregs-add-pristines.mir

Modified: llvm/trunk/include/llvm/CodeGen/LivePhysRegs.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LivePhysRegs.h?rev=313268&r1=313267&r2=313268&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LivePhysRegs.h (original)
+++ llvm/trunk/include/llvm/CodeGen/LivePhysRegs.h Thu Sep 14 08:53:11 2017
@@ -108,6 +108,12 @@ public:
   /// Returns true if register \p Reg and no aliasing register is in the set.
   bool available(const MachineRegisterInfo &MRI, unsigned Reg) const;
 
+  /// Remove defined registers and regmask kills from the set.
+  void removeDefs(const MachineInstr &MI);
+
+  /// Add uses to the set.
+  void addUses(const MachineInstr &MI);
+
   /// Simulates liveness when stepping backwards over an instruction(bundle).
   /// Remove Defs, add uses. This is the recommended way of calculating
   /// liveness.
@@ -168,6 +174,9 @@ inline raw_ostream &operator<<(raw_ostre
 /// instance \p LiveRegs.
 void computeLiveIns(LivePhysRegs &LiveRegs, const MachineBasicBlock &MBB);
 
+/// Recomputes dead and kill flags in \p MBB.
+void recomputeLivenessFlags(MachineBasicBlock &MBB);
+
 /// Adds registers contained in \p LiveRegs to the block live-in list of \p MBB.
 /// Does not add reserved registers.
 void addLiveIns(MachineBasicBlock &MBB, const LivePhysRegs &LiveRegs);

Modified: llvm/trunk/lib/CodeGen/IfConversion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IfConversion.cpp?rev=313268&r1=313267&r2=313268&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/IfConversion.cpp (original)
+++ llvm/trunk/lib/CodeGen/IfConversion.cpp Thu Sep 14 08:53:11 2017
@@ -179,7 +179,6 @@ namespace {
     MachineRegisterInfo *MRI;
 
     LivePhysRegs Redefs;
-    LivePhysRegs DontKill;
 
     bool PreRegAlloc;
     bool MadeChange;
@@ -461,6 +460,9 @@ bool IfConverter::runOnMachineFunction(M
       }
       }
 
+      if (RetVal && MRI->tracksLiveness())
+        recomputeLivenessFlags(*BBI.BB);
+
       Change |= RetVal;
 
       NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev +
@@ -1380,13 +1382,6 @@ static void UpdatePredRedefs(MachineInst
       MIB.addReg(Reg, RegState::Implicit | RegState::Define);
       continue;
     }
-    assert(Op.isReg() && "Register operand required");
-    if (Op.isDead()) {
-      // If we found a dead def, but it needs to be live, then remove the dead
-      // flag.
-      if (Redefs.contains(Op.getReg()))
-        Op.setIsDead(false);
-    }
     if (LiveBeforeMI.count(Reg))
       MIB.addReg(Reg, RegState::Implicit);
     else {
@@ -1403,26 +1398,6 @@ static void UpdatePredRedefs(MachineInst
   }
 }
 
-/// Remove kill flags from operands with a registers in the \p DontKill set.
-static void RemoveKills(MachineInstr &MI, const LivePhysRegs &DontKill) {
-  for (MIBundleOperands O(MI); O.isValid(); ++O) {
-    if (!O->isReg() || !O->isKill())
-      continue;
-    if (DontKill.contains(O->getReg()))
-      O->setIsKill(false);
-  }
-}
-
-/// Walks a range of machine instructions and removes kill flags for registers
-/// in the \p DontKill set.
-static void RemoveKills(MachineBasicBlock::iterator I,
-                        MachineBasicBlock::iterator E,
-                        const LivePhysRegs &DontKill,
-                        const MCRegisterInfo &MCRI) {
-  for (MachineInstr &MI : make_range(I, E))
-    RemoveKills(MI, DontKill);
-}
-
 /// If convert a simple (split, no rejoin) sub-CFG.
 bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
   BBInfo &TrueBBI  = BBAnalysis[BBI.TrueBB->getNumber()];
@@ -1453,16 +1428,12 @@ bool IfConverter::IfConvertSimple(BBInfo
       llvm_unreachable("Unable to reverse branch condition!");
 
   Redefs.init(*TRI);
-  DontKill.init(*TRI);
 
   if (MRI->tracksLiveness()) {
     // Initialize liveins to the first BB. These are potentiall redefined by
     // predicated instructions.
     Redefs.addLiveIns(CvtMBB);
     Redefs.addLiveIns(NextMBB);
-    // Compute a set of registers which must not be killed by instructions in
-    // BB1: This is everything live-in to BB2.
-    DontKill.addLiveIns(NextMBB);
   }
 
   // Remove the branches from the entry so we can add the contents of the true
@@ -1478,7 +1449,6 @@ bool IfConverter::IfConvertSimple(BBInfo
     BBI.BB->removeSuccessor(&CvtMBB, true);
   } else {
     // Predicate the instructions in the true block.
-    RemoveKills(CvtMBB.begin(), CvtMBB.end(), DontKill, *TRI);
     PredicateBlock(*CvtBBI, CvtMBB.end(), Cond);
 
     // Merge converted block into entry block. The BB to Cvt edge is removed
@@ -1567,8 +1537,6 @@ bool IfConverter::IfConvertTriangle(BBIn
     Redefs.addLiveIns(NextMBB);
   }
 
-  DontKill.clear();
-
   bool HasEarlyExit = CvtBBI->FalseBB != nullptr;
   BranchProbability CvtNext, CvtFalse, BBNext, BBCvt;
 
@@ -1751,25 +1719,12 @@ bool IfConverter::IfConvertDiamondCommon
       --NumDups1;
   }
 
-  // Compute a set of registers which must not be killed by instructions in BB1:
-  // This is everything used+live in BB2 after the duplicated instructions. We
-  // can compute this set by simulating liveness backwards from the end of BB2.
-  DontKill.init(*TRI);
   if (MRI->tracksLiveness()) {
-    for (const MachineInstr &MI : make_range(MBB2.rbegin(), ++DI2.getReverse()))
-      DontKill.stepBackward(MI);
-
     for (const MachineInstr &MI : make_range(MBB1.begin(), DI1)) {
       SmallVector<std::pair<unsigned, const MachineOperand*>, 4> Dummy;
       Redefs.stepForward(MI, Dummy);
     }
   }
-  // Kill flags in the true block for registers living into the false block
-  // must be removed. This should be done before extracting the common
-  // instructions from the beginning of the MBB1, since these instructions
-  // can actually differ between MBB1 and MBB2 in terms of <kill> flags.
-  RemoveKills(MBB1.begin(), MBB1.end(), DontKill, *TRI);
-
   BBI.BB->splice(BBI.BB->end(), &MBB1, MBB1.begin(), DI1);
   MBB2.erase(MBB2.begin(), DI2);
 
@@ -2085,10 +2040,6 @@ void IfConverter::CopyAndPredicateBlock(
     // If the predicated instruction now redefines a register as the result of
     // if-conversion, add an implicit kill.
     UpdatePredRedefs(*MI, Redefs);
-
-    // Some kill flags may not be correct anymore.
-    if (!DontKill.empty())
-      RemoveKills(*MI, DontKill);
   }
 
   if (!IgnoreBr) {

Modified: llvm/trunk/lib/CodeGen/LivePhysRegs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LivePhysRegs.cpp?rev=313268&r1=313267&r2=313268&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LivePhysRegs.cpp (original)
+++ llvm/trunk/lib/CodeGen/LivePhysRegs.cpp Thu Sep 14 08:53:11 2017
@@ -40,10 +40,8 @@ void LivePhysRegs::removeRegsInMask(cons
   }
 }
 
-/// Simulates liveness when stepping backwards over an instruction(bundle):
-/// Remove Defs, add uses. This is the recommended way of calculating liveness.
-void LivePhysRegs::stepBackward(const MachineInstr &MI) {
-  // Remove defined registers and regmask kills from the set.
+/// Remove defined registers and regmask kills from the set.
+void LivePhysRegs::removeDefs(const MachineInstr &MI) {
   for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
     if (O->isReg()) {
       if (!O->isDef())
@@ -55,8 +53,10 @@ void LivePhysRegs::stepBackward(const Ma
     } else if (O->isRegMask())
       removeRegsInMask(*O);
   }
+}
 
-  // Add uses to the set.
+/// Add uses to the set.
+void LivePhysRegs::addUses(const MachineInstr &MI) {
   for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
     if (!O->isReg() || !O->readsReg())
       continue;
@@ -67,6 +67,16 @@ void LivePhysRegs::stepBackward(const Ma
   }
 }
 
+/// Simulates liveness when stepping backwards over an instruction(bundle):
+/// Remove Defs, add uses. This is the recommended way of calculating liveness.
+void LivePhysRegs::stepBackward(const MachineInstr &MI) {
+  // Remove defined registers and regmask kills from the set.
+  removeDefs(MI);
+
+  // Add uses to the set.
+  addUses(MI);
+}
+
 /// Simulates liveness when stepping forward over an instruction(bundle): Remove
 /// killed-uses, add defs. This is the not recommended way, because it depends
 /// on accurate kill flags. If possible use stepBackward() instead of this
@@ -265,6 +275,53 @@ void llvm::addLiveIns(MachineBasicBlock
   }
 }
 
+void llvm::recomputeLivenessFlags(MachineBasicBlock &MBB) {
+  const MachineFunction &MF = *MBB.getParent();
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
+  const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
+
+  // We walk through the block backwards and start with the live outs.
+  LivePhysRegs LiveRegs;
+  LiveRegs.init(TRI);
+  LiveRegs.addLiveOutsNoPristines(MBB);
+
+  for (MachineInstr &MI : make_range(MBB.rbegin(), MBB.rend())) {
+    // Recompute dead flags.
+    for (MIBundleOperands MO(MI); MO.isValid(); ++MO) {
+      if (!MO->isReg() || !MO->isDef() || MO->isDebug())
+        continue;
+
+      unsigned Reg = MO->getReg();
+      if (Reg == 0)
+        continue;
+      assert(TargetRegisterInfo::isPhysicalRegister(Reg));
+
+      bool IsNotLive = LiveRegs.available(MRI, Reg);
+      MO->setIsDead(IsNotLive);
+    }
+
+    // Step backward over defs.
+    LiveRegs.removeDefs(MI);
+
+    // Recompute kill flags.
+    for (MIBundleOperands MO(MI); MO.isValid(); ++MO) {
+      if (!MO->isReg() || !MO->readsReg() || MO->isDebug())
+        continue;
+
+      unsigned Reg = MO->getReg();
+      if (Reg == 0)
+        continue;
+      assert(TargetRegisterInfo::isPhysicalRegister(Reg));
+
+      bool IsNotLive = LiveRegs.available(MRI, Reg);
+      MO->setIsKill(IsNotLive);
+    }
+
+    // Complete the stepbackward.
+    LiveRegs.addUses(MI);
+  }
+}
+
 void llvm::computeAndAddLiveIns(LivePhysRegs &LiveRegs,
                                 MachineBasicBlock &MBB) {
   computeLiveIns(LiveRegs, MBB);

Modified: llvm/trunk/test/CodeGen/Hexagon/branch-folder-hoist-kills.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/branch-folder-hoist-kills.mir?rev=313268&r1=313267&r2=313268&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/branch-folder-hoist-kills.mir (original)
+++ llvm/trunk/test/CodeGen/Hexagon/branch-folder-hoist-kills.mir Thu Sep 14 08:53:11 2017
@@ -16,7 +16,7 @@
 #         %R1<def> = A2_sxth %R0<kill>               ; hoisted, kills r0
 #         A2_nop %P0<imp-def>
 #         %R0<def> = C2_cmoveit %P0, 2, %R0<imp-use> ; predicated A2_tfrsi
-#         %R0<def> = C2_cmoveif %P0, 1, %R0<imp-use> ; predicated A2_tfrsi
+#         %R0<def> = C2_cmoveif killed %P0, 1, %R0<imp-use> ; predicated A2_tfrsi
 #         %R0<def> = A2_add %R0<kill>, %R1<kill>
 #         J2_jumpr %R31, %PC<imp-def,dead>
 #
@@ -24,7 +24,7 @@
 # CHECK: %r1 = A2_sxth killed %r0
 # CHECK: %r0 = C2_cmoveit %p0, 2
 # CHECK-NOT: implicit-def %r0
-# CHECK: %r0 = C2_cmoveif %p0, 1, implicit %r0
+# CHECK: %r0 = C2_cmoveif killed %p0, 1, implicit killed %r0
 
 ---
 name: fred

Modified: llvm/trunk/test/CodeGen/Hexagon/ifcvt-impuse-livein.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/ifcvt-impuse-livein.mir?rev=313268&r1=313267&r2=313268&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/ifcvt-impuse-livein.mir (original)
+++ llvm/trunk/test/CodeGen/Hexagon/ifcvt-impuse-livein.mir Thu Sep 14 08:53:11 2017
@@ -32,7 +32,7 @@ body: |
     ; block bb.1 in the original diamond. After if-conversion, the diamond
     ; became a single block, and so r2 is now live on entry to the instructions
     ; originating from bb.2.
-    ; CHECK: %r2 = C2_cmoveit %p1, 1, implicit %r2
+    ; CHECK: %r2 = C2_cmoveit %p1, 1, implicit killed %r2
         %r2 = A2_tfrsi 1
   bb.3:
     liveins: %r0, %r2

Modified: llvm/trunk/test/CodeGen/Hexagon/ifcvt-live-subreg.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/ifcvt-live-subreg.mir?rev=313268&r1=313267&r2=313268&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/ifcvt-live-subreg.mir (original)
+++ llvm/trunk/test/CodeGen/Hexagon/ifcvt-live-subreg.mir Thu Sep 14 08:53:11 2017
@@ -8,8 +8,8 @@
 # CHECK-LABEL: bb.0:
 # CHECK: liveins: %r0, %r1, %p0, %d8
 # CHECK: %d8 = A2_combinew killed %r0, killed %r1
-# CHECK: %d8 = L2_ploadrdf_io %p0, %r29, 0, implicit %d8
-# CHECK: J2_jumprf %p0, killed %r31, implicit-def %pc, implicit-def %pc, implicit killed %d8
+# CHECK: %d8 = L2_ploadrdf_io %p0, %r29, 0, implicit killed %d8
+# CHECK: J2_jumprf killed %p0, %r31, implicit-def %pc, implicit-def %pc, implicit %d8
 
 --- |
   define void @foo() {
@@ -35,7 +35,7 @@ body:             |
     J2_jumpf killed %p0, %bb.2, implicit-def %pc
 
   bb.1:
-    liveins: %d0, %r17
+    liveins: %r17
     %r0 = A2_tfrsi 0
     %r1 = A2_tfrsi 0
     A2_nop ; non-predicable

Modified: llvm/trunk/test/CodeGen/Hexagon/livephysregs-add-pristines.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/livephysregs-add-pristines.mir?rev=313268&r1=313267&r2=313268&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/livephysregs-add-pristines.mir (original)
+++ llvm/trunk/test/CodeGen/Hexagon/livephysregs-add-pristines.mir Thu Sep 14 08:53:11 2017
@@ -2,7 +2,7 @@
 
 # The register r23 is live on the path bb.0->bb.2->bb.3. Make sure we add
 # an implicit use of r23 to the predicated redefinition:
-# CHECK: %r23 = A2_tfrt %p0, killed %r1, implicit %r23
+# CHECK: %r23 = A2_tfrt killed %p0, killed %r1, implicit killed %r23
 
 # LivePhysRegs::addPristines could accidentally remove a callee-saved
 # register, if it determined that it wasn't pristine. Doing that caused




More information about the llvm-commits mailing list