1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[MCRegInfo] Add forward sub and super register iterators. (NFC)

This patch adds forward iterators mc_difflist_iterator,
mc_subreg_iterator and mc_superreg_iterator, based on the existing
DiffListIterator. Those are used to provide iterator ranges over
sub- and super-register from TRI, which are slightly more convenient
than the existing MCSubRegIterator/MCSuperRegIterator. Unfortunately,
it duplicates a bit of functionality, but the new iterators are a bit
more convenient (and can be used with various existing iterator
utilities)  and should probably replace the old iterators in the future.

This patch updates some existing users.

Reviewers: evandro, qcolombet, paquette, MatzeB, arsenm

Reviewed By: qcolombet

Differential Revision: https://reviews.llvm.org/D70565
This commit is contained in:
Florian Hahn 2019-12-05 09:16:08 +00:00
parent 4e6a226ee3
commit 63adb49233
5 changed files with 133 additions and 42 deletions

View File

@ -16,11 +16,13 @@
#define LLVM_MC_MCREGISTERINFO_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/MC/MCRegister.h"
#include <cassert>
#include <cstdint>
#include <iterator>
#include <utility>
namespace llvm {
@ -177,6 +179,9 @@ private:
DenseMap<MCRegister, int> L2CVRegs; // LLVM to CV regs mapping
public:
// Forward declaration to become a friend class of DiffListIterator.
template <class SubT> class mc_difflist_iterator;
/// DiffListIterator - Base iterator class that can traverse the
/// differentially encoded register and regunit lists in DiffLists.
/// Don't use this class directly, use one of the specialized sub-classes
@ -220,8 +225,105 @@ public:
if (!advance())
List = nullptr;
}
template <class SubT> friend class MCRegisterInfo::mc_difflist_iterator;
};
/// Forward iterator using DiffListIterator.
template <class SubT>
class mc_difflist_iterator
: public iterator_facade_base<mc_difflist_iterator<SubT>,
std::forward_iterator_tag, MCPhysReg> {
MCRegisterInfo::DiffListIterator Iter;
/// Current value as MCPhysReg, so we can return a reference to it.
MCPhysReg Val;
protected:
mc_difflist_iterator(MCRegisterInfo::DiffListIterator Iter) : Iter(Iter) {}
// Allow conversion between instantiations where valid.
mc_difflist_iterator(MCRegister Reg, const MCPhysReg *DiffList) {
Iter.init(Reg, DiffList);
Val = *Iter;
}
public:
// Allow default construction to build variables, but this doesn't build
// a useful iterator.
mc_difflist_iterator() = default;
/// Return an iterator past the last element.
static SubT end() {
SubT End;
End.Iter.List = nullptr;
return End;
}
bool operator==(const mc_difflist_iterator &Arg) const {
return Iter.List == Arg.Iter.List;
}
const MCPhysReg &operator*() const { return Val; }
using mc_difflist_iterator::iterator_facade_base::operator++;
void operator++() {
assert(Iter.List && "Cannot increment the end iterator!");
++Iter;
Val = *Iter;
}
};
/// Forward iterator over all sub-registers.
/// TODO: Replace remaining uses of MCSubRegIterator.
class mc_subreg_iterator : public mc_difflist_iterator<mc_subreg_iterator> {
public:
mc_subreg_iterator(MCRegisterInfo::DiffListIterator Iter)
: mc_difflist_iterator(Iter) {}
mc_subreg_iterator() = default;
mc_subreg_iterator(MCRegister Reg, const MCRegisterInfo *MCRI)
: mc_difflist_iterator(Reg, MCRI->DiffLists + MCRI->get(Reg).SubRegs) {}
};
/// Forward iterator over all super-registers.
/// TODO: Replace remaining uses of MCSuperRegIterator.
class mc_superreg_iterator
: public mc_difflist_iterator<mc_superreg_iterator> {
public:
mc_superreg_iterator(MCRegisterInfo::DiffListIterator Iter)
: mc_difflist_iterator(Iter) {}
mc_superreg_iterator() = default;
mc_superreg_iterator(MCRegister Reg, const MCRegisterInfo *MCRI)
: mc_difflist_iterator(Reg,
MCRI->DiffLists + MCRI->get(Reg).SuperRegs) {}
};
/// Return an iterator range over all sub-registers of \p Reg, excluding \p
/// Reg.
iterator_range<mc_subreg_iterator> subregs(MCRegister Reg) const {
return make_range(std::next(mc_subreg_iterator(Reg, this)),
mc_subreg_iterator::end());
}
/// Return an iterator range over all sub-registers of \p Reg, including \p
/// Reg.
iterator_range<mc_subreg_iterator> subregs_inclusive(MCRegister Reg) const {
return make_range({Reg, this}, mc_subreg_iterator::end());
}
/// Return an iterator range over all super-registers of \p Reg, excluding \p
/// Reg.
iterator_range<mc_superreg_iterator> superregs(MCRegister Reg) const {
return make_range(std::next(mc_superreg_iterator(Reg, this)),
mc_superreg_iterator::end());
}
/// Return an iterator range over all super-registers of \p Reg, including \p
/// Reg.
iterator_range<mc_superreg_iterator>
superregs_inclusive(MCRegister Reg) const {
return make_range({Reg, this}, mc_superreg_iterator::end());
}
// These iterators are allowed to sub-class DiffListIterator and access
// internal list pointers.
friend class MCSubRegIterator;

