mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-08 21:10:35 +00:00
RegisterScavenging: Move scavenging logic from PEI to RegisterScavenging; NFC
These parts do not depend on any PrologEpilogInserter logic and therefore better fits RegisterScaveging.cpp. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304596 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
efbf6a8cda
commit
465de97122
@ -204,6 +204,10 @@ private:
|
||||
void setLiveInsUsed(const MachineBasicBlock &MBB);
|
||||
};
|
||||
|
||||
/// Replaces all frame index virtual registers with physical registers. Uses the
|
||||
/// register scavenger to find an appropriate register to use.
|
||||
void scavengeFrameVirtualRegs(MachineFunction &MF, RegScavenger &RS);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_CODEGEN_REGISTERSCAVENGING_H
|
||||
|
@ -54,8 +54,6 @@ static void doSpillCalleeSavedRegs(MachineFunction &MF, RegScavenger *RS,
|
||||
const MBBVector &SaveBlocks,
|
||||
const MBBVector &RestoreBlocks);
|
||||
|
||||
static void doScavengeFrameVirtualRegs(MachineFunction &MF, RegScavenger *RS);
|
||||
|
||||
namespace {
|
||||
class PEI : public MachineFunctionPass {
|
||||
public:
|
||||
@ -84,7 +82,7 @@ private:
|
||||
const MBBVector &SaveBlocks,
|
||||
const MBBVector &RestoreBlocks)>
|
||||
SpillCalleeSavedRegisters;
|
||||
std::function<void(MachineFunction &MF, RegScavenger *RS)>
|
||||
std::function<void(MachineFunction &MF, RegScavenger &RS)>
|
||||
ScavengeFrameVirtualRegs;
|
||||
|
||||
bool UsesCalleeSaves = false;
|
||||
@ -142,7 +140,6 @@ MachineFunctionPass *llvm::createPrologEpilogInserterPass() {
|
||||
return new PEI();
|
||||
}
|
||||
|
||||
STATISTIC(NumScavengedRegs, "Number of frame index regs scavenged");
|
||||
STATISTIC(NumBytesStackSpace,
|
||||
"Number of bytes used for stack in all functions");
|
||||
|
||||
@ -168,10 +165,10 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) {
|
||||
SpillCalleeSavedRegisters = [](MachineFunction &, RegScavenger *,
|
||||
unsigned &, unsigned &, const MBBVector &,
|
||||
const MBBVector &) {};
|
||||
ScavengeFrameVirtualRegs = [](MachineFunction &, RegScavenger *) {};
|
||||
ScavengeFrameVirtualRegs = [](MachineFunction &, RegScavenger &) {};
|
||||
} else {
|
||||
SpillCalleeSavedRegisters = doSpillCalleeSavedRegs;
|
||||
ScavengeFrameVirtualRegs = doScavengeFrameVirtualRegs;
|
||||
ScavengeFrameVirtualRegs = scavengeFrameVirtualRegs;
|
||||
UsesCalleeSaves = true;
|
||||
}
|
||||
}
|
||||
@ -222,7 +219,7 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) {
|
||||
// post-pass, scavenge the virtual registers that frame index elimination
|
||||
// inserted.
|
||||
if (TRI->requiresRegisterScavenging(Fn) && FrameIndexVirtualScavenging) {
|
||||
ScavengeFrameVirtualRegs(Fn, RS);
|
||||
ScavengeFrameVirtualRegs(Fn, *RS);
|
||||
|
||||
// Clear any vregs created by virtual scavenging.
|
||||
Fn.getRegInfo().clearVirtRegs();
|
||||
@ -1153,92 +1150,3 @@ void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &Fn,
|
||||
RS->forward(MI);
|
||||
}
|
||||
}
|
||||
|
||||
/// doScavengeFrameVirtualRegs - Replace all frame index virtual registers
|
||||
/// with physical registers. Use the register scavenger to find an
|
||||
/// appropriate register to use.
|
||||
///
|
||||
/// FIXME: Iterating over the instruction stream is unnecessary. We can simply
|
||||
/// iterate over the vreg use list, which at this point only contains machine
|
||||
/// operands for which eliminateFrameIndex need a new scratch reg.
|
||||
static void
|
||||
doScavengeFrameVirtualRegs(MachineFunction &MF, RegScavenger *RS) {
|
||||
// Run through the instructions and find any virtual registers.
|
||||
MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
for (MachineBasicBlock &MBB : MF) {
|
||||
RS->enterBasicBlock(MBB);
|
||||
|
||||
int SPAdj = 0;
|
||||
|
||||
// The instruction stream may change in the loop, so check MBB.end()
|
||||
// directly.
|
||||
for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) {
|
||||
// We might end up here again with a NULL iterator if we scavenged a
|
||||
// register for which we inserted spill code for definition by what was
|
||||
// originally the first instruction in MBB.
|
||||
if (I == MachineBasicBlock::iterator(nullptr))
|
||||
I = MBB.begin();
|
||||
|
||||
const MachineInstr &MI = *I;
|
||||
MachineBasicBlock::iterator J = std::next(I);
|
||||
MachineBasicBlock::iterator P =
|
||||
I == MBB.begin() ? MachineBasicBlock::iterator(nullptr)
|
||||
: std::prev(I);
|
||||
|
||||
// RS should process this instruction before we might scavenge at this
|
||||
// location. This is because we might be replacing a virtual register
|
||||
// defined by this instruction, and if so, registers killed by this
|
||||
// instruction are available, and defined registers are not.
|
||||
RS->forward(I);
|
||||
|
||||
for (const MachineOperand &MO : MI.operands()) {
|
||||
if (!MO.isReg())
|
||||
continue;
|
||||
unsigned Reg = MO.getReg();
|
||||
if (!TargetRegisterInfo::isVirtualRegister(Reg))
|
||||
continue;
|
||||
|
||||
// When we first encounter a new virtual register, it
|
||||
// must be a definition.
|
||||
assert(MO.isDef() && "frame index virtual missing def!");
|
||||
// Scavenge a new scratch register
|
||||
const TargetRegisterClass *RC = MRI.getRegClass(Reg);
|
||||
unsigned ScratchReg = RS->scavengeRegister(RC, J, SPAdj);
|
||||
|
||||
++NumScavengedRegs;
|
||||
|
||||
// Replace this reference to the virtual register with the
|
||||
// scratch register.
|
||||
assert(ScratchReg && "Missing scratch register!");
|
||||
MRI.replaceRegWith(Reg, ScratchReg);
|
||||
|
||||
// Because this instruction was processed by the RS before this
|
||||
// register was allocated, make sure that the RS now records the
|
||||
// register as being used.
|
||||
RS->setRegUsed(ScratchReg);
|
||||
}
|
||||
|
||||
// If the scavenger needed to use one of its spill slots, the
|
||||
// spill code will have been inserted in between I and J. This is a
|
||||
// problem because we need the spill code before I: Move I to just
|
||||
// prior to J.
|
||||
if (I != std::prev(J)) {
|
||||
MBB.splice(J, &MBB, I);
|
||||
|
||||
// Before we move I, we need to prepare the RS to visit I again.
|
||||
// Specifically, RS will assert if it sees uses of registers that
|
||||
// it believes are undefined. Because we have already processed
|
||||
// register kills in I, when it visits I again, it will believe that
|
||||
// those registers are undefined. To avoid this situation, unprocess
|
||||
// the instruction I.
|
||||
assert(RS->getCurrentPosition() == I &&
|
||||
"The register scavenger has an unexpected position");
|
||||
I = P;
|
||||
RS->unprocess(P);
|
||||
} else
|
||||
++I;
|
||||
}
|
||||
}
|
||||
|
||||
MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/CodeGen/RegisterScavenging.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
@ -39,6 +40,8 @@ using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "reg-scavenging"
|
||||
|
||||
STATISTIC(NumScavengedRegs, "Number of frame index regs scavenged");
|
||||
|
||||
void RegScavenger::setRegUsed(unsigned Reg, LaneBitmask LaneMask) {
|
||||
LiveUnits.addRegMasked(Reg, LaneMask);
|
||||
}
|
||||
@ -469,3 +472,88 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
|
||||
|
||||
return SReg;
|
||||
}
|
||||
|
||||
void llvm::scavengeFrameVirtualRegs(MachineFunction &MF, RegScavenger &RS) {
|
||||
// FIXME: Iterating over the instruction stream is unnecessary. We can simply
|
||||
// iterate over the vreg use list, which at this point only contains machine
|
||||
// operands for which eliminateFrameIndex need a new scratch reg.
|
||||
|
||||
// Run through the instructions and find any virtual registers.
|
||||
MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
for (MachineBasicBlock &MBB : MF) {
|
||||
RS.enterBasicBlock(MBB);
|
||||
|
||||
int SPAdj = 0;
|
||||
|
||||
// The instruction stream may change in the loop, so check MBB.end()
|
||||
// directly.
|
||||
for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) {
|
||||
// We might end up here again with a NULL iterator if we scavenged a
|
||||
// register for which we inserted spill code for definition by what was
|
||||
// originally the first instruction in MBB.
|
||||
if (I == MachineBasicBlock::iterator(nullptr))
|
||||
I = MBB.begin();
|
||||
|
||||
const MachineInstr &MI = *I;
|
||||
MachineBasicBlock::iterator J = std::next(I);
|
||||
MachineBasicBlock::iterator P =
|
||||
I == MBB.begin() ? MachineBasicBlock::iterator(nullptr)
|
||||
: std::prev(I);
|
||||
|
||||
// RS should process this instruction before we might scavenge at this
|
||||
// location. This is because we might be replacing a virtual register
|
||||
// defined by this instruction, and if so, registers killed by this
|
||||
// instruction are available, and defined registers are not.
|
||||
RS.forward(I);
|
||||
|
||||
for (const MachineOperand &MO : MI.operands()) {
|
||||
if (!MO.isReg())
|
||||
continue;
|
||||
unsigned Reg = MO.getReg();
|
||||
if (!TargetRegisterInfo::isVirtualRegister(Reg))
|
||||
continue;
|
||||
|
||||
// When we first encounter a new virtual register, it
|
||||
// must be a definition.
|
||||
assert(MO.isDef() && "frame index virtual missing def!");
|
||||
// Scavenge a new scratch register
|
||||
const TargetRegisterClass *RC = MRI.getRegClass(Reg);
|
||||
unsigned ScratchReg = RS.scavengeRegister(RC, J, SPAdj);
|
||||
|
||||
++NumScavengedRegs;
|
||||
|
||||
// Replace this reference to the virtual register with the
|
||||
// scratch register.
|
||||
assert(ScratchReg && "Missing scratch register!");
|
||||
MRI.replaceRegWith(Reg, ScratchReg);
|
||||
|
||||
// Because this instruction was processed by the RS before this
|
||||
// register was allocated, make sure that the RS now records the
|
||||
// register as being used.
|
||||
RS.setRegUsed(ScratchReg);
|
||||
}
|
||||
|
||||
// If the scavenger needed to use one of its spill slots, the
|
||||
// spill code will have been inserted in between I and J. This is a
|
||||
// problem because we need the spill code before I: Move I to just
|
||||
// prior to J.
|
||||
if (I != std::prev(J)) {
|
||||
MBB.splice(J, &MBB, I);
|
||||
|
||||
// Before we move I, we need to prepare the RS to visit I again.
|
||||
// Specifically, RS will assert if it sees uses of registers that
|
||||
// it believes are undefined. Because we have already processed
|
||||
// register kills in I, when it visits I again, it will believe that
|
||||
// those registers are undefined. To avoid this situation, unprocess
|
||||
// the instruction I.
|
||||
assert(RS.getCurrentPosition() == I &&
|
||||
"The register scavenger has an unexpected position");
|
||||
I = P;
|
||||
RS.unprocess(P);
|
||||
} else
|
||||
++I;
|
||||
}
|
||||
}
|
||||
|
||||
MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user