LLVM: include/llvm/CodeGen/MachineFrameInfo.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef LLVM_CODEGEN_MACHINEFRAMEINFO_H
14#define LLVM_CODEGEN_MACHINEFRAMEINFO_H
15
20#include
21#include
22
23namespace llvm {
24class raw_ostream;
25class MachineFunction;
26class MachineBasicBlock;
27class BitVector;
28class AllocaInst;
29
30
31
32
33
36 union {
39 };
40
41
42
43
44
45
46
47
48
49
50
51
52 bool Restored = true;
53
54
55 bool SpilledToReg = false;
56
57public:
59
60
66 SpilledToReg = false;
67 }
70 SpilledToReg = true;
71 }
75};
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
107public:
108
109
111 SSPLK_None,
113 SSPLK_LargeArray,
115 SSPLK_SmallArray,
117 SSPLK_AddrOf
118
120
121private:
122
123 struct StackObject {
124
125
126 int64_t SPOffset;
127
128
129
131
132
134
135
136
137
138 bool isImmutable;
139
140
141
142 bool isSpillSlot;
143
144
145
146
147
148
149 bool isStatepointSpillSlot = false;
150
151
152
153
154
155
156
157
158
159
161
162
163
165
166
167
168 bool PreAllocated = false;
169
170
171
172
173
174 bool isAliased;
175
176
177 bool isZExt = false;
178
179
180 bool isSExt = false;
181
183
184 StackObject(uint64_t Size, Align Alignment, int64_t SPOffset,
185 bool IsImmutable, bool IsSpillSlot, const AllocaInst *Alloca,
186 bool IsAliased, uint8_t StackID = 0)
187 : SPOffset(SPOffset), Size(Size), Alignment(Alignment),
188 isImmutable(IsImmutable), isSpillSlot(IsSpillSlot), StackID(StackID),
189 Alloca(Alloca), isAliased(IsAliased) {}
190 };
191
192
193 Align StackAlignment;
194
195
196
197
198
199
200
201
202
203
204
205
206 bool StackRealignable;
207
208
209 bool ForcedRealign;
210
211
212 std::vector Objects;
213
214
215
216
217 unsigned NumFixedObjects = 0;
218
219
220
221 bool HasVarSizedObjects = false;
222
223
224
225 bool FrameAddressTaken = false;
226
227
228
229 bool ReturnAddressTaken = false;
230
231
232
233 bool HasStackMap = false;
234
235
236
237 bool HasPatchPoint = false;
238
239
240
241
242
244
245
246
247
248
249
250
251
252
253
254 int64_t OffsetAdjustment = 0;
255
256
257
258
259
260
261
262
263 Align MaxAlignment;
264
265
266
267
268 bool AdjustsStack = false;
269
270
271 bool HasCalls = false;
272
273
274 int StackProtectorIdx = -1;
275
276
277 int FunctionContextIdx = -1;
278
279
280
281
282
283 uint64_t MaxCallFrameSize = ~UINT64_C(0);
284
285
286
287 unsigned CVBytesOfCalleeSavedRegisters = 0;
288
289
290
291
292
293 std::vector CSInfo;
294
295
296 bool CSIValid = false;
297
298
299
300 SmallVector<std::pair<int, int64_t>, 32> LocalFrameObjects;
301
302
303 int64_t LocalFrameSize = 0;
304
305
306
307 Align LocalFrameMaxAlign;
308
309
310
311
312 bool UseLocalStackAllocationBlock = false;
313
314
315
316 bool HasOpaqueSPAdjustment = false;
317
318
319
320 bool HasCopyImplyingStackAdjustment = false;
321
322
323 bool HasVAStart = false;
324
325
326 bool HasMustTailInVarArgFunc = false;
327
328
329
330
331 bool HasTailCall = false;
332
333
334 MachineBasicBlock *Save = nullptr;
335
336 MachineBasicBlock *Restore = nullptr;
337
338
339 uint64_t UnsafeStackSize = 0;
340
341public:
343 bool ForcedRealign)
344 : StackAlignment(StackAlignment),
345 StackRealignable(StackRealignable), ForcedRealign(ForcedRealign) {}
346
348
350
351
353
354
355
356
358
359
363
364
365
369
370
371
372
375
376
377
378
381
382
383
384
387
388
389
390
393
394
395
396
397
398
399
400
401
402
403
406 }
407
408
410
411
412 int getObjectIndexEnd() const { return (int)Objects.size()-NumFixedObjects; }
413
414
416
417
419
420
422 LocalFrameObjects.push_back(std::pair<int, int64_t>(ObjectIndex, Offset));
423 Objects[ObjectIndex + NumFixedObjects].PreAllocated = true;
424 }
425
426
428 assert (i >= 0 && (unsigned)i < LocalFrameObjects.size() &&
429 "Invalid local object reference!");
430 return LocalFrameObjects[i];
431 }
432
433
435
436
438
439
441
442
443
445 LocalFrameMaxAlign = Alignment;
446 }
447
448
450
451
452
454 return UseLocalStackAllocationBlock;
455 }
456
457
458
459
461 UseLocalStackAllocationBlock = v;
462 }
463
464
466 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
467 "Invalid Object Idx!");
468 return Objects[ObjectIdx+NumFixedObjects].PreAllocated;
469 }
470
471
473 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
474 "Invalid Object Idx!");
475 return Objects[ObjectIdx+NumFixedObjects].Size;
476 }
477
478
480 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
481 "Invalid Object Idx!");
482 Objects[ObjectIdx+NumFixedObjects].Size = Size;
483 }
484
485
487 assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
488 "Invalid Object Idx!");
489 return Objects[ObjectIdx + NumFixedObjects].Alignment;
490 }
491
492
496 }
497
498
500 assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
501 "Invalid Object Idx!");
502 Objects[ObjectIdx + NumFixedObjects].Alignment = Alignment;
503
504
508 }
509
510
511
513 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
514 "Invalid Object Idx!");
515 return Objects[ObjectIdx+NumFixedObjects].Alloca;
516 }
517
518
519
521 assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
522 "Invalid Object Idx!");
523 Objects[ObjectIdx + NumFixedObjects].Alloca = nullptr;
524 }
525
526
527
529 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
530 "Invalid Object Idx!");
532 "Getting frame offset for a dead object?");
533 return Objects[ObjectIdx+NumFixedObjects].SPOffset;
534 }
535
537 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
538 "Invalid Object Idx!");
539 return Objects[ObjectIdx+NumFixedObjects].isZExt;
540 }
541
543 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
544 "Invalid Object Idx!");
545 Objects[ObjectIdx+NumFixedObjects].isZExt = IsZExt;
546 }
547
549 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
550 "Invalid Object Idx!");
551 return Objects[ObjectIdx+NumFixedObjects].isSExt;
552 }
553
555 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
556 "Invalid Object Idx!");
557 Objects[ObjectIdx+NumFixedObjects].isSExt = IsSExt;
558 }
559
560
561
563 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
564 "Invalid Object Idx!");
566 "Setting frame offset for a dead object?");
567 Objects[ObjectIdx+NumFixedObjects].SPOffset = SPOffset;
568 }
569
571 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
572 "Invalid Object Idx!");
573 return (SSPLayoutKind)Objects[ObjectIdx+NumFixedObjects].SSPLayout;
574 }
575
577 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
578 "Invalid Object Idx!");
580 "Setting SSP layout for a dead object?");
581 Objects[ObjectIdx+NumFixedObjects].SSPLayout = Kind;
582 }
583
584
585
586
588
589
591
592
594
595
597
598
600
601
602
604
605
607
608
609
611 return ForcedRealign || MaxAlignment > StackAlignment;
612 }
613
614
615
616
619
620
623
624
627
628
629
631 return HasCopyImplyingStackAdjustment;
632 }
634 HasCopyImplyingStackAdjustment = B;
635 }
636
637
640
641
644
645
648
649
650
651
652
653
654
655
656
659 std::vectorMachineBasicBlock::iterator *FrameSDOps = nullptr);
660
661
662
663
664
665
667
668
670 return 0;
671 return MaxCallFrameSize;
672 }
674 return MaxCallFrameSize != ~UINT64_C(0);
675 }
677
678
679
681 return CVBytesOfCalleeSavedRegisters;
682 }
684 CVBytesOfCalleeSavedRegisters = S;
685 }
686
687
688
689
690
692 bool isAliased = false);
693
694
695
697 bool IsImmutable = false);
698
699
701 return ObjectIdx < 0 && (ObjectIdx >= -(int)NumFixedObjects);
702 }
703
704
705
707 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
708 "Invalid Object Idx!");
709 return Objects[ObjectIdx+NumFixedObjects].isAliased;
710 }
711
712
714 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
715 "Invalid Object Idx!");
716 Objects[ObjectIdx+NumFixedObjects].isAliased = IsAliased;
717 }
718
719
721
722 if (HasTailCall)
723 return false;
724 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
725 "Invalid Object Idx!");
726 return Objects[ObjectIdx+NumFixedObjects].isImmutable;
727 }
728
729
731 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
732 "Invalid Object Idx!");
733 Objects[ObjectIdx+NumFixedObjects].isImmutable = IsImmutable;
734 }
735
736
738 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
739 "Invalid Object Idx!");
740 return Objects[ObjectIdx+NumFixedObjects].isSpillSlot;
741 }
742
744 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
745 "Invalid Object Idx!");
746 return Objects[ObjectIdx+NumFixedObjects].isStatepointSpillSlot;
747 }
748
749
751 return Objects[ObjectIdx+NumFixedObjects].StackID;
752 }
753
754
756 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
757 "Invalid Object Idx!");
758 Objects[ObjectIdx+NumFixedObjects].StackID = ID;
759
760
761 }
762
763
765 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
766 "Invalid Object Idx!");
767 return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL;
768 }
769
770
771
773 assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
774 "Invalid Object Idx!");
775 return Objects[ObjectIdx + NumFixedObjects].Size == 0;
776 }
777
779 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
780 "Invalid Object Idx!");
781 Objects[ObjectIdx+NumFixedObjects].isStatepointSpillSlot = true;
783 }
784
785
786
789
790
791
793
794
796
797 Objects[ObjectIdx+NumFixedObjects].Size = ~0ULL;
798 }
799
800
801
802
804
805
807 return CSInfo;
808 }
809
811
812
813
815 CSInfo = std::move(CSI);
816 }
817
818
820
822
827
830
831
832
833
834
835
836
837
838
840
841
842
844
845
847};
848
849}
850
851#endif
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
an instruction to allocate memory on the stack
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
void setDstReg(Register SpillReg)
unsigned getDstReg() const
bool isSpilledToReg() const
CalleeSavedInfo(unsigned R, int FI=0)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool needsSplitStackProlog() const
Return true if this function requires a split stack prolog, even if it uses no stack space.
void setMaxCallFrameSize(uint64_t S)
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
void clearObjectAllocation(int ObjectIdx)
Remove the underlying Alloca of the specified stack object if it exists.
void setObjectZExt(int ObjectIdx, bool IsZExt)
void setIsImmutableObjectIndex(int ObjectIdx, bool IsImmutable)
Marks the immutability of an object.
SSPLayoutKind getObjectSSPLayout(int ObjectIdx) const
bool isObjectPreAllocated(int ObjectIdx) const
Return true if the object was pre-allocated into the local block.
void computeMaxCallFrameSize(MachineFunction &MF, std::vector< MachineBasicBlock::iterator > *FrameSDOps=nullptr)
Computes the maximum size of a callframe.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
void setAdjustsStack(bool V)
const AllocaInst * getObjectAllocation(int ObjectIdx) const
Return the underlying Alloca of the specified stack object if it exists.
void setRestorePoint(MachineBasicBlock *NewRestore)
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void ensureMaxAlignment(Align Alignment)
Make sure the function is at least Align bytes aligned.
bool isReturnAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
MachineFrameInfo(Align StackAlignment, bool StackRealignable, bool ForcedRealign)
int64_t getLocalFrameObjectCount() const
Return the number of objects allocated into the local object block.
void setHasPatchPoint(bool s=true)
bool hasCalls() const
Return true if the current function has any function calls.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
std::vector< CalleeSavedInfo > & getCalleeSavedInfo()
void setUseLocalStackAllocationBlock(bool v)
setUseLocalStackAllocationBlock - Set whether the local allocation blob should be allocated together ...
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
Align getLocalFrameMaxAlign() const
Return the required alignment of the local object blob.
void setLocalFrameSize(int64_t sz)
Set the size of the local object blob.
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
SSPLayoutKind
Stack Smashing Protection (SSP) rules require that vulnerable stack allocations are located close the...
@ SSPLK_SmallArray
Array or nested array < SSP-buffer-size.
@ SSPLK_LargeArray
Array or nested array >= SSP-buffer-size.
@ SSPLK_AddrOf
The address of this allocation is exposed and triggered protection.
@ SSPLK_None
Did not trigger a stack protector.
void markAsStatepointSpillSlotObjectIndex(int ObjectIdx)
std::pair< int, int64_t > getLocalFrameObjectMap(int i) const
Get the local offset mapping for a for an object.
bool contributesToMaxAlignment(uint8_t StackID)
Should this stack ID be considered in MaxAlignment.
void setFrameAddressIsTaken(bool T)
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
bool shouldRealignStack() const
Return true if stack realignment is forced by function attributes or if the stack alignment.
bool hasPatchPoint() const
This method may be called any time after instruction selection is complete to determine if there is a...
void setHasStackMap(bool s=true)
bool hasOpaqueSPAdjustment() const
Returns true if the function contains opaque dynamic stack adjustments.
void setObjectSExt(int ObjectIdx, bool IsSExt)
void setObjectSSPLayout(int ObjectIdx, SSPLayoutKind Kind)
bool getUseLocalStackAllocationBlock() const
Get whether the local allocation blob should be allocated together or let PEI allocate the locals in ...
MachineBasicBlock * getRestorePoint() const
void setLocalFrameMaxAlign(Align Alignment)
Required alignment of the local object blob, which is the strictest alignment of any object in it.
bool isImmutableObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to an immutable object.
void setCVBytesOfCalleeSavedRegisters(unsigned S)
int getStackProtectorIndex() const
Return the index for the stack protector object.
int64_t getOffsetAdjustment() const
Return the correction for frame offsets.
int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
void setObjectSize(int ObjectIdx, int64_t Size)
Change the size of the specified stack object.
uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
void setStackID(int ObjectIdx, uint8_t ID)
void setHasTailCall(bool V=true)
bool hasTailCall() const
Returns true if the function contains a tail call.
bool hasMustTailInVarArgFunc() const
Returns true if the function is variadic and contains a musttail call.
void setStackProtectorIndex(int I)
void setIsAliasedObjectIndex(int ObjectIdx, bool IsAliased)
Set "maybe pointed to by an LLVM IR value" for an object.
void setCalleeSavedInfoValid(bool v)
bool isStatepointSpillSlotObjectIndex(int ObjectIdx) const
bool isCalleeSavedInfoValid() const
Has the callee saved info been calculated yet?
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
bool isObjectZExt(int ObjectIdx) const
void mapLocalFrameObject(int ObjectIndex, int64_t Offset)
Map a frame index into the local object block.
bool isSpillSlotObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a spill slot.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool isMaxCallFrameSizeComputed() const
void setHasOpaqueSPAdjustment(bool B)
int64_t getLocalFrameSize() const
Get the size of the local object blob.
bool isObjectSExt(int ObjectIdx) const
BitVector getPristineRegs(const MachineFunction &MF) const
Return a set of physical registers that are pristine.
bool hasStackMap() const
This method may be called any time after instruction selection is complete to determine if there is a...
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
void RemoveStackObject(int ObjectIdx)
Remove or mark dead a statically sized stack object.
void setCalleeSavedInfo(std::vector< CalleeSavedInfo > CSI)
Used by prolog/epilog inserter to set the function's callee saved information.
void setHasCopyImplyingStackAdjustment(bool B)
void print(const MachineFunction &MF, raw_ostream &OS) const
Used by the MachineFunction printer to print information about stack objects.
unsigned getNumObjects() const
Return the number of objects.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
unsigned getCVBytesOfCalleeSavedRegisters() const
Returns how many bytes of callee-saved registers the target pushed in the prologue.
bool isVariableSizedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a variable sized object.
int CreateVariableSizedObject(Align Alignment, const AllocaInst *Alloca)
Notify the MachineFrameInfo object that a variable sized object has been created.
void setSavePoint(MachineBasicBlock *NewSave)
uint64_t getUnsafeStackSize() const
void dump(const MachineFunction &MF) const
dump - Print the function to stderr.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
bool hasStackProtectorIndex() const
bool hasCopyImplyingStackAdjustment() const
Returns true if the function contains operations which will lower down to instructions which manipula...
bool hasStackObjects() const
Return true if there are any stack objects in this function.
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
MachineFrameInfo(const MachineFrameInfo &)=delete
bool isStackRealignable() const
uint8_t getStackID(int ObjectIdx) const
unsigned getNumFixedObjects() const
Return the number of fixed objects.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
bool hasFunctionContextIndex() const
void setStackSize(uint64_t Size)
Set the size of the stack.
void setHasVAStart(bool B)
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
int getObjectIndexBegin() const
Return the minimum frame object index.
void setUnsafeStackSize(uint64_t Size)
void setHasMustTailInVarArgFunc(bool B)
void setObjectAlignment(int ObjectIdx, Align Alignment)
setObjectAlignment - Change the alignment of the specified stack object.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
MachineBasicBlock * getSavePoint() const
void setOffsetAdjustment(int64_t Adj)
Set the correction for frame offsets.
int getFunctionContextIndex() const
Return the index for the function context object.
bool isAliasedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to an object that might be pointed to by an LLVM IR v...
void setFunctionContextIndex(int I)
Wrapper class representing virtual and physical registers.
This class implements an extremely fast bulk output stream that can only output to a stream.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
This struct is a compact representation of a valid (non-zero power of two) alignment.