diff --git a/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/llvm/include/llvm/CodeGen/MachineFrameInfo.h index 870d2f16877da33d23a8f9afb7974b273361ccb9..40ebcd3c3163117428e1dba2cc0dd17a0e1309df 100644 --- a/llvm/include/llvm/CodeGen/MachineFrameInfo.h +++ b/llvm/include/llvm/CodeGen/MachineFrameInfo.h @@ -20,6 +20,28 @@ class Type; class MachineDebugInfo; class MachineFunction; +/// The CalleeSavedInfo class tracks the information need to locate where a +/// callee saved register in the current frame. +class CalleeSavedInfo { + +private: + unsigned Reg; + const TargetRegisterClass *RegClass; + int FrameIdx; + +public: + CalleeSavedInfo(unsigned R, const TargetRegisterClass *RC, int FI = 0) + : Reg(R) + , RegClass(RC) + , FrameIdx(FI) + {} + + // Accessors. + unsigned getReg() const { return Reg; } + const TargetRegisterClass *getRegClass() const { return RegClass; } + int getFrameIdx() const { return FrameIdx; } + void setFrameIdx(int FI) { FrameIdx = FI; } +}; /// The MachineFrameInfo class represents an abstract stack frame until /// prolog/epilog code is inserted. This class is key to allowing stack frame @@ -111,6 +133,12 @@ class MachineFrameInfo { /// unsigned MaxCallFrameSize; + /// CSInfo - The prolog/epilog code inserter fills in this vector with each + /// callee saved register saved in the frame. Beyond it's use by the prolog/ + /// epilog code inserter, this data used for debug info and exception + /// handling. + std::vector CSInfo; + /// DebugInfo - This field is set (via setMachineDebugInfo) by a debug info /// consumer (ex. DwarfWriter) to indicate that frame layout information /// should be acquired. Typically, it's the responsibility of the target's @@ -242,6 +270,10 @@ public: Objects.push_back(StackObject(0, 1, -1)); return Objects.size()-NumFixedObjects-1; } + + /// getCalleeSavedInfo - Returns a reference to call saved info vector for the + /// current function. + std::vector &getCalleeSavedInfo() { return CSInfo; } /// getMachineDebugInfo - Used by a prologue/epilogue emitter (MRegisterInfo) /// to provide frame layout information. diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index e98815a5d88e5b7d2eea0881a093c5a7b442978b..3d37b88218f6eddc4a1e574ef403036d20ec8c2c 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -71,15 +71,10 @@ namespace { // replaceFrameIndices(Fn); - RegsToSave.clear(); - StackSlots.clear(); return true; } - + private: - std::vector > RegsToSave; - std::vector StackSlots; - void calculateCallerSavedRegisters(MachineFunction &Fn); void saveCallerSavedRegisters(MachineFunction &Fn); void calculateFrameObjectOffsets(MachineFunction &Fn); @@ -144,23 +139,24 @@ void PEI::calculateCallerSavedRegisters(MachineFunction &Fn) { const bool *PhysRegsUsed = Fn.getUsedPhysregs(); const TargetRegisterClass* const *CSRegClasses = RegInfo->getCalleeSaveRegClasses(); + std::vector &CSI = FFI->getCalleeSavedInfo(); for (unsigned i = 0; CSRegs[i]; ++i) { unsigned Reg = CSRegs[i]; if (PhysRegsUsed[Reg]) { // If the reg is modified, save it! - RegsToSave.push_back(std::make_pair(Reg, CSRegClasses[i])); + CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); } else { for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); *AliasSet; ++AliasSet) { // Check alias registers too. if (PhysRegsUsed[*AliasSet]) { - RegsToSave.push_back(std::make_pair(Reg, CSRegClasses[i])); + CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); break; } } } } - if (RegsToSave.empty()) + if (CSI.empty()) return; // Early exit if no caller saved registers are modified! unsigned NumFixedSpillSlots; @@ -169,9 +165,9 @@ void PEI::calculateCallerSavedRegisters(MachineFunction &Fn) { // Now that we know which registers need to be saved and restored, allocate // stack slots for them. - for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { - unsigned Reg = RegsToSave[i].first; - const TargetRegisterClass *RC = RegsToSave[i].second; + for (unsigned i = 0, e = CSI.size(); i != e; ++i) { + unsigned Reg = CSI[i].getReg(); + const TargetRegisterClass *RC = CSI[i].getRegClass(); // Check to see if this physreg must be spilled to a particular stack slot // on this target. @@ -188,7 +184,7 @@ void PEI::calculateCallerSavedRegisters(MachineFunction &Fn) { // Spill it to the stack where we must. FrameIdx = FFI->CreateFixedObject(RC->getSize(), FixedSlot->second); } - StackSlots.push_back(FrameIdx); + CSI[i].setFrameIdx(FrameIdx); } } @@ -196,8 +192,12 @@ void PEI::calculateCallerSavedRegisters(MachineFunction &Fn) { /// that are modified in the function. /// void PEI::saveCallerSavedRegisters(MachineFunction &Fn) { + // Get callee saved register information. + MachineFrameInfo *FFI = Fn.getFrameInfo(); + std::vector &CSI = FFI->getCalleeSavedInfo(); + // Early exit if no caller saved registers are modified! - if (RegsToSave.empty()) + if (CSI.empty()) return; const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); @@ -206,10 +206,10 @@ void PEI::saveCallerSavedRegisters(MachineFunction &Fn) { // code into the entry block. MachineBasicBlock *MBB = Fn.begin(); MachineBasicBlock::iterator I = MBB->begin(); - for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { + for (unsigned i = 0, e = CSI.size(); i != e; ++i) { // Insert the spill to the stack frame. - RegInfo->storeRegToStackSlot(*MBB, I, RegsToSave[i].first, StackSlots[i], - RegsToSave[i].second); + RegInfo->storeRegToStackSlot(*MBB, I, CSI[i].getReg(), CSI[i].getFrameIdx(), + CSI[i].getRegClass()); } // Add code to restore the callee-save registers in each exiting block. @@ -233,9 +233,10 @@ void PEI::saveCallerSavedRegisters(MachineFunction &Fn) { // Restore all registers immediately before the return and any terminators // that preceed it. - for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { - RegInfo->loadRegFromStackSlot(*MBB, I, RegsToSave[i].first, - StackSlots[i], RegsToSave[i].second); + for (unsigned i = 0, e = CSI.size(); i != e; ++i) { + RegInfo->loadRegFromStackSlot(*MBB, I, CSI[i].getReg(), + CSI[i].getFrameIdx(), + CSI[i].getRegClass()); assert(I != MBB->begin() && "loadRegFromStackSlot didn't insert any code!"); // Insert in reverse order. loadRegFromStackSlot can insert multiple