[llvm] r197262 - Revert "Convert liveness tracking to work on a sub-register level instead of just register units."

Andrew Trick atrick at apple.com
Fri Dec 13 11:04:08 PST 2013


Author: atrick
Date: Fri Dec 13 13:04:08 2013
New Revision: 197262

URL: http://llvm.org/viewvc/llvm-project?rev=197262&view=rev
Log:
Revert "Convert liveness tracking to work on a sub-register level instead of just register units."

This reverts commit r197253.

This was a great change, but Juergen should be the commit author.

Added:
    llvm/trunk/include/llvm/CodeGen/LiveRegUnits.h
    llvm/trunk/lib/CodeGen/LiveRegUnits.cpp
Removed:
    llvm/trunk/include/llvm/CodeGen/LivePhysRegs.h
    llvm/trunk/lib/CodeGen/LivePhysRegs.cpp
Modified:
    llvm/trunk/lib/CodeGen/CMakeLists.txt
    llvm/trunk/lib/CodeGen/ExecutionDepsFix.cpp
    llvm/trunk/lib/CodeGen/IfConversion.cpp

Removed: llvm/trunk/include/llvm/CodeGen/LivePhysRegs.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LivePhysRegs.h?rev=197261&view=auto
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LivePhysRegs.h (original)
+++ llvm/trunk/include/llvm/CodeGen/LivePhysRegs.h (removed)
@@ -1,119 +0,0 @@
-//===- llvm/CodeGen/LivePhysRegs.h - Live Physical Register Set -*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a set of live physical registers. This can be used for
-// ad hoc liveness tracking after register allocation. You can start with the
-// live-ins/live-outs at the beginning/end of a block and update the information
-// while walking the instructions inside the block.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_LIVE_PHYS_REGS_H
-#define LLVM_CODEGEN_LIVE_PHYS_REGS_H
-
-#include "llvm/ADT/SparseSet.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include <cassert>
-
-namespace llvm {
-
-class MachineInstr;
-
-/// \brief A set of live physical registers with functions to track liveness
-/// when walking backward/forward through a basic block.
-class LivePhysRegs {
-  const TargetRegisterInfo *TRI;
-  SparseSet<unsigned> LiveRegs;
-
-  LivePhysRegs(const LivePhysRegs&) LLVM_DELETED_FUNCTION;
-  LivePhysRegs &operator=(const LivePhysRegs&) LLVM_DELETED_FUNCTION;
-public:
-  /// \brief Constructs a new empty LivePhysRegs set.
-  LivePhysRegs() : TRI(0), LiveRegs() {}
-
-  /// \brief Constructs and initialize an empty LivePhysRegs set.
-  LivePhysRegs(const TargetRegisterInfo *TRI) : TRI(TRI) {
-    LiveRegs.setUniverse(TRI->getNumRegs());
-  }
-
-  /// \brief Clear and initialize the LivePhysRegs set.
-  void init(const TargetRegisterInfo *_TRI) {
-    TRI = _TRI;
-    LiveRegs.clear();
-    LiveRegs.setUniverse(TRI->getNumRegs());
-  }
-
-  /// \brief Clears the LivePhysRegs set.
-  void clear() { LiveRegs.clear(); }
-
-  /// \brief Returns true if the set is empty.
-  bool empty() const { return LiveRegs.empty(); }
-
-  /// \brief Adds a physical register and all its sub-registers to the set.
-  void addReg(unsigned Reg) {
-    assert(TRI && "LivePhysRegs is not initialized.");
-    for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
-         SubRegs.isValid(); ++SubRegs)
-      LiveRegs.insert(*SubRegs);
-  }
-
-  /// \brief Removes a physical register, all its sub-registers, and all its
-  /// super-registers from the set.
-  void removeReg(unsigned Reg) {
-    assert(TRI && "LivePhysRegs is not initialized.");
-    for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
-         SubRegs.isValid(); ++SubRegs)
-      LiveRegs.erase(*SubRegs);
-    for (MCSuperRegIterator SuperRegs(Reg, TRI, /*IncludeSelf=*/false);
-         SuperRegs.isValid(); ++SuperRegs)
-      LiveRegs.erase(*SuperRegs);
-  }
-
-  /// \brief Removes physical registers clobbered by the regmask operand @p MO.
-  void removeRegsInMask(const MachineOperand &MO);
-
-  /// \brief Returns true if register @p Reg is contained in the set. This also
-  /// works if only the super register of @p Reg has been defined, because we
-  /// always add also all sub-registers to the set.
-  bool contains(unsigned Reg) const { return LiveRegs.count(Reg); }
-
-  /// \brief Simulates liveness when stepping backwards over an
-  /// instruction(bundle): Remove Defs, add uses. This is the recommended way of
-  /// calculating liveness.
-  void stepBackward(const MachineInstr &MI);
-
-  /// \brief 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 stepBackwards() instead of this function.
-  void stepForward(const MachineInstr &MI);
-
-  /// \brief Adds all live-in registers of basic block @p MBB.
-  void addLiveIns(const MachineBasicBlock *MBB) {
-    for (MachineBasicBlock::livein_iterator LI = MBB->livein_begin(),
-         LE = MBB->livein_end(); LI != LE; ++LI)
-      addReg(*LI);
-  }
-
-  /// \brief Adds all live-out registers of basic block @p MBB.
-  void addLiveOuts(const MachineBasicBlock *MBB) {
-    for (MachineBasicBlock::const_succ_iterator SI = MBB->succ_begin(),
-         SE = MBB->succ_end(); SI != SE; ++SI)
-      addLiveIns(*SI);
-  }
-
-  typedef SparseSet<unsigned>::const_iterator const_iterator;
-  const_iterator begin() const { return LiveRegs.begin(); }
-  const_iterator end() const { return LiveRegs.end(); }
-};
-
-} // namespace llvm
-
-#endif

