71#define DEBUG_TYPE "aarch64-machine-sme-abi"
109 Register StatusFlags = AArch64::NoRegister;
110 Register X0Save = AArch64::NoRegister;
116 ZAState NeededState{ZAState::ANY};
118 LiveRegs PhysLiveRegs = LiveRegs::None;
125 ZAState FixedEntryState{ZAState::ANY};
126 ZAState DesiredIncomingState{ZAState::ANY};
127 ZAState DesiredOutgoingState{ZAState::ANY};
128 LiveRegs PhysLiveRegsAtEntry = LiveRegs::None;
129 LiveRegs PhysLiveRegsAtExit = LiveRegs::None;
135 std::optional<MachineBasicBlock::iterator> AfterSMEProloguePt;
136 LiveRegs PhysLiveRegsAfterSMEPrologue = LiveRegs::None;
143 EmitContext() =
default;
148 return *TPIDR2BlockFI;
151 return *TPIDR2BlockFI;
156 if (AgnosticZABufferPtr != AArch64::NoRegister)
157 return AgnosticZABufferPtr;
160 AgnosticZABufferPtr =
161 BufferPtr != AArch64::NoRegister
164 return AgnosticZABufferPtr;
169 bool needsSaveBuffer()
const {
170 assert(!(TPIDR2BlockFI && AgnosticZABufferPtr) &&
171 "Cannot have both a TPIDR2 block and agnostic ZA buffer");
172 return TPIDR2BlockFI || AgnosticZABufferPtr != AArch64::NoRegister;
176 std::optional<int> TPIDR2BlockFI;
177 Register AgnosticZABufferPtr = AArch64::NoRegister;
185static bool isLegalEdgeBundleZAState(ZAState State) {
187 case ZAState::ACTIVE:
188 case ZAState::LOCAL_SAVED:
195StringRef getZAStateString(ZAState State) {
196#define MAKE_CASE(V) \
216 return AArch64::MPR128RegClass.contains(SR) ||
217 AArch64::ZTRRegClass.contains(SR);
223static std::pair<ZAState, MachineBasicBlock::iterator>
225 bool ZAOffAtReturn) {
228 if (
MI.getOpcode() == AArch64::InOutZAUsePseudo)
229 return {ZAState::ACTIVE, std::prev(InsertPt)};
231 if (
MI.getOpcode() == AArch64::RequiresZASavePseudo)
232 return {ZAState::LOCAL_SAVED, std::prev(InsertPt)};
235 return {ZAOffAtReturn ? ZAState::OFF : ZAState::ACTIVE, InsertPt};
237 for (
auto &MO :
MI.operands()) {
238 if (isZAorZTRegOp(
TRI, MO))
239 return {ZAState::ACTIVE, InsertPt};
242 return {ZAState::ANY, InsertPt};
246 inline static char ID = 0;
253 StringRef getPassName()
const override {
return "Machine SME ABI pass"; }
265 FunctionInfo collectNeededZAStates(
SMEAttrs SMEFnAttrs);
270 const FunctionInfo &FnInfo);
274 void insertStateChanges(EmitContext &,
const FunctionInfo &FnInfo,
281 void propagateDesiredStates(FunctionInfo &FnInfo,
bool Forwards =
true);
305 LiveRegs PhysLiveRegs,
bool IsSave);
313 std::pair<MachineBasicBlock::iterator, LiveRegs>
323 if (AFI->getSMEFnAttrs().hasAgnosticZAInterface())
324 return emitFullZASaveRestore(Context,
MBB,
MBBI, PhysLiveRegs,
326 return emitSetupLazySave(Context,
MBB,
MBBI);
330 if (AFI->getSMEFnAttrs().hasAgnosticZAInterface())
331 return emitFullZASaveRestore(Context,
MBB,
MBBI, PhysLiveRegs,
333 return emitRestoreLazySave(Context,
MBB,
MBBI, PhysLiveRegs);
338 if (AFI->getSMEFnAttrs().hasAgnosticZAInterface())
339 return emitAllocateFullZASaveBuffer(Context,
MBB,
MBBI, PhysLiveRegs);
340 return emitAllocateLazySaveBuffer(Context,
MBB,
MBBI);
363 LiveRegs PhysLiveRegs = LiveRegs::None;
365 PhysLiveRegs |= LiveRegs::NZCV;
369 PhysLiveRegs |= LiveRegs::W0;
370 if (!LiveUnits.
available(AArch64::W0_HI))
371 PhysLiveRegs |= LiveRegs::W0_HI;
376 if (PhysLiveRegs & LiveRegs::NZCV)
377 LiveUnits.
addReg(AArch64::NZCV);
378 if (PhysLiveRegs & LiveRegs::W0)
379 LiveUnits.
addReg(AArch64::W0);
380 if (PhysLiveRegs & LiveRegs::W0_HI)
381 LiveUnits.
addReg(AArch64::W0_HI);
384FunctionInfo MachineSMEABI::collectNeededZAStates(
SMEAttrs SMEFnAttrs) {
387 "Expected function to have ZA/ZT0 state!");
390 LiveRegs PhysLiveRegsAfterSMEPrologue = LiveRegs::None;
391 std::optional<MachineBasicBlock::iterator> AfterSMEProloguePt;
394 BlockInfo &
Block = Blocks[
MBB.getNumber()];
396 if (
MBB.isEntryBlock()) {
399 ? ZAState::CALLER_DORMANT
401 }
else if (
MBB.isEHPad()) {
403 Block.FixedEntryState = ZAState::LOCAL_SAVED;
409 Block.PhysLiveRegsAtExit = getPhysLiveRegs(LiveUnits);
410 auto FirstTerminatorInsertPt =
MBB.getFirstTerminator();
411 auto FirstNonPhiInsertPt =
MBB.getFirstNonPHI();
415 LiveRegs PhysLiveRegs = getPhysLiveRegs(LiveUnits);
420 if (
MI.getOpcode() == AArch64::SMEStateAllocPseudo) {
421 AfterSMEProloguePt =
MBBI;
422 PhysLiveRegsAfterSMEPrologue = PhysLiveRegs;
425 auto [NeededState, InsertPt] = getZAStateBeforeInst(
428 InsertPt->getOpcode() == AArch64::ADJCALLSTACKDOWN) &&
429 "Unexpected state change insertion point!");
431 if (
MBBI == FirstTerminatorInsertPt)
432 Block.PhysLiveRegsAtExit = PhysLiveRegs;
433 if (
MBBI == FirstNonPhiInsertPt)
434 Block.PhysLiveRegsAtEntry = PhysLiveRegs;
435 if (NeededState != ZAState::ANY)
436 Block.Insts.push_back({NeededState, InsertPt, PhysLiveRegs});
440 std::reverse(
Block.Insts.begin(),
Block.Insts.end());
444 if (!
Block.Insts.empty()) {
445 Block.DesiredIncomingState =
Block.Insts.front().NeededState;
446 Block.DesiredOutgoingState =
Block.Insts.back().NeededState;
450 return FunctionInfo{std::move(Blocks), AfterSMEProloguePt,
451 PhysLiveRegsAfterSMEPrologue};
454void MachineSMEABI::propagateDesiredStates(FunctionInfo &FnInfo,
459 auto GetBlockState = [](BlockInfo &
Block,
bool Incoming) -> ZAState & {
464 for (
auto [BlockID, BlockInfo] :
enumerate(FnInfo.Blocks)) {
465 if (!isLegalEdgeBundleZAState(GetBlockState(BlockInfo, Forwards)))
469 while (!Worklist.
empty()) {
471 BlockInfo &
Block = FnInfo.Blocks[
MBB->getNumber()];
475 int StateCounts[ZAState::NUM_ZA_STATE] = {0};
478 BlockInfo &PredOrSuccBlock = FnInfo.Blocks[PredOrSucc->getNumber()];
479 ZAState ZAState = GetBlockState(PredOrSuccBlock, !Forwards);
480 if (isLegalEdgeBundleZAState(ZAState))
481 StateCounts[ZAState]++;
484 ZAState PropagatedState = ZAState(
max_element(StateCounts) - StateCounts);
485 ZAState &CurrentState = GetBlockState(
Block, Forwards);
486 if (PropagatedState != CurrentState) {
487 CurrentState = PropagatedState;
488 ZAState &OtherState = GetBlockState(
Block, !Forwards);
490 if (OtherState == ZAState::ANY)
491 OtherState = PropagatedState;
496 BlockInfo &SuccOrPredBlock = FnInfo.Blocks[SuccOrPred->getNumber()];
497 if (!isLegalEdgeBundleZAState(GetBlockState(SuccOrPredBlock, Forwards)))
507MachineSMEABI::assignBundleZAStates(
const EdgeBundles &Bundles,
508 const FunctionInfo &FnInfo) {
511 LLVM_DEBUG(
dbgs() <<
"Assigning ZA state for edge bundle: " <<
I <<
'\n');
516 int EdgeStateCounts[ZAState::NUM_ZA_STATE] = {0};
517 for (
unsigned BlockID : Bundles.
getBlocks(
I)) {
520 const BlockInfo &
Block = FnInfo.Blocks[BlockID];
521 bool InEdge = Bundles.
getBundle(BlockID,
false) ==
I;
522 bool OutEdge = Bundles.
getBundle(BlockID,
true) ==
I;
525 InEdge && isLegalEdgeBundleZAState(
Block.DesiredIncomingState);
527 OutEdge && isLegalEdgeBundleZAState(
Block.DesiredOutgoingState);
530 << getZAStateString(
Block.DesiredIncomingState));
531 EdgeStateCounts[
Block.DesiredIncomingState]++;
535 << getZAStateString(
Block.DesiredOutgoingState));
536 EdgeStateCounts[
Block.DesiredOutgoingState]++;
538 if (!LegalInEdge && !LegalOutEgde)
543 ZAState BundleState =
544 ZAState(
max_element(EdgeStateCounts) - EdgeStateCounts);
546 if (BundleState == ZAState::ANY)
547 BundleState = ZAState::ACTIVE;
550 dbgs() <<
"Chosen ZA state: " << getZAStateString(BundleState) <<
'\n'
553 dbgs() <<
" " << getZAStateString(ZAState(State)) <<
": " <<
Count;
557 BundleStates[
I] = BundleState;
563std::pair<MachineBasicBlock::iterator, LiveRegs>
564MachineSMEABI::findStateChangeInsertionPoint(
569 if (Inst !=
Block.Insts.end()) {
570 InsertPt = Inst->InsertPt;
571 PhysLiveRegs = Inst->PhysLiveRegs;
573 InsertPt =
MBB.getFirstTerminator();
574 PhysLiveRegs =
Block.PhysLiveRegsAtExit;
577 if (!(PhysLiveRegs & LiveRegs::NZCV))
578 return {InsertPt, PhysLiveRegs};
582 if (Inst ==
Block.Insts.begin()) {
583 PrevStateChangeI =
MBB.begin();
589 PrevStateChangeI = std::prev(Inst)->InsertPt;
594 setPhysLiveRegs(LiveUnits, PhysLiveRegs);
597 if (
I->getOpcode() ==
TII->getCallFrameDestroyOpcode() ||
I->isCall())
601 return {
I, getPhysLiveRegs(LiveUnits)};
603 return {InsertPt, PhysLiveRegs};
606void MachineSMEABI::insertStateChanges(EmitContext &Context,
607 const FunctionInfo &FnInfo,
611 const BlockInfo &
Block = FnInfo.Blocks[
MBB.getNumber()];
612 ZAState InState = BundleStates[Bundles.
getBundle(
MBB.getNumber(),
615 ZAState CurrentState =
Block.FixedEntryState;
616 if (CurrentState == ZAState::ANY)
617 CurrentState = InState;
619 for (
auto &Inst :
Block.Insts) {
620 if (CurrentState != Inst.NeededState) {
621 auto [InsertPt, PhysLiveRegs] =
622 findStateChangeInsertionPoint(
MBB,
Block, &Inst);
623 emitStateChange(Context,
MBB, InsertPt, CurrentState, Inst.NeededState,
625 CurrentState = Inst.NeededState;
629 if (
MBB.succ_empty())
634 if (CurrentState != OutState) {
635 auto [InsertPt, PhysLiveRegs] =
636 findStateChangeInsertionPoint(
MBB,
Block,
Block.Insts.end());
637 emitStateChange(Context,
MBB, InsertPt, CurrentState, OutState,
646 return MBBI->getDebugLoc();
650void MachineSMEABI::emitSetupLazySave(EmitContext &Context,
656 Register TPIDR2 =
MRI->createVirtualRegister(&AArch64::GPR64spRegClass);
657 Register TPIDR2Ptr =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
666 .
addImm(AArch64SysReg::TPIDR2_EL0)
670PhysRegSave MachineSMEABI::createPhysRegSave(
LiveRegs PhysLiveRegs,
674 PhysRegSave RegSave{PhysLiveRegs};
675 if (PhysLiveRegs & LiveRegs::NZCV) {
676 RegSave.StatusFlags =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
678 .
addImm(AArch64SysReg::NZCV)
683 if (PhysLiveRegs & LiveRegs::W0) {
684 RegSave.X0Save =
MRI->createVirtualRegister(PhysLiveRegs & LiveRegs::W0_HI
685 ? &AArch64::GPR64RegClass
686 : &AArch64::GPR32RegClass);
688 .
addReg(PhysLiveRegs & LiveRegs::W0_HI ? AArch64::X0 : AArch64::W0);
693void MachineSMEABI::restorePhyRegSave(
const PhysRegSave &RegSave,
697 if (RegSave.StatusFlags != AArch64::NoRegister)
699 .
addImm(AArch64SysReg::NZCV)
700 .
addReg(RegSave.StatusFlags)
703 if (RegSave.X0Save != AArch64::NoRegister)
705 RegSave.PhysLiveRegs & LiveRegs::W0_HI ? AArch64::X0 : AArch64::W0)
709void MachineSMEABI::emitRestoreLazySave(EmitContext &Context,
715 Register TPIDR2EL0 =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
719 PhysRegSave RegSave = createPhysRegSave(PhysLiveRegs,
MBB,
MBBI,
DL);
723 .
addImm(AArch64SVCR::SVCRZA)
727 .
addImm(AArch64SysReg::TPIDR2_EL0);
738 .
addRegMask(
TRI->SMEABISupportRoutinesCallPreservedMaskFromX0());
741 .
addImm(AArch64SysReg::TPIDR2_EL0)
744 restorePhyRegSave(RegSave,
MBB,
MBBI,
DL);
754 .
addImm(AArch64SysReg::TPIDR2_EL0)
759 .
addImm(AArch64SVCR::SVCRZA)
763void MachineSMEABI::emitAllocateLazySaveBuffer(
768 Register SP =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
769 Register SVL =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
776 if (Buffer == AArch64::NoRegister) {
784 "Lazy ZA save is not yet supported on Windows");
785 Buffer =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
806 "TPIDR2 block initialization is not supported on big-endian targets");
824 Register TPIDR2EL0 =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
827 .
addImm(AArch64SysReg::TPIDR2_EL0);
836 .
addRegMask(
TRI->SMEABISupportRoutinesCallPreservedMaskFromX0());
841 .
addImm(AArch64SVCR::SVCRZA)
845void MachineSMEABI::emitFullZASaveRestore(EmitContext &Context,
848 LiveRegs PhysLiveRegs,
bool IsSave) {
853 PhysRegSave RegSave = createPhysRegSave(PhysLiveRegs,
MBB,
MBBI,
DL);
857 .
addReg(Context.getAgnosticZABufferPtr(*MF));
863 IsSave ? RTLIB::SMEABI_SME_SAVE : RTLIB::SMEABI_SME_RESTORE))
868 restorePhyRegSave(RegSave,
MBB,
MBBI,
DL);
871void MachineSMEABI::emitAllocateFullZASaveBuffer(
879 Register BufferPtr = Context.getAgnosticZABufferPtr(*MF);
880 Register BufferSize =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
882 PhysRegSave RegSave = createPhysRegSave(PhysLiveRegs,
MBB,
MBBI,
DL);
912 restorePhyRegSave(RegSave,
MBB,
MBBI,
DL);
915void MachineSMEABI::emitStateChange(EmitContext &Context,
918 ZAState From, ZAState To,
921 if (From == ZAState::ANY || To == ZAState::ANY)
926 if (From == ZAState::CALLER_DORMANT && To == ZAState::OFF)
931 if (From == ZAState::CALLER_DORMANT) {
933 "CALLER_DORMANT state requires private ZA interface");
935 "CALLER_DORMANT state only valid in entry block");
936 emitNewZAPrologue(
MBB,
MBB.getFirstNonPHI());
937 if (To == ZAState::ACTIVE)
943 From = ZAState::ACTIVE;
946 if (From == ZAState::ACTIVE && To == ZAState::LOCAL_SAVED)
947 emitZASave(Context,
MBB, InsertPt, PhysLiveRegs);
948 else if (From == ZAState::LOCAL_SAVED && To == ZAState::ACTIVE)
949 emitZARestore(Context,
MBB, InsertPt, PhysLiveRegs);
950 else if (To == ZAState::OFF) {
951 assert(From != ZAState::CALLER_DORMANT &&
952 "CALLER_DORMANT to OFF should have already been handled");
954 "Should not turn ZA off in agnostic ZA function");
955 emitZAOff(
MBB, InsertPt, From == ZAState::LOCAL_SAVED);
957 dbgs() <<
"Error: Transition from " << getZAStateString(From) <<
" to "
958 << getZAStateString(To) <<
'\n';
973 SMEAttrs SMEFnAttrs = AFI->getSMEFnAttrs();
974 if (!SMEFnAttrs.hasZAState() && !SMEFnAttrs.hasZT0State() &&
975 !SMEFnAttrs.hasAgnosticZAInterface())
978 assert(MF.getRegInfo().isSSA() &&
"Expected to be run on SSA form!");
982 TII = Subtarget->getInstrInfo();
983 TRI = Subtarget->getRegisterInfo();
984 MRI = &MF.getRegInfo();
987 getAnalysis<EdgeBundlesWrapperLegacy>().getEdgeBundles();
989 FunctionInfo FnInfo = collectNeededZAStates(SMEFnAttrs);
1023 for (
bool Forwards : {
true,
false})
1024 propagateDesiredStates(FnInfo, Forwards);
1029 EmitContext Context;
1030 insertStateChanges(Context, FnInfo, Bundles, BundleStates);
1032 if (Context.needsSaveBuffer()) {
1033 if (FnInfo.AfterSMEProloguePt) {
1037 emitAllocateZASaveBuffer(Context, *
MBBI->getParent(),
MBBI,
1038 FnInfo.PhysLiveRegsAfterSMEPrologue);
1041 emitAllocateZASaveBuffer(
1043 FnInfo.Blocks[EntryBlock.
getNumber()].PhysLiveRegsAtEntry);
1051 return new MachineSMEABI(OptLevel);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, given a range of instructions.
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the SmallVector class.
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
Register getEarlyAllocSMESaveBuffer() const
SMEAttrs getSMEFnAttrs() const
bool isTargetWindows() const
const AArch64RegisterInfo * getRegisterInfo() const override
const AArch64TargetLowering * getTargetLowering() const override
bool isLittleEndian() const
Represent the analysis usage information of a pass.
AnalysisUsage & addPreservedID(const void *ID)
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
ArrayRef< unsigned > getBlocks(unsigned Bundle) const
getBlocks - Return an array of blocks that are connected to Bundle.
unsigned getBundle(unsigned N, bool Out) const
getBundle - Return the ingoing (Out = false) or outgoing (Out = true) bundle number for basic block N
unsigned getNumBundles() const
getNumBundles - Return the total number of bundles in the CFG.
FunctionPass class - This class is used to implement most global optimizations.
A set of register units used to track register liveness.
bool available(MCRegister Reg) const
Returns true if no part of physical register Reg is live.
void addReg(MCRegister Reg)
Adds register units covered by physical register Reg.
LLVM_ABI void stepBackward(const MachineInstr &MI)
Updates liveness when stepping backwards over the instruction MI.
LLVM_ABI void addLiveOuts(const MachineBasicBlock &MBB)
Adds registers living out of block MBB.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI 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.
LLVM_ABI int CreateVariableSizedObject(Align Alignment, const AllocaInst *Alloca)
Notify the MachineFrameInfo object that a variable sized object has been created.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineBasicBlock * getBlockNumbered(unsigned N) const
getBlockNumbered - MachineBasicBlocks are automatically numbered when they are inserted into the mach...
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition 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 Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
SMEAttrs is a utility class to parse the SME ACLE attributes on functions.
bool hasAgnosticZAInterface() const
bool hasPrivateZAInterface() const
typename SuperClass::const_iterator const_iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, unsigned Imm)
getArithExtendImm - Encode the extend type and shift amount for an arithmetic instruction: imm: 3-bit...
CallingConv Namespace - This namespace contains an enum with a value for the well-known calling conve...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1
Preserve X1-X15, X19-X29, SP, Z0-Z31, P0-P15.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
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.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
auto successors(const MachineBasicBlock *BB)
FunctionPass * createMachineSMEABIPass(CodeGenOptLevel)
LLVM_ABI char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
LLVM_ABI char & MachineLoopInfoID
MachineLoopInfo - This pass is a loop analysis pass.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
CodeGenOptLevel
Code generation optimization level.
@ LLVM_MARK_AS_BITMASK_ENUM
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
auto max_element(R &&Range)
Provide wrappers to std::max_element which take ranges instead of having to pass begin/end explicitly...
auto predecessors(const MachineBasicBlock *BB)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...