/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/Mips/MipsFrameLowering.cpp
Line | Count | Source |
1 | | //===-- MipsFrameLowering.cpp - Mips Frame Information --------------------===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file contains the Mips implementation of TargetFrameLowering class. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "MipsFrameLowering.h" |
15 | | #include "MCTargetDesc/MipsBaseInfo.h" |
16 | | #include "MipsInstrInfo.h" |
17 | | #include "MipsMachineFunction.h" |
18 | | #include "MipsTargetMachine.h" |
19 | | #include "llvm/CodeGen/MachineFrameInfo.h" |
20 | | #include "llvm/CodeGen/MachineFunction.h" |
21 | | #include "llvm/CodeGen/MachineInstrBuilder.h" |
22 | | #include "llvm/CodeGen/MachineModuleInfo.h" |
23 | | #include "llvm/CodeGen/MachineRegisterInfo.h" |
24 | | #include "llvm/IR/DataLayout.h" |
25 | | #include "llvm/IR/Function.h" |
26 | | #include "llvm/Target/TargetOptions.h" |
27 | | |
28 | | using namespace llvm; |
29 | | |
30 | | |
31 | | //===----------------------------------------------------------------------===// |
32 | | // |
33 | | // Stack Frame Processing methods |
34 | | // +----------------------------+ |
35 | | // |
36 | | // The stack is allocated decrementing the stack pointer on |
37 | | // the first instruction of a function prologue. Once decremented, |
38 | | // all stack references are done thought a positive offset |
39 | | // from the stack/frame pointer, so the stack is considering |
40 | | // to grow up! Otherwise terrible hacks would have to be made |
41 | | // to get this stack ABI compliant :) |
42 | | // |
43 | | // The stack frame required by the ABI (after call): |
44 | | // Offset |
45 | | // |
46 | | // 0 ---------- |
47 | | // 4 Args to pass |
48 | | // . saved $GP (used in PIC) |
49 | | // . Alloca allocations |
50 | | // . Local Area |
51 | | // . CPU "Callee Saved" Registers |
52 | | // . saved FP |
53 | | // . saved RA |
54 | | // . FPU "Callee Saved" Registers |
55 | | // StackSize ----------- |
56 | | // |
57 | | // Offset - offset from sp after stack allocation on function prologue |
58 | | // |
59 | | // The sp is the stack pointer subtracted/added from the stack size |
60 | | // at the Prologue/Epilogue |
61 | | // |
62 | | // References to the previous stack (to obtain arguments) are done |
63 | | // with offsets that exceeds the stack size: (stacksize+(4*(num_arg-1)) |
64 | | // |
65 | | // Examples: |
66 | | // - reference to the actual stack frame |
67 | | // for any local area var there is smt like : FI >= 0, StackOffset: 4 |
68 | | // sw REGX, 4(SP) |
69 | | // |
70 | | // - reference to previous stack frame |
71 | | // suppose there's a load to the 5th arguments : FI < 0, StackOffset: 16. |
72 | | // The emitted instruction will be something like: |
73 | | // lw REGX, 16+StackSize(SP) |
74 | | // |
75 | | // Since the total stack size is unknown on LowerFormalArguments, all |
76 | | // stack references (ObjectOffset) created to reference the function |
77 | | // arguments, are negative numbers. This way, on eliminateFrameIndex it's |
78 | | // possible to detect those references and the offsets are adjusted to |
79 | | // their real location. |
80 | | // |
81 | | //===----------------------------------------------------------------------===// |
82 | | |
83 | 8.96k | const MipsFrameLowering *MipsFrameLowering::create(const MipsSubtarget &ST) { |
84 | 8.96k | if (ST.inMips16Mode()) |
85 | 2.37k | return llvm::createMips16FrameLowering(ST); |
86 | 6.59k | |
87 | 6.59k | return llvm::createMipsSEFrameLowering(ST); |
88 | 6.59k | } |
89 | | |
90 | | // hasFP - Return true if the specified function should have a dedicated frame |
91 | | // pointer register. This is true if the function has variable sized allocas, |
92 | | // if it needs dynamic stack realignment, if frame pointer elimination is |
93 | | // disabled, or if the frame address is taken. |
94 | 123k | bool MipsFrameLowering::hasFP(const MachineFunction &MF) const { |
95 | 123k | const MachineFrameInfo &MFI = MF.getFrameInfo(); |
96 | 123k | const TargetRegisterInfo *TRI = STI.getRegisterInfo(); |
97 | 123k | |
98 | 123k | return MF.getTarget().Options.DisableFramePointerElim(MF) || |
99 | 123k | MFI.hasVarSizedObjects()119k || MFI.isFrameAddressTaken()119k || |
100 | 119k | TRI->needsStackRealignment(MF); |
101 | 123k | } |
102 | | |
103 | 12.1k | bool MipsFrameLowering::hasBP(const MachineFunction &MF) const { |
104 | 12.1k | const MachineFrameInfo &MFI = MF.getFrameInfo(); |
105 | 12.1k | const TargetRegisterInfo *TRI = STI.getRegisterInfo(); |
106 | 12.1k | |
107 | 96 | return MFI.hasVarSizedObjects() && TRI->needsStackRealignment(MF); |
108 | 12.1k | } |
109 | | |
110 | 11.9k | uint64_t MipsFrameLowering::estimateStackSize(const MachineFunction &MF) const { |
111 | 11.9k | const MachineFrameInfo &MFI = MF.getFrameInfo(); |
112 | 11.9k | const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); |
113 | 11.9k | |
114 | 11.9k | int64_t Offset = 0; |
115 | 11.9k | |
116 | 11.9k | // Iterate over fixed sized objects. |
117 | 14.0k | for (int I = MFI.getObjectIndexBegin(); I != 014.0k ; ++I2.09k ) |
118 | 2.09k | Offset = std::max(Offset, -MFI.getObjectOffset(I)); |
119 | 11.9k | |
120 | 11.9k | // Conservatively assume all callee-saved registers will be saved. |
121 | 215k | for (const MCPhysReg *R = TRI.getCalleeSavedRegs(&MF); *R215k ; ++R203k ) { |
122 | 203k | unsigned Size = TRI.getSpillSize(*TRI.getMinimalPhysRegClass(*R)); |
123 | 203k | Offset = alignTo(Offset + Size, Size); |
124 | 203k | } |
125 | 11.9k | |
126 | 11.9k | unsigned MaxAlign = MFI.getMaxAlignment(); |
127 | 11.9k | |
128 | 11.9k | // Check that MaxAlign is not zero if there is a stack object that is not a |
129 | 11.9k | // callee-saved spill. |
130 | 11.9k | assert(!MFI.getObjectIndexEnd() || MaxAlign); |
131 | 11.9k | |
132 | 11.9k | // Iterate over other objects. |
133 | 13.6k | for (unsigned I = 0, E = MFI.getObjectIndexEnd(); I != E13.6k ; ++I1.74k ) |
134 | 1.74k | Offset = alignTo(Offset + MFI.getObjectSize(I), MaxAlign); |
135 | 11.9k | |
136 | 11.9k | // Call frame. |
137 | 11.9k | if (MFI.adjustsStack() && 11.9k hasReservedCallFrame(MF)1.60k ) |
138 | 1.54k | Offset = alignTo(Offset + MFI.getMaxCallFrameSize(), |
139 | 1.54k | std::max(MaxAlign, getStackAlignment())); |
140 | 11.9k | |
141 | 11.9k | return alignTo(Offset, getStackAlignment()); |
142 | 11.9k | } |
143 | | |
144 | | // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions |
145 | | MachineBasicBlock::iterator MipsFrameLowering:: |
146 | | eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, |
147 | 5.73k | MachineBasicBlock::iterator I) const { |
148 | 5.73k | unsigned SP = STI.getABI().IsN64() ? Mips::SP_641.47k : Mips::SP4.25k ; |
149 | 5.73k | |
150 | 5.73k | if (!hasReservedCallFrame(MF)5.73k ) { |
151 | 206 | int64_t Amount = I->getOperand(0).getImm(); |
152 | 206 | if (I->getOpcode() == Mips::ADJCALLSTACKDOWN) |
153 | 103 | Amount = -Amount; |
154 | 206 | |
155 | 206 | STI.getInstrInfo()->adjustStackPtr(SP, Amount, MBB, I); |
156 | 206 | } |
157 | 5.73k | |
158 | 5.73k | return MBB.erase(I); |
159 | 5.73k | } |