diff --git a/lib/CodeGen/RegAllocLocal.cpp b/lib/CodeGen/RegAllocLocal.cpp index e5c70a18e64..ac7b2b3d97d 100644 --- a/lib/CodeGen/RegAllocLocal.cpp +++ b/lib/CodeGen/RegAllocLocal.cpp @@ -12,29 +12,6 @@ #include "Support/Statistic.h" #include -/// PhysRegClassMap - Construct a mapping of physical register numbers to their -/// register classes. -/// -/// NOTE: This class will eventually be pulled out to somewhere shared. -/// -class PhysRegClassMap { - std::map PhysReg2RegClassMap; -public: - PhysRegClassMap(const MRegisterInfo &RI) { - for (MRegisterInfo::const_iterator I = RI.regclass_begin(), - E = RI.regclass_end(); I != E; ++I) - for (unsigned i=0; i < (*I)->getNumRegs(); ++i) - PhysReg2RegClassMap[(*I)->getRegister(i)] = *I; - } - - const TargetRegisterClass *operator[](unsigned Reg) { - assert(PhysReg2RegClassMap[Reg] && "Register is not a known physreg!"); - return PhysReg2RegClassMap[Reg]; - } - - const TargetRegisterClass *get(unsigned Reg) { return operator[](Reg); } -}; - namespace { Statistic<> NumSpilled ("ra-local", "Number of registers spilled"); Statistic<> NumReloaded("ra-local", "Number of registers reloaded"); @@ -45,7 +22,6 @@ namespace { const MRegisterInfo &RegInfo; const MachineInstrInfo &MIInfo; unsigned NumBytesAllocated; - PhysRegClassMap PhysRegClasses; // Maps SSA Regs => offsets on the stack where these values are stored std::map VirtReg2OffsetMap; @@ -89,8 +65,7 @@ namespace { public: RA(TargetMachine &tm) - : TM(tm), RegInfo(*tm.getRegisterInfo()), MIInfo(tm.getInstrInfo()), - PhysRegClasses(RegInfo) { + : TM(tm), RegInfo(*tm.getRegisterInfo()), MIInfo(tm.getInstrInfo()) { cleanupAfterFunction(); } @@ -302,7 +277,7 @@ unsigned RA::getFreeReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I, unsigned R = PhysRegsUseOrder[i]; // If the current register is compatible, use it. if (isAllocatableRegister(R)) { - if (PhysRegClasses[R] == RegClass) { + if (RegInfo.getRegClass(R) == RegClass) { PhysReg = R; break; } else { @@ -310,7 +285,7 @@ unsigned RA::getFreeReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I, // compatible, use it. if (const unsigned *AliasSet = RegInfo.getAliasSet(R)) for (unsigned a = 0; AliasSet[a]; ++a) - if (PhysRegClasses[AliasSet[a]] == RegClass) { + if (RegInfo.getRegClass(AliasSet[a]) == RegClass) { PhysReg = AliasSet[a]; // Take an aliased register break; } @@ -561,7 +536,7 @@ void RA::EmitPrologue() { const unsigned *CSRegs = RegInfo.getCalleeSaveRegs(); for (unsigned i = 0; CSRegs[i]; ++i) { - const TargetRegisterClass *RegClass = PhysRegClasses[CSRegs[i]]; + const TargetRegisterClass *RegClass = RegInfo.getRegClass(CSRegs[i]); unsigned Offset = getStackSpaceFor(CSRegs[i], RegClass); // Insert the spill to the stack frame... @@ -584,7 +559,7 @@ void RA::EmitEpilogue(MachineBasicBlock &MBB) { const unsigned *CSRegs = RegInfo.getCalleeSaveRegs(); for (unsigned i = 0; CSRegs[i]; ++i) { - const TargetRegisterClass *RegClass = PhysRegClasses[CSRegs[i]]; + const TargetRegisterClass *RegClass = RegInfo.getRegClass(CSRegs[i]); unsigned Offset = getStackSpaceFor(CSRegs[i], RegClass); ++NumReloaded; I = RegInfo.loadRegOffset2Reg(MBB, I, CSRegs[i], RegInfo.getFramePointer(), @@ -606,8 +581,9 @@ bool RA::runOnMachineFunction(MachineFunction &Fn) { // blocks. // FIXME: In this pass, count how many uses of each VReg exist! for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); - MBB != MBBe; ++MBB) + MBB != MBBe; ++MBB) { EliminatePHINodes(*MBB); + } // Loop over all of the basic blocks, eliminating virtual register references for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); diff --git a/lib/CodeGen/RegAllocSimple.cpp b/lib/CodeGen/RegAllocSimple.cpp index 925915ee771..34d4d57da05 100644 --- a/lib/CodeGen/RegAllocSimple.cpp +++ b/lib/CodeGen/RegAllocSimple.cpp @@ -62,6 +62,13 @@ namespace { /// in predecessor basic blocks. void EliminatePHINodes(MachineBasicBlock &MBB); + /// EmitPrologue/EmitEpilogue - Use the register info object to add a + /// prologue/epilogue to the function and save/restore any callee saved + /// registers we are responsible for. + /// + void EmitPrologue(); + void EmitEpilogue(MachineBasicBlock &MBB); + /// getStackSpaceFor - This returns the offset of the specified virtual /// register on the stack, allocating space if neccesary. @@ -307,6 +314,55 @@ void RegAllocSimple::AllocateBasicBlock(MachineBasicBlock &MBB) { } } + +/// EmitPrologue - Use the register info object to add a prologue to the +/// function and save any callee saved registers we are responsible for. +/// +void RegAllocSimple::EmitPrologue() { + // Get a list of the callee saved registers, so that we can save them on entry + // to the function. + // + MachineBasicBlock &MBB = MF->front(); // Prolog goes in entry BB + MachineBasicBlock::iterator I = MBB.begin(); + + const unsigned *CSRegs = RegInfo->getCalleeSaveRegs(); + for (unsigned i = 0; CSRegs[i]; ++i) { + const TargetRegisterClass *RegClass = RegInfo->getRegClass(CSRegs[i]); + unsigned Offset = getStackSpaceFor(CSRegs[i], RegClass); + + // Insert the spill to the stack frame... + I = RegInfo->storeReg2RegOffset(MBB, I,CSRegs[i],RegInfo->getFramePointer(), + -Offset, RegClass->getDataSize()); + ++NumSpilled; + } + + // Add prologue to the function... + RegInfo->emitPrologue(*MF, NumBytesAllocated); +} + + +/// EmitEpilogue - Use the register info object to add a epilogue to the +/// function and restore any callee saved registers we are responsible for. +/// +void RegAllocSimple::EmitEpilogue(MachineBasicBlock &MBB) { + // Insert instructions before the return. + MachineBasicBlock::iterator I = --MBB.end(); + + const unsigned *CSRegs = RegInfo->getCalleeSaveRegs(); + for (unsigned i = 0; CSRegs[i]; ++i) { + const TargetRegisterClass *RegClass = RegInfo->getRegClass(CSRegs[i]); + unsigned Offset = getStackSpaceFor(CSRegs[i], RegClass); + + I = RegInfo->loadRegOffset2Reg(MBB, I, CSRegs[i],RegInfo->getFramePointer(), + -Offset, RegClass->getDataSize()); + --I; // Insert in reverse order + ++NumReloaded; + } + + RegInfo->emitEpilogue(MBB, NumBytesAllocated); +} + + /// runOnMachineFunction - Register allocate the whole function /// bool RegAllocSimple::runOnMachineFunction(MachineFunction &Fn) { @@ -328,8 +384,8 @@ bool RegAllocSimple::runOnMachineFunction(MachineFunction &Fn) { // FIXME: This is X86 specific! Move to frame manager NumBytesAllocated = (NumBytesAllocated + 3) & ~3; - // Add prologue to the function... - RegInfo->emitPrologue(Fn, NumBytesAllocated); + // Emit a prologue for the function... + EmitPrologue(); const MachineInstrInfo &MII = TM.getInstrInfo(); @@ -338,7 +394,7 @@ bool RegAllocSimple::runOnMachineFunction(MachineFunction &Fn) { MBB != MBBe; ++MBB) { // If last instruction is a return instruction, add an epilogue if (MII.isReturn(MBB->back()->getOpcode())) - RegInfo->emitEpilogue(*MBB, NumBytesAllocated); + EmitEpilogue(*MBB); } cleanupAfterFunction();