LLVM: lib/Target/M68k/M68kFrameLowering.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
15
20
33
34using namespace llvm;
35
36#define DEBUG_TYPE "m68k-frame"
37
40 TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {
41 SlotSize = STI.getSlotSize();
42 StackPtr = TRI->getStackRegister();
43}
44
48
51 TRI->hasStackRealignment(MF);
52}
53
54
59
63 (hasFP(MF) && !TRI->hasStackRealignment(MF)) ||
64 TRI->hasBasePointer(MF);
65}
66
72
73
74
75
76
81
82
83
84
85 if (TRI->hasBasePointer(MF))
86 FrameReg = TRI->getBaseRegister();
87 else if (TRI->hasStackRealignment(MF))
88 FrameReg = TRI->getStackRegister();
89 else
90 FrameReg = TRI->getFrameRegister(MF);
91
92
93
94
95
99 bool HasFP = hasFP(MF);
100
101
102 if (TRI->hasBasePointer(MF)) {
103 assert(HasFP && "VLAs and dynamic stack realign, but no FP?!");
104 if (FI < 0) {
105
107 }
108
111 }
112 if (TRI->hasStackRealignment(MF)) {
113 if (FI < 0) {
114
116 }
117
120 }
121
122 if (!HasFP)
124
125
127
128
130 if (TailCallReturnAddrDelta < 0)
131 Offset -= TailCallReturnAddrDelta;
132
134}
135
136
137
138
144 return 0;
145
147
149 return 0;
150
151 switch (MBBI->getOpcode()) {
152 default:
153 return 0;
154 case TargetOpcode::PATCHABLE_RET:
155 case M68k::RET: {
157
158 for (unsigned i = 0, e = MBBI->getNumOperands(); i != e; ++i) {
161 continue;
163 if ()
164 continue;
166 Uses.insert(*AI);
167 }
168
169 for (auto CS : AvailableRegs)
170 if (.count(CS))
171 return CS;
172 }
173 }
174
175 return 0;
176}
177
181 return RegMask.PhysReg == Reg;
182 });
183}
184
185uint64_t
186M68kFrameLowering::calculateMaxStackAlign(const MachineFunction &MF) const {
187 const MachineFrameInfo &MFI = MF.getFrameInfo();
188 uint64_t MaxAlign = MFI.getMaxAlign().value();
192 MaxAlign = (StackAlign > MaxAlign) ? StackAlign : MaxAlign;
193 else if (MaxAlign < SlotSize)
194 MaxAlign = SlotSize;
195 }
196 return MaxAlign;
197}
198
202 uint64_t MaxAlign) const {
203 uint64_t Val = -MaxAlign;
204 unsigned AndOp = M68k::AND32di;
205 unsigned MovOp = M68k::MOV32rr;
206
207
208
209
210 unsigned Tmp = M68k::D0;
211
215
220
221
222 MI->getOperand(3).setIsDead();
223
227}
228
233 unsigned Opcode = I->getOpcode();
234 bool IsDestroy = Opcode == TII.getCallFrameDestroyOpcode();
236 uint64_t Amount = I->getOperand(0).getImm();
237 uint64_t InternalAmt = (IsDestroy || Amount) ? I->getOperand(1).getImm() : 0;
239
240 if (!ReserveCallFrame) {
241
242
243
244
245
246
247
249 Amount = alignTo(Amount, StackAlign);
250
252
253
254
255
256
257
258
259
260 bool HasDwarfEHHandlers = !MF.getLandingPads().empty();
261
262 if (HasDwarfEHHandlers && !IsDestroy &&
266 }
267
268 if (Amount == 0)
269 return I;
270
271
272
273 Amount -= InternalAmt;
274
275
276
277
278 if (IsDestroy && InternalAmt && DwarfCFI && (MF))
281
282
283 int64_t StackAdjustment = IsDestroy ? Amount : -Amount;
284 int64_t CfaAdjustment = -StackAdjustment;
285
286 if (StackAdjustment) {
287
288
289
292
293 if (StackAdjustment) {
294 BuildStackAdjustment(MBB, I, DL, StackAdjustment, false);
295 }
296 }
297
299
300
301
302
303
304
305
306
307
308 if (CfaAdjustment) {
309 BuildCFI(
312 }
313 }
314
315 return I;
316 }
317
318 if (IsDestroy && InternalAmt) {
319
320
321
322
323
324
327 while (CI != B && !std::prev(CI)->isCall())
328 --CI;
329 BuildStackAdjustment(MBB, CI, DL, -InternalAmt, false);
330 }
331
332 return I;
333}
334
335
336
339 int64_t NumBytes, bool InEpilogue) const {
340 bool IsSub = NumBytes < 0;
342
343 uint64_t Chunk = (1LL << 31) - 1;
345
347 if (Offset > Chunk) {
348
349
351
353 Reg = M68k::D0;
354 else
356
357 if (Reg) {
358 unsigned Opc = M68k::MOV32ri;
360 Opc = IsSub ? M68k::SUB32ar : M68k::ADD32ar;
364
365 MI->getOperand(3).setIsDead();
367 continue;
368 }
369 }
370
372
374 MBB, MBBI, DL, IsSub ? -ThisVal : ThisVal, InEpilogue);
375 if (IsSub)
377 else
379
381 }
382}
383
386 bool MergeWithPrevious) const {
387 if ((MergeWithPrevious && MBBI == MBB.begin()) ||
388 (!MergeWithPrevious && MBBI == MBB.end()))
389 return 0;
390
393 MergeWithPrevious ? nullptr : std::next(MBBI);
394 unsigned Opc = PI->getOpcode();
396
397 if (!MergeWithPrevious && NI != MBB.end() &&
398 NI->getOpcode() == TargetOpcode::CFI_INSTRUCTION) {
399
401 }
402
403 if (Opc == M68k::ADD32ai && PI->getOperand(0).getReg() == StackPtr) {
404 assert(PI->getOperand(1).getReg() == StackPtr);
405 Offset += PI->getOperand(2).getImm();
406 MBB.erase(PI);
407 if (!MergeWithPrevious)
409 } else if (Opc == M68k::SUB32ai && PI->getOperand(0).getReg() == StackPtr) {
410 assert(PI->getOperand(1).getReg() == StackPtr);
411 Offset -= PI->getOperand(2).getImm();
412 MBB.erase(PI);
413 if (!MergeWithPrevious)
415 }
416
418}
419
423 assert(Offset != 0 && "zero offset stack adjustment requested");
424
425
426
427 bool IsSub = Offset < 0;
429 unsigned Opc = IsSub ? M68k::SUB32ai : M68k::ADD32ai;
430
434
435
436 MI->getOperand(3).setIsDead();
437 return MI;
438}
439
445 unsigned CFIIndex = MF.addFrameInst(CFIInst);
448}
449
450void M68kFrameLowering::emitPrologueCalleeSavedFrameMoves(
456
457
459 if (CSI.empty())
460 return;
461
462
463 for (const auto &I : CSI) {
465 MCRegister Reg = I.getReg();
466
467 unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
470 }
471}
472
476 "MF used frame lowering for wrong subtarget");
477
481 uint64_t MaxAlign = calculateMaxStackAlign(MF);
483 bool HasFP = hasFP(MF);
486 const unsigned MachineFramePtr = FramePtr;
487 unsigned BasePtr = TRI->getBaseRegister();
488
489
490
492
493
495
496 if (TailCallReturnAddrDelta < 0) {
498 TailCallReturnAddrDelta);
499 }
500
501
502
503
504 if (TailCallReturnAddrDelta < 0) {
505 BuildStackAdjustment(MBB, MBBI, DL, TailCallReturnAddrDelta,
506 false)
508 }
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
525 int stackGrowth = -SlotSize;
526
527 if (HasFP) {
528
529 uint64_t FrameSize = StackSize - SlotSize;
530
531
533 FrameSize += SlotSize;
534
536
537
538 if (TRI->hasStackRealignment(MF))
539 NumBytes = alignTo(NumBytes, MaxAlign);
540
541
542
543
545
550
551 if (NeedsDwarfCFI) {
552
553
557
558
559 int DwarfFramePtr = TRI->getDwarfRegNum(MachineFramePtr, true);
560 assert(DwarfFramePtr > 0);
563 2 * stackGrowth));
564 }
565
566 if (NeedsDwarfCFI) {
567
568
569 unsigned DwarfFramePtr = TRI->getDwarfRegNum(MachineFramePtr, true);
572 }
573
574
575
577 EveryMBB.addLiveIn(MachineFramePtr);
578 } else {
580 }
581
582
583 bool PushedRegs = false;
585
587 MBBI->getOpcode() == M68k::PUSH32r) {
588 PushedRegs = true;
590
591 if (!HasFP && NeedsDwarfCFI) {
592
593
598 }
599 }
600
601
602
603 if (TRI->hasStackRealignment(MF)) {
604 assert(HasFP && "There should be a frame pointer if stack is realigned.");
605 BuildStackAlignAND(MBB, MBBI, DL, StackPtr, MaxAlign);
606 }
607
608
609
610
612
613
614 if (!HasFP)
616
617 unsigned SPOrEstablisher = StackPtr;
618
619
620
621
622
623 if (TRI->hasBasePointer(MF)) {
624
626 .addReg(SPOrEstablisher)
629
630
631 unsigned Opm = M68k::MOV32ja;
635 .addReg(SPOrEstablisher)
637 }
638 }
639
640 if (((!HasFP && NumBytes) || PushedRegs) && NeedsDwarfCFI) {
641
642 if (!HasFP && NumBytes) {
643
645 BuildCFI(
648 }
649
650
651 if (PushedRegs)
652 emitPrologueCalleeSavedFrameMoves(MBB, MBBI, DL);
653 }
654
655
656
657
658
659
660
661
662}
663
665 return Opc == M68k::TCRETURNj || Opc == M68k::TCRETURNq;
666}
667
673 std::optional RetOpcode;
675 RetOpcode = MBBI->getOpcode();
680 unsigned MachineFramePtr = FramePtr;
681
682
684 uint64_t MaxAlign = calculateMaxStackAlign(MF);
687
689
690 uint64_t FrameSize = StackSize - SlotSize;
691 NumBytes = FrameSize - CSSize;
692
693
694
695 if (TRI->hasStackRealignment(MF))
696 NumBytes = alignTo(FrameSize, MaxAlign);
697
698 } else {
699 NumBytes = StackSize - CSSize;
700 }
701
702
703 while (MBBI != MBB.begin()) {
705 unsigned Opc = PI->getOpcode();
706
708 Opc != M68k::DBG_VALUE && !PI->isTerminator())
709 break;
710
712 }
714
717
718
719
722
723
724
725
726
728 if (TRI->hasStackRealignment(MF))
729 MBBI = FirstCSPop;
730 uint64_t LEAAmount = -CSSize;
731
732
733
734
735 if (LEAAmount != 0) {
736 unsigned Opc = M68k::LEA32p;
739 LEAAmount);
741 } else {
746 }
747 } else if (hasFP(MF)) {
751 } else if (NumBytes) {
752
755 }
756
758
760 assert(Offset >= 0 && "TCDelta should never be positive");
762 MBBI = MBB.getFirstTerminator();
763
764
767 }
768 }
769}
770
775
777
780
781 if (TailCallReturnAddrDelta < 0) {
782
783
784
785
786
787
788
789
790
792 TailCallReturnAddrDelta - SlotSize, true);
793 }
794
795
796 if (TRI->hasBasePointer(MF)) {
797 SavedRegs.set(TRI->getBaseRegister());
798 }
799}
800
803 std::vector &CSI) const {
806
808
810
811 SpillSlotOffset -= SlotSize;
813
814
815
816
818 for (unsigned i = 0, e = CSI.size(); i < e; ++i) {
819 if (TRI->regsOverlap(CSI[i].getReg(), FPReg)) {
820 CSI.erase(CSI.begin() + i);
821 break;
822 }
823 }
824 }
825
826
827 return false;
828}
829
834 auto DL = MBB.findDebugLoc(MI);
835
836 int FI = 0;
837 unsigned Mask = 0;
838 for (const auto &Info : CSI) {
839 FI = std::max(FI, Info.getFrameIdx());
841 unsigned Shift = MRI.getSpillRegisterOrder(Reg);
842 Mask |= 1 << Shift;
843 }
844
845 auto I =
849
850
853 for (const auto &Info : CSI) {
855 bool IsLiveIn = RI.isLiveIn(Reg);
856 if (!IsLiveIn)
857 MBB.addLiveIn(Reg);
860 }
861
862 return true;
863}
864
869 auto DL = MBB.findDebugLoc(MI);
870
871 int FI = 0;
872 unsigned Mask = 0;
873 for (const auto &Info : CSI) {
874 FI = std::max(FI, Info.getFrameIdx());
876 unsigned Shift = MRI.getSpillRegisterOrder(Reg);
877 Mask |= 1 << Shift;
878 }
879
883
884
885 for (const auto &Info : CSI) {
888 }
889
890 return true;
891}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isRegLiveIn(MachineBasicBlock &MBB, unsigned Reg)
Definition M68kFrameLowering.cpp:178
static bool isTailCallOpcode(unsigned Opc)
Definition M68kFrameLowering.cpp:664
static unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const M68kRegisterInfo *TRI)
Return a caller-saved register that isn't live when it reaches the "return" instruction.
Definition M68kFrameLowering.cpp:139
This file contains the M68k declaration of TargetFrameLowering class.
This file exposes functions that may be used with BuildMI from the MachineInstrBuilder....
This file contains the M68k implementation of the TargetInstrInfo class.
This file declares the M68k specific subclass of MachineFunctionInfo.
This file declares the M68k specific subclass of TargetSubtargetInfo.
Register const TargetRegisterInfo * TRI
static constexpr MCPhysReg FPReg
Remove Loads Into Fake Uses
This file defines the SmallSet class.
static const unsigned FramePtr
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool hasFPImpl(const MachineFunction &MF) const override
Return true if the specified function should have a dedicated frame pointer register.
Definition M68kFrameLowering.cpp:45
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
Definition M68kFrameLowering.cpp:771
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Insert epilog code into the function.
Definition M68kFrameLowering.cpp:668
void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, int64_t NumBytes, bool InEpilogue) const
Emit a series of instructions to increment / decrement the stack pointer by a constant value.
Definition M68kFrameLowering.cpp:337
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
Allows target to override spill slot assignment logic.
Definition M68kFrameLowering.cpp:801
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
Issues instruction(s) to spill all callee saved registers and returns true if it isn't possible / pro...
Definition M68kFrameLowering.cpp:830
bool hasReservedCallFrame(const MachineFunction &MF) const override
Under normal circumstances, when a frame pointer is not required, we reserve argument space for call ...
Definition M68kFrameLowering.cpp:55
M68kFrameLowering(const M68kSubtarget &sti, Align Alignment)
Definition M68kFrameLowering.cpp:38
int mergeSPUpdates(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, bool doMergeWithPrevious) const
Check the instruction before/after the passed instruction.
Definition M68kFrameLowering.cpp:384
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
This method should return the base register and offset used to reference a frame index location.
Definition M68kFrameLowering.cpp:78
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
Definition M68kFrameLowering.cpp:229
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Insert prolog code into the function.
Definition M68kFrameLowering.cpp:473
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
Issues instruction(s) to restore all callee saved registers and returns true if it isn't possible / p...
Definition M68kFrameLowering.cpp:865
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override
If there is a reserved call frame, the call frame pseudos can be simplified.
Definition M68kFrameLowering.cpp:60
bool needsFrameIndexResolution(const MachineFunction &MF) const override
Definition M68kFrameLowering.cpp:67
int getRestoreBasePointerOffset() const
unsigned getCalleeSavedFrameSize() const
bool getRestoreBasePointer() const
void setCalleeSavedFrameSize(unsigned bytes)
bool getHasPushSequences() const
int getTCReturnAddrDelta() const
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
static MCCFIInstruction createGnuArgsSize(MCSymbol *L, int64_t Size, SMLoc Loc={})
A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int64_t Adjustment, SMLoc Loc={})
.cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but Offset is a relative value that is added/subt...
const MCRegisterInfo * getRegisterInfo() const
MCRegAliasIterator enumerates all registers aliasing Reg.
Wrapper class representing physical registers. Should be passed by value.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI 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 ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
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...
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
bool hasStackObjects() const
Return true if there are any stack objects in this function.
LLVM_ABI int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
void setOffsetAdjustment(int64_t Adj)
Set the correction for frame offsets.
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
bool needsFrameMoves() const
True if this function needs frame moves for debug or exceptions.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
bool callsEHReturn() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const std::vector< LandingPadInfo > & getLandingPads() const
Return a reference to the landing pad info for the current function.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool isLiveIn(Register Reg) const
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Wrapper class representing virtual and physical registers.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
StackOffset holds a fixed and a scalable offset in bytes.
int64_t getFixed() const
Returns the fixed component of the stack.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
TargetFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl=Align(1), bool StackReal=true)
LLVM_ABI bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static const MachineInstrBuilder & addMemOperand(const MachineInstrBuilder &MIB, int FI, int Offset=0)
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
static const MachineInstrBuilder & addRegIndirectWithDisp(const MachineInstrBuilder &MIB, Register Reg, bool IsKill, int Offset)
addRegIndirectWithDisp - This function is used to add a memory reference of the form (Offset,...
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ DwarfCFI
DWARF-like instruction based exceptions.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Pair of physical register and lane mask.