[llvm] r292705 - LiveRegUnits: Add accumulateBackward() function

Matthias Braun via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 20 18:21:04 PST 2017


Author: matze
Date: Fri Jan 20 20:21:04 2017
New Revision: 292705

URL: http://llvm.org/viewvc/llvm-project?rev=292705&view=rev
Log:
LiveRegUnits: Add accumulateBackward() function

Re-Commit r292543 with a fix for the situation when the chain end is
MBB.end().

This function can be used to accumulate the set of all read and modified
register in a sequence of instructions.

Use this code in AArch64A57FPLoadBalancing::scavengeRegister() to prove
the concept.

- The AArch64A57LoadBalancing code is using a backwards analysis now
  which is irrespective of kill flags. This is the main motivation for
  this change.

Differential Revision: http://reviews.llvm.org/D22082

Modified:
    llvm/trunk/include/llvm/CodeGen/LiveRegUnits.h
    llvm/trunk/lib/CodeGen/LiveRegUnits.cpp
    llvm/trunk/lib/Target/AArch64/AArch64A57FPLoadBalancing.cpp

Modified: llvm/trunk/include/llvm/CodeGen/LiveRegUnits.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveRegUnits.h?rev=292705&r1=292704&r2=292705&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LiveRegUnits.h (original)
+++ llvm/trunk/include/llvm/CodeGen/LiveRegUnits.h Fri Jan 20 20:21:04 2017
@@ -76,6 +76,10 @@ public:
   /// The regmask has the same format as the one in the RegMask machine operand.
   void removeRegsNotPreserved(const uint32_t *RegMask);
 
+  /// Adds register units not preserved by the regmask \p RegMask.
+  /// The regmask has the same format as the one in the RegMask machine operand.
+  void addRegsInMask(const uint32_t *RegMask);
+
   /// Returns true if no part of physical register \p Reg is live.
   bool available(unsigned Reg) const {
     for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
@@ -88,6 +92,11 @@ public:
   /// Updates liveness when stepping backwards over the instruction \p MI.
   void stepBackward(const MachineInstr &MI);
 
+  /// Mark all register units live during instruction \p MI.
+  /// This can be used to accumulate live/unoccupied registers over a range of
+  /// instructions.
+  void accumulateBackward(const MachineInstr &MI);
+
   /// Adds registers living out of block \p MBB.
   /// Live out registers are the union of the live-in registers of the successor
   /// blocks and pristine registers. Live out registers of the end block are the

Modified: llvm/trunk/lib/CodeGen/LiveRegUnits.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRegUnits.cpp?rev=292705&r1=292704&r2=292705&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveRegUnits.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveRegUnits.cpp Fri Jan 20 20:21:04 2017
@@ -26,6 +26,15 @@ void LiveRegUnits::removeRegsNotPreserve
   }
 }
 
+void LiveRegUnits::addRegsInMask(const uint32_t *RegMask) {
+  for (unsigned U = 0, E = TRI->getNumRegUnits(); U != E; ++U) {
+    for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) {
+      if (MachineOperand::clobbersPhysReg(RegMask, *RootReg))
+        Units.set(U);
+    }
+  }
+}
+
 void LiveRegUnits::stepBackward(const MachineInstr &MI) {
   // Remove defined registers and regmask kills from the set.
   for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
@@ -51,6 +60,21 @@ void LiveRegUnits::stepBackward(const Ma
   }
 }
 
+void LiveRegUnits::accumulateBackward(const MachineInstr &MI) {
+  // Add defs, uses and regmask clobbers to the set.
+  for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
+    if (O->isReg()) {
+      unsigned Reg = O->getReg();
+      if (!TargetRegisterInfo::isPhysicalRegister(Reg))
+        continue;
+      if (!O->isDef() && !O->readsReg())
+        continue;
+      addReg(Reg);
+    } else if (O->isRegMask())
+      addRegsInMask(O->getRegMask());
+  }
+}
+
 /// Add live-in registers of basic block \p MBB to \p LiveUnits.
 static void addLiveIns(LiveRegUnits &LiveUnits, const MachineBasicBlock &MBB) {
   for (const auto &LI : MBB.liveins())

Modified: llvm/trunk/lib/Target/AArch64/AArch64A57FPLoadBalancing.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64A57FPLoadBalancing.cpp?rev=292705&r1=292704&r2=292705&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64A57FPLoadBalancing.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64A57FPLoadBalancing.cpp Fri Jan 20 20:21:04 2017
@@ -493,43 +493,30 @@ bool AArch64A57FPLoadBalancing::colorCha
 
 int AArch64A57FPLoadBalancing::scavengeRegister(Chain *G, Color C,
                                                 MachineBasicBlock &MBB) {
-  RegScavenger RS;
-  RS.enterBasicBlock(MBB);
-  RS.forward(MachineBasicBlock::iterator(G->getStart()));
-
   // Can we find an appropriate register that is available throughout the life
-  // of the chain?
-  unsigned RegClassID = G->getStart()->getDesc().OpInfo[0].RegClass;
-  BitVector AvailableRegs = RS.getRegsAvailable(TRI->getRegClass(RegClassID));
-  for (MachineBasicBlock::iterator I = G->begin(), E = G->end(); I != E; ++I) {
-    RS.forward(I);
-    AvailableRegs &= RS.getRegsAvailable(TRI->getRegClass(RegClassID));
-
-    // Remove any registers clobbered by a regmask or any def register that is
-    // immediately dead.
-    for (auto J : I->operands()) {
-      if (J.isRegMask())
-        AvailableRegs.clearBitsNotInMask(J.getRegMask());
-
-      if (J.isReg() && J.isDef()) {
-        MCRegAliasIterator AI(J.getReg(), TRI, /*IncludeSelf=*/true);
-        if (J.isDead())
-          for (; AI.isValid(); ++AI)
-            AvailableRegs.reset(*AI);
-#ifndef NDEBUG
-        else
-          for (; AI.isValid(); ++AI)
-            assert(!AvailableRegs[*AI] &&
-                   "Non-dead def should have been removed by now!");
-#endif
-      }
-    }
+  // of the chain? Simulate liveness backwards until the end of the chain.
+  LiveRegUnits Units(*TRI);
+  Units.addLiveOuts(MBB);
+  MachineBasicBlock::iterator I = MBB.end();
+  MachineBasicBlock::iterator ChainEnd = G->end();
+  while (I != ChainEnd) {
+    --I;
+    Units.stepBackward(*I);
   }
 
+  // Check which register units are alive throughout the chain.
+  MachineBasicBlock::iterator ChainBegin = G->begin();
+  assert(ChainBegin != ChainEnd && "Chain should contain instructions");
+  do {
+    --I;
+    Units.accumulateBackward(*I);
+  } while (I != ChainBegin);
+
   // Make sure we allocate in-order, to get the cheapest registers first.
+  unsigned RegClassID = ChainBegin->getDesc().OpInfo[0].RegClass;
   auto Ord = RCI.getOrder(TRI->getRegClass(RegClassID));
   for (auto Reg : Ord) {
-    if (!AvailableRegs[Reg])
+    if (!Units.available(Reg))
       continue;
     if (C == getColor(Reg))
       return Reg;




More information about the llvm-commits mailing list