const MachineBlockFrequencyInfo *MBFI,
const MachineBasicBlock *MBB);
- LiveInterval &getInterval(unsigned Reg) {
+ LiveInterval &getInterval(Register Reg) {
if (hasInterval(Reg))
- return *VirtRegIntervals[Reg];
+ return *VirtRegIntervals[Reg.id()];
else
return createAndComputeVirtRegInterval(Reg);
}
- const LiveInterval &getInterval(unsigned Reg) const {
+ const LiveInterval &getInterval(Register Reg) const {
return const_cast<LiveIntervals*>(this)->getInterval(Reg);
}
- bool hasInterval(unsigned Reg) const {
- return VirtRegIntervals.inBounds(Reg) && VirtRegIntervals[Reg];
+ bool hasInterval(Register Reg) const {
+ return VirtRegIntervals.inBounds(Reg.id()) &&
+ VirtRegIntervals[Reg.id()];
}
/// Interval creation.
- LiveInterval &createEmptyInterval(unsigned Reg) {
+ LiveInterval &createEmptyInterval(Register Reg) {
assert(!hasInterval(Reg) && "Interval already exists!");
- VirtRegIntervals.grow(Reg);
- VirtRegIntervals[Reg] = createInterval(Reg);
- return *VirtRegIntervals[Reg];
+ VirtRegIntervals.grow(Reg.id());
+ VirtRegIntervals[Reg.id()] = createInterval(Reg);
+ return *VirtRegIntervals[Reg.id()];
}
- LiveInterval &createAndComputeVirtRegInterval(unsigned Reg) {
+ LiveInterval &createAndComputeVirtRegInterval(Register Reg) {
LiveInterval &LI = createEmptyInterval(Reg);
computeVirtRegInterval(LI);
return LI;
ModifiedRegUnits.addRegsInMask(O->getRegMask());
if (!O->isReg())
continue;
- unsigned Reg = O->getReg();
- if (!Register::isPhysicalRegister(Reg))
+ Register Reg = O->getReg();
+ if (!Reg.isPhysical())
continue;
if (O->isDef()) {
// Some architectures (e.g. AArch64 XZR/WZR) have registers that are
/// Adds the specified register as a live in. Note that it is an error to add
/// the same register to the same set more than once unless the intention is
/// to call sortUniqueLiveIns after all registers are added.
- void addLiveIn(MCPhysReg PhysReg,
+ void addLiveIn(MCRegister PhysReg,
LaneBitmask LaneMask = LaneBitmask::getAll()) {
LiveIns.push_back(RegisterMaskPair(PhysReg, LaneMask));
}
/// Add PhysReg as live in to this block, and ensure that there is a copy of
/// PhysReg to a virtual register of class RC. Return the virtual register
/// that is a copy of the live in PhysReg.
- unsigned addLiveIn(MCPhysReg PhysReg, const TargetRegisterClass *RC);
+ unsigned addLiveIn(MCRegister PhysReg, const TargetRegisterClass *RC);
/// Remove the specified register from the live in set.
void removeLiveIn(MCPhysReg Reg,
/// Return true if the instruction is a debug value which describes a part of
/// a variable as unavailable.
bool isUndefDebugValue() const {
- return isDebugValue() && getOperand(0).isReg() && !getOperand(0).getReg();
+ return isDebugValue() && getOperand(0).isReg() && !getOperand(0).getReg().isValid();
}
bool isPHI() const {
/// getRegUseDefListHead - Return the head pointer for the register use/def
/// list for the specified virtual or physical register.
- MachineOperand *&getRegUseDefListHead(unsigned RegNo) {
- if (Register::isVirtualRegister(RegNo))
- return VRegInfo[RegNo].second;
- return PhysRegUseDefLists[RegNo];
+ MachineOperand *&getRegUseDefListHead(Register RegNo) {
+ if (RegNo.isVirtual())
+ return VRegInfo[RegNo.id()].second;
+ return PhysRegUseDefLists[RegNo.id()];
}
- MachineOperand *getRegUseDefListHead(unsigned RegNo) const {
- if (Register::isVirtualRegister(RegNo))
- return VRegInfo[RegNo].second;
- return PhysRegUseDefLists[RegNo];
+ MachineOperand *getRegUseDefListHead(Register RegNo) const {
+ if (RegNo.isVirtual())
+ return VRegInfo[RegNo.id()].second;
+ return PhysRegUseDefLists[RegNo.id()];
}
/// Get the next element in the use-def chain.
bool shouldTrackSubRegLiveness(const TargetRegisterClass &RC) const {
return subRegLivenessEnabled() && RC.HasDisjunctSubRegs;
}
- bool shouldTrackSubRegLiveness(unsigned VReg) const {
- assert(Register::isVirtualRegister(VReg) && "Must pass a VReg");
+ bool shouldTrackSubRegLiveness(Register VReg) const {
+ assert(VReg.isVirtual() && "Must pass a VReg");
return shouldTrackSubRegLiveness(*getRegClass(VReg));
}
bool subRegLivenessEnabled() const {
/// of the specified register, skipping those marked as Debug.
using reg_nodbg_iterator =
defusechain_iterator<true, true, true, true, false, false>;
- reg_nodbg_iterator reg_nodbg_begin(unsigned RegNo) const {
+ reg_nodbg_iterator reg_nodbg_begin(Register RegNo) const {
return reg_nodbg_iterator(getRegUseDefListHead(RegNo));
}
static reg_nodbg_iterator reg_nodbg_end() {
/// reg_nodbg_empty - Return true if the only instructions using or defining
/// Reg are Debug instructions.
- bool reg_nodbg_empty(unsigned RegNo) const {
+ bool reg_nodbg_empty(Register RegNo) const {
return reg_nodbg_begin(RegNo) == reg_nodbg_end();
}
/// Return the register class of the specified virtual register.
/// This shouldn't be used directly unless \p Reg has a register class.
/// \see getRegClassOrNull when this might happen.
- const TargetRegisterClass *getRegClass(unsigned Reg) const {
- assert(VRegInfo[Reg].first.is<const TargetRegisterClass *>() &&
+ const TargetRegisterClass *getRegClass(Register Reg) const {
+ assert(VRegInfo[Reg.id()].first.is<const TargetRegisterClass *>() &&
"Register class not set, wrong accessor");
- return VRegInfo[Reg].first.get<const TargetRegisterClass *>();
+ return VRegInfo[Reg.id()].first.get<const TargetRegisterClass *>();
}
/// Return the register class of \p Reg, or null if Reg has not been assigned
/// specified virtual register. If there are many hints, this returns the
/// one with the greatest weight.
std::pair<unsigned, unsigned>
- getRegAllocationHint(unsigned VReg) const {
- assert(Register::isVirtualRegister(VReg));
- unsigned BestHint = (RegAllocHints[VReg].second.size() ?
- RegAllocHints[VReg].second[0] : 0);
- return std::pair<unsigned, unsigned>(RegAllocHints[VReg].first, BestHint);
+ getRegAllocationHint(Register VReg) const {
+ assert(VReg.isVirtual());
+ unsigned BestHint = (RegAllocHints[VReg.id()].second.size() ?
+ RegAllocHints[VReg.id()].second[0] : 0);
+ return std::pair<unsigned, unsigned>(RegAllocHints[VReg.id()].first,
+ BestHint);
}
/// getSimpleHint - same as getRegAllocationHint except it will only return
/// a target independent hint.
- unsigned getSimpleHint(unsigned VReg) const {
- assert(Register::isVirtualRegister(VReg));
+ Register getSimpleHint(Register VReg) const {
+ assert(VReg.isVirtual());
std::pair<unsigned, unsigned> Hint = getRegAllocationHint(VReg);
return Hint.first ? 0 : Hint.second;
}
///
/// Reserved registers may belong to an allocatable register class, but the
/// target has explicitly requested that they are not used.
- bool isReserved(unsigned PhysReg) const {
- return getReservedRegs().test(PhysReg);
+ bool isReserved(Register PhysReg) const {
+ return getReservedRegs().test(PhysReg.id());
}
/// Returns true when the given register unit is considered reserved.
return Reg;
}
+ unsigned id() const { return Reg; }
+
operator MCRegister() const {
return MCRegister(Reg);
}
/// Comparisons between register objects
bool operator==(const Register &Other) const { return Reg == Other.Reg; }
bool operator!=(const Register &Other) const { return Reg != Other.Reg; }
+ bool operator==(const MCRegister &Other) const { return Reg == Other.id(); }
+ bool operator!=(const MCRegister &Other) const { return Reg != Other.id(); }
/// Comparisons against register constants. E.g.
/// * R == AArch64::WZR
return DenseMapInfo<unsigned>::getTombstoneKey();
}
static unsigned getHashValue(const Register &Val) {
- return DenseMapInfo<unsigned>::getHashValue(Val);
+ return DenseMapInfo<unsigned>::getHashValue(Val.id());
}
static bool isEqual(const Register &LHS, const Register &RHS) {
- return DenseMapInfo<unsigned>::isEqual(LHS, RHS);
+ return DenseMapInfo<unsigned>::isEqual(LHS.id(), RHS.id());
}
};
/// Returns true if the two registers are equal or alias each other.
/// The registers may be virtual registers.
- bool regsOverlap(unsigned regA, unsigned regB) const {
+ bool regsOverlap(Register regA, Register regB) const {
if (regA == regB) return true;
- if (Register::isVirtualRegister(regA) || Register::isVirtualRegister(regB))
+ if (regA.isVirtual() || regB.isVirtual())
return false;
// Regunits are numerically ordered. Find a common unit.
/// %physreg17 - a physical register when no TRI instance given.
///
/// Usage: OS << printReg(Reg, TRI, SubRegIdx) << '\n';
-Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI = nullptr,
+Printable printReg(Register Reg, const TargetRegisterInfo *TRI = nullptr,
unsigned SubIdx = 0,
const MachineRegisterInfo *MRI = nullptr);
/// it; even spilled virtual registers (the register mapped to a
/// spilled register is the temporary used to load it from the
/// stack).
- IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2PhysMap;
+ IndexedMap<Register, VirtReg2IndexFunctor> Virt2PhysMap;
/// Virt2StackSlotMap - This is virtual register to stack slot
/// mapping. Each spilled virtual register has an entry in it
/// returns true if the specified virtual register is
/// mapped to a physical register
- bool hasPhys(unsigned virtReg) const {
+ bool hasPhys(Register virtReg) const {
return getPhys(virtReg) != NO_PHYS_REG;
}
/// virtual register
Register getPhys(Register virtReg) const {
assert(virtReg.isVirtual());
- return Virt2PhysMap[virtReg];
+ return Virt2PhysMap[virtReg.id()];
}
/// creates a mapping for the specified virtual register to
/// the specified physical register
- void assignVirt2Phys(unsigned virtReg, MCPhysReg physReg);
+ void assignVirt2Phys(Register virtReg, MCPhysReg physReg);
/// clears the specified virtual register's, physical
/// register mapping
- void clearVirt(unsigned virtReg) {
- assert(Register::isVirtualRegister(virtReg));
- assert(Virt2PhysMap[virtReg] != NO_PHYS_REG &&
+ void clearVirt(Register virtReg) {
+ assert(virtReg.isVirtual());
+ assert(Virt2PhysMap[virtReg.id()] != NO_PHYS_REG &&
"attempt to clear a not assigned virtual register");
- Virt2PhysMap[virtReg] = NO_PHYS_REG;
+ Virt2PhysMap[virtReg.id()] = NO_PHYS_REG;
}
/// clears all virtual to physical register mappings
}
/// returns true if VirtReg is assigned to its preferred physreg.
- bool hasPreferredPhys(unsigned VirtReg);
+ bool hasPreferredPhys(Register VirtReg);
/// returns true if VirtReg has a known preferred register.
/// This returns false if VirtReg has a preference that is a virtual
/// register that hasn't been assigned yet.
- bool hasKnownPreference(unsigned VirtReg);
+ bool hasKnownPreference(Register VirtReg);
/// records virtReg is a split live interval from SReg.
- void setIsSplitFromReg(unsigned virtReg, unsigned SReg) {
- Virt2SplitMap[virtReg] = SReg;
+ void setIsSplitFromReg(Register virtReg, unsigned SReg) {
+ Virt2SplitMap[virtReg.id()] = SReg;
}
/// returns the live interval virtReg is split from.
- unsigned getPreSplitReg(unsigned virtReg) const {
- return Virt2SplitMap[virtReg];
+ unsigned getPreSplitReg(Register virtReg) const {
+ return Virt2SplitMap[virtReg.id()];
}
/// getOriginal - Return the original virtual register that VirtReg descends
/// returns true if the specified virtual register is not
/// mapped to a stack slot or rematerialized.
- bool isAssignedReg(unsigned virtReg) const {
+ bool isAssignedReg(Register virtReg) const {
if (getStackSlot(virtReg) == NO_STACK_SLOT)
return true;
// Split register can be assigned a physical register as well as a
// stack slot or remat id.
- return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg] != NO_PHYS_REG);
+ return (Virt2SplitMap[virtReg.id()] &&
+ Virt2PhysMap[virtReg.id()] != NO_PHYS_REG);
}
/// returns the stack slot mapped to the specified virtual
/// register
- int getStackSlot(unsigned virtReg) const {
- assert(Register::isVirtualRegister(virtReg));
- return Virt2StackSlotMap[virtReg];
+ int getStackSlot(Register virtReg) const {
+ assert(virtReg.isVirtual());
+ return Virt2StackSlotMap[virtReg.id()];
}
/// create a mapping for the specifed virtual register to
/// the next available stack slot
- int assignVirt2StackSlot(unsigned virtReg);
+ int assignVirt2StackSlot(Register virtReg);
/// create a mapping for the specified virtual register to
/// the specified stack slot
- void assignVirt2StackSlot(unsigned virtReg, int SS);
+ void assignVirt2StackSlot(Register virtReg, int SS);
void print(raw_ostream &OS, const Module* M = nullptr) const override;
void dump() const;
return Reg;
}
+ unsigned id() const {
+ return Reg;
+ }
+
bool isValid() const {
return Reg != 0;
}
return DenseMapInfo<unsigned>::getTombstoneKey();
}
static unsigned getHashValue(const MCRegister &Val) {
- return DenseMapInfo<unsigned>::getHashValue(Val);
+ return DenseMapInfo<unsigned>::getHashValue(Val.id());
}
static bool isEqual(const MCRegister &LHS, const MCRegister &RHS) {
- return DenseMapInfo<unsigned>::isEqual(LHS, RHS);
+ return DenseMapInfo<unsigned>::isEqual(LHS.id(), RHS.id());
}
};
}
unsigned
-MachineBasicBlock::addLiveIn(MCPhysReg PhysReg, const TargetRegisterClass *RC) {
+MachineBasicBlock::addLiveIn(MCRegister PhysReg, const TargetRegisterClass *RC) {
assert(getParent() && "MBB must be inserted in function");
- assert(Register::isPhysicalRegister(PhysReg) && "Expected physreg");
+ assert(PhysReg.isPhysical() && "Expected physreg");
assert(RC && "Register class is required");
assert((isEHPad() || this == &getParent()->front()) &&
"Only the entry block and landing pads can have physreg live ins");
namespace llvm {
-Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI,
+Printable printReg(Register Reg, const TargetRegisterInfo *TRI,
unsigned SubIdx, const MachineRegisterInfo *MRI) {
return Printable([Reg, TRI, SubIdx, MRI](raw_ostream &OS) {
if (!Reg)
Virt2SplitMap.resize(NumRegs);
}
-void VirtRegMap::assignVirt2Phys(unsigned virtReg, MCPhysReg physReg) {
- assert(Register::isVirtualRegister(virtReg) &&
- Register::isPhysicalRegister(physReg));
- assert(Virt2PhysMap[virtReg] == NO_PHYS_REG &&
+void VirtRegMap::assignVirt2Phys(Register virtReg, MCPhysReg physReg) {
+ assert(virtReg.isVirtual() && Register::isPhysicalRegister(physReg));
+ assert(Virt2PhysMap[virtReg.id()] == NO_PHYS_REG &&
"attempt to assign physical register to already mapped "
"virtual register");
assert(!getRegInfo().isReserved(physReg) &&
"Attempt to map virtReg to a reserved physReg");
- Virt2PhysMap[virtReg] = physReg;
+ Virt2PhysMap[virtReg.id()] = physReg;
}
unsigned VirtRegMap::createSpillSlot(const TargetRegisterClass *RC) {
return SS;
}
-bool VirtRegMap::hasPreferredPhys(unsigned VirtReg) {
- unsigned Hint = MRI->getSimpleHint(VirtReg);
- if (!Hint)
+bool VirtRegMap::hasPreferredPhys(Register VirtReg) {
+ Register Hint = MRI->getSimpleHint(VirtReg);
+ if (!Hint.isValid())
return false;
- if (Register::isVirtualRegister(Hint))
+ if (Hint.isVirtual())
Hint = getPhys(Hint);
return getPhys(VirtReg) == Hint;
}
-bool VirtRegMap::hasKnownPreference(unsigned VirtReg) {
+bool VirtRegMap::hasKnownPreference(Register VirtReg) {
std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(VirtReg);
if (Register::isPhysicalRegister(Hint.second))
return true;
return false;
}
-int VirtRegMap::assignVirt2StackSlot(unsigned virtReg) {
- assert(Register::isVirtualRegister(virtReg));
- assert(Virt2StackSlotMap[virtReg] == NO_STACK_SLOT &&
+int VirtRegMap::assignVirt2StackSlot(Register virtReg) {
+ assert(virtReg.isVirtual());
+ assert(Virt2StackSlotMap[virtReg.id()] == NO_STACK_SLOT &&
"attempt to assign stack slot to already spilled register");
const TargetRegisterClass* RC = MF->getRegInfo().getRegClass(virtReg);
- return Virt2StackSlotMap[virtReg] = createSpillSlot(RC);
+ return Virt2StackSlotMap[virtReg.id()] = createSpillSlot(RC);
}
-void VirtRegMap::assignVirt2StackSlot(unsigned virtReg, int SS) {
- assert(Register::isVirtualRegister(virtReg));
- assert(Virt2StackSlotMap[virtReg] == NO_STACK_SLOT &&
+void VirtRegMap::assignVirt2StackSlot(Register virtReg, int SS) {
+ assert(virtReg.isVirtual());
+ assert(Virt2StackSlotMap[virtReg.id()] == NO_STACK_SLOT &&
"attempt to assign stack slot to already spilled register");
assert((SS >= 0 ||
(SS >= MF->getFrameInfo().getObjectIndexBegin())) &&
"illegal fixed frame index");
- Virt2StackSlotMap[virtReg] = SS;
+ Virt2StackSlotMap[virtReg.id()] = SS;
}
void VirtRegMap::print(raw_ostream &OS, const Module*) const {
void rewrite();
void addMBBLiveIns();
bool readsUndefSubreg(const MachineOperand &MO) const;
- void addLiveInsForSubRanges(const LiveInterval &LI, unsigned PhysReg) const;
+ void addLiveInsForSubRanges(const LiveInterval &LI, Register PhysReg) const;
void handleIdentityCopy(MachineInstr &MI) const;
void expandCopyBundle(MachineInstr &MI) const;
- bool subRegLiveThrough(const MachineInstr &MI, unsigned SuperPhysReg) const;
+ bool subRegLiveThrough(const MachineInstr &MI, Register SuperPhysReg) const;
public:
static char ID;
}
void VirtRegRewriter::addLiveInsForSubRanges(const LiveInterval &LI,
- unsigned PhysReg) const {
+ Register PhysReg) const {
assert(!LI.empty());
assert(LI.hasSubRanges());
// assignments.
void VirtRegRewriter::addMBBLiveIns() {
for (unsigned Idx = 0, IdxE = MRI->getNumVirtRegs(); Idx != IdxE; ++Idx) {
- unsigned VirtReg = Register::index2VirtReg(Idx);
+ Register VirtReg = Register::index2VirtReg(Idx);
if (MRI->reg_nodbg_empty(VirtReg))
continue;
LiveInterval &LI = LIS->getInterval(VirtReg);
continue;
// This is a virtual register that is live across basic blocks. Its
// assigned PhysReg must be marked as live-in to those blocks.
- unsigned PhysReg = VRM->getPhys(VirtReg);
+ Register PhysReg = VRM->getPhys(VirtReg);
assert(PhysReg != VirtRegMap::NO_PHYS_REG && "Unmapped virtual register.");
if (LI.hasSubRanges()) {
if (MO.isUndef())
return true;
- unsigned Reg = MO.getReg();
+ Register Reg = MO.getReg();
const LiveInterval &LI = LIS->getInterval(Reg);
const MachineInstr &MI = *MO.getParent();
SlotIndex BaseIndex = LIS->getInstructionIndex(MI);
/// \pre \p MI defines a subregister of a virtual register that
/// has been assigned to \p SuperPhysReg.
bool VirtRegRewriter::subRegLiveThrough(const MachineInstr &MI,
- unsigned SuperPhysReg) const {
+ Register SuperPhysReg) const {
SlotIndex MIIndex = LIS->getInstructionIndex(MI);
SlotIndex BeforeMIUses = MIIndex.getBaseIndex();
SlotIndex AfterMIDefs = MIIndex.getBoundaryIndex();
void VirtRegRewriter::rewrite() {
bool NoSubRegLiveness = !MRI->subRegLivenessEnabled();
- SmallVector<unsigned, 8> SuperDeads;
- SmallVector<unsigned, 8> SuperDefs;
- SmallVector<unsigned, 8> SuperKills;
+ SmallVector<Register, 8> SuperDeads;
+ SmallVector<Register, 8> SuperDefs;
+ SmallVector<Register, 8> SuperKills;
for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end();
MBBI != MBBE; ++MBBI) {
if (MO.isRegMask())
MRI->addPhysRegsUsedFromRegMask(MO.getRegMask());
- if (!MO.isReg() || !Register::isVirtualRegister(MO.getReg()))
+ if (!MO.isReg() || !MO.getReg().isVirtual())
continue;
- unsigned VirtReg = MO.getReg();
- unsigned PhysReg = VRM->getPhys(VirtReg);
+ Register VirtReg = MO.getReg();
+ Register PhysReg = VRM->getPhys(VirtReg);
assert(PhysReg != VirtRegMap::NO_PHYS_REG &&
"Instruction uses unmapped VirtReg");
assert(!MRI->isReserved(PhysReg) && "Reserved register assignment");
// PhysReg operands cannot have subregister indexes.
PhysReg = TRI->getSubReg(PhysReg, SubReg);
- assert(PhysReg && "Invalid SubReg for physical register");
+ assert(PhysReg.isValid() && "Invalid SubReg for physical register");
MO.setSubReg(0);
}
// Rewrite. Note we could have used MachineOperand::substPhysReg(), but