[llvm-commits] CVS: llvm/lib/CodeGen/RegAllocSimple.cpp
Chris Lattner
lattner at cs.uiuc.edu
Sun Dec 15 13:52:01 PST 2002
Changes in directory llvm/lib/CodeGen:
RegAllocSimple.cpp updated: 1.17 -> 1.18
---
Log message:
* Simplify code a bit by breaking the PHI node handling stuff out into a seperate
function from normal regalloc code
* Make the regalloc for a block a function instead of part of runOnMachineBB, which
makes it easier to see what's going on in runOnMBB.
---
Diffs of the changes:
Index: llvm/lib/CodeGen/RegAllocSimple.cpp
diff -u llvm/lib/CodeGen/RegAllocSimple.cpp:1.17 llvm/lib/CodeGen/RegAllocSimple.cpp:1.18
--- llvm/lib/CodeGen/RegAllocSimple.cpp:1.17 Sun Dec 15 13:07:34 2002
+++ llvm/lib/CodeGen/RegAllocSimple.cpp Sun Dec 15 13:51:14 2002
@@ -60,10 +60,8 @@
std::map<unsigned, unsigned> RegsUsed;
std::map<const TargetRegisterClass*, unsigned> RegClassIdx;
- RegAllocSimple(TargetMachine &tm) : TM(tm),
- RegInfo(tm.getRegisterInfo()),
- PhysRegClasses(RegInfo)
- {
+ RegAllocSimple(TargetMachine &tm)
+ : TM(tm), RegInfo(tm.getRegisterInfo()), PhysRegClasses(RegInfo) {
RegsUsed[RegInfo->getFramePointer()] = 1;
RegsUsed[RegInfo->getStackPointer()] = 1;
@@ -75,7 +73,8 @@
return RegsUsed.find(Reg) == RegsUsed.end();
}
- ///
+ /// allocateStackSpaceFor - This allocates space for the specified virtual
+ /// register to be held on the stack.
unsigned allocateStackSpaceFor(unsigned VirtReg,
const TargetRegisterClass *regClass);
@@ -85,7 +84,7 @@
/// Returns all `borrowed' registers back to the free pool
void clearAllRegs() {
- RegClassIdx.clear();
+ RegClassIdx.clear();
}
/// Invalidates any references, real or implicit, to physical registers
@@ -106,23 +105,23 @@
void cleanupAfterFunction() {
VirtReg2OffsetMap.clear();
SSA2PhysRegMap.clear();
- NumBytesAllocated = 4; /* FIXME: This is X86 specific */
+ NumBytesAllocated = 4; // FIXME: This is X86 specific
}
/// Moves value from memory into that register
MachineBasicBlock::iterator
- moveUseToReg (MachineBasicBlock *MBB,
+ moveUseToReg (MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, unsigned VirtReg,
unsigned &PhysReg);
/// Saves reg value on the stack (maps virtual register to stack value)
MachineBasicBlock::iterator
- saveVirtRegToStack (MachineBasicBlock *MBB,
+ saveVirtRegToStack (MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, unsigned VirtReg,
unsigned PhysReg);
MachineBasicBlock::iterator
- savePhysRegToStack (MachineBasicBlock *MBB,
+ savePhysRegToStack (MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, unsigned PhysReg);
/// runOnFunction - Top level implementation of instruction selection for
@@ -130,6 +129,13 @@
///
bool runOnMachineFunction(MachineFunction &Fn);
+ /// AllocateBasicBlock - Register allocate the specified basic block.
+ void AllocateBasicBlock(MachineBasicBlock &MBB);
+
+ /// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions
+ /// in predecessor basic blocks.
+ void EliminatePHINodes(MachineBasicBlock &MBB);
+
bool runOnFunction(Function &Fn) {
return runOnMachineFunction(MachineFunction::get(&Fn));
}
@@ -137,6 +143,8 @@
}
+/// allocateStackSpaceFor - This allocates space for the specified virtual
+/// register to be held on the stack.
unsigned RegAllocSimple::allocateStackSpaceFor(unsigned VirtReg,
const TargetRegisterClass *regClass)
{
@@ -180,7 +188,7 @@
}
MachineBasicBlock::iterator
-RegAllocSimple::moveUseToReg (MachineBasicBlock *MBB,
+RegAllocSimple::moveUseToReg (MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned VirtReg, unsigned &PhysReg)
{
@@ -191,13 +199,13 @@
PhysReg = getFreeReg(VirtReg);
// Add move instruction(s)
- return RegInfo->loadRegOffset2Reg(MBB, I, PhysReg,
+ return RegInfo->loadRegOffset2Reg(&MBB, I, PhysReg,
RegInfo->getFramePointer(),
-stackOffset, regClass->getDataSize());
}
MachineBasicBlock::iterator
-RegAllocSimple::saveVirtRegToStack (MachineBasicBlock *MBB,
+RegAllocSimple::saveVirtRegToStack (MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned VirtReg, unsigned PhysReg)
{
@@ -207,13 +215,13 @@
unsigned stackOffset = allocateStackSpaceFor(VirtReg, regClass);
// Add move instruction(s)
- return RegInfo->storeReg2RegOffset(MBB, I, PhysReg,
+ return RegInfo->storeReg2RegOffset(&MBB, I, PhysReg,
RegInfo->getFramePointer(),
-stackOffset, regClass->getDataSize());
}
MachineBasicBlock::iterator
-RegAllocSimple::savePhysRegToStack (MachineBasicBlock *MBB,
+RegAllocSimple::savePhysRegToStack (MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned PhysReg)
{
@@ -223,157 +231,157 @@
unsigned offset = allocateStackSpaceFor(PhysReg, regClass);
// Add move instruction(s)
- return RegInfo->storeReg2RegOffset(MBB, I, PhysReg,
+ return RegInfo->storeReg2RegOffset(&MBB, I, PhysReg,
RegInfo->getFramePointer(),
offset, regClass->getDataSize());
}
-bool RegAllocSimple::runOnMachineFunction(MachineFunction &Fn) {
- cleanupAfterFunction();
-
- unsigned virtualReg, physReg;
- DEBUG(std::cerr << "Machine Function " << "\n");
- MF = &Fn;
-
- for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
- MBB != MBBe; ++MBB)
- {
- MachineBasicBlock *CurrMBB = &(*MBB);
-
- // Handle PHI instructions specially: add moves to each pred block
- while (MBB->front()->getOpcode() == 0) {
- MachineInstr *MI = MBB->front();
- // get rid of the phi
- MBB->erase(MBB->begin());
+/// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions in
+/// predecessor basic blocks.
+void RegAllocSimple::EliminatePHINodes(MachineBasicBlock &MBB) {
+ while (MBB.front()->getOpcode() == 0) {
+ MachineInstr *MI = MBB.front();
+ // get rid of the phi
+ MBB.erase(MBB.begin());
- // a preliminary pass that will invalidate any registers that
- // are used by the instruction (including implicit uses)
- invalidatePhysRegs(MI);
-
- DEBUG(std::cerr << "num invalid regs: " << RegsUsed.size() << "\n");
-
- DEBUG(std::cerr << "num ops: " << MI->getNumOperands() << "\n");
- MachineOperand &targetReg = MI->getOperand(0);
-
- // If it's a virtual register, allocate a physical one
- // otherwise, just use whatever register is there now
- // note: it MUST be a register -- we're assigning to it
- virtualReg = (unsigned) targetReg.getAllocatedRegNum();
- if (targetReg.isVirtualRegister()) {
- physReg = getFreeReg(virtualReg);
- } else {
- physReg = 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 = PhysRegClasses[physReg];
- assert(regClass && "Target register class not found!");
- unsigned dataSize = regClass->getDataSize();
-
- for (int i = MI->getNumOperands() - 1; i >= 2; i-=2) {
- MachineOperand &opVal = MI->getOperand(i-1);
-
- // Get the MachineBasicBlock equivalent of the BasicBlock that is the
- // source path the phi
- MachineBasicBlock *opBlock = MI->getOperand(i).getMachineBasicBlock();
- MachineBasicBlock::iterator opI = opBlock->end();
- MachineInstr *opMI = *(--opI);
- const MachineInstrInfo &MII = TM.getInstrInfo();
- // must backtrack over ALL the branches in the previous block, until no more
- while ((MII.isBranch(opMI->getOpcode()) || MII.isReturn(opMI->getOpcode()))
- && opI != opBlock->begin())
- {
- opMI = *(--opI);
- }
- // move back to the first branch instruction so new instructions
- // are inserted right in front of it and not in front of a non-branch
- ++opI;
-
-
- // Retrieve the constant value from this op, move it to target
- // register of the phi
- if (opVal.getType() == MachineOperand::MO_SignExtendedImmed ||
- opVal.getType() == MachineOperand::MO_UnextendedImmed)
- {
- opI = RegInfo->moveImm2Reg(opBlock, opI, physReg,
- (unsigned) opVal.getImmedValue(),
- dataSize);
- saveVirtRegToStack(opBlock, opI, virtualReg, physReg);
- } else {
- // Allocate a physical register and add a move in the BB
- unsigned opVirtualReg = (unsigned) opVal.getAllocatedRegNum();
- unsigned opPhysReg; // = getFreeReg(opVirtualReg);
- opI = moveUseToReg(opBlock, opI, opVirtualReg, physReg);
- //opI = RegInfo->moveReg2Reg(opBlock, opI, physReg, opPhysReg,
- // dataSize);
- // Save that register value to the stack of the TARGET REG
- saveVirtRegToStack(opBlock, opI, virtualReg, physReg);
- }
+ // a preliminary pass that will invalidate any registers that
+ // are used by the instruction (including implicit uses)
+ invalidatePhysRegs(MI);
+
+ DEBUG(std::cerr << "num invalid regs: " << RegsUsed.size() << "\n");
+
+ DEBUG(std::cerr << "num ops: " << MI->getNumOperands() << "\n");
+ MachineOperand &targetReg = MI->getOperand(0);
+
+ // If it's a virtual register, allocate a physical one
+ // otherwise, just use whatever register is there now
+ // note: it MUST be a register -- we're assigning to it
+ unsigned virtualReg = (unsigned) targetReg.getAllocatedRegNum();
+ unsigned physReg;
+ if (targetReg.isVirtualRegister()) {
+ physReg = getFreeReg(virtualReg);
+ } else {
+ physReg = 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 = PhysRegClasses[physReg];
+ assert(regClass && "Target register class not found!");
+ unsigned dataSize = regClass->getDataSize();
+
+ for (int i = MI->getNumOperands() - 1; i >= 2; i-=2) {
+ MachineOperand &opVal = MI->getOperand(i-1);
+
+ // Get the MachineBasicBlock equivalent of the BasicBlock that is the
+ // source path the phi
+ MachineBasicBlock &opBlock = *MI->getOperand(i).getMachineBasicBlock();
+ MachineBasicBlock::iterator opI = opBlock.end();
+ MachineInstr *opMI = *--opI;
+ const MachineInstrInfo &MII = TM.getInstrInfo();
- // make regs available to other instructions
- clearAllRegs();
+ // must backtrack over ALL the branches in the previous block, until no
+ // more
+ while (MII.isBranch(opMI->getOpcode()) && opI != opBlock.begin())
+ opMI = *--opI;
+
+ // move back to the first branch instruction so new instructions
+ // are inserted right in front of it and not in front of a non-branch
+ if (!MII.isBranch(opMI->getOpcode()))
+ ++opI;
+
+ // Retrieve the constant value from this op, move it to target
+ // register of the phi
+ if (opVal.isImmediate()) {
+ opI = RegInfo->moveImm2Reg(&opBlock, opI, physReg,
+ (unsigned) opVal.getImmedValue(),
+ dataSize);
+ saveVirtRegToStack(opBlock, opI, virtualReg, physReg);
+ } else {
+ // Allocate a physical register and add a move in the BB
+ unsigned opVirtualReg = (unsigned) opVal.getAllocatedRegNum();
+ unsigned opPhysReg; // = getFreeReg(opVirtualReg);
+ opI = moveUseToReg(opBlock, opI, opVirtualReg, physReg);
+ //opI = RegInfo->moveReg2Reg(opBlock, opI, physReg, opPhysReg,
+ // dataSize);
+ // Save that register value to the stack of the TARGET REG
+ saveVirtRegToStack(opBlock, opI, virtualReg, physReg);
}
- // really delete the instruction
- delete MI;
+ // make regs available to other instructions
+ clearAllRegs();
}
+
+ // really delete the instruction
+ delete MI;
+ }
+}
- //loop over each basic block
- for (MachineBasicBlock::iterator I = MBB->begin(); I != MBB->end(); ++I)
- {
- MachineInstr *MI = *I;
-
- // a preliminary pass that will invalidate any registers that
- // are used by the instruction (including implicit uses)
- invalidatePhysRegs(MI);
-
- // Loop over uses, move from memory into registers
- for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
- MachineOperand &op = MI->getOperand(i);
-
- if (op.getType() == MachineOperand::MO_SignExtendedImmed ||
- op.getType() == MachineOperand::MO_UnextendedImmed)
- {
- DEBUG(std::cerr << "const\n");
- } else if (op.isVirtualRegister()) {
- virtualReg = (unsigned) op.getAllocatedRegNum();
- DEBUG(std::cerr << "op: " << op << "\n");
- DEBUG(std::cerr << "\t inst[" << i << "]: ";
- MI->print(std::cerr, TM));
-
- // make sure the same virtual register maps to the same physical
- // register in any given instruction
- if (VirtReg2PhysRegMap.find(virtualReg) != VirtReg2PhysRegMap.end()) {
- physReg = VirtReg2PhysRegMap[virtualReg];
- } else {
- if (op.opIsDef()) {
- if (TM.getInstrInfo().isTwoAddrInstr(MI->getOpcode()) && i == 0) {
- // must be same register number as the first operand
- // This maps a = b + c into b += c, and saves b into a's spot
- physReg = (unsigned) MI->getOperand(1).getAllocatedRegNum();
- } else {
- physReg = getFreeReg(virtualReg);
- }
- MachineBasicBlock::iterator J = I;
- J = saveVirtRegToStack(CurrMBB, ++J, virtualReg, physReg);
- I = --J;
+
+void RegAllocSimple::AllocateBasicBlock(MachineBasicBlock &MBB) {
+ // Handle PHI instructions specially: add moves to each pred block
+ EliminatePHINodes(MBB);
+
+ //loop over each basic block
+ for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) {
+ MachineInstr *MI = *I;
+
+ // a preliminary pass that will invalidate any registers that
+ // are used by the instruction (including implicit uses)
+ invalidatePhysRegs(MI);
+
+ // Loop over uses, move from memory into registers
+ for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
+ MachineOperand &op = MI->getOperand(i);
+
+ if (op.isImmediate()) {
+ DEBUG(std::cerr << "const\n");
+ } else if (op.isVirtualRegister()) {
+ unsigned virtualReg = (unsigned) op.getAllocatedRegNum();
+ DEBUG(std::cerr << "op: " << op << "\n");
+ DEBUG(std::cerr << "\t inst[" << i << "]: ";
+ MI->print(std::cerr, TM));
+
+ // make sure the same virtual register maps to the same physical
+ // register in any given instruction
+ unsigned physReg;
+ if (VirtReg2PhysRegMap.find(virtualReg) != VirtReg2PhysRegMap.end()) {
+ physReg = VirtReg2PhysRegMap[virtualReg];
+ } else {
+ if (op.opIsDef()) {
+ if (TM.getInstrInfo().isTwoAddrInstr(MI->getOpcode()) && i == 0) {
+ // must be same register number as the first operand
+ // This maps a = b + c into b += c, and saves b into a's spot
+ physReg = (unsigned) MI->getOperand(1).getAllocatedRegNum();
} else {
- I = moveUseToReg(CurrMBB, I, virtualReg, physReg);
+ physReg = getFreeReg(virtualReg);
}
- VirtReg2PhysRegMap[virtualReg] = physReg;
+ MachineBasicBlock::iterator J = I;
+ J = saveVirtRegToStack(MBB, ++J, virtualReg, physReg);
+ I = --J;
+ } else {
+ I = moveUseToReg(MBB, I, virtualReg, physReg);
}
- MI->SetMachineOperandReg(i, physReg);
- DEBUG(std::cerr << "virt: " << virtualReg <<
- ", phys: " << op.getAllocatedRegNum() << "\n");
+ VirtReg2PhysRegMap[virtualReg] = physReg;
}
+ MI->SetMachineOperandReg(i, physReg);
+ DEBUG(std::cerr << "virt: " << virtualReg <<
+ ", phys: " << op.getAllocatedRegNum() << "\n");
}
-
- clearAllRegs();
- VirtReg2PhysRegMap.clear();
}
-
+
+ clearAllRegs();
+ VirtReg2PhysRegMap.clear();
}
+}
+
+bool RegAllocSimple::runOnMachineFunction(MachineFunction &Fn) {
+ DEBUG(std::cerr << "Machine Function " << "\n");
+ MF = &Fn;
+
+ for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
+ MBB != MBBe; ++MBB)
+ AllocateBasicBlock(*MBB);
// add prologue we should preserve callee-save registers...
MachineFunction::iterator Fi = Fn.begin();
@@ -381,21 +389,22 @@
MachineBasicBlock::iterator MBBi = MBB->begin();
RegInfo->emitPrologue(MBB, MBBi, NumBytesAllocated);
+ const MachineInstrInfo &MII = TM.getInstrInfo();
+
// add epilogue to restore the callee-save registers
// loop over the basic block
for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
- MBB != MBBe; ++MBB)
- {
+ MBB != MBBe; ++MBB) {
// check if last instruction is a RET
- MachineBasicBlock::iterator I = (*MBB).end();
- MachineInstr *MI = *(--I);
- const MachineInstrInfo &MII = TM.getInstrInfo();
+ MachineBasicBlock::iterator I = MBB->end();
+ MachineInstr *MI = *--I;
if (MII.isReturn(MI->getOpcode())) {
// this block has a return instruction, add epilogue
RegInfo->emitEpilogue(MBB, I, NumBytesAllocated);
}
}
+ cleanupAfterFunction();
return false; // We never modify the LLVM itself.
}
More information about the llvm-commits
mailing list