mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
Simplify PHI node elimination significantly by doing it as a prepass to
register allocation llvm-svn: 5066
This commit is contained in:
parent
4964e751cd
commit
6a2d7bef14
@ -212,6 +212,7 @@ RegAllocSimple::saveVirtRegToStack (MachineBasicBlock &MBB,
|
|||||||
|
|
||||||
/// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions in
|
/// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions in
|
||||||
/// predecessor basic blocks.
|
/// predecessor basic blocks.
|
||||||
|
///
|
||||||
void RegAllocSimple::EliminatePHINodes(MachineBasicBlock &MBB) {
|
void RegAllocSimple::EliminatePHINodes(MachineBasicBlock &MBB) {
|
||||||
const MachineInstrInfo &MII = TM.getInstrInfo();
|
const MachineInstrInfo &MII = TM.getInstrInfo();
|
||||||
|
|
||||||
@ -220,26 +221,12 @@ void RegAllocSimple::EliminatePHINodes(MachineBasicBlock &MBB) {
|
|||||||
// Unlink the PHI node from the basic block... but don't delete the PHI yet
|
// Unlink the PHI node from the basic block... but don't delete the PHI yet
|
||||||
MBB.erase(MBB.begin());
|
MBB.erase(MBB.begin());
|
||||||
|
|
||||||
DEBUG(std::cerr << "num invalid regs: " << RegsUsed.size() << "\n");
|
|
||||||
DEBUG(std::cerr << "num ops: " << MI->getNumOperands() << "\n");
|
DEBUG(std::cerr << "num ops: " << MI->getNumOperands() << "\n");
|
||||||
assert(MI->getOperand(0).isVirtualRegister() &&
|
assert(MI->getOperand(0).isVirtualRegister() &&
|
||||||
"PHI node doesn't write virt reg?");
|
"PHI node doesn't write virt reg?");
|
||||||
|
|
||||||
// a preliminary pass that will invalidate any registers that
|
|
||||||
// are used by the instruction (including implicit uses)
|
|
||||||
invalidatePhysRegs(MI);
|
|
||||||
|
|
||||||
// Allocate a physical reg to hold this temporary.
|
|
||||||
//
|
|
||||||
unsigned virtualReg = MI->getOperand(0).getAllocatedRegNum();
|
unsigned virtualReg = MI->getOperand(0).getAllocatedRegNum();
|
||||||
unsigned physReg = getFreeReg(virtualReg);
|
|
||||||
|
|
||||||
// Find the register class of the target register: should be the
|
|
||||||
// same as the values we're trying to store there
|
|
||||||
const TargetRegisterClass* regClass = MF->getRegClass(virtualReg);
|
|
||||||
assert(regClass && "Target register class not found!");
|
|
||||||
unsigned dataSize = regClass->getDataSize();
|
|
||||||
|
|
||||||
for (int i = MI->getNumOperands() - 1; i >= 2; i-=2) {
|
for (int i = MI->getNumOperands() - 1; i >= 2; i-=2) {
|
||||||
MachineOperand &opVal = MI->getOperand(i-1);
|
MachineOperand &opVal = MI->getOperand(i-1);
|
||||||
|
|
||||||
@ -274,27 +261,20 @@ void RegAllocSimple::EliminatePHINodes(MachineBasicBlock &MBB) {
|
|||||||
// are inserted right in front of it and not in front of a non-branch
|
// are inserted right in front of it and not in front of a non-branch
|
||||||
if (!MII.isBranch(opMI->getOpcode()))
|
if (!MII.isBranch(opMI->getOpcode()))
|
||||||
++opI;
|
++opI;
|
||||||
|
|
||||||
|
unsigned dataSize = MF->getRegClass(virtualReg)->getDataSize();
|
||||||
|
|
||||||
// Retrieve the constant value from this op, move it to target
|
// Retrieve the constant value from this op, move it to target
|
||||||
// register of the phi
|
// register of the phi
|
||||||
if (opVal.isImmediate()) {
|
if (opVal.isImmediate()) {
|
||||||
opI = RegInfo->moveImm2Reg(opBlock, opI, physReg,
|
opI = RegInfo->moveImm2Reg(opBlock, opI, virtualReg,
|
||||||
(unsigned) opVal.getImmedValue(),
|
(unsigned) opVal.getImmedValue(),
|
||||||
dataSize);
|
dataSize);
|
||||||
} else {
|
} else {
|
||||||
// Allocate a physical register and add a move in the BB
|
opI = RegInfo->moveReg2Reg(opBlock, opI, virtualReg,
|
||||||
unsigned opVirtualReg = opVal.getAllocatedRegNum();
|
opVal.getAllocatedRegNum(), dataSize);
|
||||||
unsigned opPhysReg;
|
|
||||||
opI = moveUseToReg(opBlock, opI, opVirtualReg, physReg);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save that register value to the stack of the TARGET REG
|
|
||||||
saveVirtRegToStack(opBlock, opI, virtualReg, physReg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// make regs available to other instructions
|
|
||||||
clearAllRegs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// really delete the PHI instruction now!
|
// really delete the PHI instruction now!
|
||||||
@ -304,9 +284,6 @@ void RegAllocSimple::EliminatePHINodes(MachineBasicBlock &MBB) {
|
|||||||
|
|
||||||
|
|
||||||
void RegAllocSimple::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
void RegAllocSimple::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
||||||
// Handle PHI instructions specially: add moves to each pred block
|
|
||||||
EliminatePHINodes(MBB);
|
|
||||||
|
|
||||||
// loop over each instruction
|
// loop over each instruction
|
||||||
for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) {
|
for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) {
|
||||||
// Made to combat the incorrect allocation of r2 = add r1, r1
|
// Made to combat the incorrect allocation of r2 = add r1, r1
|
||||||
@ -366,6 +343,12 @@ bool RegAllocSimple::runOnMachineFunction(MachineFunction &Fn) {
|
|||||||
DEBUG(std::cerr << "Machine Function " << "\n");
|
DEBUG(std::cerr << "Machine Function " << "\n");
|
||||||
MF = &Fn;
|
MF = &Fn;
|
||||||
|
|
||||||
|
// First pass: eliminate PHI instructions by inserting copies into predecessor
|
||||||
|
// blocks.
|
||||||
|
for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
|
||||||
|
MBB != MBBe; ++MBB)
|
||||||
|
EliminatePHINodes(*MBB);
|
||||||
|
|
||||||
// Loop over all of the basic blocks, eliminating virtual register references
|
// Loop over all of the basic blocks, eliminating virtual register references
|
||||||
for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
|
for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
|
||||||
MBB != MBBe; ++MBB)
|
MBB != MBBe; ++MBB)
|
||||||
|
Loading…
Reference in New Issue
Block a user