View File

@ -124,8 +124,8 @@ namespace {
void addRegWithSubRegs(RegVector &RV, unsigned Reg) {
RV.push_back(Reg);
if (Register::isPhysicalRegister(Reg))
for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs)
RV.push_back(*SubRegs);
for (const MCPhysReg &SubReg : TRI->subregs(Reg))
RV.push_back(SubReg);
}
struct BBInfo {
@ -802,18 +802,16 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
report("MBB live-in list contains non-physical register", MBB);
continue;
}
for (MCSubRegIterator SubRegs(LI.PhysReg, TRI, /*IncludeSelf=*/true);
SubRegs.isValid(); ++SubRegs)
regsLive.insert(*SubRegs);
for (const MCPhysReg &SubReg : TRI->subregs_inclusive(LI.PhysReg))
regsLive.insert(SubReg);
}
}
const MachineFrameInfo &MFI = MF->getFrameInfo();
BitVector PR = MFI.getPristineRegs(*MF);
for (unsigned I : PR.set_bits()) {
for (MCSubRegIterator SubRegs(I, TRI, /*IncludeSelf=*/true);
SubRegs.isValid(); ++SubRegs)
regsLive.insert(*SubRegs);
for (const MCPhysReg &SubReg : TRI->subregs_inclusive(I))
regsLive.insert(SubReg);
}
regsKilled.clear();
@ -2016,9 +2014,9 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
bool Bad = !isReserved(Reg);
// We are fine if just any subregister has a defined value.
if (Bad) {
for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid();
++SubRegs) {
if (regsLive.count(*SubRegs)) {
for (const MCPhysReg &SubReg : TRI->subregs(Reg)) {
if (regsLive.count(SubReg)) {
Bad = false;
break;
}
@ -2036,9 +2034,8 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
if (!Register::isPhysicalRegister(MOP.getReg()))
continue;
for (MCSubRegIterator SubRegs(MOP.getReg(), TRI); SubRegs.isValid();
++SubRegs) {
if (*SubRegs == Reg) {
for (const MCPhysReg &SubReg : TRI->subregs(MOP.getReg())) {
if (SubReg == Reg) {
Bad = false;
break;
}

View File

@ -221,8 +221,8 @@ void RegScavenger::forward() {
// Ideally we would like a way to model this, but leaving the
// insert_subreg around causes both correctness and performance issues.
bool SubUsed = false;
for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs)
if (isRegUsed(*SubRegs)) {
for (const MCPhysReg &SubReg : TRI->subregs(Reg))
if (isRegUsed(SubReg)) {
SubUsed = true;
break;
}

View File

@ -74,27 +74,23 @@ void MipsRegInfoRecord::SetPhysRegUsed(unsigned Reg,
const MCRegisterInfo *MCRegInfo) {
unsigned Value = 0;
for (MCSubRegIterator SubRegIt(Reg, MCRegInfo, true); SubRegIt.isValid();
++SubRegIt) {
unsigned CurrentSubReg = *SubRegIt;
unsigned EncVal = MCRegInfo->getEncodingValue(CurrentSubReg);
for (const MCPhysReg &SubReg : MCRegInfo->subregs_inclusive(Reg)) {
unsigned EncVal = MCRegInfo->getEncodingValue(SubReg);
Value |= 1 << EncVal;
if (GPR32RegClass->contains(CurrentSubReg) ||
GPR64RegClass->contains(CurrentSubReg))
if (GPR32RegClass->contains(SubReg) || GPR64RegClass->contains(SubReg))
ri_gprmask |= Value;
else if (COP0RegClass->contains(CurrentSubReg))
else if (COP0RegClass->contains(SubReg))
ri_cprmask[0] |= Value;
// MIPS COP1 is the FPU.
else if (FGR32RegClass->contains(CurrentSubReg) ||
FGR64RegClass->contains(CurrentSubReg) ||
AFGR64RegClass->contains(CurrentSubReg) ||
MSA128BRegClass->contains(CurrentSubReg))
else if (FGR32RegClass->contains(SubReg) ||
FGR64RegClass->contains(SubReg) ||
AFGR64RegClass->contains(SubReg) ||
MSA128BRegClass->contains(SubReg))
ri_cprmask[1] |= Value;
else if (COP2RegClass->contains(CurrentSubReg))
else if (COP2RegClass->contains(SubReg))
ri_cprmask[2] |= Value;
else if (COP3RegClass->contains(CurrentSubReg))
else if (COP3RegClass->contains(SubReg))
ri_cprmask[3] |= Value;
}
}

View File

@ -530,23 +530,20 @@ BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
Reserved.set(X86::MXCSR);
// Set the stack-pointer register and its aliases as reserved.
for (MCSubRegIterator I(X86::RSP, this, /*IncludeSelf=*/true); I.isValid();
++I)
Reserved.set(*I);
for (const MCPhysReg &SubReg : subregs_inclusive(X86::RSP))
Reserved.set(SubReg);
// Set the Shadow Stack Pointer as reserved.
Reserved.set(X86::SSP);
// Set the instruction pointer register and its aliases as reserved.
for (MCSubRegIterator I(X86::RIP, this, /*IncludeSelf=*/true); I.isValid();
++I)
Reserved.set(*I);
for (const MCPhysReg &SubReg : subregs_inclusive(X86::RIP))
Reserved.set(SubReg);
// Set the frame-pointer register and its aliases as reserved if needed.
if (TFI->hasFP(MF)) {
for (MCSubRegIterator I(X86::RBP, this, /*IncludeSelf=*/true); I.isValid();
++I)
Reserved.set(*I);
for (const MCPhysReg &SubReg : subregs_inclusive(X86::RBP))
Reserved.set(SubReg);
}
// Set the base-pointer register and its aliases as reserved if needed.
@ -559,9 +556,8 @@ BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
"this calling convention.");
Register BasePtr = getX86SubSuperRegister(getBaseRegister(), 64);
for (MCSubRegIterator I(BasePtr, this, /*IncludeSelf=*/true);
I.isValid(); ++I)
Reserved.set(*I);
for (const MCPhysReg &SubReg : subregs_inclusive(BasePtr))
Reserved.set(SubReg);
}
// Mark the segment registers as reserved.