forked from OSchip/llvm-project
RegAllocFast: Use Register
This commit is contained in:
parent
6cb181f086
commit
0202fa3a47
|
@ -82,12 +82,12 @@ namespace {
|
||||||
/// Everything we know about a live virtual register.
|
/// Everything we know about a live virtual register.
|
||||||
struct LiveReg {
|
struct LiveReg {
|
||||||
MachineInstr *LastUse = nullptr; ///< Last instr to use reg.
|
MachineInstr *LastUse = nullptr; ///< Last instr to use reg.
|
||||||
unsigned VirtReg; ///< Virtual register number.
|
Register VirtReg; ///< Virtual register number.
|
||||||
MCPhysReg PhysReg = 0; ///< Currently held here.
|
MCPhysReg PhysReg = 0; ///< Currently held here.
|
||||||
unsigned short LastOpNum = 0; ///< OpNum on LastUse.
|
unsigned short LastOpNum = 0; ///< OpNum on LastUse.
|
||||||
bool Dirty = false; ///< Register needs spill.
|
bool Dirty = false; ///< Register needs spill.
|
||||||
|
|
||||||
explicit LiveReg(unsigned VirtReg) : VirtReg(VirtReg) {}
|
explicit LiveReg(Register VirtReg) : VirtReg(VirtReg) {}
|
||||||
|
|
||||||
unsigned getSparseSetIndex() const {
|
unsigned getSparseSetIndex() const {
|
||||||
return Register::virtReg2Index(VirtReg);
|
return Register::virtReg2Index(VirtReg);
|
||||||
|
@ -128,7 +128,7 @@ namespace {
|
||||||
/// Maps each physical register to a RegState enum or a virtual register.
|
/// Maps each physical register to a RegState enum or a virtual register.
|
||||||
std::vector<unsigned> PhysRegState;
|
std::vector<unsigned> PhysRegState;
|
||||||
|
|
||||||
SmallVector<unsigned, 16> VirtDead;
|
SmallVector<Register, 16> VirtDead;
|
||||||
SmallVector<MachineInstr *, 32> Coalesced;
|
SmallVector<MachineInstr *, 32> Coalesced;
|
||||||
|
|
||||||
using RegUnitSet = SparseSet<uint16_t, identity<uint16_t>>;
|
using RegUnitSet = SparseSet<uint16_t, identity<uint16_t>>;
|
||||||
|
@ -184,14 +184,14 @@ namespace {
|
||||||
void allocateInstruction(MachineInstr &MI);
|
void allocateInstruction(MachineInstr &MI);
|
||||||
void handleDebugValue(MachineInstr &MI);
|
void handleDebugValue(MachineInstr &MI);
|
||||||
void handleThroughOperands(MachineInstr &MI,
|
void handleThroughOperands(MachineInstr &MI,
|
||||||
SmallVectorImpl<unsigned> &VirtDead);
|
SmallVectorImpl<Register> &VirtDead);
|
||||||
bool isLastUseOfLocalReg(const MachineOperand &MO) const;
|
bool isLastUseOfLocalReg(const MachineOperand &MO) const;
|
||||||
|
|
||||||
void addKillFlag(const LiveReg &LRI);
|
void addKillFlag(const LiveReg &LRI);
|
||||||
void killVirtReg(LiveReg &LR);
|
void killVirtReg(LiveReg &LR);
|
||||||
void killVirtReg(unsigned VirtReg);
|
void killVirtReg(Register VirtReg);
|
||||||
void spillVirtReg(MachineBasicBlock::iterator MI, LiveReg &LR);
|
void spillVirtReg(MachineBasicBlock::iterator MI, LiveReg &LR);
|
||||||
void spillVirtReg(MachineBasicBlock::iterator MI, unsigned VirtReg);
|
void spillVirtReg(MachineBasicBlock::iterator MI, Register VirtReg);
|
||||||
|
|
||||||
void usePhysReg(MachineOperand &MO);
|
void usePhysReg(MachineOperand &MO);
|
||||||
void definePhysReg(MachineBasicBlock::iterator MI, MCPhysReg PhysReg,
|
void definePhysReg(MachineBasicBlock::iterator MI, MCPhysReg PhysReg,
|
||||||
|
@ -199,34 +199,34 @@ namespace {
|
||||||
unsigned calcSpillCost(MCPhysReg PhysReg) const;
|
unsigned calcSpillCost(MCPhysReg PhysReg) const;
|
||||||
void assignVirtToPhysReg(LiveReg &, MCPhysReg PhysReg);
|
void assignVirtToPhysReg(LiveReg &, MCPhysReg PhysReg);
|
||||||
|
|
||||||
LiveRegMap::iterator findLiveVirtReg(unsigned VirtReg) {
|
LiveRegMap::iterator findLiveVirtReg(Register VirtReg) {
|
||||||
return LiveVirtRegs.find(Register::virtReg2Index(VirtReg));
|
return LiveVirtRegs.find(Register::virtReg2Index(VirtReg));
|
||||||
}
|
}
|
||||||
|
|
||||||
LiveRegMap::const_iterator findLiveVirtReg(unsigned VirtReg) const {
|
LiveRegMap::const_iterator findLiveVirtReg(Register VirtReg) const {
|
||||||
return LiveVirtRegs.find(Register::virtReg2Index(VirtReg));
|
return LiveVirtRegs.find(Register::virtReg2Index(VirtReg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void allocVirtReg(MachineInstr &MI, LiveReg &LR, unsigned Hint);
|
void allocVirtReg(MachineInstr &MI, LiveReg &LR, Register Hint);
|
||||||
void allocVirtRegUndef(MachineOperand &MO);
|
void allocVirtRegUndef(MachineOperand &MO);
|
||||||
MCPhysReg defineVirtReg(MachineInstr &MI, unsigned OpNum, unsigned VirtReg,
|
MCPhysReg defineVirtReg(MachineInstr &MI, unsigned OpNum, Register VirtReg,
|
||||||
unsigned Hint);
|
Register Hint);
|
||||||
LiveReg &reloadVirtReg(MachineInstr &MI, unsigned OpNum, unsigned VirtReg,
|
LiveReg &reloadVirtReg(MachineInstr &MI, unsigned OpNum, Register VirtReg,
|
||||||
unsigned Hint);
|
Register Hint);
|
||||||
void spillAll(MachineBasicBlock::iterator MI, bool OnlyLiveOut);
|
void spillAll(MachineBasicBlock::iterator MI, bool OnlyLiveOut);
|
||||||
bool setPhysReg(MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg);
|
bool setPhysReg(MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg);
|
||||||
|
|
||||||
unsigned traceCopies(unsigned VirtReg) const;
|
Register traceCopies(Register VirtReg) const;
|
||||||
unsigned traceCopyChain(unsigned Reg) const;
|
Register traceCopyChain(Register Reg) const;
|
||||||
|
|
||||||
int getStackSpaceFor(unsigned VirtReg);
|
int getStackSpaceFor(Register VirtReg);
|
||||||
void spill(MachineBasicBlock::iterator Before, unsigned VirtReg,
|
void spill(MachineBasicBlock::iterator Before, Register VirtReg,
|
||||||
MCPhysReg AssignedReg, bool Kill);
|
MCPhysReg AssignedReg, bool Kill);
|
||||||
void reload(MachineBasicBlock::iterator Before, unsigned VirtReg,
|
void reload(MachineBasicBlock::iterator Before, Register VirtReg,
|
||||||
MCPhysReg PhysReg);
|
MCPhysReg PhysReg);
|
||||||
|
|
||||||
bool mayLiveOut(unsigned VirtReg);
|
bool mayLiveOut(Register VirtReg);
|
||||||
bool mayLiveIn(unsigned VirtReg);
|
bool mayLiveIn(Register VirtReg);
|
||||||
|
|
||||||
void dumpState();
|
void dumpState();
|
||||||
};
|
};
|
||||||
|
@ -244,7 +244,7 @@ void RegAllocFast::setPhysRegState(MCPhysReg PhysReg, unsigned NewState) {
|
||||||
|
|
||||||
/// This allocates space for the specified virtual register to be held on the
|
/// This allocates space for the specified virtual register to be held on the
|
||||||
/// stack.
|
/// stack.
|
||||||
int RegAllocFast::getStackSpaceFor(unsigned VirtReg) {
|
int RegAllocFast::getStackSpaceFor(Register VirtReg) {
|
||||||
// Find the location Reg would belong...
|
// Find the location Reg would belong...
|
||||||
int SS = StackSlotForVirtReg[VirtReg];
|
int SS = StackSlotForVirtReg[VirtReg];
|
||||||
// Already has space allocated?
|
// Already has space allocated?
|
||||||
|
@ -263,7 +263,7 @@ int RegAllocFast::getStackSpaceFor(unsigned VirtReg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns false if \p VirtReg is known to not live out of the current block.
|
/// Returns false if \p VirtReg is known to not live out of the current block.
|
||||||
bool RegAllocFast::mayLiveOut(unsigned VirtReg) {
|
bool RegAllocFast::mayLiveOut(Register VirtReg) {
|
||||||
if (MayLiveAcrossBlocks.test(Register::virtReg2Index(VirtReg))) {
|
if (MayLiveAcrossBlocks.test(Register::virtReg2Index(VirtReg))) {
|
||||||
// Cannot be live-out if there are no successors.
|
// Cannot be live-out if there are no successors.
|
||||||
return !MBB->succ_empty();
|
return !MBB->succ_empty();
|
||||||
|
@ -292,7 +292,7 @@ bool RegAllocFast::mayLiveOut(unsigned VirtReg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns false if \p VirtReg is known to not be live into the current block.
|
/// Returns false if \p VirtReg is known to not be live into the current block.
|
||||||
bool RegAllocFast::mayLiveIn(unsigned VirtReg) {
|
bool RegAllocFast::mayLiveIn(Register VirtReg) {
|
||||||
if (MayLiveAcrossBlocks.test(Register::virtReg2Index(VirtReg)))
|
if (MayLiveAcrossBlocks.test(Register::virtReg2Index(VirtReg)))
|
||||||
return !MBB->pred_empty();
|
return !MBB->pred_empty();
|
||||||
|
|
||||||
|
@ -311,7 +311,7 @@ bool RegAllocFast::mayLiveIn(unsigned VirtReg) {
|
||||||
|
|
||||||
/// Insert spill instruction for \p AssignedReg before \p Before. Update
|
/// Insert spill instruction for \p AssignedReg before \p Before. Update
|
||||||
/// DBG_VALUEs with \p VirtReg operands with the stack slot.
|
/// DBG_VALUEs with \p VirtReg operands with the stack slot.
|
||||||
void RegAllocFast::spill(MachineBasicBlock::iterator Before, unsigned VirtReg,
|
void RegAllocFast::spill(MachineBasicBlock::iterator Before, Register VirtReg,
|
||||||
MCPhysReg AssignedReg, bool Kill) {
|
MCPhysReg AssignedReg, bool Kill) {
|
||||||
LLVM_DEBUG(dbgs() << "Spilling " << printReg(VirtReg, TRI)
|
LLVM_DEBUG(dbgs() << "Spilling " << printReg(VirtReg, TRI)
|
||||||
<< " in " << printReg(AssignedReg, TRI));
|
<< " in " << printReg(AssignedReg, TRI));
|
||||||
|
@ -339,7 +339,7 @@ void RegAllocFast::spill(MachineBasicBlock::iterator Before, unsigned VirtReg,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert reload instruction for \p PhysReg before \p Before.
|
/// Insert reload instruction for \p PhysReg before \p Before.
|
||||||
void RegAllocFast::reload(MachineBasicBlock::iterator Before, unsigned VirtReg,
|
void RegAllocFast::reload(MachineBasicBlock::iterator Before, Register VirtReg,
|
||||||
MCPhysReg PhysReg) {
|
MCPhysReg PhysReg) {
|
||||||
LLVM_DEBUG(dbgs() << "Reloading " << printReg(VirtReg, TRI) << " into "
|
LLVM_DEBUG(dbgs() << "Reloading " << printReg(VirtReg, TRI) << " into "
|
||||||
<< printReg(PhysReg, TRI) << '\n');
|
<< printReg(PhysReg, TRI) << '\n');
|
||||||
|
@ -393,7 +393,7 @@ void RegAllocFast::killVirtReg(LiveReg &LR) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark virtreg as no longer available.
|
/// Mark virtreg as no longer available.
|
||||||
void RegAllocFast::killVirtReg(unsigned VirtReg) {
|
void RegAllocFast::killVirtReg(Register VirtReg) {
|
||||||
assert(Register::isVirtualRegister(VirtReg) &&
|
assert(Register::isVirtualRegister(VirtReg) &&
|
||||||
"killVirtReg needs a virtual register");
|
"killVirtReg needs a virtual register");
|
||||||
LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
|
LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
|
||||||
|
@ -404,7 +404,7 @@ void RegAllocFast::killVirtReg(unsigned VirtReg) {
|
||||||
/// This method spills the value specified by VirtReg into the corresponding
|
/// This method spills the value specified by VirtReg into the corresponding
|
||||||
/// stack slot if needed.
|
/// stack slot if needed.
|
||||||
void RegAllocFast::spillVirtReg(MachineBasicBlock::iterator MI,
|
void RegAllocFast::spillVirtReg(MachineBasicBlock::iterator MI,
|
||||||
unsigned VirtReg) {
|
Register VirtReg) {
|
||||||
assert(Register::isVirtualRegister(VirtReg) &&
|
assert(Register::isVirtualRegister(VirtReg) &&
|
||||||
"Spilling a physical register is illegal!");
|
"Spilling a physical register is illegal!");
|
||||||
LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
|
LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
|
||||||
|
@ -456,7 +456,7 @@ void RegAllocFast::usePhysReg(MachineOperand &MO) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Register PhysReg = MO.getReg();
|
Register PhysReg = MO.getReg();
|
||||||
assert(Register::isPhysicalRegister(PhysReg) && "Bad usePhysReg operand");
|
assert(PhysReg.isPhysical() && "Bad usePhysReg operand");
|
||||||
|
|
||||||
markRegUsedInInstr(PhysReg);
|
markRegUsedInInstr(PhysReg);
|
||||||
switch (PhysRegState[PhysReg]) {
|
switch (PhysRegState[PhysReg]) {
|
||||||
|
@ -520,7 +520,7 @@ void RegAllocFast::usePhysReg(MachineOperand &MO) {
|
||||||
void RegAllocFast::definePhysReg(MachineBasicBlock::iterator MI,
|
void RegAllocFast::definePhysReg(MachineBasicBlock::iterator MI,
|
||||||
MCPhysReg PhysReg, RegState NewState) {
|
MCPhysReg PhysReg, RegState NewState) {
|
||||||
markRegUsedInInstr(PhysReg);
|
markRegUsedInInstr(PhysReg);
|
||||||
switch (unsigned VirtReg = PhysRegState[PhysReg]) {
|
switch (Register VirtReg = PhysRegState[PhysReg]) {
|
||||||
case regDisabled:
|
case regDisabled:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -536,7 +536,7 @@ void RegAllocFast::definePhysReg(MachineBasicBlock::iterator MI,
|
||||||
setPhysRegState(PhysReg, NewState);
|
setPhysRegState(PhysReg, NewState);
|
||||||
for (MCRegAliasIterator AI(PhysReg, TRI, false); AI.isValid(); ++AI) {
|
for (MCRegAliasIterator AI(PhysReg, TRI, false); AI.isValid(); ++AI) {
|
||||||
MCPhysReg Alias = *AI;
|
MCPhysReg Alias = *AI;
|
||||||
switch (unsigned VirtReg = PhysRegState[Alias]) {
|
switch (Register VirtReg = PhysRegState[Alias]) {
|
||||||
case regDisabled:
|
case regDisabled:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -562,7 +562,7 @@ unsigned RegAllocFast::calcSpillCost(MCPhysReg PhysReg) const {
|
||||||
<< " is already used in instr.\n");
|
<< " is already used in instr.\n");
|
||||||
return spillImpossible;
|
return spillImpossible;
|
||||||
}
|
}
|
||||||
switch (unsigned VirtReg = PhysRegState[PhysReg]) {
|
switch (Register VirtReg = PhysRegState[PhysReg]) {
|
||||||
case regDisabled:
|
case regDisabled:
|
||||||
break;
|
break;
|
||||||
case regFree:
|
case regFree:
|
||||||
|
@ -584,7 +584,7 @@ unsigned RegAllocFast::calcSpillCost(MCPhysReg PhysReg) const {
|
||||||
unsigned Cost = 0;
|
unsigned Cost = 0;
|
||||||
for (MCRegAliasIterator AI(PhysReg, TRI, false); AI.isValid(); ++AI) {
|
for (MCRegAliasIterator AI(PhysReg, TRI, false); AI.isValid(); ++AI) {
|
||||||
MCPhysReg Alias = *AI;
|
MCPhysReg Alias = *AI;
|
||||||
switch (unsigned VirtReg = PhysRegState[Alias]) {
|
switch (Register VirtReg = PhysRegState[Alias]) {
|
||||||
case regDisabled:
|
case regDisabled:
|
||||||
break;
|
break;
|
||||||
case regFree:
|
case regFree:
|
||||||
|
@ -608,7 +608,7 @@ unsigned RegAllocFast::calcSpillCost(MCPhysReg PhysReg) const {
|
||||||
/// proper container for VirtReg now. The physical register must not be used
|
/// proper container for VirtReg now. The physical register must not be used
|
||||||
/// for anything else when this is called.
|
/// for anything else when this is called.
|
||||||
void RegAllocFast::assignVirtToPhysReg(LiveReg &LR, MCPhysReg PhysReg) {
|
void RegAllocFast::assignVirtToPhysReg(LiveReg &LR, MCPhysReg PhysReg) {
|
||||||
unsigned VirtReg = LR.VirtReg;
|
Register VirtReg = LR.VirtReg;
|
||||||
LLVM_DEBUG(dbgs() << "Assigning " << printReg(VirtReg, TRI) << " to "
|
LLVM_DEBUG(dbgs() << "Assigning " << printReg(VirtReg, TRI) << " to "
|
||||||
<< printReg(PhysReg, TRI) << '\n');
|
<< printReg(PhysReg, TRI) << '\n');
|
||||||
assert(LR.PhysReg == 0 && "Already assigned a physreg");
|
assert(LR.PhysReg == 0 && "Already assigned a physreg");
|
||||||
|
@ -621,13 +621,13 @@ static bool isCoalescable(const MachineInstr &MI) {
|
||||||
return MI.isFullCopy();
|
return MI.isFullCopy();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned RegAllocFast::traceCopyChain(unsigned Reg) const {
|
Register RegAllocFast::traceCopyChain(Register Reg) const {
|
||||||
static const unsigned ChainLengthLimit = 3;
|
static const unsigned ChainLengthLimit = 3;
|
||||||
unsigned C = 0;
|
unsigned C = 0;
|
||||||
do {
|
do {
|
||||||
if (Register::isPhysicalRegister(Reg))
|
if (Reg.isPhysical())
|
||||||
return Reg;
|
return Reg;
|
||||||
assert(Register::isVirtualRegister(Reg));
|
assert(Reg.isVirtual());
|
||||||
|
|
||||||
MachineInstr *VRegDef = MRI->getUniqueVRegDef(Reg);
|
MachineInstr *VRegDef = MRI->getUniqueVRegDef(Reg);
|
||||||
if (!VRegDef || !isCoalescable(*VRegDef))
|
if (!VRegDef || !isCoalescable(*VRegDef))
|
||||||
|
@ -640,26 +640,26 @@ unsigned RegAllocFast::traceCopyChain(unsigned Reg) const {
|
||||||
/// Check if any of \p VirtReg's definitions is a copy. If it is follow the
|
/// Check if any of \p VirtReg's definitions is a copy. If it is follow the
|
||||||
/// chain of copies to check whether we reach a physical register we can
|
/// chain of copies to check whether we reach a physical register we can
|
||||||
/// coalesce with.
|
/// coalesce with.
|
||||||
unsigned RegAllocFast::traceCopies(unsigned VirtReg) const {
|
Register RegAllocFast::traceCopies(Register VirtReg) const {
|
||||||
static const unsigned DefLimit = 3;
|
static const unsigned DefLimit = 3;
|
||||||
unsigned C = 0;
|
unsigned C = 0;
|
||||||
for (const MachineInstr &MI : MRI->def_instructions(VirtReg)) {
|
for (const MachineInstr &MI : MRI->def_instructions(VirtReg)) {
|
||||||
if (isCoalescable(MI)) {
|
if (isCoalescable(MI)) {
|
||||||
Register Reg = MI.getOperand(1).getReg();
|
Register Reg = MI.getOperand(1).getReg();
|
||||||
Reg = traceCopyChain(Reg);
|
Reg = traceCopyChain(Reg);
|
||||||
if (Reg != 0)
|
if (Reg.isValid())
|
||||||
return Reg;
|
return Reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++C >= DefLimit)
|
if (++C >= DefLimit)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return Register();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocates a physical register for VirtReg.
|
/// Allocates a physical register for VirtReg.
|
||||||
void RegAllocFast::allocVirtReg(MachineInstr &MI, LiveReg &LR, unsigned Hint0) {
|
void RegAllocFast::allocVirtReg(MachineInstr &MI, LiveReg &LR, Register Hint0) {
|
||||||
const unsigned VirtReg = LR.VirtReg;
|
const Register VirtReg = LR.VirtReg;
|
||||||
|
|
||||||
assert(Register::isVirtualRegister(VirtReg) &&
|
assert(Register::isVirtualRegister(VirtReg) &&
|
||||||
"Can only allocate virtual registers");
|
"Can only allocate virtual registers");
|
||||||
|
@ -670,7 +670,7 @@ void RegAllocFast::allocVirtReg(MachineInstr &MI, LiveReg &LR, unsigned Hint0) {
|
||||||
<< " with hint " << printReg(Hint0, TRI) << '\n');
|
<< " with hint " << printReg(Hint0, TRI) << '\n');
|
||||||
|
|
||||||
// Take hint when possible.
|
// Take hint when possible.
|
||||||
if (Register::isPhysicalRegister(Hint0) && MRI->isAllocatable(Hint0) &&
|
if (Hint0.isPhysical() && MRI->isAllocatable(Hint0) &&
|
||||||
RC.contains(Hint0)) {
|
RC.contains(Hint0)) {
|
||||||
// Ignore the hint if we would have to spill a dirty register.
|
// Ignore the hint if we would have to spill a dirty register.
|
||||||
unsigned Cost = calcSpillCost(Hint0);
|
unsigned Cost = calcSpillCost(Hint0);
|
||||||
|
@ -686,12 +686,12 @@ void RegAllocFast::allocVirtReg(MachineInstr &MI, LiveReg &LR, unsigned Hint0) {
|
||||||
<< "occupied\n");
|
<< "occupied\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Hint0 = 0;
|
Hint0 = Register();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try other hint.
|
// Try other hint.
|
||||||
unsigned Hint1 = traceCopies(VirtReg);
|
Register Hint1 = traceCopies(VirtReg);
|
||||||
if (Register::isPhysicalRegister(Hint1) && MRI->isAllocatable(Hint1) &&
|
if (Hint1.isPhysical() && MRI->isAllocatable(Hint1) &&
|
||||||
RC.contains(Hint1) && !isRegUsedInInstr(Hint1)) {
|
RC.contains(Hint1) && !isRegUsedInInstr(Hint1)) {
|
||||||
// Ignore the hint if we would have to spill a dirty register.
|
// Ignore the hint if we would have to spill a dirty register.
|
||||||
unsigned Cost = calcSpillCost(Hint1);
|
unsigned Cost = calcSpillCost(Hint1);
|
||||||
|
@ -707,7 +707,7 @@ void RegAllocFast::allocVirtReg(MachineInstr &MI, LiveReg &LR, unsigned Hint0) {
|
||||||
<< "occupied\n");
|
<< "occupied\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Hint1 = 0;
|
Hint1 = Register();
|
||||||
}
|
}
|
||||||
|
|
||||||
MCPhysReg BestReg = 0;
|
MCPhysReg BestReg = 0;
|
||||||
|
@ -775,14 +775,14 @@ void RegAllocFast::allocVirtRegUndef(MachineOperand &MO) {
|
||||||
|
|
||||||
/// Allocates a register for VirtReg and mark it as dirty.
|
/// Allocates a register for VirtReg and mark it as dirty.
|
||||||
MCPhysReg RegAllocFast::defineVirtReg(MachineInstr &MI, unsigned OpNum,
|
MCPhysReg RegAllocFast::defineVirtReg(MachineInstr &MI, unsigned OpNum,
|
||||||
unsigned VirtReg, unsigned Hint) {
|
Register VirtReg, Register Hint) {
|
||||||
assert(Register::isVirtualRegister(VirtReg) && "Not a virtual register");
|
assert(Register::isVirtualRegister(VirtReg) && "Not a virtual register");
|
||||||
LiveRegMap::iterator LRI;
|
LiveRegMap::iterator LRI;
|
||||||
bool New;
|
bool New;
|
||||||
std::tie(LRI, New) = LiveVirtRegs.insert(LiveReg(VirtReg));
|
std::tie(LRI, New) = LiveVirtRegs.insert(LiveReg(VirtReg));
|
||||||
if (!LRI->PhysReg) {
|
if (!LRI->PhysReg) {
|
||||||
// If there is no hint, peek at the only use of this register.
|
// If there is no hint, peek at the only use of this register.
|
||||||
if ((!Hint || !Register::isPhysicalRegister(Hint)) &&
|
if ((!Hint || !Hint.isPhysical()) &&
|
||||||
MRI->hasOneNonDBGUse(VirtReg)) {
|
MRI->hasOneNonDBGUse(VirtReg)) {
|
||||||
const MachineInstr &UseMI = *MRI->use_instr_nodbg_begin(VirtReg);
|
const MachineInstr &UseMI = *MRI->use_instr_nodbg_begin(VirtReg);
|
||||||
// It's a copy, use the destination register as a hint.
|
// It's a copy, use the destination register as a hint.
|
||||||
|
@ -807,8 +807,8 @@ MCPhysReg RegAllocFast::defineVirtReg(MachineInstr &MI, unsigned OpNum,
|
||||||
/// Make sure VirtReg is available in a physreg and return it.
|
/// Make sure VirtReg is available in a physreg and return it.
|
||||||
RegAllocFast::LiveReg &RegAllocFast::reloadVirtReg(MachineInstr &MI,
|
RegAllocFast::LiveReg &RegAllocFast::reloadVirtReg(MachineInstr &MI,
|
||||||
unsigned OpNum,
|
unsigned OpNum,
|
||||||
unsigned VirtReg,
|
Register VirtReg,
|
||||||
unsigned Hint) {
|
Register Hint) {
|
||||||
assert(Register::isVirtualRegister(VirtReg) && "Not a virtual register");
|
assert(Register::isVirtualRegister(VirtReg) && "Not a virtual register");
|
||||||
LiveRegMap::iterator LRI;
|
LiveRegMap::iterator LRI;
|
||||||
bool New;
|
bool New;
|
||||||
|
@ -884,13 +884,13 @@ bool RegAllocFast::setPhysReg(MachineInstr &MI, MachineOperand &MO,
|
||||||
// Handles special instruction operand like early clobbers and tied ops when
|
// Handles special instruction operand like early clobbers and tied ops when
|
||||||
// there are additional physreg defines.
|
// there are additional physreg defines.
|
||||||
void RegAllocFast::handleThroughOperands(MachineInstr &MI,
|
void RegAllocFast::handleThroughOperands(MachineInstr &MI,
|
||||||
SmallVectorImpl<unsigned> &VirtDead) {
|
SmallVectorImpl<Register> &VirtDead) {
|
||||||
LLVM_DEBUG(dbgs() << "Scanning for through registers:");
|
LLVM_DEBUG(dbgs() << "Scanning for through registers:");
|
||||||
SmallSet<unsigned, 8> ThroughRegs;
|
SmallSet<Register, 8> ThroughRegs;
|
||||||
for (const MachineOperand &MO : MI.operands()) {
|
for (const MachineOperand &MO : MI.operands()) {
|
||||||
if (!MO.isReg()) continue;
|
if (!MO.isReg()) continue;
|
||||||
Register Reg = MO.getReg();
|
Register Reg = MO.getReg();
|
||||||
if (!Register::isVirtualRegister(Reg))
|
if (!Reg.isVirtual())
|
||||||
continue;
|
continue;
|
||||||
if (MO.isEarlyClobber() || (MO.isUse() && MO.isTied()) ||
|
if (MO.isEarlyClobber() || (MO.isUse() && MO.isTied()) ||
|
||||||
(MO.getSubReg() && MI.readsVirtualRegister(Reg))) {
|
(MO.getSubReg() && MI.readsVirtualRegister(Reg))) {
|
||||||
|
@ -905,7 +905,7 @@ void RegAllocFast::handleThroughOperands(MachineInstr &MI,
|
||||||
for (const MachineOperand &MO : MI.operands()) {
|
for (const MachineOperand &MO : MI.operands()) {
|
||||||
if (!MO.isReg() || !MO.isDef()) continue;
|
if (!MO.isReg() || !MO.isDef()) continue;
|
||||||
Register Reg = MO.getReg();
|
Register Reg = MO.getReg();
|
||||||
if (!Reg || !Register::isPhysicalRegister(Reg))
|
if (!Reg || !Reg.isPhysical())
|
||||||
continue;
|
continue;
|
||||||
markRegUsedInInstr(Reg);
|
markRegUsedInInstr(Reg);
|
||||||
for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
|
for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
|
||||||
|
@ -914,7 +914,7 @@ void RegAllocFast::handleThroughOperands(MachineInstr &MI,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SmallVector<unsigned, 8> PartialDefs;
|
SmallVector<Register, 8> PartialDefs;
|
||||||
LLVM_DEBUG(dbgs() << "Allocating tied uses.\n");
|
LLVM_DEBUG(dbgs() << "Allocating tied uses.\n");
|
||||||
for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
|
for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
|
||||||
MachineOperand &MO = MI.getOperand(I);
|
MachineOperand &MO = MI.getOperand(I);
|
||||||
|
@ -961,7 +961,7 @@ void RegAllocFast::handleThroughOperands(MachineInstr &MI,
|
||||||
for (const MachineOperand &MO : MI.operands()) {
|
for (const MachineOperand &MO : MI.operands()) {
|
||||||
if (!MO.isReg() || (MO.isDef() && !MO.isEarlyClobber())) continue;
|
if (!MO.isReg() || (MO.isDef() && !MO.isEarlyClobber())) continue;
|
||||||
Register Reg = MO.getReg();
|
Register Reg = MO.getReg();
|
||||||
if (!Reg || !Register::isPhysicalRegister(Reg))
|
if (!Reg || !Reg.isPhysical())
|
||||||
continue;
|
continue;
|
||||||
LLVM_DEBUG(dbgs() << "\tSetting " << printReg(Reg, TRI)
|
LLVM_DEBUG(dbgs() << "\tSetting " << printReg(Reg, TRI)
|
||||||
<< " as used in instr\n");
|
<< " as used in instr\n");
|
||||||
|
@ -969,7 +969,7 @@ void RegAllocFast::handleThroughOperands(MachineInstr &MI,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also mark PartialDefs as used to avoid reallocation.
|
// Also mark PartialDefs as used to avoid reallocation.
|
||||||
for (unsigned PartialDef : PartialDefs)
|
for (Register PartialDef : PartialDefs)
|
||||||
markRegUsedInInstr(PartialDef);
|
markRegUsedInInstr(PartialDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1002,7 +1002,7 @@ void RegAllocFast::dumpState() {
|
||||||
e = LiveVirtRegs.end(); i != e; ++i) {
|
e = LiveVirtRegs.end(); i != e; ++i) {
|
||||||
if (!i->PhysReg)
|
if (!i->PhysReg)
|
||||||
continue;
|
continue;
|
||||||
assert(Register::isVirtualRegister(i->VirtReg) && "Bad map key");
|
assert(i->VirtReg.isVirtual() && "Bad map key");
|
||||||
assert(Register::isPhysicalRegister(i->PhysReg) && "Bad map value");
|
assert(Register::isPhysicalRegister(i->PhysReg) && "Bad map value");
|
||||||
assert(PhysRegState[i->PhysReg] == i->VirtReg && "Bad inverse map");
|
assert(PhysRegState[i->PhysReg] == i->VirtReg && "Bad inverse map");
|
||||||
}
|
}
|
||||||
|
@ -1013,8 +1013,8 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
|
||||||
const MCInstrDesc &MCID = MI.getDesc();
|
const MCInstrDesc &MCID = MI.getDesc();
|
||||||
|
|
||||||
// If this is a copy, we may be able to coalesce.
|
// If this is a copy, we may be able to coalesce.
|
||||||
unsigned CopySrcReg = 0;
|
Register CopySrcReg;
|
||||||
unsigned CopyDstReg = 0;
|
Register CopyDstReg;
|
||||||
unsigned CopySrcSub = 0;
|
unsigned CopySrcSub = 0;
|
||||||
unsigned CopyDstSub = 0;
|
unsigned CopyDstSub = 0;
|
||||||
if (MI.isCopy()) {
|
if (MI.isCopy()) {
|
||||||
|
@ -1082,7 +1082,7 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
|
||||||
(hasTiedOps && (hasPhysDefs || MCID.getNumDefs() > 1))) {
|
(hasTiedOps && (hasPhysDefs || MCID.getNumDefs() > 1))) {
|
||||||
handleThroughOperands(MI, VirtDead);
|
handleThroughOperands(MI, VirtDead);
|
||||||
// Don't attempt coalescing when we have funny stuff going on.
|
// Don't attempt coalescing when we have funny stuff going on.
|
||||||
CopyDstReg = 0;
|
CopyDstReg = Register();
|
||||||
// Pretend we have early clobbers so the use operands get marked below.
|
// Pretend we have early clobbers so the use operands get marked below.
|
||||||
// This is not necessary for the common case of a single tied use.
|
// This is not necessary for the common case of a single tied use.
|
||||||
hasEarlyClobbers = true;
|
hasEarlyClobbers = true;
|
||||||
|
@ -1095,7 +1095,7 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
|
||||||
MachineOperand &MO = MI.getOperand(I);
|
MachineOperand &MO = MI.getOperand(I);
|
||||||
if (!MO.isReg()) continue;
|
if (!MO.isReg()) continue;
|
||||||
Register Reg = MO.getReg();
|
Register Reg = MO.getReg();
|
||||||
if (!Register::isVirtualRegister(Reg))
|
if (!Reg.isVirtual())
|
||||||
continue;
|
continue;
|
||||||
if (MO.isUse()) {
|
if (MO.isUse()) {
|
||||||
if (MO.isUndef()) {
|
if (MO.isUndef()) {
|
||||||
|
@ -1124,7 +1124,7 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
|
||||||
if (!MO.isReg() || !MO.isUse())
|
if (!MO.isReg() || !MO.isUse())
|
||||||
continue;
|
continue;
|
||||||
Register Reg = MO.getReg();
|
Register Reg = MO.getReg();
|
||||||
if (!Register::isVirtualRegister(Reg))
|
if (!Reg.isVirtual())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
assert(MO.isUndef() && "Should only have undef virtreg uses left");
|
assert(MO.isUndef() && "Should only have undef virtreg uses left");
|
||||||
|
@ -1139,7 +1139,7 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
|
||||||
for (const MachineOperand &MO : MI.operands()) {
|
for (const MachineOperand &MO : MI.operands()) {
|
||||||
if (!MO.isReg()) continue;
|
if (!MO.isReg()) continue;
|
||||||
Register Reg = MO.getReg();
|
Register Reg = MO.getReg();
|
||||||
if (!Reg || !Register::isPhysicalRegister(Reg))
|
if (!Reg || !Reg.isPhysical())
|
||||||
continue;
|
continue;
|
||||||
// Look for physreg defs and tied uses.
|
// Look for physreg defs and tied uses.
|
||||||
if (!MO.isDef() && !MO.isTied()) continue;
|
if (!MO.isDef() && !MO.isTied()) continue;
|
||||||
|
@ -1168,7 +1168,7 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
|
||||||
continue;
|
continue;
|
||||||
Register Reg = MO.getReg();
|
Register Reg = MO.getReg();
|
||||||
|
|
||||||
if (!Reg || !Register::isPhysicalRegister(Reg) || !MRI->isAllocatable(Reg))
|
if (!Reg || !Reg.isPhysical() || !MRI->isAllocatable(Reg))
|
||||||
continue;
|
continue;
|
||||||
definePhysReg(MI, Reg, MO.isDead() ? regFree : regReserved);
|
definePhysReg(MI, Reg, MO.isDead() ? regFree : regReserved);
|
||||||
}
|
}
|
||||||
|
@ -1182,12 +1182,12 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
|
||||||
Register Reg = MO.getReg();
|
Register Reg = MO.getReg();
|
||||||
|
|
||||||
// We have already dealt with phys regs in the previous scan.
|
// We have already dealt with phys regs in the previous scan.
|
||||||
if (Register::isPhysicalRegister(Reg))
|
if (Reg.isPhysical())
|
||||||
continue;
|
continue;
|
||||||
MCPhysReg PhysReg = defineVirtReg(MI, I, Reg, CopySrcReg);
|
MCPhysReg PhysReg = defineVirtReg(MI, I, Reg, CopySrcReg);
|
||||||
if (setPhysReg(MI, MI.getOperand(I), PhysReg)) {
|
if (setPhysReg(MI, MI.getOperand(I), PhysReg)) {
|
||||||
VirtDead.push_back(Reg);
|
VirtDead.push_back(Reg);
|
||||||
CopyDstReg = 0; // cancel coalescing;
|
CopyDstReg = Register(); // cancel coalescing;
|
||||||
} else
|
} else
|
||||||
CopyDstReg = (CopyDstReg == Reg || CopyDstReg == PhysReg) ? PhysReg : 0;
|
CopyDstReg = (CopyDstReg == Reg || CopyDstReg == PhysReg) ? PhysReg : 0;
|
||||||
}
|
}
|
||||||
|
@ -1196,7 +1196,7 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
|
||||||
// register are allocated identically. We didn't need to do this for uses
|
// register are allocated identically. We didn't need to do this for uses
|
||||||
// because we are crerating our own kill flags, and they are always at the
|
// because we are crerating our own kill flags, and they are always at the
|
||||||
// last use.
|
// last use.
|
||||||
for (unsigned VirtReg : VirtDead)
|
for (Register VirtReg : VirtDead)
|
||||||
killVirtReg(VirtReg);
|
killVirtReg(VirtReg);
|
||||||
VirtDead.clear();
|
VirtDead.clear();
|
||||||
|
|
||||||
|
@ -1234,7 +1234,7 @@ void RegAllocFast::handleDebugValue(MachineInstr &MI) {
|
||||||
|
|
||||||
// We can't allocate a physreg for a DebugValue, sorry!
|
// We can't allocate a physreg for a DebugValue, sorry!
|
||||||
LLVM_DEBUG(dbgs() << "Unable to allocate vreg used by DBG_VALUE");
|
LLVM_DEBUG(dbgs() << "Unable to allocate vreg used by DBG_VALUE");
|
||||||
MO.setReg(0);
|
MO.setReg(Register());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If Reg hasn't been spilled, put this DBG_VALUE in LiveDbgValueMap so
|
// If Reg hasn't been spilled, put this DBG_VALUE in LiveDbgValueMap so
|
||||||
|
|
Loading…
Reference in New Issue