Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
35267 views
1
//=- AArch64MachineFunctionInfo.h - AArch64 machine function info -*- C++ -*-=//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file declares AArch64-specific per-machine-function information.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64MACHINEFUNCTIONINFO_H
14
#define LLVM_LIB_TARGET_AARCH64_AARCH64MACHINEFUNCTIONINFO_H
15
16
#include "AArch64Subtarget.h"
17
#include "llvm/ADT/ArrayRef.h"
18
#include "llvm/ADT/SmallPtrSet.h"
19
#include "llvm/ADT/SmallVector.h"
20
#include "llvm/CodeGen/CallingConvLower.h"
21
#include "llvm/CodeGen/MIRYamlMapping.h"
22
#include "llvm/CodeGen/MachineFrameInfo.h"
23
#include "llvm/CodeGen/MachineFunction.h"
24
#include "llvm/IR/Function.h"
25
#include "llvm/MC/MCLinkerOptimizationHint.h"
26
#include "llvm/MC/MCSymbol.h"
27
#include <cassert>
28
#include <optional>
29
30
namespace llvm {
31
32
namespace yaml {
33
struct AArch64FunctionInfo;
34
} // end namespace yaml
35
36
class AArch64Subtarget;
37
class MachineInstr;
38
39
struct TPIDR2Object {
40
int FrameIndex = std::numeric_limits<int>::max();
41
unsigned Uses = 0;
42
};
43
44
/// AArch64FunctionInfo - This class is derived from MachineFunctionInfo and
45
/// contains private AArch64-specific information for each MachineFunction.
46
class AArch64FunctionInfo final : public MachineFunctionInfo {
47
/// Number of bytes of arguments this function has on the stack. If the callee
48
/// is expected to restore the argument stack this should be a multiple of 16,
49
/// all usable during a tail call.
50
///
51
/// The alternative would forbid tail call optimisation in some cases: if we
52
/// want to transfer control from a function with 8-bytes of stack-argument
53
/// space to a function with 16-bytes then misalignment of this value would
54
/// make a stack adjustment necessary, which could not be undone by the
55
/// callee.
56
unsigned BytesInStackArgArea = 0;
57
58
/// The number of bytes to restore to deallocate space for incoming
59
/// arguments. Canonically 0 in the C calling convention, but non-zero when
60
/// callee is expected to pop the args.
61
unsigned ArgumentStackToRestore = 0;
62
63
/// Space just below incoming stack pointer reserved for arguments being
64
/// passed on the stack during a tail call. This will be the difference
65
/// between the largest tail call argument space needed in this function and
66
/// what's already available by reusing space of incoming arguments.
67
unsigned TailCallReservedStack = 0;
68
69
/// HasStackFrame - True if this function has a stack frame. Set by
70
/// determineCalleeSaves().
71
bool HasStackFrame = false;
72
73
/// Amount of stack frame size, not including callee-saved registers.
74
uint64_t LocalStackSize = 0;
75
76
/// The start and end frame indices for the SVE callee saves.
77
int MinSVECSFrameIndex = 0;
78
int MaxSVECSFrameIndex = 0;
79
80
/// Amount of stack frame size used for saving callee-saved registers.
81
unsigned CalleeSavedStackSize = 0;
82
unsigned SVECalleeSavedStackSize = 0;
83
bool HasCalleeSavedStackSize = false;
84
85
/// Number of TLS accesses using the special (combinable)
86
/// _TLS_MODULE_BASE_ symbol.
87
unsigned NumLocalDynamicTLSAccesses = 0;
88
89
/// FrameIndex for start of varargs area for arguments passed on the
90
/// stack.
91
int VarArgsStackIndex = 0;
92
93
/// Offset of start of varargs area for arguments passed on the stack.
94
unsigned VarArgsStackOffset = 0;
95
96
/// FrameIndex for start of varargs area for arguments passed in
97
/// general purpose registers.
98
int VarArgsGPRIndex = 0;
99
100
/// Size of the varargs area for arguments passed in general purpose
101
/// registers.
102
unsigned VarArgsGPRSize = 0;
103
104
/// FrameIndex for start of varargs area for arguments passed in
105
/// floating-point registers.
106
int VarArgsFPRIndex = 0;
107
108
/// Size of the varargs area for arguments passed in floating-point
109
/// registers.
110
unsigned VarArgsFPRSize = 0;
111
112
/// The stack slots used to add space between FPR and GPR accesses when using
113
/// hazard padding. StackHazardCSRSlotIndex is added between GPR and FPR CSRs.
114
/// StackHazardSlotIndex is added between (sorted) stack objects.
115
int StackHazardSlotIndex = std::numeric_limits<int>::max();
116
int StackHazardCSRSlotIndex = std::numeric_limits<int>::max();
117
118
/// True if this function has a subset of CSRs that is handled explicitly via
119
/// copies.
120
bool IsSplitCSR = false;
121
122
/// True when the stack gets realigned dynamically because the size of stack
123
/// frame is unknown at compile time. e.g., in case of VLAs.
124
bool StackRealigned = false;
125
126
/// True when the callee-save stack area has unused gaps that may be used for
127
/// other stack allocations.
128
bool CalleeSaveStackHasFreeSpace = false;
129
130
/// SRetReturnReg - sret lowering includes returning the value of the
131
/// returned struct in a register. This field holds the virtual register into
132
/// which the sret argument is passed.
133
Register SRetReturnReg;
134
135
/// SVE stack size (for predicates and data vectors) are maintained here
136
/// rather than in FrameInfo, as the placement and Stack IDs are target
137
/// specific.
138
uint64_t StackSizeSVE = 0;
139
140
/// HasCalculatedStackSizeSVE indicates whether StackSizeSVE is valid.
141
bool HasCalculatedStackSizeSVE = false;
142
143
/// Has a value when it is known whether or not the function uses a
144
/// redzone, and no value otherwise.
145
/// Initialized during frame lowering, unless the function has the noredzone
146
/// attribute, in which case it is set to false at construction.
147
std::optional<bool> HasRedZone;
148
149
/// ForwardedMustTailRegParms - A list of virtual and physical registers
150
/// that must be forwarded to every musttail call.
151
SmallVector<ForwardedRegister, 1> ForwardedMustTailRegParms;
152
153
/// FrameIndex for the tagged base pointer.
154
std::optional<int> TaggedBasePointerIndex;
155
156
/// Offset from SP-at-entry to the tagged base pointer.
157
/// Tagged base pointer is set up to point to the first (lowest address)
158
/// tagged stack slot.
159
unsigned TaggedBasePointerOffset;
160
161
/// OutliningStyle denotes, if a function was outined, how it was outlined,
162
/// e.g. Tail Call, Thunk, or Function if none apply.
163
std::optional<std::string> OutliningStyle;
164
165
// Offset from SP-after-callee-saved-spills (i.e. SP-at-entry minus
166
// CalleeSavedStackSize) to the address of the frame record.
167
int CalleeSaveBaseToFrameRecordOffset = 0;
168
169
/// SignReturnAddress is true if PAC-RET is enabled for the function with
170
/// defaults being sign non-leaf functions only, with the B key.
171
bool SignReturnAddress = false;
172
173
/// SignReturnAddressAll modifies the default PAC-RET mode to signing leaf
174
/// functions as well.
175
bool SignReturnAddressAll = false;
176
177
/// SignWithBKey modifies the default PAC-RET mode to signing with the B key.
178
bool SignWithBKey = false;
179
180
/// SigningInstrOffset captures the offset of the PAC-RET signing instruction
181
/// within the prologue, so it can be re-used for authentication in the
182
/// epilogue when using PC as a second salt (FEAT_PAuth_LR)
183
MCSymbol *SignInstrLabel = nullptr;
184
185
/// BranchTargetEnforcement enables placing BTI instructions at potential
186
/// indirect branch destinations.
187
bool BranchTargetEnforcement = false;
188
189
/// Indicates that SP signing should be diversified with PC as-per PAuthLR.
190
/// This is set by -mbranch-protection and will emit NOP instructions unless
191
/// the subtarget feature +pauthlr is also used (in which case non-NOP
192
/// instructions are emitted).
193
bool BranchProtectionPAuthLR = false;
194
195
/// Whether this function has an extended frame record [Ctx, FP, LR]. If so,
196
/// bit 60 of the in-memory FP will be 1 to enable other tools to detect the
197
/// extended record.
198
bool HasSwiftAsyncContext = false;
199
200
/// The stack slot where the Swift asynchronous context is stored.
201
int SwiftAsyncContextFrameIdx = std::numeric_limits<int>::max();
202
203
bool IsMTETagged = false;
204
205
/// The function has Scalable Vector or Scalable Predicate register argument
206
/// or return type
207
bool IsSVECC = false;
208
209
/// The frame-index for the TPIDR2 object used for lazy saves.
210
TPIDR2Object TPIDR2;
211
212
/// Whether this function changes streaming mode within the function.
213
bool HasStreamingModeChanges = false;
214
215
/// True if the function need unwind information.
216
mutable std::optional<bool> NeedsDwarfUnwindInfo;
217
218
/// True if the function need asynchronous unwind information.
219
mutable std::optional<bool> NeedsAsyncDwarfUnwindInfo;
220
221
int64_t StackProbeSize = 0;
222
223
// Holds a register containing pstate.sm. This is set
224
// on function entry to record the initial pstate of a function.
225
Register PStateSMReg = MCRegister::NoRegister;
226
227
// Has the PNReg used to build PTRUE instruction.
228
// The PTRUE is used for the LD/ST of ZReg pairs in save and restore.
229
unsigned PredicateRegForFillSpill = 0;
230
231
// The stack slots where VG values are stored to.
232
int64_t VGIdx = std::numeric_limits<int>::max();
233
int64_t StreamingVGIdx = std::numeric_limits<int>::max();
234
235
public:
236
AArch64FunctionInfo(const Function &F, const AArch64Subtarget *STI);
237
238
MachineFunctionInfo *
239
clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
240
const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
241
const override;
242
243
void setPredicateRegForFillSpill(unsigned Reg) {
244
PredicateRegForFillSpill = Reg;
245
}
246
unsigned getPredicateRegForFillSpill() const {
247
return PredicateRegForFillSpill;
248
}
249
250
Register getPStateSMReg() const { return PStateSMReg; };
251
void setPStateSMReg(Register Reg) { PStateSMReg = Reg; };
252
253
int64_t getVGIdx() const { return VGIdx; };
254
void setVGIdx(unsigned Idx) { VGIdx = Idx; };
255
256
int64_t getStreamingVGIdx() const { return StreamingVGIdx; };
257
void setStreamingVGIdx(unsigned FrameIdx) { StreamingVGIdx = FrameIdx; };
258
259
bool isSVECC() const { return IsSVECC; };
260
void setIsSVECC(bool s) { IsSVECC = s; };
261
262
TPIDR2Object &getTPIDR2Obj() { return TPIDR2; }
263
264
void initializeBaseYamlFields(const yaml::AArch64FunctionInfo &YamlMFI);
265
266
unsigned getBytesInStackArgArea() const { return BytesInStackArgArea; }
267
void setBytesInStackArgArea(unsigned bytes) { BytesInStackArgArea = bytes; }
268
269
unsigned getArgumentStackToRestore() const { return ArgumentStackToRestore; }
270
void setArgumentStackToRestore(unsigned bytes) {
271
ArgumentStackToRestore = bytes;
272
}
273
274
unsigned getTailCallReservedStack() const { return TailCallReservedStack; }
275
void setTailCallReservedStack(unsigned bytes) {
276
TailCallReservedStack = bytes;
277
}
278
279
bool hasCalculatedStackSizeSVE() const { return HasCalculatedStackSizeSVE; }
280
281
void setStackSizeSVE(uint64_t S) {
282
HasCalculatedStackSizeSVE = true;
283
StackSizeSVE = S;
284
}
285
286
uint64_t getStackSizeSVE() const { return StackSizeSVE; }
287
288
bool hasStackFrame() const { return HasStackFrame; }
289
void setHasStackFrame(bool s) { HasStackFrame = s; }
290
291
bool isStackRealigned() const { return StackRealigned; }
292
void setStackRealigned(bool s) { StackRealigned = s; }
293
294
bool hasCalleeSaveStackFreeSpace() const {
295
return CalleeSaveStackHasFreeSpace;
296
}
297
void setCalleeSaveStackHasFreeSpace(bool s) {
298
CalleeSaveStackHasFreeSpace = s;
299
}
300
bool isSplitCSR() const { return IsSplitCSR; }
301
void setIsSplitCSR(bool s) { IsSplitCSR = s; }
302
303
void setLocalStackSize(uint64_t Size) { LocalStackSize = Size; }
304
uint64_t getLocalStackSize() const { return LocalStackSize; }
305
306
void setOutliningStyle(std::string Style) { OutliningStyle = Style; }
307
std::optional<std::string> getOutliningStyle() const {
308
return OutliningStyle;
309
}
310
311
void setCalleeSavedStackSize(unsigned Size) {
312
CalleeSavedStackSize = Size;
313
HasCalleeSavedStackSize = true;
314
}
315
316
// When CalleeSavedStackSize has not been set (for example when
317
// some MachineIR pass is run in isolation), then recalculate
318
// the CalleeSavedStackSize directly from the CalleeSavedInfo.
319
// Note: This information can only be recalculated after PEI
320
// has assigned offsets to the callee save objects.
321
unsigned getCalleeSavedStackSize(const MachineFrameInfo &MFI) const {
322
bool ValidateCalleeSavedStackSize = false;
323
324
#ifndef NDEBUG
325
// Make sure the calculated size derived from the CalleeSavedInfo
326
// equals the cached size that was calculated elsewhere (e.g. in
327
// determineCalleeSaves).
328
ValidateCalleeSavedStackSize = HasCalleeSavedStackSize;
329
#endif
330
331
if (!HasCalleeSavedStackSize || ValidateCalleeSavedStackSize) {
332
assert(MFI.isCalleeSavedInfoValid() && "CalleeSavedInfo not calculated");
333
if (MFI.getCalleeSavedInfo().empty())
334
return 0;
335
336
int64_t MinOffset = std::numeric_limits<int64_t>::max();
337
int64_t MaxOffset = std::numeric_limits<int64_t>::min();
338
for (const auto &Info : MFI.getCalleeSavedInfo()) {
339
int FrameIdx = Info.getFrameIdx();
340
if (MFI.getStackID(FrameIdx) != TargetStackID::Default)
341
continue;
342
int64_t Offset = MFI.getObjectOffset(FrameIdx);
343
int64_t ObjSize = MFI.getObjectSize(FrameIdx);
344
MinOffset = std::min<int64_t>(Offset, MinOffset);
345
MaxOffset = std::max<int64_t>(Offset + ObjSize, MaxOffset);
346
}
347
348
if (SwiftAsyncContextFrameIdx != std::numeric_limits<int>::max()) {
349
int64_t Offset = MFI.getObjectOffset(getSwiftAsyncContextFrameIdx());
350
int64_t ObjSize = MFI.getObjectSize(getSwiftAsyncContextFrameIdx());
351
MinOffset = std::min<int64_t>(Offset, MinOffset);
352
MaxOffset = std::max<int64_t>(Offset + ObjSize, MaxOffset);
353
}
354
355
if (StackHazardCSRSlotIndex != std::numeric_limits<int>::max()) {
356
int64_t Offset = MFI.getObjectOffset(StackHazardCSRSlotIndex);
357
int64_t ObjSize = MFI.getObjectSize(StackHazardCSRSlotIndex);
358
MinOffset = std::min<int64_t>(Offset, MinOffset);
359
MaxOffset = std::max<int64_t>(Offset + ObjSize, MaxOffset);
360
}
361
362
unsigned Size = alignTo(MaxOffset - MinOffset, 16);
363
assert((!HasCalleeSavedStackSize || getCalleeSavedStackSize() == Size) &&
364
"Invalid size calculated for callee saves");
365
return Size;
366
}
367
368
return getCalleeSavedStackSize();
369
}
370
371
unsigned getCalleeSavedStackSize() const {
372
assert(HasCalleeSavedStackSize &&
373
"CalleeSavedStackSize has not been calculated");
374
return CalleeSavedStackSize;
375
}
376
377
// Saves the CalleeSavedStackSize for SVE vectors in 'scalable bytes'
378
void setSVECalleeSavedStackSize(unsigned Size) {
379
SVECalleeSavedStackSize = Size;
380
}
381
unsigned getSVECalleeSavedStackSize() const {
382
return SVECalleeSavedStackSize;
383
}
384
385
void setMinMaxSVECSFrameIndex(int Min, int Max) {
386
MinSVECSFrameIndex = Min;
387
MaxSVECSFrameIndex = Max;
388
}
389
390
int getMinSVECSFrameIndex() const { return MinSVECSFrameIndex; }
391
int getMaxSVECSFrameIndex() const { return MaxSVECSFrameIndex; }
392
393
void incNumLocalDynamicTLSAccesses() { ++NumLocalDynamicTLSAccesses; }
394
unsigned getNumLocalDynamicTLSAccesses() const {
395
return NumLocalDynamicTLSAccesses;
396
}
397
398
std::optional<bool> hasRedZone() const { return HasRedZone; }
399
void setHasRedZone(bool s) { HasRedZone = s; }
400
401
int getVarArgsStackIndex() const { return VarArgsStackIndex; }
402
void setVarArgsStackIndex(int Index) { VarArgsStackIndex = Index; }
403
404
unsigned getVarArgsStackOffset() const { return VarArgsStackOffset; }
405
void setVarArgsStackOffset(unsigned Offset) { VarArgsStackOffset = Offset; }
406
407
int getVarArgsGPRIndex() const { return VarArgsGPRIndex; }
408
void setVarArgsGPRIndex(int Index) { VarArgsGPRIndex = Index; }
409
410
unsigned getVarArgsGPRSize() const { return VarArgsGPRSize; }
411
void setVarArgsGPRSize(unsigned Size) { VarArgsGPRSize = Size; }
412
413
int getVarArgsFPRIndex() const { return VarArgsFPRIndex; }
414
void setVarArgsFPRIndex(int Index) { VarArgsFPRIndex = Index; }
415
416
unsigned getVarArgsFPRSize() const { return VarArgsFPRSize; }
417
void setVarArgsFPRSize(unsigned Size) { VarArgsFPRSize = Size; }
418
419
bool hasStackHazardSlotIndex() const {
420
return StackHazardSlotIndex != std::numeric_limits<int>::max();
421
}
422
int getStackHazardSlotIndex() const { return StackHazardSlotIndex; }
423
void setStackHazardSlotIndex(int Index) {
424
assert(StackHazardSlotIndex == std::numeric_limits<int>::max());
425
StackHazardSlotIndex = Index;
426
}
427
int getStackHazardCSRSlotIndex() const { return StackHazardCSRSlotIndex; }
428
void setStackHazardCSRSlotIndex(int Index) {
429
assert(StackHazardCSRSlotIndex == std::numeric_limits<int>::max());
430
StackHazardCSRSlotIndex = Index;
431
}
432
433
unsigned getSRetReturnReg() const { return SRetReturnReg; }
434
void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
435
436
unsigned getJumpTableEntrySize(int Idx) const {
437
return JumpTableEntryInfo[Idx].first;
438
}
439
MCSymbol *getJumpTableEntryPCRelSymbol(int Idx) const {
440
return JumpTableEntryInfo[Idx].second;
441
}
442
void setJumpTableEntryInfo(int Idx, unsigned Size, MCSymbol *PCRelSym) {
443
if ((unsigned)Idx >= JumpTableEntryInfo.size())
444
JumpTableEntryInfo.resize(Idx+1);
445
JumpTableEntryInfo[Idx] = std::make_pair(Size, PCRelSym);
446
}
447
448
using SetOfInstructions = SmallPtrSet<const MachineInstr *, 16>;
449
450
const SetOfInstructions &getLOHRelated() const { return LOHRelated; }
451
452
// Shortcuts for LOH related types.
453
class MILOHDirective {
454
MCLOHType Kind;
455
456
/// Arguments of this directive. Order matters.
457
SmallVector<const MachineInstr *, 3> Args;
458
459
public:
460
using LOHArgs = ArrayRef<const MachineInstr *>;
461
462
MILOHDirective(MCLOHType Kind, LOHArgs Args)
463
: Kind(Kind), Args(Args.begin(), Args.end()) {
464
assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!");
465
}
466
467
MCLOHType getKind() const { return Kind; }
468
LOHArgs getArgs() const { return Args; }
469
};
470
471
using MILOHArgs = MILOHDirective::LOHArgs;
472
using MILOHContainer = SmallVector<MILOHDirective, 32>;
473
474
const MILOHContainer &getLOHContainer() const { return LOHContainerSet; }
475
476
/// Add a LOH directive of this @p Kind and this @p Args.
477
void addLOHDirective(MCLOHType Kind, MILOHArgs Args) {
478
LOHContainerSet.push_back(MILOHDirective(Kind, Args));
479
LOHRelated.insert(Args.begin(), Args.end());
480
}
481
482
SmallVectorImpl<ForwardedRegister> &getForwardedMustTailRegParms() {
483
return ForwardedMustTailRegParms;
484
}
485
486
std::optional<int> getTaggedBasePointerIndex() const {
487
return TaggedBasePointerIndex;
488
}
489
void setTaggedBasePointerIndex(int Index) { TaggedBasePointerIndex = Index; }
490
491
unsigned getTaggedBasePointerOffset() const {
492
return TaggedBasePointerOffset;
493
}
494
void setTaggedBasePointerOffset(unsigned Offset) {
495
TaggedBasePointerOffset = Offset;
496
}
497
498
int getCalleeSaveBaseToFrameRecordOffset() const {
499
return CalleeSaveBaseToFrameRecordOffset;
500
}
501
void setCalleeSaveBaseToFrameRecordOffset(int Offset) {
502
CalleeSaveBaseToFrameRecordOffset = Offset;
503
}
504
505
bool shouldSignReturnAddress(const MachineFunction &MF) const;
506
bool shouldSignReturnAddress(bool SpillsLR) const;
507
508
bool needsShadowCallStackPrologueEpilogue(MachineFunction &MF) const;
509
510
bool shouldSignWithBKey() const { return SignWithBKey; }
511
512
MCSymbol *getSigningInstrLabel() const { return SignInstrLabel; }
513
void setSigningInstrLabel(MCSymbol *Label) { SignInstrLabel = Label; }
514
515
bool isMTETagged() const { return IsMTETagged; }
516
517
bool branchTargetEnforcement() const { return BranchTargetEnforcement; }
518
519
bool branchProtectionPAuthLR() const { return BranchProtectionPAuthLR; }
520
521
void setHasSwiftAsyncContext(bool HasContext) {
522
HasSwiftAsyncContext = HasContext;
523
}
524
bool hasSwiftAsyncContext() const { return HasSwiftAsyncContext; }
525
526
void setSwiftAsyncContextFrameIdx(int FI) {
527
SwiftAsyncContextFrameIdx = FI;
528
}
529
int getSwiftAsyncContextFrameIdx() const { return SwiftAsyncContextFrameIdx; }
530
531
bool needsDwarfUnwindInfo(const MachineFunction &MF) const;
532
bool needsAsyncDwarfUnwindInfo(const MachineFunction &MF) const;
533
534
bool hasStreamingModeChanges() const { return HasStreamingModeChanges; }
535
void setHasStreamingModeChanges(bool HasChanges) {
536
HasStreamingModeChanges = HasChanges;
537
}
538
539
bool hasStackProbing() const { return StackProbeSize != 0; }
540
541
int64_t getStackProbeSize() const { return StackProbeSize; }
542
543
private:
544
// Hold the lists of LOHs.
545
MILOHContainer LOHContainerSet;
546
SetOfInstructions LOHRelated;
547
548
SmallVector<std::pair<unsigned, MCSymbol *>, 2> JumpTableEntryInfo;
549
};
550
551
namespace yaml {
552
struct AArch64FunctionInfo final : public yaml::MachineFunctionInfo {
553
std::optional<bool> HasRedZone;
554
555
AArch64FunctionInfo() = default;
556
AArch64FunctionInfo(const llvm::AArch64FunctionInfo &MFI);
557
558
void mappingImpl(yaml::IO &YamlIO) override;
559
~AArch64FunctionInfo() = default;
560
};
561
562
template <> struct MappingTraits<AArch64FunctionInfo> {
563
static void mapping(IO &YamlIO, AArch64FunctionInfo &MFI) {
564
YamlIO.mapOptional("hasRedZone", MFI.HasRedZone);
565
}
566
};
567
568
} // end namespace yaml
569
570
} // end namespace llvm
571
572
#endif // LLVM_LIB_TARGET_AARCH64_AARCH64MACHINEFUNCTIONINFO_H
573
574