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:
parent
4e6a226ee3
commit
63adb49233
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user