Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 1 | //===-- PrologEpilogInserter.cpp - Insert Prolog/Epilog code in function --===// |
Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 2 | // |
John Criswell | b576c94 | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file was developed by the LLVM research group and is distributed under |
| 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. |
Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 7 | // |
John Criswell | b576c94 | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 9 | // |
| 10 | // This pass is responsible for finalizing the functions frame layout, saving |
| 11 | // callee saved registers, and for emitting prolog & epilog code for the |
| 12 | // function. |
| 13 | // |
| 14 | // This pass must be run after register allocation. After this pass is |
| 15 | // executed, it is illegal to construct MO_FrameIndex operands. |
| 16 | // |
| 17 | //===----------------------------------------------------------------------===// |
| 18 | |
Chris Lattner | f00a3f9 | 2003-01-13 00:23:41 +0000 | [diff] [blame] | 19 | #include "llvm/CodeGen/Passes.h" |
| 20 | #include "llvm/CodeGen/MachineFunctionPass.h" |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 21 | #include "llvm/CodeGen/MachineInstr.h" |
Chris Lattner | eb24db9 | 2002-12-28 21:08:26 +0000 | [diff] [blame] | 22 | #include "llvm/CodeGen/MachineFrameInfo.h" |
Evan Cheng | 49dd064 | 2007-02-23 01:11:26 +0000 | [diff] [blame] | 23 | #include "llvm/CodeGen/RegisterScavenging.h" |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 24 | #include "llvm/Target/TargetMachine.h" |
| 25 | #include "llvm/Target/MRegisterInfo.h" |
Chris Lattner | 8bd66e6 | 2002-12-28 21:00:25 +0000 | [diff] [blame] | 26 | #include "llvm/Target/TargetFrameInfo.h" |
Chris Lattner | 3501fea | 2003-01-14 22:00:31 +0000 | [diff] [blame] | 27 | #include "llvm/Target/TargetInstrInfo.h" |
Chris Lattner | a4f0b3a | 2006-08-27 12:54:02 +0000 | [diff] [blame] | 28 | #include "llvm/Support/Compiler.h" |
Evan Cheng | 8e33473 | 2007-05-01 09:01:42 +0000 | [diff] [blame] | 29 | #include "llvm/ADT/STLExtras.h" |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 30 | #include <climits> |
Chris Lattner | 05d8350 | 2004-02-15 00:14:20 +0000 | [diff] [blame] | 31 | using namespace llvm; |
Brian Gaeke | d0fde30 | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 32 | |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 33 | namespace { |
Chris Lattner | f8c68f6 | 2006-06-28 22:17:39 +0000 | [diff] [blame] | 34 | struct VISIBILITY_HIDDEN PEI : public MachineFunctionPass { |
Devang Patel | 1997473 | 2007-05-03 01:11:54 +0000 | [diff] [blame^] | 35 | static char ID; |
Devang Patel | 794fd75 | 2007-05-01 21:15:47 +0000 | [diff] [blame] | 36 | PEI() : MachineFunctionPass((intptr_t)&ID) {} |
| 37 | |
Chris Lattner | f00a3f9 | 2003-01-13 00:23:41 +0000 | [diff] [blame] | 38 | const char *getPassName() const { |
| 39 | return "Prolog/Epilog Insertion & Frame Finalization"; |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 40 | } |
| 41 | |
| 42 | /// runOnMachineFunction - Insert prolog/epilog code and replace abstract |
| 43 | /// frame indexes with appropriate references. |
| 44 | /// |
| 45 | bool runOnMachineFunction(MachineFunction &Fn) { |
Evan Cheng | 87f8bf6 | 2007-03-06 10:02:38 +0000 | [diff] [blame] | 46 | const MRegisterInfo *MRI = Fn.getTarget().getRegisterInfo(); |
| 47 | RS = MRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL; |
| 48 | |
Jim Laskey | 44c3b9f | 2007-01-26 21:22:28 +0000 | [diff] [blame] | 49 | // Get MachineModuleInfo so that we can track the construction of the |
Jim Laskey | 4188699 | 2006-04-07 16:34:46 +0000 | [diff] [blame] | 50 | // frame. |
Jim Laskey | 44c3b9f | 2007-01-26 21:22:28 +0000 | [diff] [blame] | 51 | if (MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>()) { |
| 52 | Fn.getFrameInfo()->setMachineModuleInfo(MMI); |
Jim Laskey | 4188699 | 2006-04-07 16:34:46 +0000 | [diff] [blame] | 53 | } |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 54 | |
| 55 | // Allow the target machine to make some adjustments to the function |
| 56 | // e.g. UsedPhysRegs before calculateCalleeSavedRegisters. |
Evan Cheng | 87f8bf6 | 2007-03-06 10:02:38 +0000 | [diff] [blame] | 57 | MRI->processFunctionBeforeCalleeSavedScan(Fn, RS); |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 58 | |
Evan Cheng | 692d4e0 | 2006-09-26 22:29:31 +0000 | [diff] [blame] | 59 | // Scan the function for modified callee saved registers and insert spill |
| 60 | // code for any callee saved registers that are modified. Also calculate |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 61 | // the MaxCallFrameSize and HasCalls variables for the function's frame |
| 62 | // information and eliminates call frame pseudo instructions. |
Evan Cheng | 692d4e0 | 2006-09-26 22:29:31 +0000 | [diff] [blame] | 63 | calculateCalleeSavedRegisters(Fn); |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 64 | |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 65 | // Add the code to save and restore the callee saved registers |
| 66 | saveCalleeSavedRegisters(Fn); |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 67 | |
| 68 | // Allow the target machine to make final modifications to the function |
| 69 | // before the frame layout is finalized. |
| 70 | Fn.getTarget().getRegisterInfo()->processFunctionBeforeFrameFinalized(Fn); |
| 71 | |
| 72 | // Calculate actual frame offsets for all of the abstract stack objects... |
| 73 | calculateFrameObjectOffsets(Fn); |
| 74 | |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 75 | // Add prolog and epilog code to the function. This function is required |
| 76 | // to align the stack frame as necessary for any stack variables or |
Evan Cheng | 692d4e0 | 2006-09-26 22:29:31 +0000 | [diff] [blame] | 77 | // called functions. Because of this, calculateCalleeSavedRegisters |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 78 | // must be called before this function in order to set the HasCalls |
| 79 | // and MaxCallFrameSize variables. |
Chris Lattner | 4ac7d73 | 2003-01-15 22:52:34 +0000 | [diff] [blame] | 80 | insertPrologEpilogCode(Fn); |
| 81 | |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 82 | // Replace all MO_FrameIndex operands with physical register references |
| 83 | // and actual offsets. |
| 84 | // |
| 85 | replaceFrameIndices(Fn); |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 86 | |
Evan Cheng | 87f8bf6 | 2007-03-06 10:02:38 +0000 | [diff] [blame] | 87 | delete RS; |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 88 | return true; |
| 89 | } |
Jim Laskey | f3e4f0e | 2006-08-25 19:45:51 +0000 | [diff] [blame] | 90 | |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 91 | private: |
Evan Cheng | 87f8bf6 | 2007-03-06 10:02:38 +0000 | [diff] [blame] | 92 | RegScavenger *RS; |
| 93 | |
Evan Cheng | ad93d7f | 2007-01-02 21:31:15 +0000 | [diff] [blame] | 94 | // MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee saved |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 95 | // stack frame indexes. |
| 96 | unsigned MinCSFrameIndex, MaxCSFrameIndex; |
| 97 | |
Evan Cheng | 692d4e0 | 2006-09-26 22:29:31 +0000 | [diff] [blame] | 98 | void calculateCalleeSavedRegisters(MachineFunction &Fn); |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 99 | void saveCalleeSavedRegisters(MachineFunction &Fn); |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 100 | void calculateFrameObjectOffsets(MachineFunction &Fn); |
| 101 | void replaceFrameIndices(MachineFunction &Fn); |
| 102 | void insertPrologEpilogCode(MachineFunction &Fn); |
| 103 | }; |
Devang Patel | 1997473 | 2007-05-03 01:11:54 +0000 | [diff] [blame^] | 104 | char PEI::ID = 0; |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 105 | } |
| 106 | |
Brian Gaeke | d0fde30 | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 107 | |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 108 | /// createPrologEpilogCodeInserter - This function returns a pass that inserts |
| 109 | /// prolog and epilog code, and eliminates abstract frame references. |
| 110 | /// |
Chris Lattner | 05d8350 | 2004-02-15 00:14:20 +0000 | [diff] [blame] | 111 | FunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); } |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 112 | |
| 113 | |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 114 | /// calculateCalleeSavedRegisters - Scan the function for modified callee saved |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 115 | /// registers. Also calculate the MaxCallFrameSize and HasCalls variables for |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 116 | /// the function's frame information and eliminates call frame pseudo |
| 117 | /// instructions. |
| 118 | /// |
Evan Cheng | 692d4e0 | 2006-09-26 22:29:31 +0000 | [diff] [blame] | 119 | void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 120 | const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 121 | const TargetFrameInfo *TFI = Fn.getTarget().getFrameInfo(); |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 122 | |
| 123 | // Get the callee saved register list... |
Evan Cheng | ad93d7f | 2007-01-02 21:31:15 +0000 | [diff] [blame] | 124 | const unsigned *CSRegs = RegInfo->getCalleeSavedRegs(); |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 125 | |
| 126 | // Get the function call frame set-up and tear-down instruction opcode |
| 127 | int FrameSetupOpcode = RegInfo->getCallFrameSetupOpcode(); |
| 128 | int FrameDestroyOpcode = RegInfo->getCallFrameDestroyOpcode(); |
| 129 | |
Evan Cheng | 7d3223e | 2006-12-07 02:25:34 +0000 | [diff] [blame] | 130 | // These are used to keep track the callee-save area. Initialize them. |
| 131 | MinCSFrameIndex = INT_MAX; |
| 132 | MaxCSFrameIndex = 0; |
| 133 | |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 134 | // Early exit for targets which have no callee saved registers and no call |
| 135 | // frame setup/destroy pseudo instructions. |
| 136 | if ((CSRegs == 0 || CSRegs[0] == 0) && |
| 137 | FrameSetupOpcode == -1 && FrameDestroyOpcode == -1) |
| 138 | return; |
| 139 | |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 140 | unsigned MaxCallFrameSize = 0; |
| 141 | bool HasCalls = false; |
| 142 | |
Evan Cheng | 5c3885c | 2007-05-01 00:52:08 +0000 | [diff] [blame] | 143 | std::vector<MachineBasicBlock::iterator> FrameSDOps; |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 144 | for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) |
Evan Cheng | 5c3885c | 2007-05-01 00:52:08 +0000 | [diff] [blame] | 145 | for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) |
Alkis Evlogimenos | c0b9dc5 | 2004-02-12 02:27:10 +0000 | [diff] [blame] | 146 | if (I->getOpcode() == FrameSetupOpcode || |
Chris Lattner | d555da5 | 2004-08-07 07:07:57 +0000 | [diff] [blame] | 147 | I->getOpcode() == FrameDestroyOpcode) { |
Chris Lattner | 2a82ef3 | 2005-05-13 21:07:15 +0000 | [diff] [blame] | 148 | assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo" |
Chris Lattner | d555da5 | 2004-08-07 07:07:57 +0000 | [diff] [blame] | 149 | " instructions should have a single immediate argument!"); |
| 150 | unsigned Size = I->getOperand(0).getImmedValue(); |
| 151 | if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; |
| 152 | HasCalls = true; |
Evan Cheng | 5c3885c | 2007-05-01 00:52:08 +0000 | [diff] [blame] | 153 | FrameSDOps.push_back(I); |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 154 | } |
| 155 | |
Chris Lattner | eb24db9 | 2002-12-28 21:08:26 +0000 | [diff] [blame] | 156 | MachineFrameInfo *FFI = Fn.getFrameInfo(); |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 157 | FFI->setHasCalls(HasCalls); |
| 158 | FFI->setMaxCallFrameSize(MaxCallFrameSize); |
Evan Cheng | 8e33473 | 2007-05-01 09:01:42 +0000 | [diff] [blame] | 159 | |
Evan Cheng | 5c3885c | 2007-05-01 00:52:08 +0000 | [diff] [blame] | 160 | for (unsigned i = 0, e = FrameSDOps.size(); i != e; ++i) { |
| 161 | MachineBasicBlock::iterator I = FrameSDOps[i]; |
Evan Cheng | 8e33473 | 2007-05-01 09:01:42 +0000 | [diff] [blame] | 162 | // If call frames are not being included as part of the stack frame, |
| 163 | // and there is no dynamic allocation (therefore referencing frame slots |
| 164 | // off sp), leave the pseudo ops alone. We'll eliminate them later. |
| 165 | if (RegInfo->hasReservedCallFrame(Fn) || RegInfo->hasFP(Fn)) |
| 166 | RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I); |
Evan Cheng | 5c3885c | 2007-05-01 00:52:08 +0000 | [diff] [blame] | 167 | } |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 168 | |
| 169 | // Now figure out which *callee saved* registers are modified by the current |
| 170 | // function, thus needing to be saved and restored in the prolog/epilog. |
| 171 | // |
Chris Lattner | 80a4f16 | 2005-09-30 16:59:07 +0000 | [diff] [blame] | 172 | const TargetRegisterClass* const *CSRegClasses = |
Evan Cheng | ad93d7f | 2007-01-02 21:31:15 +0000 | [diff] [blame] | 173 | RegInfo->getCalleeSavedRegClasses(); |
Jim Laskey | 08ede26 | 2006-08-25 22:56:30 +0000 | [diff] [blame] | 174 | std::vector<CalleeSavedInfo> CSI; |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 175 | for (unsigned i = 0; CSRegs[i]; ++i) { |
| 176 | unsigned Reg = CSRegs[i]; |
Evan Cheng | 6c087e5 | 2007-04-25 22:13:27 +0000 | [diff] [blame] | 177 | if (Fn.isPhysRegUsed(Reg)) { |
Chris Lattner | 80a4f16 | 2005-09-30 16:59:07 +0000 | [diff] [blame] | 178 | // If the reg is modified, save it! |
Jim Laskey | f3e4f0e | 2006-08-25 19:45:51 +0000 | [diff] [blame] | 179 | CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); |
Alkis Evlogimenos | 73ff512 | 2003-10-08 05:20:08 +0000 | [diff] [blame] | 180 | } else { |
| 181 | for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); |
Chris Lattner | 3563015 | 2005-01-23 23:13:12 +0000 | [diff] [blame] | 182 | *AliasSet; ++AliasSet) { // Check alias registers too. |
Evan Cheng | 6c087e5 | 2007-04-25 22:13:27 +0000 | [diff] [blame] | 183 | if (Fn.isPhysRegUsed(*AliasSet)) { |
Jim Laskey | f3e4f0e | 2006-08-25 19:45:51 +0000 | [diff] [blame] | 184 | CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); |
Chris Lattner | d555da5 | 2004-08-07 07:07:57 +0000 | [diff] [blame] | 185 | break; |
Chris Lattner | ecf8afd | 2004-08-07 07:18:41 +0000 | [diff] [blame] | 186 | } |
Alkis Evlogimenos | 73ff512 | 2003-10-08 05:20:08 +0000 | [diff] [blame] | 187 | } |
| 188 | } |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 189 | } |
| 190 | |
Jim Laskey | f3e4f0e | 2006-08-25 19:45:51 +0000 | [diff] [blame] | 191 | if (CSI.empty()) |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 192 | return; // Early exit if no callee saved registers are modified! |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 193 | |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 194 | unsigned NumFixedSpillSlots; |
Alkis Evlogimenos | 8c9b4de | 2004-08-15 09:18:55 +0000 | [diff] [blame] | 195 | const std::pair<unsigned,int> *FixedSpillSlots = |
Evan Cheng | ad93d7f | 2007-01-02 21:31:15 +0000 | [diff] [blame] | 196 | TFI->getCalleeSavedSpillSlots(NumFixedSpillSlots); |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 197 | |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 198 | // Now that we know which registers need to be saved and restored, allocate |
| 199 | // stack slots for them. |
Jim Laskey | f3e4f0e | 2006-08-25 19:45:51 +0000 | [diff] [blame] | 200 | for (unsigned i = 0, e = CSI.size(); i != e; ++i) { |
| 201 | unsigned Reg = CSI[i].getReg(); |
| 202 | const TargetRegisterClass *RC = CSI[i].getRegClass(); |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 203 | |
| 204 | // Check to see if this physreg must be spilled to a particular stack slot |
| 205 | // on this target. |
Alkis Evlogimenos | 8c9b4de | 2004-08-15 09:18:55 +0000 | [diff] [blame] | 206 | const std::pair<unsigned,int> *FixedSlot = FixedSpillSlots; |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 207 | while (FixedSlot != FixedSpillSlots+NumFixedSpillSlots && |
| 208 | FixedSlot->first != Reg) |
| 209 | ++FixedSlot; |
| 210 | |
Chris Lattner | fa1face | 2004-08-21 19:45:10 +0000 | [diff] [blame] | 211 | int FrameIdx; |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 212 | if (FixedSlot == FixedSpillSlots+NumFixedSpillSlots) { |
| 213 | // Nope, just spill it anywhere convenient. |
Evan Cheng | 5feaa9a | 2006-09-28 18:52:32 +0000 | [diff] [blame] | 214 | unsigned Align = RC->getAlignment(); |
| 215 | unsigned StackAlign = TFI->getStackAlignment(); |
| 216 | // We may not be able to sastify the desired alignment specification of |
| 217 | // the TargetRegisterClass if the stack alignment is smaller. Use the min. |
| 218 | Align = std::min(Align, StackAlign); |
| 219 | FrameIdx = FFI->CreateStackObject(RC->getSize(), Align); |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 220 | if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx; |
| 221 | if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx; |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 222 | } else { |
| 223 | // Spill it to the stack where we must. |
Chris Lattner | 8fb040e | 2005-09-30 17:19:22 +0000 | [diff] [blame] | 224 | FrameIdx = FFI->CreateFixedObject(RC->getSize(), FixedSlot->second); |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 225 | } |
Jim Laskey | f3e4f0e | 2006-08-25 19:45:51 +0000 | [diff] [blame] | 226 | CSI[i].setFrameIdx(FrameIdx); |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 227 | } |
Jim Laskey | 08ede26 | 2006-08-25 22:56:30 +0000 | [diff] [blame] | 228 | |
| 229 | FFI->setCalleeSavedInfo(CSI); |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 230 | } |
| 231 | |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 232 | /// saveCalleeSavedRegisters - Insert spill code for any callee saved registers |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 233 | /// that are modified in the function. |
| 234 | /// |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 235 | void PEI::saveCalleeSavedRegisters(MachineFunction &Fn) { |
Jim Laskey | f3e4f0e | 2006-08-25 19:45:51 +0000 | [diff] [blame] | 236 | // Get callee saved register information. |
| 237 | MachineFrameInfo *FFI = Fn.getFrameInfo(); |
Jim Laskey | 08ede26 | 2006-08-25 22:56:30 +0000 | [diff] [blame] | 238 | const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo(); |
Jim Laskey | f3e4f0e | 2006-08-25 19:45:51 +0000 | [diff] [blame] | 239 | |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 240 | // Early exit if no callee saved registers are modified! |
Jim Laskey | f3e4f0e | 2006-08-25 19:45:51 +0000 | [diff] [blame] | 241 | if (CSI.empty()) |
Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 242 | return; |
Chris Lattner | c330b68 | 2004-08-12 19:01:14 +0000 | [diff] [blame] | 243 | |
| 244 | const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 245 | |
| 246 | // Now that we have a stack slot for each register to be saved, insert spill |
Chris Lattner | 92b9fce | 2005-01-23 21:45:01 +0000 | [diff] [blame] | 247 | // code into the entry block. |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 248 | MachineBasicBlock *MBB = Fn.begin(); |
| 249 | MachineBasicBlock::iterator I = MBB->begin(); |
Evan Cheng | ad93d7f | 2007-01-02 21:31:15 +0000 | [diff] [blame] | 250 | if (!RegInfo->spillCalleeSavedRegisters(*MBB, I, CSI)) { |
| 251 | for (unsigned i = 0, e = CSI.size(); i != e; ++i) { |
Evan Cheng | 49dd064 | 2007-02-23 01:11:26 +0000 | [diff] [blame] | 252 | // Add the callee-saved register as live-in. It's killed at the spill. |
| 253 | MBB->addLiveIn(CSI[i].getReg()); |
| 254 | |
Evan Cheng | ad93d7f | 2007-01-02 21:31:15 +0000 | [diff] [blame] | 255 | // Insert the spill to the stack frame. |
| 256 | RegInfo->storeRegToStackSlot(*MBB, I, CSI[i].getReg(), |
Evan Cheng | 49dd064 | 2007-02-23 01:11:26 +0000 | [diff] [blame] | 257 | CSI[i].getFrameIdx(), CSI[i].getRegClass()); |
Evan Cheng | ad93d7f | 2007-01-02 21:31:15 +0000 | [diff] [blame] | 258 | } |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 259 | } |
| 260 | |
| 261 | // Add code to restore the callee-save registers in each exiting block. |
Chris Lattner | 9bcdcd1 | 2004-06-02 05:57:12 +0000 | [diff] [blame] | 262 | const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); |
Chris Lattner | 92b9fce | 2005-01-23 21:45:01 +0000 | [diff] [blame] | 263 | for (MachineFunction::iterator FI = Fn.begin(), E = Fn.end(); FI != E; ++FI) |
| 264 | // If last instruction is a return instruction, add an epilogue. |
Alkis Evlogimenos | c0b9dc5 | 2004-02-12 02:27:10 +0000 | [diff] [blame] | 265 | if (!FI->empty() && TII.isReturn(FI->back().getOpcode())) { |
| 266 | MBB = FI; |
| 267 | I = MBB->end(); --I; |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 268 | |
Chris Lattner | 4fc9979 | 2005-05-15 03:09:58 +0000 | [diff] [blame] | 269 | // Skip over all terminator instructions, which are part of the return |
| 270 | // sequence. |
| 271 | MachineBasicBlock::iterator I2 = I; |
| 272 | while (I2 != MBB->begin() && TII.isTerminatorInstr((--I2)->getOpcode())) |
| 273 | I = I2; |
| 274 | |
Chris Lattner | dfd5870 | 2005-08-29 00:10:46 +0000 | [diff] [blame] | 275 | bool AtStart = I == MBB->begin(); |
Chris Lattner | ed461e0 | 2005-08-26 22:18:32 +0000 | [diff] [blame] | 276 | MachineBasicBlock::iterator BeforeI = I; |
| 277 | if (!AtStart) |
| 278 | --BeforeI; |
| 279 | |
Chris Lattner | 4fc9979 | 2005-05-15 03:09:58 +0000 | [diff] [blame] | 280 | // Restore all registers immediately before the return and any terminators |
| 281 | // that preceed it. |
Evan Cheng | ad93d7f | 2007-01-02 21:31:15 +0000 | [diff] [blame] | 282 | if (!RegInfo->restoreCalleeSavedRegisters(*MBB, I, CSI)) { |
| 283 | for (unsigned i = 0, e = CSI.size(); i != e; ++i) { |
| 284 | RegInfo->loadRegFromStackSlot(*MBB, I, CSI[i].getReg(), |
| 285 | CSI[i].getFrameIdx(), |
| 286 | CSI[i].getRegClass()); |
| 287 | assert(I != MBB->begin() && |
| 288 | "loadRegFromStackSlot didn't insert any code!"); |
| 289 | // Insert in reverse order. loadRegFromStackSlot can insert multiple |
| 290 | // instructions. |
| 291 | if (AtStart) |
| 292 | I = MBB->begin(); |
| 293 | else { |
| 294 | I = BeforeI; |
| 295 | ++I; |
| 296 | } |
Chris Lattner | ed461e0 | 2005-08-26 22:18:32 +0000 | [diff] [blame] | 297 | } |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 298 | } |
| 299 | } |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 300 | } |
| 301 | |
| 302 | |
| 303 | /// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the |
Chris Lattner | 92b9fce | 2005-01-23 21:45:01 +0000 | [diff] [blame] | 304 | /// abstract stack objects. |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 305 | /// |
| 306 | void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { |
Chris Lattner | 9bcdcd1 | 2004-06-02 05:57:12 +0000 | [diff] [blame] | 307 | const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo(); |
Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 308 | |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 309 | bool StackGrowsDown = |
| 310 | TFI.getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; |
Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 311 | |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 312 | // Loop over all of the stack objects, assigning sequential addresses... |
Chris Lattner | eb24db9 | 2002-12-28 21:08:26 +0000 | [diff] [blame] | 313 | MachineFrameInfo *FFI = Fn.getFrameInfo(); |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 314 | |
Chris Lattner | cbef8ba | 2005-11-06 17:43:20 +0000 | [diff] [blame] | 315 | unsigned MaxAlign = 0; |
Chris Lattner | 78d6db5 | 2003-01-16 02:22:08 +0000 | [diff] [blame] | 316 | |
Chris Lattner | 05d8350 | 2004-02-15 00:14:20 +0000 | [diff] [blame] | 317 | // Start at the beginning of the local area. |
Chris Lattner | 577aec1 | 2004-06-10 06:23:35 +0000 | [diff] [blame] | 318 | // The Offset is the distance from the stack top in the direction |
| 319 | // of stack growth -- so it's always positive. |
Chris Lattner | a401b1e | 2007-04-25 04:20:54 +0000 | [diff] [blame] | 320 | int64_t Offset = TFI.getOffsetOfLocalArea(); |
Chris Lattner | 577aec1 | 2004-06-10 06:23:35 +0000 | [diff] [blame] | 321 | if (StackGrowsDown) |
Chris Lattner | 7f7bbc2 | 2004-06-11 06:37:11 +0000 | [diff] [blame] | 322 | Offset = -Offset; |
Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 323 | assert(Offset >= 0 |
Chris Lattner | 577aec1 | 2004-06-10 06:23:35 +0000 | [diff] [blame] | 324 | && "Local area offset should be in direction of stack growth"); |
Chris Lattner | 05d8350 | 2004-02-15 00:14:20 +0000 | [diff] [blame] | 325 | |
Chris Lattner | 577aec1 | 2004-06-10 06:23:35 +0000 | [diff] [blame] | 326 | // If there are fixed sized objects that are preallocated in the local area, |
| 327 | // non-fixed objects can't be allocated right at the start of local area. |
Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 328 | // We currently don't support filling in holes in between fixed sized objects, |
Chris Lattner | 577aec1 | 2004-06-10 06:23:35 +0000 | [diff] [blame] | 329 | // so we adjust 'Offset' to point to the end of last fixed sized |
Chris Lattner | 05d8350 | 2004-02-15 00:14:20 +0000 | [diff] [blame] | 330 | // preallocated object. |
| 331 | for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { |
Chris Lattner | a401b1e | 2007-04-25 04:20:54 +0000 | [diff] [blame] | 332 | int64_t FixedOff; |
Chris Lattner | 577aec1 | 2004-06-10 06:23:35 +0000 | [diff] [blame] | 333 | if (StackGrowsDown) { |
| 334 | // The maximum distance from the stack pointer is at lower address of |
| 335 | // the object -- which is given by offset. For down growing stack |
| 336 | // the offset is negative, so we negate the offset to get the distance. |
| 337 | FixedOff = -FFI->getObjectOffset(i); |
| 338 | } else { |
Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 339 | // The maximum distance from the start pointer is at the upper |
Chris Lattner | 577aec1 | 2004-06-10 06:23:35 +0000 | [diff] [blame] | 340 | // address of the object. |
| 341 | FixedOff = FFI->getObjectOffset(i) + FFI->getObjectSize(i); |
Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 342 | } |
| 343 | if (FixedOff > Offset) Offset = FixedOff; |
Chris Lattner | 05d8350 | 2004-02-15 00:14:20 +0000 | [diff] [blame] | 344 | } |
| 345 | |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 346 | // First assign frame offsets to stack objects that are used to spill |
Evan Cheng | ad93d7f | 2007-01-02 21:31:15 +0000 | [diff] [blame] | 347 | // callee saved registers. |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 348 | if (StackGrowsDown) { |
Evan Cheng | 5c3885c | 2007-05-01 00:52:08 +0000 | [diff] [blame] | 349 | for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) { |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 350 | // If stack grows down, we need to add size of find the lowest |
| 351 | // address of the object. |
| 352 | Offset += FFI->getObjectSize(i); |
| 353 | |
| 354 | unsigned Align = FFI->getObjectAlignment(i); |
| 355 | // If the alignment of this object is greater than that of the stack, then |
| 356 | // increase the stack alignment to match. |
| 357 | MaxAlign = std::max(MaxAlign, Align); |
| 358 | // Adjust to alignment boundary |
| 359 | Offset = (Offset+Align-1)/Align*Align; |
| 360 | |
| 361 | FFI->setObjectOffset(i, -Offset); // Set the computed offset |
| 362 | } |
| 363 | } else { |
Evan Cheng | 5c3885c | 2007-05-01 00:52:08 +0000 | [diff] [blame] | 364 | for (unsigned i = MaxCSFrameIndex; i >= MinCSFrameIndex; --i) { |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 365 | unsigned Align = FFI->getObjectAlignment(i); |
| 366 | // If the alignment of this object is greater than that of the stack, then |
| 367 | // increase the stack alignment to match. |
| 368 | MaxAlign = std::max(MaxAlign, Align); |
| 369 | // Adjust to alignment boundary |
| 370 | Offset = (Offset+Align-1)/Align*Align; |
| 371 | |
| 372 | FFI->setObjectOffset(i, Offset); |
| 373 | Offset += FFI->getObjectSize(i); |
| 374 | } |
| 375 | } |
| 376 | |
Evan Cheng | 87f8bf6 | 2007-03-06 10:02:38 +0000 | [diff] [blame] | 377 | // Make sure the special register scavenging spill slot is closest to the |
| 378 | // frame pointer if a frame pointer is required. |
| 379 | const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); |
| 380 | if (RS && RegInfo->hasFP(Fn)) { |
| 381 | int SFI = RS->getScavengingFrameIndex(); |
| 382 | if (SFI >= 0) { |
Evan Cheng | 5c3885c | 2007-05-01 00:52:08 +0000 | [diff] [blame] | 383 | // If stack grows down, we need to add size of the lowest |
Evan Cheng | 87f8bf6 | 2007-03-06 10:02:38 +0000 | [diff] [blame] | 384 | // address of the object. |
| 385 | if (StackGrowsDown) |
| 386 | Offset += FFI->getObjectSize(SFI); |
| 387 | |
| 388 | unsigned Align = FFI->getObjectAlignment(SFI); |
| 389 | // Adjust to alignment boundary |
| 390 | Offset = (Offset+Align-1)/Align*Align; |
| 391 | |
| 392 | if (StackGrowsDown) { |
| 393 | FFI->setObjectOffset(SFI, -Offset); // Set the computed offset |
| 394 | } else { |
| 395 | FFI->setObjectOffset(SFI, Offset); |
| 396 | Offset += FFI->getObjectSize(SFI); |
| 397 | } |
| 398 | } |
| 399 | } |
| 400 | |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 401 | // Then assign frame offsets to stack objects that are not used to spill |
Evan Cheng | ad93d7f | 2007-01-02 21:31:15 +0000 | [diff] [blame] | 402 | // callee saved registers. |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 403 | for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 404 | if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) |
| 405 | continue; |
Evan Cheng | 87f8bf6 | 2007-03-06 10:02:38 +0000 | [diff] [blame] | 406 | if (RS && (int)i == RS->getScavengingFrameIndex()) |
| 407 | continue; |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 408 | |
Chris Lattner | 577aec1 | 2004-06-10 06:23:35 +0000 | [diff] [blame] | 409 | // If stack grows down, we need to add size of find the lowest |
| 410 | // address of the object. |
| 411 | if (StackGrowsDown) |
| 412 | Offset += FFI->getObjectSize(i); |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 413 | |
| 414 | unsigned Align = FFI->getObjectAlignment(i); |
Nate Begeman | ae232e7 | 2005-11-06 09:00:38 +0000 | [diff] [blame] | 415 | // If the alignment of this object is greater than that of the stack, then |
| 416 | // increase the stack alignment to match. |
| 417 | MaxAlign = std::max(MaxAlign, Align); |
| 418 | // Adjust to alignment boundary |
| 419 | Offset = (Offset+Align-1)/Align*Align; |
Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 420 | |
Chris Lattner | 577aec1 | 2004-06-10 06:23:35 +0000 | [diff] [blame] | 421 | if (StackGrowsDown) { |
| 422 | FFI->setObjectOffset(i, -Offset); // Set the computed offset |
| 423 | } else { |
Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 424 | FFI->setObjectOffset(i, Offset); |
Chris Lattner | 577aec1 | 2004-06-10 06:23:35 +0000 | [diff] [blame] | 425 | Offset += FFI->getObjectSize(i); |
| 426 | } |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 427 | } |
| 428 | |
Evan Cheng | 87f8bf6 | 2007-03-06 10:02:38 +0000 | [diff] [blame] | 429 | // Make sure the special register scavenging spill slot is closest to the |
| 430 | // stack pointer. |
| 431 | if (RS) { |
| 432 | int SFI = RS->getScavengingFrameIndex(); |
| 433 | if (SFI >= 0) { |
| 434 | // If stack grows down, we need to add size of find the lowest |
| 435 | // address of the object. |
| 436 | if (StackGrowsDown) |
| 437 | Offset += FFI->getObjectSize(SFI); |
| 438 | |
| 439 | unsigned Align = FFI->getObjectAlignment(SFI); |
| 440 | // Adjust to alignment boundary |
| 441 | Offset = (Offset+Align-1)/Align*Align; |
| 442 | |
| 443 | if (StackGrowsDown) { |
| 444 | FFI->setObjectOffset(SFI, -Offset); // Set the computed offset |
| 445 | } else { |
| 446 | FFI->setObjectOffset(SFI, Offset); |
| 447 | Offset += FFI->getObjectSize(SFI); |
| 448 | } |
| 449 | } |
| 450 | } |
| 451 | |
Evan Cheng | 367372a | 2007-01-23 09:38:11 +0000 | [diff] [blame] | 452 | // Round up the size to a multiple of the alignment, but only if there are |
| 453 | // calls or alloca's in the function. This ensures that any calls to |
| 454 | // subroutines have their stack frames suitable aligned. |
Evan Cheng | 02a2029 | 2007-01-25 22:12:41 +0000 | [diff] [blame] | 455 | if (!RegInfo->targetHandlesStackFrameRounding() && |
| 456 | (FFI->hasCalls() || FFI->hasVarSizedObjects())) { |
Evan Cheng | 5c3885c | 2007-05-01 00:52:08 +0000 | [diff] [blame] | 457 | // If we have reserved argument space for call sites in the function |
| 458 | // immediately on entry to the current function, count it as part of the |
| 459 | // overall stack size. |
| 460 | if (RegInfo->hasReservedCallFrame(Fn)) |
Evan Cheng | 367372a | 2007-01-23 09:38:11 +0000 | [diff] [blame] | 461 | Offset += FFI->getMaxCallFrameSize(); |
| 462 | |
| 463 | unsigned AlignMask = TFI.getStackAlignment() - 1; |
Chris Lattner | ea84c5e | 2007-04-25 04:30:24 +0000 | [diff] [blame] | 464 | Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); |
Evan Cheng | 367372a | 2007-01-23 09:38:11 +0000 | [diff] [blame] | 465 | } |
| 466 | |
| 467 | // Update frame info to pretend that this is part of the stack... |
Chris Lattner | 7f7bbc2 | 2004-06-11 06:37:11 +0000 | [diff] [blame] | 468 | FFI->setStackSize(Offset+TFI.getOffsetOfLocalArea()); |
Chris Lattner | cbef8ba | 2005-11-06 17:43:20 +0000 | [diff] [blame] | 469 | |
| 470 | // Remember the required stack alignment in case targets need it to perform |
| 471 | // dynamic stack alignment. |
Chris Lattner | 4672f71 | 2006-04-03 21:39:57 +0000 | [diff] [blame] | 472 | assert(FFI->getMaxAlignment() == MaxAlign && |
| 473 | "Stack alignment calculation broken!"); |
Chris Lattner | 4ac7d73 | 2003-01-15 22:52:34 +0000 | [diff] [blame] | 474 | } |
| 475 | |
| 476 | |
Evan Cheng | c2b4ec3 | 2006-09-28 00:10:27 +0000 | [diff] [blame] | 477 | /// insertPrologEpilogCode - Scan the function for modified callee saved |
| 478 | /// registers, insert spill code for these callee saved registers, then add |
Chris Lattner | 4ac7d73 | 2003-01-15 22:52:34 +0000 | [diff] [blame] | 479 | /// prolog and epilog code to the function. |
| 480 | /// |
| 481 | void PEI::insertPrologEpilogCode(MachineFunction &Fn) { |
| 482 | // Add prologue to the function... |
| 483 | Fn.getTarget().getRegisterInfo()->emitPrologue(Fn); |
| 484 | |
| 485 | // Add epilogue to restore the callee-save registers in each exiting block |
Chris Lattner | 9bcdcd1 | 2004-06-02 05:57:12 +0000 | [diff] [blame] | 486 | const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); |
Chris Lattner | 4ac7d73 | 2003-01-15 22:52:34 +0000 | [diff] [blame] | 487 | for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { |
| 488 | // If last instruction is a return instruction, add an epilogue |
Alkis Evlogimenos | c0b9dc5 | 2004-02-12 02:27:10 +0000 | [diff] [blame] | 489 | if (!I->empty() && TII.isReturn(I->back().getOpcode())) |
Chris Lattner | 4ac7d73 | 2003-01-15 22:52:34 +0000 | [diff] [blame] | 490 | Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I); |
| 491 | } |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 492 | } |
| 493 | |
| 494 | |
| 495 | /// replaceFrameIndices - Replace all MO_FrameIndex operands with physical |
| 496 | /// register references and actual offsets. |
| 497 | /// |
| 498 | void PEI::replaceFrameIndices(MachineFunction &Fn) { |
| 499 | if (!Fn.getFrameInfo()->hasStackObjects()) return; // Nothing to do? |
| 500 | |
| 501 | const TargetMachine &TM = Fn.getTarget(); |
| 502 | assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!"); |
| 503 | const MRegisterInfo &MRI = *TM.getRegisterInfo(); |
Evan Cheng | 8e33473 | 2007-05-01 09:01:42 +0000 | [diff] [blame] | 504 | const TargetFrameInfo *TFI = TM.getFrameInfo(); |
| 505 | bool StackGrowsDown = |
| 506 | TFI->getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; |
| 507 | int FrameSetupOpcode = MRI.getCallFrameSetupOpcode(); |
| 508 | int FrameDestroyOpcode = MRI.getCallFrameDestroyOpcode(); |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 509 | |
Evan Cheng | 49dd064 | 2007-02-23 01:11:26 +0000 | [diff] [blame] | 510 | for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { |
Evan Cheng | 8e33473 | 2007-05-01 09:01:42 +0000 | [diff] [blame] | 511 | int SPAdj = 0; // SP offset due to call frame setup / destroy. |
Evan Cheng | 23322d1 | 2007-03-01 02:25:51 +0000 | [diff] [blame] | 512 | if (RS) RS->enterBasicBlock(BB); |
Chris Lattner | 0ebe9c1 | 2007-04-09 01:19:33 +0000 | [diff] [blame] | 513 | for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { |
Evan Cheng | 8e33473 | 2007-05-01 09:01:42 +0000 | [diff] [blame] | 514 | MachineInstr *MI = I; |
Chris Lattner | d2eae62 | 2007-04-09 00:46:10 +0000 | [diff] [blame] | 515 | |
Evan Cheng | 8e33473 | 2007-05-01 09:01:42 +0000 | [diff] [blame] | 516 | // Remember how much SP has been adjustment to create the call frame. |
| 517 | if (I->getOpcode() == FrameSetupOpcode || |
| 518 | I->getOpcode() == FrameDestroyOpcode) { |
| 519 | int Size = I->getOperand(0).getImmedValue(); |
| 520 | if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) || |
| 521 | (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode)) |
| 522 | Size = -Size; |
| 523 | SPAdj += Size; |
| 524 | MachineBasicBlock::iterator PrevI = prior(I); |
| 525 | MRI.eliminateCallFramePseudoInstr(Fn, *BB, I); |
| 526 | // Visit the instructions created by eliminateCallFramePseudoInstr(). |
| 527 | I = next(PrevI); |
| 528 | MI = NULL; |
| 529 | } else { |
| 530 | I++; |
| 531 | for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) |
| 532 | if (MI->getOperand(i).isFrameIndex()) { |
| 533 | // If this instruction has a FrameIndex operand, we need to use that |
| 534 | // target machine register info object to eliminate it. |
| 535 | MRI.eliminateFrameIndex(MI, SPAdj, RS); |
| 536 | |
| 537 | // Revisit the instruction in full. Some instructions (e.g. inline |
| 538 | // asm instructions) can have multiple frame indices. |
| 539 | --I; |
| 540 | MI = 0; |
| 541 | break; |
| 542 | } |
| 543 | } |
Evan Cheng | 49dd064 | 2007-02-23 01:11:26 +0000 | [diff] [blame] | 544 | // Update register states. |
Chris Lattner | 0ebe9c1 | 2007-04-09 01:19:33 +0000 | [diff] [blame] | 545 | if (RS && MI) RS->forward(MI); |
Evan Cheng | 49dd064 | 2007-02-23 01:11:26 +0000 | [diff] [blame] | 546 | } |
Evan Cheng | 8e33473 | 2007-05-01 09:01:42 +0000 | [diff] [blame] | 547 | assert(SPAdj == 0 && "Unbalanced call frame setup / destroy pairs?"); |
Evan Cheng | 49dd064 | 2007-02-23 01:11:26 +0000 | [diff] [blame] | 548 | } |
Chris Lattner | 58b3328 | 2002-12-28 20:43:30 +0000 | [diff] [blame] | 549 | } |