Added: llvm/trunk/include/llvm/CodeGen/LiveRegUnits.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveRegUnits.h?rev=197262&view=auto
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LiveRegUnits.h (added)
+++ llvm/trunk/include/llvm/CodeGen/LiveRegUnits.h Fri Dec 13 13:04:08 2013
@@ -0,0 +1,88 @@
+//===-- llvm/CodeGen/LiveRegUnits.h - Live register unit set ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a Set of live register units. This can be used for ad
+// hoc liveness tracking after register allocation. You can start with the
+// live-ins/live-outs at the beginning/end of a block and update the information
+// while walking the instructions inside the block.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEREGUNITS_H
+#define LLVM_CODEGEN_LIVEREGUNITS_H
+
+#include "llvm/ADT/SparseSet.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include <cassert>
+
+namespace llvm {
+
+class MachineInstr;
+
+/// A set of live register units with functions to track liveness when walking
+/// backward/forward through a basic block.
+class LiveRegUnits {
+  SparseSet<unsigned> LiveUnits;
+
+  LiveRegUnits(const LiveRegUnits&) LLVM_DELETED_FUNCTION;
+  LiveRegUnits &operator=(const LiveRegUnits&) LLVM_DELETED_FUNCTION;
+public:
+  /// \brief Constructs a new empty LiveRegUnits set.
+  LiveRegUnits() {}
+
+  void init(const TargetRegisterInfo *TRI) {
+    LiveUnits.clear();
+    LiveUnits.setUniverse(TRI->getNumRegs());
+  }
+
+  void clear() { LiveUnits.clear(); }
+
+  bool empty() const { return LiveUnits.empty(); }
+
+  /// \brief Adds a register to the set.
+  void addReg(unsigned Reg, const MCRegisterInfo &MCRI) {
+    for (MCRegUnitIterator RUnits(Reg, &MCRI); RUnits.isValid(); ++RUnits)
+      LiveUnits.insert(*RUnits);
+  }
+
+  /// \brief Removes a register from the set.
+  void removeReg(unsigned Reg, const MCRegisterInfo &MCRI) {
+    for (MCRegUnitIterator RUnits(Reg, &MCRI); RUnits.isValid(); ++RUnits)
+      LiveUnits.erase(*RUnits);
+  }
+
+  /// \brief Removes registers clobbered by the regmask operand @p Op.
+  void removeRegsInMask(const MachineOperand &Op, const MCRegisterInfo &MCRI);
+
+  /// \brief Returns true if register @p Reg (or one of its super register) is
+  /// contained in the set.
+  bool contains(unsigned Reg, const MCRegisterInfo &MCRI) const {
+    for (MCRegUnitIterator RUnits(Reg, &MCRI); RUnits.isValid(); ++RUnits) {
+      if (LiveUnits.count(*RUnits))
+        return true;
+    }
+    return false;
+  }
+
+  /// \brief Simulates liveness when stepping backwards over an
+  /// instruction(bundle): Remove Defs, add uses.
+  void stepBackward(const MachineInstr &MI, const MCRegisterInfo &MCRI);
+
+  /// \brief Simulates liveness when stepping forward over an
+  /// instruction(bundle): Remove killed-uses, add defs.
+  void stepForward(const MachineInstr &MI, const MCRegisterInfo &MCRI);
+
+  /// \brief Adds all registers in the live-in list of block @p BB.
+  void addLiveIns(const MachineBasicBlock *MBB, const MCRegisterInfo &MCRI);
+};
+
+} // namespace llvm
+
+#endif

Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=197262&r1=197261&r2=197262&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CMakeLists.txt (original)
+++ llvm/trunk/lib/CodeGen/CMakeLists.txt Fri Dec 13 13:04:08 2013
@@ -35,7 +35,7 @@ add_llvm_library(LLVMCodeGen
   LiveRangeCalc.cpp
   LiveRangeEdit.cpp
   LiveRegMatrix.cpp
-  LivePhysRegs.cpp
+  LiveRegUnits.cpp
   LiveStackAnalysis.cpp
   LiveVariables.cpp
   LocalStackSlotAllocation.cpp

Modified: llvm/trunk/lib/CodeGen/ExecutionDepsFix.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ExecutionDepsFix.cpp?rev=197262&r1=197261&r2=197262&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ExecutionDepsFix.cpp (original)
+++ llvm/trunk/lib/CodeGen/ExecutionDepsFix.cpp Fri Dec 13 13:04:08 2013
@@ -23,7 +23,7 @@
 #define DEBUG_TYPE "execution-fix"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/ADT/PostOrderIterator.h"
-#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/CodeGen/LiveRegUnits.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/Support/Allocator.h"
@@ -141,7 +141,7 @@ class ExeDepsFix : public MachineFunctio
   std::vector<std::pair<MachineInstr*, unsigned> > UndefReads;
 
   /// Storage for register unit liveness.
-  LivePhysRegs LiveRegSet;
+  LiveRegUnits LiveUnits;
 
   /// Current instruction number.
   /// The first instruction in each basic block is 0.
@@ -352,7 +352,7 @@ void ExeDepsFix::enterBasicBlock(Machine
 
   // Set up UndefReads to track undefined register reads.
   UndefReads.clear();
-  LiveRegSet.clear();
+  LiveUnits.clear();
 
   // Set up LiveRegs to represent registers entering MBB.
   if (!LiveRegs)
@@ -547,19 +547,21 @@ void ExeDepsFix::processUndefReads(Machi
     return;
 
   // Collect this block's live out register units.
-  LiveRegSet.init(TRI);
-  LiveRegSet.addLiveOuts(MBB);
-
+  LiveUnits.init(TRI);
+  for (MachineBasicBlock::const_succ_iterator SI = MBB->succ_begin(),
+         SE = MBB->succ_end(); SI != SE; ++SI) {
+    LiveUnits.addLiveIns(*SI, *TRI);
+  }
   MachineInstr *UndefMI = UndefReads.back().first;
   unsigned OpIdx = UndefReads.back().second;
 
   for (MachineBasicBlock::reverse_iterator I = MBB->rbegin(), E = MBB->rend();
        I != E; ++I) {
     // Update liveness, including the current instrucion's defs.
-    LiveRegSet.stepBackward(*I);
+    LiveUnits.stepBackward(*I, *TRI);
 
     if (UndefMI == &*I) {
-      if (!LiveRegSet.contains(UndefMI->getOperand(OpIdx).getReg()))
+      if (!LiveUnits.contains(UndefMI->getOperand(OpIdx).getReg(), *TRI))
         TII->breakPartialRegDependency(UndefMI, OpIdx, TRI);
 
       UndefReads.pop_back();

Modified: llvm/trunk/lib/CodeGen/IfConversion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IfConversion.cpp?rev=197262&r1=197261&r2=197262&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/IfConversion.cpp (original)
+++ llvm/trunk/lib/CodeGen/IfConversion.cpp Fri Dec 13 13:04:08 2013
@@ -23,7 +23,7 @@
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/TargetSchedule.h"
-#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/CodeGen/LiveRegUnits.h"
 #include "llvm/MC/MCInstrItineraries.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
@@ -162,8 +162,8 @@ namespace {
     const MachineBranchProbabilityInfo *MBPI;
     MachineRegisterInfo *MRI;
 
-    LivePhysRegs Redefs;
-    LivePhysRegs DontKill;
+    LiveRegUnits Redefs;
+    LiveRegUnits DontKill;
 
     bool PreRegAlloc;
     bool MadeChange;
@@ -968,22 +968,23 @@ void IfConverter::RemoveExtraEdges(BBInf
 
 /// Behaves like LiveRegUnits::StepForward() but also adds implicit uses to all
 /// values defined in MI which are not live/used by MI.
-static void UpdatePredRedefs(MachineInstr *MI, LivePhysRegs &Redefs) {
+static void UpdatePredRedefs(MachineInstr *MI, LiveRegUnits &Redefs,
+                             const TargetRegisterInfo *TRI) {
   for (ConstMIBundleOperands Ops(MI); Ops.isValid(); ++Ops) {
     if (!Ops->isReg() || !Ops->isKill())
       continue;
     unsigned Reg = Ops->getReg();
     if (Reg == 0)
       continue;
-    Redefs.removeReg(Reg);
+    Redefs.removeReg(Reg, *TRI);
   }
   for (MIBundleOperands Ops(MI); Ops.isValid(); ++Ops) {
     if (!Ops->isReg() || !Ops->isDef())
       continue;
     unsigned Reg = Ops->getReg();
-    if (Reg == 0 || Redefs.contains(Reg))
+    if (Reg == 0 || Redefs.contains(Reg, *TRI))
       continue;
-    Redefs.addReg(Reg);
+    Redefs.addReg(Reg, *TRI);
 
     MachineOperand &Op = *Ops;
     MachineInstr *MI = Op.getParent();
@@ -995,11 +996,12 @@ 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) {
+static void RemoveKills(MachineInstr &MI, const LiveRegUnits &DontKill,
+                        const MCRegisterInfo &MCRI) {
   for (MIBundleOperands O(&MI); O.isValid(); ++O) {
     if (!O->isReg() || !O->isKill())
       continue;
-    if (DontKill.contains(O->getReg()))
+    if (DontKill.contains(O->getReg(), MCRI))
       O->setIsKill(false);
   }
 }
@@ -1010,10 +1012,10 @@ static void RemoveKills(MachineInstr &MI
  */
 static void RemoveKills(MachineBasicBlock::iterator I,
                         MachineBasicBlock::iterator E,
-                        const LivePhysRegs &DontKill,
+                        const LiveRegUnits &DontKill,
                         const MCRegisterInfo &MCRI) {
   for ( ; I != E; ++I)
-    RemoveKills(*I, DontKill);
+    RemoveKills(*I, DontKill, MCRI);
 }
 
 /// IfConvertSimple - If convert a simple (split, no rejoin) sub-CFG.
@@ -1047,13 +1049,13 @@ bool IfConverter::IfConvertSimple(BBInfo
   // Initialize liveins to the first BB. These are potentiall redefined by
   // predicated instructions.
   Redefs.init(TRI);
-  Redefs.addLiveIns(CvtBBI->BB);
-  Redefs.addLiveIns(NextBBI->BB);
+  Redefs.addLiveIns(CvtBBI->BB, *TRI);
+  Redefs.addLiveIns(NextBBI->BB, *TRI);
 
   // Compute a set of registers which must not be killed by instructions in
   // BB1: This is everything live-in to BB2.
   DontKill.init(TRI);
-  DontKill.addLiveIns(NextBBI->BB);
+  DontKill.addLiveIns(NextBBI->BB, *TRI);
 
   if (CvtBBI->BB->pred_size() > 1) {
     BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
@@ -1152,8 +1154,8 @@ bool IfConverter::IfConvertTriangle(BBIn
   // Initialize liveins to the first BB. These are potentially redefined by
   // predicated instructions.
   Redefs.init(TRI);
-  Redefs.addLiveIns(CvtBBI->BB);
-  Redefs.addLiveIns(NextBBI->BB);
+  Redefs.addLiveIns(CvtBBI->BB, *TRI);
+  Redefs.addLiveIns(NextBBI->BB, *TRI);
 
   DontKill.clear();
 
@@ -1282,7 +1284,7 @@ bool IfConverter::IfConvertDiamond(BBInf
   // Initialize liveins to the first BB. These are potentially redefined by
   // predicated instructions.
   Redefs.init(TRI);
-  Redefs.addLiveIns(BBI1->BB);
+  Redefs.addLiveIns(BBI1->BB, *TRI);
 
   // Remove the duplicated instructions at the beginnings of both paths.
   MachineBasicBlock::iterator DI1 = BBI1->BB->begin();
@@ -1315,12 +1317,12 @@ bool IfConverter::IfConvertDiamond(BBInf
   DontKill.init(TRI);
   for (MachineBasicBlock::reverse_iterator I = BBI2->BB->rbegin(),
        E = MachineBasicBlock::reverse_iterator(DI2); I != E; ++I) {
-    DontKill.stepBackward(*I);
+    DontKill.stepBackward(*I, *TRI);
   }
 
   for (MachineBasicBlock::const_iterator I = BBI1->BB->begin(), E = DI1; I != E;
        ++I) {
-    Redefs.stepForward(*I);
+    Redefs.stepForward(*I, *TRI);
   }
   BBI.BB->splice(BBI.BB->end(), BBI1->BB, BBI1->BB->begin(), DI1);
   BBI2->BB->erase(BBI2->BB->begin(), DI2);
@@ -1504,7 +1506,7 @@ void IfConverter::PredicateBlock(BBInfo
 
     // If the predicated instruction now redefines a register as the result of
     // if-conversion, add an implicit kill.
-    UpdatePredRedefs(I, Redefs);
+    UpdatePredRedefs(I, Redefs, TRI);
   }
 
   std::copy(Cond.begin(), Cond.end(), std::back_inserter(BBI.Predicate));
@@ -1550,11 +1552,11 @@ void IfConverter::CopyAndPredicateBlock(
 
     // If the predicated instruction now redefines a register as the result of
     // if-conversion, add an implicit kill.
-    UpdatePredRedefs(MI, Redefs);
+    UpdatePredRedefs(MI, Redefs, TRI);
 
     // Some kill flags may not be correct anymore.
     if (!DontKill.empty())
-      RemoveKills(*MI, DontKill);
+      RemoveKills(*MI, DontKill, *TRI);
   }
 
   if (!IgnoreBr) {

Removed: llvm/trunk/lib/CodeGen/LivePhysRegs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LivePhysRegs.cpp?rev=197261&view=auto
==============================================================================
--- llvm/trunk/lib/CodeGen/LivePhysRegs.cpp (original)
+++ llvm/trunk/lib/CodeGen/LivePhysRegs.cpp (removed)
@@ -1,91 +0,0 @@
-//===--- LivePhysRegs.cpp - Live Physical Register Set --------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the LivePhysRegs utility for tracking liveness of
-// physical registers across machine instructions in forward or backward order.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/LivePhysRegs.h"
-#include "llvm/CodeGen/MachineInstrBundle.h"
-using namespace llvm;
-
-
-/// We assume the high bits of a physical super-register are not preserved
-/// unless the instruction has an implicit-use operand reading the
-/// super-register.
-
-/// \brief Remove all registers from the set that get clobbered by the register
-/// mask.
-void LivePhysRegs::removeRegsInMask(const MachineOperand &MO) {
-  SparseSet<unsigned>::iterator LRI = LiveRegs.begin();
-  while (LRI != LiveRegs.end()) {
-    if (MO.clobbersPhysReg(*LRI))
-      LRI = LiveRegs.erase(LRI);
-    else
-      ++LRI;
-  }
-}
-
-/// 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.
-  for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
-    if (O->isReg()) {
-      if (!O->isDef())
-        continue;
-      unsigned Reg = O->getReg();
-      if (Reg == 0)
-        continue;
-      removeReg(Reg);
-    } else if (O->isRegMask())
-      removeRegsInMask(*O);
-  }
-
-  // Add uses to the set.
-  for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
-    if (!O->isReg() || !O->readsReg() || O->isUndef())
-      continue;
-    unsigned Reg = O->getReg();
-    if (Reg == 0)
-      continue;
-    addReg(Reg);
-  }
-}
-
-/// 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 stepBackwards() instead of this
-/// function.
-void LivePhysRegs::stepForward(const MachineInstr &MI) {
-  SmallVector<unsigned, 4> Defs;
-  // Remove killed registers from the set.
-  for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
-    if (O->isReg()) {
-      unsigned Reg = O->getReg();
-      if (Reg == 0)
-        continue;
-      if (O->isDef()) {
-        if (!O->isDead())
-          Defs.push_back(Reg);
-      } else {
-        if (!O->isKill())
-          continue;
-        assert(O->isUse());
-        removeReg(Reg);
-      }
-    } else if (O->isRegMask())
-      removeRegsInMask(*O);
-  }
-
-  // Add defs to the set.
-  for (unsigned i = 0, e = Defs.size(); i != e; ++i)
-    addReg(Defs[i]);
-}

Added: llvm/trunk/lib/CodeGen/LiveRegUnits.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRegUnits.cpp?rev=197262&view=auto
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveRegUnits.cpp (added)
+++ llvm/trunk/lib/CodeGen/LiveRegUnits.cpp Fri Dec 13 13:04:08 2013
@@ -0,0 +1,111 @@
+//===-- LiveInterval.cpp - Live Interval Representation -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the LiveRegUnits utility for tracking liveness of
+// physical register units across machine instructions in forward or backward
+// order.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/LiveRegUnits.h"
+#include "llvm/CodeGen/MachineInstrBundle.h"
+using namespace llvm;
+
+/// Return true if the given MachineOperand clobbers the given register unit.
+/// A register unit is only clobbered if all its super-registers are clobbered.
+static bool operClobbersUnit(const MachineOperand *MO, unsigned Unit,
+                             const MCRegisterInfo *MCRI) {
+  for (MCRegUnitRootIterator RI(Unit, MCRI); RI.isValid(); ++RI) {
+    for (MCSuperRegIterator SI(*RI, MCRI, true); SI.isValid(); ++SI) {
+      if (!MO->clobbersPhysReg(*SI))
+        return false;
+    }
+  }
+  return true;
+}
+
+/// We assume the high bits of a physical super register are not preserved
+/// unless the instruction has an implicit-use operand reading the
+/// super-register or a register unit for the upper bits is available.
+void LiveRegUnits::removeRegsInMask(const MachineOperand &Op,
+                                    const MCRegisterInfo &MCRI) {
+  SparseSet<unsigned>::iterator LUI = LiveUnits.begin();
+  while (LUI != LiveUnits.end()) {
+    if (operClobbersUnit(&Op, *LUI, &MCRI))
+      LUI = LiveUnits.erase(LUI);
+    else
+      ++LUI;
+  }
+}
+
+void LiveRegUnits::stepBackward(const MachineInstr &MI,
+                                const MCRegisterInfo &MCRI) {
+  // Remove defined registers and regmask kills from the set.
+  for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
+    if (O->isReg()) {
+      if (!O->isDef())
+        continue;
+      unsigned Reg = O->getReg();
+      if (Reg == 0)
+        continue;
+      removeReg(Reg, MCRI);
+    } else if (O->isRegMask()) {
+      removeRegsInMask(*O, MCRI);
+    }
+  }
+  // Add uses to the set.
+  for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
+    if (!O->isReg() || !O->readsReg() || O->isUndef())
+      continue;
+    unsigned Reg = O->getReg();
+    if (Reg == 0)
+      continue;
+    addReg(Reg, MCRI);
+  }
+}
+
+/// Uses with kill flag get removed from the set, defs added. If possible
+/// use StepBackward() instead of this function because some kill flags may
+/// be missing.
+void LiveRegUnits::stepForward(const MachineInstr &MI,
+                               const MCRegisterInfo &MCRI) {
+  SmallVector<unsigned, 4> Defs;
+  // Remove killed registers from the set.
+  for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
+    if (O->isReg()) {
+      unsigned Reg = O->getReg();
+      if (Reg == 0)
+        continue;
+      if (O->isDef()) {
+        if (!O->isDead())
+          Defs.push_back(Reg);
+      } else {
+        if (!O->isKill())
+          continue;
+        assert(O->isUse());
+        removeReg(Reg, MCRI);
+      }
+    } else if (O->isRegMask()) {
+      removeRegsInMask(*O, MCRI);
+    }
+  }
+  // Add defs to the set.
+  for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
+    addReg(Defs[i], MCRI);
+  }
+}
+
+/// Adds all registers in the live-in list of block @p BB.
+void LiveRegUnits::addLiveIns(const MachineBasicBlock *MBB,
+                              const MCRegisterInfo &MCRI) {
+  for (MachineBasicBlock::livein_iterator L = MBB->livein_begin(),
+         LE = MBB->livein_end(); L != LE; ++L) {
+    addReg(*L, MCRI);
+  }
+}





More information about the llvm-commits mailing list