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);
384[[maybe_unused]]
bool isCallStartOpcode(
unsigned Opc) {
386 case AArch64::TLSDESC_CALLSEQ:
387 case AArch64::TLSDESC_AUTH_CALLSEQ:
388 case AArch64::ADJCALLSTACKDOWN:
395FunctionInfo MachineSMEABI::collectNeededZAStates(
SMEAttrs SMEFnAttrs) {
398 "Expected function to have ZA/ZT0 state!");
401 LiveRegs PhysLiveRegsAfterSMEPrologue = LiveRegs::None;
402 std::optional<MachineBasicBlock::iterator> AfterSMEProloguePt;
405 BlockInfo &
Block = Blocks[
MBB.getNumber()];
407 if (
MBB.isEntryBlock()) {
410 ? ZAState::CALLER_DORMANT
412 }
else if (
MBB.isEHPad()) {
414 Block.FixedEntryState = ZAState::LOCAL_SAVED;
420 Block.PhysLiveRegsAtExit = getPhysLiveRegs(LiveUnits);
421 auto FirstTerminatorInsertPt =
MBB.getFirstTerminator();
422 auto FirstNonPhiInsertPt =
MBB.getFirstNonPHI();
426 LiveRegs PhysLiveRegs = getPhysLiveRegs(LiveUnits);
431 if (
MI.getOpcode() == AArch64::SMEStateAllocPseudo) {
432 AfterSMEProloguePt =
MBBI;
433 PhysLiveRegsAfterSMEPrologue = PhysLiveRegs;
436 auto [NeededState, InsertPt] = getZAStateBeforeInst(
438 assert((InsertPt ==
MBBI || isCallStartOpcode(InsertPt->getOpcode())) &&
439 "Unexpected state change insertion point!");
441 if (
MBBI == FirstTerminatorInsertPt)
442 Block.PhysLiveRegsAtExit = PhysLiveRegs;
443 if (
MBBI == FirstNonPhiInsertPt)
444 Block.PhysLiveRegsAtEntry = PhysLiveRegs;
445 if (NeededState != ZAState::ANY)
446 Block.Insts.push_back({NeededState, InsertPt, PhysLiveRegs});
450 std::reverse(
Block.Insts.begin(),
Block.Insts.end());
454 if (!
Block.Insts.empty()) {
455 Block.DesiredIncomingState =
Block.Insts.front().NeededState;
456 Block.DesiredOutgoingState =
Block.Insts.back().NeededState;
460 return FunctionInfo{std::move(Blocks), AfterSMEProloguePt,
461 PhysLiveRegsAfterSMEPrologue};
464void MachineSMEABI::propagateDesiredStates(FunctionInfo &FnInfo,
469 auto GetBlockState = [](BlockInfo &
Block,
bool Incoming) -> ZAState & {
474 for (
auto [BlockID, BlockInfo] :
enumerate(FnInfo.Blocks)) {
475 if (!isLegalEdgeBundleZAState(GetBlockState(BlockInfo, Forwards)))
479 while (!Worklist.
empty()) {
481 BlockInfo &
Block = FnInfo.Blocks[
MBB->getNumber()];
485 int StateCounts[ZAState::NUM_ZA_STATE] = {0};
488 BlockInfo &PredOrSuccBlock = FnInfo.Blocks[PredOrSucc->getNumber()];
489 ZAState ZAState = GetBlockState(PredOrSuccBlock, !Forwards);
490 if (isLegalEdgeBundleZAState(ZAState))
491 StateCounts[ZAState]++;
494 ZAState PropagatedState = ZAState(
max_element(StateCounts) - StateCounts);
495 ZAState &CurrentState = GetBlockState(
Block, Forwards);
496 if (PropagatedState != CurrentState) {
497 CurrentState = PropagatedState;
498 ZAState &OtherState = GetBlockState(
Block, !Forwards);
500 if (OtherState == ZAState::ANY)
501 OtherState = PropagatedState;
506 BlockInfo &SuccOrPredBlock = FnInfo.Blocks[SuccOrPred->getNumber()];
507 if (!isLegalEdgeBundleZAState(GetBlockState(SuccOrPredBlock, Forwards)))
517MachineSMEABI::assignBundleZAStates(
const EdgeBundles &Bundles,
518 const FunctionInfo &FnInfo) {
521 LLVM_DEBUG(
dbgs() <<
"Assigning ZA state for edge bundle: " <<
I <<
'\n');
526 int EdgeStateCounts[ZAState::NUM_ZA_STATE] = {0};
527 for (
unsigned BlockID : Bundles.
getBlocks(
I)) {
530 const BlockInfo &
Block = FnInfo.Blocks[BlockID];
531 bool InEdge = Bundles.
getBundle(BlockID,
false) ==
I;
532 bool OutEdge = Bundles.
getBundle(BlockID,
true) ==
I;
535 InEdge && isLegalEdgeBundleZAState(
Block.DesiredIncomingState);
537 OutEdge && isLegalEdgeBundleZAState(
Block.DesiredOutgoingState);
540 << getZAStateString(
Block.DesiredIncomingState));
541 EdgeStateCounts[
Block.DesiredIncomingState]++;
545 << getZAStateString(
Block.DesiredOutgoingState));
546 EdgeStateCounts[
Block.DesiredOutgoingState]++;
548 if (!LegalInEdge && !LegalOutEgde)
553 ZAState BundleState =
554 ZAState(
max_element(EdgeStateCounts) - EdgeStateCounts);
556 if (BundleState == ZAState::ANY)
557 BundleState = ZAState::ACTIVE;
560 dbgs() <<
"Chosen ZA state: " << getZAStateString(BundleState) <<
'\n'
563 dbgs() <<
" " << getZAStateString(ZAState(State)) <<
": " <<
Count;
567 BundleStates[
I] = BundleState;
573std::pair<MachineBasicBlock::iterator, LiveRegs>
574MachineSMEABI::findStateChangeInsertionPoint(
579 if (Inst !=
Block.Insts.end()) {
580 InsertPt = Inst->InsertPt;
581 PhysLiveRegs = Inst->PhysLiveRegs;
583 InsertPt =
MBB.getFirstTerminator();
584 PhysLiveRegs =
Block.PhysLiveRegsAtExit;
587 if (!(PhysLiveRegs & LiveRegs::NZCV))
588 return {InsertPt, PhysLiveRegs};
592 if (Inst ==
Block.Insts.begin()) {
593 PrevStateChangeI =
MBB.begin();
599 PrevStateChangeI = std::prev(Inst)->InsertPt;
604 setPhysLiveRegs(LiveUnits, PhysLiveRegs);
607 if (
I->getOpcode() ==
TII->getCallFrameDestroyOpcode() ||
I->isCall())
611 return {
I, getPhysLiveRegs(LiveUnits)};
613 return {InsertPt, PhysLiveRegs};
616void MachineSMEABI::insertStateChanges(EmitContext &Context,
617 const FunctionInfo &FnInfo,
621 const BlockInfo &
Block = FnInfo.Blocks[
MBB.getNumber()];
622 ZAState InState = BundleStates[Bundles.
getBundle(
MBB.getNumber(),
625 ZAState CurrentState =
Block.FixedEntryState;
626 if (CurrentState == ZAState::ANY)
627 CurrentState = InState;
629 for (
auto &Inst :
Block.Insts) {
630 if (CurrentState != Inst.NeededState) {
631 auto [InsertPt, PhysLiveRegs] =
632 findStateChangeInsertionPoint(
MBB,
Block, &Inst);
633 emitStateChange(Context,
MBB, InsertPt, CurrentState, Inst.NeededState,
635 CurrentState = Inst.NeededState;
639 if (
MBB.succ_empty())
644 if (CurrentState != OutState) {
645 auto [InsertPt, PhysLiveRegs] =
646 findStateChangeInsertionPoint(
MBB,
Block,
Block.Insts.end());
647 emitStateChange(Context,
MBB, InsertPt, CurrentState, OutState,
656 return MBBI->getDebugLoc();
660void MachineSMEABI::emitSetupLazySave(EmitContext &Context,
666 Register TPIDR2 =
MRI->createVirtualRegister(&AArch64::GPR64spRegClass);
667 Register TPIDR2Ptr =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
676 .
addImm(AArch64SysReg::TPIDR2_EL0)
680PhysRegSave MachineSMEABI::createPhysRegSave(
LiveRegs PhysLiveRegs,
684 PhysRegSave RegSave{PhysLiveRegs};
685 if (PhysLiveRegs & LiveRegs::NZCV) {
686 RegSave.StatusFlags =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
688 .
addImm(AArch64SysReg::NZCV)
693 if (PhysLiveRegs & LiveRegs::W0) {
694 RegSave.X0Save =
MRI->createVirtualRegister(PhysLiveRegs & LiveRegs::W0_HI
695 ? &AArch64::GPR64RegClass
696 : &AArch64::GPR32RegClass);
698 .
addReg(PhysLiveRegs & LiveRegs::W0_HI ? AArch64::X0 : AArch64::W0);
703void MachineSMEABI::restorePhyRegSave(
const PhysRegSave &RegSave,
707 if (RegSave.StatusFlags != AArch64::NoRegister)
709 .
addImm(AArch64SysReg::NZCV)
710 .
addReg(RegSave.StatusFlags)
713 if (RegSave.X0Save != AArch64::NoRegister)
715 RegSave.PhysLiveRegs & LiveRegs::W0_HI ? AArch64::X0 : AArch64::W0)
719void MachineSMEABI::emitRestoreLazySave(EmitContext &Context,
725 Register TPIDR2EL0 =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
729 PhysRegSave RegSave = createPhysRegSave(PhysLiveRegs,
MBB,
MBBI,
DL);
733 .
addImm(AArch64SVCR::SVCRZA)
737 .
addImm(AArch64SysReg::TPIDR2_EL0);
748 .
addRegMask(
TRI->SMEABISupportRoutinesCallPreservedMaskFromX0());
751 .
addImm(AArch64SysReg::TPIDR2_EL0)
754 restorePhyRegSave(RegSave,
MBB,
MBBI,
DL);
764 .
addImm(AArch64SysReg::TPIDR2_EL0)
769 .
addImm(AArch64SVCR::SVCRZA)
773void MachineSMEABI::emitAllocateLazySaveBuffer(
778 Register SP =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
779 Register SVL =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
786 if (Buffer == AArch64::NoRegister) {
794 "Lazy ZA save is not yet supported on Windows");
795 Buffer =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
816 "TPIDR2 block initialization is not supported on big-endian targets");
834 Register TPIDR2EL0 =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
837 .
addImm(AArch64SysReg::TPIDR2_EL0);
846 .
addRegMask(
TRI->SMEABISupportRoutinesCallPreservedMaskFromX0());
851 .
addImm(AArch64SVCR::SVCRZA)
855void MachineSMEABI::emitFullZASaveRestore(EmitContext &Context,
858 LiveRegs PhysLiveRegs,
bool IsSave) {
863 PhysRegSave RegSave = createPhysRegSave(PhysLiveRegs,
MBB,
MBBI,
DL);
867 .
addReg(Context.getAgnosticZABufferPtr(*MF));
873 IsSave ? RTLIB::SMEABI_SME_SAVE : RTLIB::SMEABI_SME_RESTORE))
878 restorePhyRegSave(RegSave,
MBB,
MBBI,
DL);
881void MachineSMEABI::emitAllocateFullZASaveBuffer(
889 Register BufferPtr = Context.getAgnosticZABufferPtr(*MF);
890 Register BufferSize =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
892 PhysRegSave RegSave = createPhysRegSave(PhysLiveRegs,
MBB,
MBBI,
DL);
922 restorePhyRegSave(RegSave,
MBB,
MBBI,
DL);
925void MachineSMEABI::emitStateChange(EmitContext &Context,
928 ZAState From, ZAState To,
931 if (From == ZAState::ANY || To == ZAState::ANY)
936 if (From == ZAState::CALLER_DORMANT && To == ZAState::OFF)
941 if (From == ZAState::CALLER_DORMANT) {
943 "CALLER_DORMANT state requires private ZA interface");
945 "CALLER_DORMANT state only valid in entry block");
946 emitNewZAPrologue(
MBB,
MBB.getFirstNonPHI());
947 if (To == ZAState::ACTIVE)
953 From = ZAState::ACTIVE;
956 if (From == ZAState::ACTIVE && To == ZAState::LOCAL_SAVED)
957 emitZASave(Context,
MBB, InsertPt, PhysLiveRegs);
958 else if (From == ZAState::LOCAL_SAVED && To == ZAState::ACTIVE)
959 emitZARestore(Context,
MBB, InsertPt, PhysLiveRegs);
960 else if (To == ZAState::OFF) {
961 assert(From != ZAState::CALLER_DORMANT &&
962 "CALLER_DORMANT to OFF should have already been handled");
964 "Should not turn ZA off in agnostic ZA function");
965 emitZAOff(
MBB, InsertPt, From == ZAState::LOCAL_SAVED);
967 dbgs() <<
"Error: Transition from " << getZAStateString(From) <<
" to "
968 << getZAStateString(To) <<
'\n';
983 SMEAttrs SMEFnAttrs = AFI->getSMEFnAttrs();
984 if (!SMEFnAttrs.hasZAState() && !SMEFnAttrs.hasZT0State() &&
985 !SMEFnAttrs.hasAgnosticZAInterface())
988 assert(MF.getRegInfo().isSSA() &&
"Expected to be run on SSA form!");
992 TII = Subtarget->getInstrInfo();
993 TRI = Subtarget->getRegisterInfo();
994 MRI = &MF.getRegInfo();
997 getAnalysis<EdgeBundlesWrapperLegacy>().getEdgeBundles();
999 FunctionInfo FnInfo = collectNeededZAStates(SMEFnAttrs);
1033 for (
bool Forwards : {
true,
false})
1034 propagateDesiredStates(FnInfo, Forwards);
1039 EmitContext Context;
1040 insertStateChanges(Context, FnInfo, Bundles, BundleStates);
1042 if (Context.needsSaveBuffer()) {
1043 if (FnInfo.AfterSMEProloguePt) {
1047 emitAllocateZASaveBuffer(Context, *
MBBI->getParent(),
MBBI,
1048 FnInfo.PhysLiveRegsAfterSMEPrologue);
1051 emitAllocateZASaveBuffer(
1053 FnInfo.Blocks[EntryBlock.
getNumber()].PhysLiveRegsAtEntry);
1061 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 DebugLoc that has line number information, 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...