1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +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 #define LLVM_MC_MCREGISTERINFO_H
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/iterator_range.h"
#include "llvm/MC/LaneBitmask.h" #include "llvm/MC/LaneBitmask.h"
#include "llvm/MC/MCRegister.h" #include "llvm/MC/MCRegister.h"
#include <cassert> #include <cassert>
#include <cstdint> #include <cstdint>
#include <iterator>
#include <utility> #include <utility>
namespace llvm { namespace llvm {
@ -177,6 +179,9 @@ private:
DenseMap<MCRegister, int> L2CVRegs; // LLVM to CV regs mapping DenseMap<MCRegister, int> L2CVRegs; // LLVM to CV regs mapping
public: 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 /// DiffListIterator - Base iterator class that can traverse the
/// differentially encoded register and regunit lists in DiffLists. /// differentially encoded register and regunit lists in DiffLists.
/// Don't use this class directly, use one of the specialized sub-classes /// Don't use this class directly, use one of the specialized sub-classes
@ -220,8 +225,105 @@ public:
if (!advance()) if (!advance())
List = nullptr; 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 // These iterators are allowed to sub-class DiffListIterator and access
// internal list pointers. // internal list pointers.
friend class MCSubRegIterator; friend class MCSubRegIterator;

View File

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

View File

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

View File

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

View File

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