From a23bd2e761f528e91e2b4d14cc495b7afde3b4f2 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Fri, 13 Dec 2013 19:04:08 +0000 Subject: 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197262 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/LivePhysRegs.h | 119 ------------------------------------ include/llvm/CodeGen/LiveRegUnits.h | 88 ++++++++++++++++++++++++++ lib/CodeGen/CMakeLists.txt | 2 +- lib/CodeGen/ExecutionDepsFix.cpp | 18 +++--- lib/CodeGen/IfConversion.cpp | 46 +++++++------- lib/CodeGen/LivePhysRegs.cpp | 91 --------------------------- lib/CodeGen/LiveRegUnits.cpp | 111 +++++++++++++++++++++++++++++++++ 7 files changed, 234 insertions(+), 241 deletions(-) delete mode 100644 include/llvm/CodeGen/LivePhysRegs.h create mode 100644 include/llvm/CodeGen/LiveRegUnits.h delete mode 100644 lib/CodeGen/LivePhysRegs.cpp create mode 100644 lib/CodeGen/LiveRegUnits.cpp diff --git a/include/llvm/CodeGen/LivePhysRegs.h b/include/llvm/CodeGen/LivePhysRegs.h deleted file mode 100644 index 5cb2421ffb..0000000000 --- a/include/llvm/CodeGen/LivePhysRegs.h +++ /dev/null @@ -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 - -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 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::const_iterator const_iterator; - const_iterator begin() const { return LiveRegs.begin(); } - const_iterator end() const { return LiveRegs.end(); } -}; - -} // namespace llvm - -#endif diff --git a/include/llvm/CodeGen/LiveRegUnits.h b/include/llvm/CodeGen/LiveRegUnits.h new file mode 100644 index 0000000000..02b9c55cc6 --- /dev/null +++ b/include/llvm/CodeGen/LiveRegUnits.h @@ -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 + +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 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 diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt index 0beca0ceed..10cc9fff9a 100644 --- a/lib/CodeGen/CMakeLists.txt +++ b/lib/CodeGen/CMakeLists.txt @@ -35,7 +35,7 @@ add_llvm_library(LLVMCodeGen LiveRangeCalc.cpp LiveRangeEdit.cpp LiveRegMatrix.cpp - LivePhysRegs.cpp + LiveRegUnits.cpp LiveStackAnalysis.cpp LiveVariables.cpp LocalStackSlotAllocation.cpp diff --git a/lib/CodeGen/ExecutionDepsFix.cpp b/lib/CodeGen/ExecutionDepsFix.cpp index 1f933316c5..031f19c135 100644 --- a/lib/CodeGen/ExecutionDepsFix.cpp +++ b/lib/CodeGen/ExecutionDepsFix.cpp @@ -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 MachineFunctionPass { std::vector > 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(MachineBasicBlock *MBB) { // 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(MachineBasicBlock *MBB) { 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(); diff --git a/lib/CodeGen/IfConversion.cpp b/lib/CodeGen/IfConversion.cpp index c6cef9b114..e2d0eb44da 100644 --- a/lib/CodeGen/IfConversion.cpp +++ b/lib/CodeGen/IfConversion.cpp @@ -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(BBInfo &BBI) { /// 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(MachineInstr *MI, LivePhysRegs &Redefs) { /** * 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, const LivePhysRegs &DontKill) { */ 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 &BBI, IfcvtKind Kind) { // 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(BBInfo &BBI, IfcvtKind Kind) { // 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(BBInfo &BBI, IfcvtKind Kind, // 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(BBInfo &BBI, IfcvtKind Kind, 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 &BBI, // 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(BBInfo &ToBBI, BBInfo &FromBBI, // 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) { diff --git a/lib/CodeGen/LivePhysRegs.cpp b/lib/CodeGen/LivePhysRegs.cpp deleted file mode 100644 index 2e103333c7..0000000000 --- a/lib/CodeGen/LivePhysRegs.cpp +++ /dev/null @@ -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::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 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]); -} diff --git a/lib/CodeGen/LiveRegUnits.cpp b/lib/CodeGen/LiveRegUnits.cpp new file mode 100644 index 0000000000..6221ca2e47 --- /dev/null +++ b/lib/CodeGen/LiveRegUnits.cpp @@ -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::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 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); + } +} -- cgit v1.2.3