mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
LiveRegUnits: Add accumulateBackward() function
Re-Commit r292543 with a fix for the situation when the chain end is MBB.end(). This function can be used to accumulate the set of all read and modified register in a sequence of instructions. Use this code in AArch64A57FPLoadBalancing::scavengeRegister() to prove the concept. - The AArch64A57LoadBalancing code is using a backwards analysis now which is irrespective of kill flags. This is the main motivation for this change. Differential Revision: http://reviews.llvm.org/D22082 llvm-svn: 292705
This commit is contained in:
parent
25c35fa2ae
commit
0243836cdd
@ -76,6 +76,10 @@ public:
|
||||
/// The regmask has the same format as the one in the RegMask machine operand.
|
||||
void removeRegsNotPreserved(const uint32_t *RegMask);
|
||||
|
||||
/// Adds register units not preserved by the regmask \p RegMask.
|
||||
/// The regmask has the same format as the one in the RegMask machine operand.
|
||||
void addRegsInMask(const uint32_t *RegMask);
|
||||
|
||||
/// Returns true if no part of physical register \p Reg is live.
|
||||
bool available(unsigned Reg) const {
|
||||
for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
|
||||
@ -88,6 +92,11 @@ public:
|
||||
/// Updates liveness when stepping backwards over the instruction \p MI.
|
||||
void stepBackward(const MachineInstr &MI);
|
||||
|
||||
/// Mark all register units live during instruction \p MI.
|
||||
/// This can be used to accumulate live/unoccupied registers over a range of
|
||||
/// instructions.
|
||||
void accumulateBackward(const MachineInstr &MI);
|
||||
|
||||
/// Adds registers living out of block \p MBB.
|
||||
/// Live out registers are the union of the live-in registers of the successor
|
||||
/// blocks and pristine registers. Live out registers of the end block are the
|
||||
|
@ -26,6 +26,15 @@ void LiveRegUnits::removeRegsNotPreserved(const uint32_t *RegMask) {
|
||||
}
|
||||
}
|
||||
|
||||
void LiveRegUnits::addRegsInMask(const uint32_t *RegMask) {
|
||||
for (unsigned U = 0, E = TRI->getNumRegUnits(); U != E; ++U) {
|
||||
for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) {
|
||||
if (MachineOperand::clobbersPhysReg(RegMask, *RootReg))
|
||||
Units.set(U);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LiveRegUnits::stepBackward(const MachineInstr &MI) {
|
||||
// Remove defined registers and regmask kills from the set.
|
||||
for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
|
||||
@ -51,6 +60,21 @@ void LiveRegUnits::stepBackward(const MachineInstr &MI) {
|
||||
}
|
||||
}
|
||||
|
||||
void LiveRegUnits::accumulateBackward(const MachineInstr &MI) {
|
||||
// Add defs, uses and regmask clobbers to the set.
|
||||
for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
|
||||
if (O->isReg()) {
|
||||
unsigned Reg = O->getReg();
|
||||
if (!TargetRegisterInfo::isPhysicalRegister(Reg))
|
||||
continue;
|
||||
if (!O->isDef() && !O->readsReg())
|
||||
continue;
|
||||
addReg(Reg);
|
||||
} else if (O->isRegMask())
|
||||
addRegsInMask(O->getRegMask());
|
||||
}
|
||||
}
|
||||
|
||||
/// Add live-in registers of basic block \p MBB to \p LiveUnits.
|
||||
static void addLiveIns(LiveRegUnits &LiveUnits, const MachineBasicBlock &MBB) {
|
||||
for (const auto &LI : MBB.liveins())
|
||||
|
@ -493,43 +493,30 @@ bool AArch64A57FPLoadBalancing::colorChainSet(std::vector<Chain*> GV,
|
||||
|
||||
int AArch64A57FPLoadBalancing::scavengeRegister(Chain *G, Color C,
|
||||
MachineBasicBlock &MBB) {
|
||||
RegScavenger RS;
|
||||
RS.enterBasicBlock(MBB);
|
||||
RS.forward(MachineBasicBlock::iterator(G->getStart()));
|
||||
|
||||
// Can we find an appropriate register that is available throughout the life
|
||||
// of the chain?
|
||||
unsigned RegClassID = G->getStart()->getDesc().OpInfo[0].RegClass;
|
||||
BitVector AvailableRegs = RS.getRegsAvailable(TRI->getRegClass(RegClassID));
|
||||
for (MachineBasicBlock::iterator I = G->begin(), E = G->end(); I != E; ++I) {
|
||||
RS.forward(I);
|
||||
AvailableRegs &= RS.getRegsAvailable(TRI->getRegClass(RegClassID));
|
||||
|
||||
// Remove any registers clobbered by a regmask or any def register that is
|
||||
// immediately dead.
|
||||
for (auto J : I->operands()) {
|
||||
if (J.isRegMask())
|
||||
AvailableRegs.clearBitsNotInMask(J.getRegMask());
|
||||
|
||||
if (J.isReg() && J.isDef()) {
|
||||
MCRegAliasIterator AI(J.getReg(), TRI, /*IncludeSelf=*/true);
|
||||
if (J.isDead())
|
||||
for (; AI.isValid(); ++AI)
|
||||
AvailableRegs.reset(*AI);
|
||||
#ifndef NDEBUG
|
||||
else
|
||||
for (; AI.isValid(); ++AI)
|
||||
assert(!AvailableRegs[*AI] &&
|
||||
"Non-dead def should have been removed by now!");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// of the chain? Simulate liveness backwards until the end of the chain.
|
||||
LiveRegUnits Units(*TRI);
|
||||
Units.addLiveOuts(MBB);
|
||||
MachineBasicBlock::iterator I = MBB.end();
|
||||
MachineBasicBlock::iterator ChainEnd = G->end();
|
||||
while (I != ChainEnd) {
|
||||
--I;
|
||||
Units.stepBackward(*I);
|
||||
}
|
||||
|
||||
// Check which register units are alive throughout the chain.
|
||||
MachineBasicBlock::iterator ChainBegin = G->begin();
|
||||
assert(ChainBegin != ChainEnd && "Chain should contain instructions");
|
||||
do {
|
||||
--I;
|
||||
Units.accumulateBackward(*I);
|
||||
} while (I != ChainBegin);
|
||||
|
||||
// Make sure we allocate in-order, to get the cheapest registers first.
|
||||
unsigned RegClassID = ChainBegin->getDesc().OpInfo[0].RegClass;
|
||||
auto Ord = RCI.getOrder(TRI->getRegClass(RegClassID));
|
||||
for (auto Reg : Ord) {
|
||||
if (!AvailableRegs[Reg])
|
||||
if (!Units.available(Reg))
|
||||
continue;
|
||||
if (C == getColor(Reg))
|
||||
return Reg;
|
||||
|
Loading…
Reference in New Issue
Block a user