/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/CodeGen/MachineFrameInfo.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- MachineFrameInfo.cpp ---------------------------------------------===// |
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 | | /// \file Implements MachineFrameInfo that manages the stack frame. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "llvm/CodeGen/MachineFrameInfo.h" |
15 | | |
16 | | #include "llvm/ADT/BitVector.h" |
17 | | #include "llvm/CodeGen/MachineFunction.h" |
18 | | #include "llvm/CodeGen/MachineRegisterInfo.h" |
19 | | #include "llvm/Support/Debug.h" |
20 | | #include "llvm/Support/raw_ostream.h" |
21 | | #include "llvm/Target/TargetFrameLowering.h" |
22 | | #include "llvm/Target/TargetInstrInfo.h" |
23 | | #include "llvm/Target/TargetRegisterInfo.h" |
24 | | #include "llvm/Target/TargetSubtargetInfo.h" |
25 | | #include <cassert> |
26 | | |
27 | | #define DEBUG_TYPE "codegen" |
28 | | |
29 | | using namespace llvm; |
30 | | |
31 | 2.81M | void MachineFrameInfo::ensureMaxAlignment(unsigned Align) { |
32 | 2.81M | if (!StackRealignable) |
33 | 2.81M | assert(Align <= StackAlignment && |
34 | 2.81M | "For targets without stack realignment, Align is out of limit!"); |
35 | 2.81M | if (MaxAlignment < Align2.81M ) MaxAlignment = Align413k ; |
36 | 2.81M | } |
37 | | |
38 | | /// Clamp the alignment if requested and emit a warning. |
39 | | static inline unsigned clampStackAlignment(bool ShouldClamp, unsigned Align, |
40 | 2.48M | unsigned StackAlign) { |
41 | 2.48M | if (!ShouldClamp || 2.48M Align <= StackAlign5.09k ) |
42 | 2.48M | return Align; |
43 | 58 | DEBUG58 (dbgs() << "Warning: requested alignment " << Align |
44 | 58 | << " exceeds the stack alignment " << StackAlign |
45 | 58 | << " when stack realignment is off" << '\n'); |
46 | 58 | return StackAlign; |
47 | 58 | } |
48 | | |
49 | | int MachineFrameInfo::CreateStackObject(uint64_t Size, unsigned Alignment, |
50 | | bool isSS, const AllocaInst *Alloca, |
51 | 2.24M | uint8_t ID) { |
52 | 2.24M | assert(Size != 0 && "Cannot allocate zero size stack objects!"); |
53 | 2.24M | Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment); |
54 | 2.24M | Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, Alloca, |
55 | 2.24M | !isSS, ID)); |
56 | 2.24M | int Index = (int)Objects.size() - NumFixedObjects - 1; |
57 | 2.24M | assert(Index >= 0 && "Bad frame index!"); |
58 | 2.24M | ensureMaxAlignment(Alignment); |
59 | 2.24M | return Index; |
60 | 2.24M | } |
61 | | |
62 | | int MachineFrameInfo::CreateSpillStackObject(uint64_t Size, |
63 | 133k | unsigned Alignment) { |
64 | 133k | Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment); |
65 | 133k | CreateStackObject(Size, Alignment, true); |
66 | 133k | int Index = (int)Objects.size() - NumFixedObjects - 1; |
67 | 133k | ensureMaxAlignment(Alignment); |
68 | 133k | return Index; |
69 | 133k | } |
70 | | |
71 | | int MachineFrameInfo::CreateVariableSizedObject(unsigned Alignment, |
72 | 720 | const AllocaInst *Alloca) { |
73 | 720 | HasVarSizedObjects = true; |
74 | 720 | Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment); |
75 | 720 | Objects.push_back(StackObject(0, Alignment, 0, false, false, Alloca, true)); |
76 | 720 | ensureMaxAlignment(Alignment); |
77 | 720 | return (int)Objects.size()-NumFixedObjects-1; |
78 | 720 | } |
79 | | |
80 | | int MachineFrameInfo::CreateFixedObject(uint64_t Size, int64_t SPOffset, |
81 | 83.5k | bool Immutable, bool isAliased) { |
82 | 83.5k | assert(Size != 0 && "Cannot allocate zero size fixed stack objects!"); |
83 | 83.5k | // The alignment of the frame index can be determined from its offset from |
84 | 83.5k | // the incoming frame position. If the frame object is at offset 32 and |
85 | 83.5k | // the stack is guaranteed to be 16-byte aligned, then we know that the |
86 | 83.5k | // object is 16-byte aligned. Note that unlike the non-fixed case, if the |
87 | 83.5k | // stack needs realignment, we can't assume that the stack will in fact be |
88 | 83.5k | // aligned. |
89 | 83.5k | unsigned Align = MinAlign(SPOffset, ForcedRealign ? 125 : StackAlignment83.5k ); |
90 | 83.5k | Align = clampStackAlignment(!StackRealignable, Align, StackAlignment); |
91 | 83.5k | Objects.insert(Objects.begin(), StackObject(Size, Align, SPOffset, Immutable, |
92 | 83.5k | /*isSS*/ false, |
93 | 83.5k | /*Alloca*/ nullptr, isAliased)); |
94 | 83.5k | return -++NumFixedObjects; |
95 | 83.5k | } |
96 | | |
97 | | int MachineFrameInfo::CreateFixedSpillStackObject(uint64_t Size, |
98 | | int64_t SPOffset, |
99 | 27.7k | bool Immutable) { |
100 | 27.7k | unsigned Align = MinAlign(SPOffset, ForcedRealign ? 126 : StackAlignment27.7k ); |
101 | 27.7k | Align = clampStackAlignment(!StackRealignable, Align, StackAlignment); |
102 | 27.7k | Objects.insert(Objects.begin(), StackObject(Size, Align, SPOffset, Immutable, |
103 | 27.7k | /*isSS*/ true, |
104 | 27.7k | /*Alloca*/ nullptr, |
105 | 27.7k | /*isAliased*/ false)); |
106 | 27.7k | return -++NumFixedObjects; |
107 | 27.7k | } |
108 | | |
109 | 1.46M | BitVector MachineFrameInfo::getPristineRegs(const MachineFunction &MF) const { |
110 | 1.46M | const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); |
111 | 1.46M | BitVector BV(TRI->getNumRegs()); |
112 | 1.46M | |
113 | 1.46M | // Before CSI is calculated, no registers are considered pristine. They can be |
114 | 1.46M | // freely used and PEI will make sure they are saved. |
115 | 1.46M | if (!isCalleeSavedInfoValid()) |
116 | 957k | return BV; |
117 | 509k | |
118 | 509k | const MachineRegisterInfo &MRI = MF.getRegInfo(); |
119 | 11.1M | for (const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); CSR && 11.1M *CSR11.1M ; |
120 | 10.6M | ++CSR) |
121 | 10.6M | BV.set(*CSR); |
122 | 509k | |
123 | 509k | // Saved CSRs are not pristine. |
124 | 509k | for (auto &I : getCalleeSavedInfo()) |
125 | 815k | for (MCSubRegIterator S(I.getReg(), TRI, true); 282k S.isValid()815k ; ++S532k ) |
126 | 532k | BV.reset(*S); |
127 | 1.46M | |
128 | 1.46M | return BV; |
129 | 1.46M | } |
130 | | |
131 | 610k | unsigned MachineFrameInfo::estimateStackSize(const MachineFunction &MF) const { |
132 | 610k | const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); |
133 | 610k | const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); |
134 | 610k | unsigned MaxAlign = getMaxAlignment(); |
135 | 610k | int Offset = 0; |
136 | 610k | |
137 | 610k | // This code is very, very similar to PEI::calculateFrameObjectOffsets(). |
138 | 610k | // It really should be refactored to share code. Until then, changes |
139 | 610k | // should keep in mind that there's tight coupling between the two. |
140 | 610k | |
141 | 937k | for (int i = getObjectIndexBegin(); i != 0937k ; ++i326k ) { |
142 | 326k | int FixedOff = -getObjectOffset(i); |
143 | 326k | if (FixedOff > Offset326k ) Offset = FixedOff1.68k ; |
144 | 326k | } |
145 | 855k | for (unsigned i = 0, e = getObjectIndexEnd(); i != e855k ; ++i244k ) { |
146 | 244k | if (isDeadObjectIndex(i)) |
147 | 37.1k | continue; |
148 | 207k | Offset += getObjectSize(i); |
149 | 207k | unsigned Align = getObjectAlignment(i); |
150 | 207k | // Adjust to alignment boundary |
151 | 207k | Offset = (Offset+Align-1)/Align*Align; |
152 | 207k | |
153 | 207k | MaxAlign = std::max(Align, MaxAlign); |
154 | 207k | } |
155 | 610k | |
156 | 610k | if (adjustsStack() && 610k TFI->hasReservedCallFrame(MF)316k ) |
157 | 316k | Offset += getMaxCallFrameSize(); |
158 | 610k | |
159 | 610k | // Round up the size to a multiple of the alignment. If the function has |
160 | 610k | // any calls or alloca's, align to the target's StackAlignment value to |
161 | 610k | // ensure that the callee's frame or the alloca data is suitably aligned; |
162 | 610k | // otherwise, for leaf functions, align to the TransientStackAlignment |
163 | 610k | // value. |
164 | 610k | unsigned StackAlign; |
165 | 610k | if (adjustsStack() || 610k hasVarSizedObjects()294k || |
166 | 294k | (RegInfo->needsStackRealignment(MF) && 294k getObjectIndexEnd() != 0126 )) |
167 | 316k | StackAlign = TFI->getStackAlignment(); |
168 | 610k | else |
169 | 294k | StackAlign = TFI->getTransientStackAlignment(); |
170 | 610k | |
171 | 610k | // If the frame pointer is eliminated, all frame offsets will be relative to |
172 | 610k | // SP not FP. Align to MaxAlign so this works. |
173 | 610k | StackAlign = std::max(StackAlign, MaxAlign); |
174 | 610k | unsigned AlignMask = StackAlign - 1; |
175 | 610k | Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); |
176 | 610k | |
177 | 610k | return (unsigned)Offset; |
178 | 610k | } |
179 | | |
180 | 17.1k | void MachineFrameInfo::computeMaxCallFrameSize(const MachineFunction &MF) { |
181 | 17.1k | const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); |
182 | 17.1k | unsigned FrameSetupOpcode = TII.getCallFrameSetupOpcode(); |
183 | 17.1k | unsigned FrameDestroyOpcode = TII.getCallFrameDestroyOpcode(); |
184 | 17.1k | assert(FrameSetupOpcode != ~0u && FrameDestroyOpcode != ~0u && |
185 | 17.1k | "Can only compute MaxCallFrameSize if Setup/Destroy opcode are known"); |
186 | 17.1k | |
187 | 17.1k | MaxCallFrameSize = 0; |
188 | 58.2k | for (const MachineBasicBlock &MBB : MF) { |
189 | 516k | for (const MachineInstr &MI : MBB) { |
190 | 516k | unsigned Opcode = MI.getOpcode(); |
191 | 516k | if (Opcode == FrameSetupOpcode || 516k Opcode == FrameDestroyOpcode495k ) { |
192 | 41.7k | unsigned Size = TII.getFrameSize(MI); |
193 | 41.7k | MaxCallFrameSize = std::max(MaxCallFrameSize, Size); |
194 | 41.7k | AdjustsStack = true; |
195 | 516k | } else if (475k MI.isInlineAsm()475k ) { |
196 | 3.86k | // Some inline asm's need a stack frame, as indicated by operand 1. |
197 | 3.86k | unsigned ExtraInfo = MI.getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); |
198 | 3.86k | if (ExtraInfo & InlineAsm::Extra_IsAlignStack) |
199 | 1 | AdjustsStack = true; |
200 | 475k | } |
201 | 516k | } |
202 | 58.2k | } |
203 | 17.1k | } |
204 | | |
205 | 1.43k | void MachineFrameInfo::print(const MachineFunction &MF, raw_ostream &OS) const{ |
206 | 1.43k | if (Objects.empty()1.43k ) return1.17k ; |
207 | 260 | |
208 | 260 | const TargetFrameLowering *FI = MF.getSubtarget().getFrameLowering(); |
209 | 260 | int ValOffset = (FI ? FI->getOffsetOfLocalArea()260 : 00 ); |
210 | 260 | |
211 | 260 | OS << "Frame Objects:\n"; |
212 | 260 | |
213 | 807 | for (unsigned i = 0, e = Objects.size(); i != e807 ; ++i547 ) { |
214 | 547 | const StackObject &SO = Objects[i]; |
215 | 547 | OS << " fi#" << (int)(i-NumFixedObjects) << ": "; |
216 | 547 | |
217 | 547 | if (SO.StackID != 0) |
218 | 0 | OS << "id=" << SO.StackID << ' '; |
219 | 547 | |
220 | 547 | if (SO.Size == ~0ULL547 ) { |
221 | 1 | OS << "dead\n"; |
222 | 1 | continue; |
223 | 1 | } |
224 | 546 | if (546 SO.Size == 0546 ) |
225 | 1 | OS << "variable sized"; |
226 | 546 | else |
227 | 545 | OS << "size=" << SO.Size; |
228 | 546 | OS << ", align=" << SO.Alignment; |
229 | 546 | |
230 | 546 | if (i < NumFixedObjects) |
231 | 22 | OS << ", fixed"; |
232 | 546 | if (i < NumFixedObjects || 546 SO.SPOffset != -1524 ) { |
233 | 546 | int64_t Off = SO.SPOffset - ValOffset; |
234 | 546 | OS << ", at location [SP"; |
235 | 546 | if (Off > 0) |
236 | 27 | OS << "+" << Off; |
237 | 519 | else if (519 Off < 0519 ) |
238 | 495 | OS << Off; |
239 | 546 | OS << "]"; |
240 | 546 | } |
241 | 547 | OS << "\n"; |
242 | 547 | } |
243 | 1.43k | } |
244 | | |
245 | | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
246 | | LLVM_DUMP_METHOD void MachineFrameInfo::dump(const MachineFunction &MF) const { |
247 | | print(MF, dbgs()); |
248 | | } |
249 | | #endif |