diff --git a/include/llvm/CodeGen/LiveRegUnits.h b/include/llvm/CodeGen/LiveRegUnits.h index c7b811dd319..0c6df8838e2 100644 --- a/include/llvm/CodeGen/LiveRegUnits.h +++ b/include/llvm/CodeGen/LiveRegUnits.h @@ -32,47 +32,30 @@ class LiveRegUnits { SmallSet LiveUnits; public: - /// Constructs a new empty LiveRegUnits set. - LiveRegUnits() { - } + /// \brief Constructs a new empty LiveRegUnits set. + LiveRegUnits() {} - /// Constructs a new LiveRegUnits set by copying @p Other. + /// \brief Constructs a new LiveRegUnits set by copying @p Other. LiveRegUnits(const LiveRegUnits &Other) : LiveUnits(Other.LiveUnits) { } - /// Adds a register to the set. + /// \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); } - /// Removes a register from the set. + /// \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. - /// Note that 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 removeRegsInMask(const MachineOperand &Op, - const MCRegisterInfo &MCRI) { - const uint32_t *Mask = Op.getRegMask(); - unsigned Bit = 0; - for (unsigned R = 0; R < MCRI.getNumRegs(); ++R) { - if ((*Mask & (1u << Bit)) == 0) - removeReg(R, MCRI); - ++Bit; - if (Bit >= 32) { - Bit = 0; - ++Mask; - } - } - } + void removeRegsInMask(const MachineOperand &Op, const MCRegisterInfo &MCRI); - /// Returns true if register @p Reg (or one of its super register) is + /// \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) { @@ -82,73 +65,16 @@ public: return false; } - /// Simulates liveness when stepping backwards over an instruction(bundle): - /// Defs are removed from the set, uses added. - void 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); - } - } + /// \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). - /// - /// 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 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); - } - } + /// instruction(bundle): Remove killed-uses, add defs. + void stepForward(const MachineInstr &MI, const MCRegisterInfo &MCRI); /// Adds all registers in the live-in list of block @p BB. - void addLiveIns(const MachineBasicBlock &BB, const MCRegisterInfo &MCRI) { - for (MachineBasicBlock::livein_iterator L = BB.livein_begin(), - LE = BB.livein_end(); L != LE; ++L) { - addReg(*L, MCRI); - } - } + void addLiveIns(const MachineBasicBlock &BB, const MCRegisterInfo &MCRI); }; } // namespace llvm diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt index a00df3b2c30..5aa5a750695 100644 --- a/lib/CodeGen/CMakeLists.txt +++ b/lib/CodeGen/CMakeLists.txt @@ -35,6 +35,7 @@ add_llvm_library(LLVMCodeGen LiveRangeCalc.cpp LiveRangeEdit.cpp LiveRegMatrix.cpp + LiveRegUnits.cpp LiveStackAnalysis.cpp LiveVariables.cpp LocalStackSlotAllocation.cpp diff --git a/lib/CodeGen/LiveRegUnits.cpp b/lib/CodeGen/LiveRegUnits.cpp new file mode 100644 index 00000000000..c9fa40e25d1 --- /dev/null +++ b/lib/CodeGen/LiveRegUnits.cpp @@ -0,0 +1,102 @@ +//===-- 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; + +/// 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) { + const uint32_t *Mask = Op.getRegMask(); + unsigned Bit = 0; + for (unsigned R = 0; R < MCRI.getNumRegs(); ++R) { + if ((*Mask & (1u << Bit)) == 0) + removeReg(R, MCRI); + ++Bit; + if (Bit >= 32) { + Bit = 0; + ++Mask; + } + } +} + +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 &BB, + const MCRegisterInfo &MCRI) { + for (MachineBasicBlock::livein_iterator L = BB.livein_begin(), + LE = BB.livein_end(); L != LE; ++L) { + addReg(*L, MCRI); + } +}