[llvm-commits] CVS: llvm/lib/CodeGen/RegAllocSimple.cpp
Chris Lattner
lattner at cs.uiuc.edu
Sun Dec 15 14:37:01 PST 2002
Changes in directory llvm/lib/CodeGen:
RegAllocSimple.cpp updated: 1.19 -> 1.20
---
Log message:
Grab bag of minor cleanups. Export some statistics about the number of
spills and reloads emitted
---
Diffs of the changes:
Index: llvm/lib/CodeGen/RegAllocSimple.cpp
diff -u llvm/lib/CodeGen/RegAllocSimple.cpp:1.19 llvm/lib/CodeGen/RegAllocSimple.cpp:1.20
--- llvm/lib/CodeGen/RegAllocSimple.cpp:1.19 Sun Dec 15 14:06:35 2002
+++ llvm/lib/CodeGen/RegAllocSimple.cpp Sun Dec 15 14:36:09 2002
@@ -10,6 +10,7 @@
#include "llvm/Target/TargetMachine.h"
#include "Support/Statistic.h"
#include <iostream>
+#include <set>
/// PhysRegClassMap - Construct a mapping of physical register numbers to their
/// register classes.
@@ -36,7 +37,10 @@
namespace {
- struct RegAllocSimple : public FunctionPass {
+ Statistic<> NumSpilled ("ra-simple", "Number of registers spilled");
+ Statistic<> NumReloaded("ra-simple", "Number of registers reloaded");
+
+ class RegAllocSimple : public FunctionPass {
TargetMachine &TM;
MachineFunction *MF;
const MRegisterInfo *RegInfo;
@@ -54,20 +58,40 @@
// Made to combat the incorrect allocation of r2 = add r1, r1
std::map<unsigned, unsigned> VirtReg2PhysRegMap;
- // Maps RegClass => which index we can take a register from. Since this is a
- // simple register allocator, when we need a register of a certain class, we
- // just take the next available one.
- std::map<unsigned, unsigned> RegsUsed;
+ // RegsUsed - Keep track of what registers are currently in use.
+ std::set<unsigned> RegsUsed;
+
+ // RegClassIdx - Maps RegClass => which index we can take a register
+ // from. Since this is a simple register allocator, when we need a register
+ // of a certain class, we just take the next available one.
std::map<const TargetRegisterClass*, unsigned> RegClassIdx;
+ public:
+
RegAllocSimple(TargetMachine &tm)
: TM(tm), RegInfo(tm.getRegisterInfo()), PhysRegClasses(RegInfo) {
- RegsUsed[RegInfo->getFramePointer()] = 1;
- RegsUsed[RegInfo->getStackPointer()] = 1;
+ RegsUsed.insert(RegInfo->getFramePointer());
+ RegsUsed.insert(RegInfo->getStackPointer());
cleanupAfterFunction();
}
+ bool runOnFunction(Function &Fn) {
+ return runOnMachineFunction(MachineFunction::get(&Fn));
+ }
+
+ private:
+ /// runOnMachineFunction - Register allocate the whole function
+ 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 isAvailableReg(unsigned Reg) {
// assert(Reg < MRegisterInfo::FirstVirtualReg && "...");
return RegsUsed.find(Reg) == RegsUsed.end();
@@ -78,8 +102,11 @@
unsigned allocateStackSpaceFor(unsigned VirtReg,
const TargetRegisterClass *regClass);
- /// Given size (in bytes), returns a register that is currently unused
+ /// Given a virtual register, returns a physical register that is currently
+ /// unused.
+ ///
/// Side effect: marks that register as being used until manually cleared
+ ///
unsigned getFreeReg(unsigned virtualReg);
/// Returns all `borrowed' registers back to the free pool
@@ -91,15 +118,14 @@
///
void invalidatePhysRegs(const MachineInstr *MI) {
unsigned Opcode = MI->getOpcode();
- const MachineInstrInfo &MII = TM.getInstrInfo();
- const MachineInstrDescriptor &Desc = MII.get(Opcode);
+ const MachineInstrDescriptor &Desc = TM.getInstrInfo().get(Opcode);
const unsigned *regs = Desc.ImplicitUses;
while (*regs)
- RegsUsed[*regs++] = 1;
+ RegsUsed.insert(*regs++);
regs = Desc.ImplicitDefs;
while (*regs)
- RegsUsed[*regs++] = 1;
+ RegsUsed.insert(*regs++);
}
void cleanupAfterFunction() {
@@ -123,22 +149,6 @@
MachineBasicBlock::iterator
savePhysRegToStack (MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, unsigned PhysReg);
-
- /// runOnFunction - Top level implementation of instruction selection for
- /// the entire function.
- ///
- 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));
- }
};
}
@@ -182,9 +192,8 @@
if (isAvailableReg(physReg))
return physReg;
- else {
+ else
return getFreeReg(virtualReg);
- }
}
MachineBasicBlock::iterator
@@ -199,6 +208,7 @@
PhysReg = getFreeReg(VirtReg);
// Add move instruction(s)
+ ++NumReloaded;
return RegInfo->loadRegOffset2Reg(MBB, I, PhysReg,
RegInfo->getFramePointer(),
-stackOffset, regClass->getDataSize());
@@ -215,6 +225,7 @@
unsigned stackOffset = allocateStackSpaceFor(VirtReg, regClass);
// Add move instruction(s)
+ ++NumSpilled;
return RegInfo->storeReg2RegOffset(MBB, I, PhysReg,
RegInfo->getFramePointer(),
-stackOffset, regClass->getDataSize());
@@ -231,6 +242,7 @@
unsigned offset = allocateStackSpaceFor(PhysReg, regClass);
// Add move instruction(s)
+ ++NumSpilled;
return RegInfo->storeReg2RegOffset(MBB, I, PhysReg,
RegInfo->getFramePointer(),
offset, regClass->getDataSize());
@@ -239,9 +251,11 @@
/// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions in
/// predecessor basic blocks.
void RegAllocSimple::EliminatePHINodes(MachineBasicBlock &MBB) {
+ const MachineInstrInfo &MII = TM.getInstrInfo();
+
while (MBB.front()->getOpcode() == 0) {
MachineInstr *MI = MBB.front();
- // get rid of the phi
+ // Unlink the PHI node from the basic block... but don't delete the PHI
MBB.erase(MBB.begin());
// a preliminary pass that will invalidate any registers that
@@ -249,13 +263,13 @@
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
+ // 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()) {
@@ -278,7 +292,6 @@
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
@@ -300,10 +313,9 @@
} else {
// Allocate a physical register and add a move in the BB
unsigned opVirtualReg = (unsigned) opVal.getAllocatedRegNum();
- unsigned opPhysReg; // = getFreeReg(opVirtualReg);
+ unsigned opPhysReg;
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);
}
@@ -334,9 +346,7 @@
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()) {
+ if (op.isVirtualRegister()) {
unsigned virtualReg = (unsigned) op.getAllocatedRegNum();
DEBUG(std::cerr << "op: " << op << "\n");
DEBUG(std::cerr << "\t inst[" << i << "]: ";
@@ -352,7 +362,7 @@
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();
+ physReg = MI->getOperand(1).getAllocatedRegNum();
} else {
physReg = getFreeReg(virtualReg);
}
@@ -375,6 +385,8 @@
}
}
+/// runOnMachineFunction - Register allocate the whole function
+///
bool RegAllocSimple::runOnMachineFunction(MachineFunction &Fn) {
DEBUG(std::cerr << "Machine Function " << "\n");
MF = &Fn;
@@ -393,9 +405,7 @@
for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
MBB != MBBe; ++MBB) {
// check if last instruction is a RET
- MachineBasicBlock::iterator I = MBB->end();
- MachineInstr *MI = *--I;
- if (MII.isReturn(MI->getOpcode())) {
+ if (MII.isReturn(MBB->back()->getOpcode())) {
// this block has a return instruction, add epilogue
RegInfo->emitEpilogue(*MBB, NumBytesAllocated);
}
More information about the llvm-commits
mailing list