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()) {
409 Block.FixedEntryState = ZAState::ENTRY;
410 }
else if (
MBB.isEHPad()) {
412 Block.FixedEntryState = ZAState::LOCAL_SAVED;
418 Block.PhysLiveRegsAtExit = getPhysLiveRegs(LiveUnits);
419 auto FirstTerminatorInsertPt =
MBB.getFirstTerminator();
420 auto FirstNonPhiInsertPt =
MBB.getFirstNonPHI();
424 LiveRegs PhysLiveRegs = getPhysLiveRegs(LiveUnits);
429 if (
MI.getOpcode() == AArch64::SMEStateAllocPseudo) {
430 AfterSMEProloguePt =
MBBI;
431 PhysLiveRegsAfterSMEPrologue = PhysLiveRegs;
434 auto [NeededState, InsertPt] = getZAStateBeforeInst(
436 assert((InsertPt ==
MBBI || isCallStartOpcode(InsertPt->getOpcode())) &&
437 "Unexpected state change insertion point!");
439 if (
MBBI == FirstTerminatorInsertPt)
440 Block.PhysLiveRegsAtExit = PhysLiveRegs;
441 if (
MBBI == FirstNonPhiInsertPt)
442 Block.PhysLiveRegsAtEntry = PhysLiveRegs;
443 if (NeededState != ZAState::ANY)
444 Block.Insts.push_back({NeededState, InsertPt, PhysLiveRegs});
448 std::reverse(
Block.Insts.begin(),
Block.Insts.end());
452 if (!
Block.Insts.empty()) {
453 Block.DesiredIncomingState =
Block.Insts.front().NeededState;
454 Block.DesiredOutgoingState =
Block.Insts.back().NeededState;
458 return FunctionInfo{std::move(Blocks), AfterSMEProloguePt,
459 PhysLiveRegsAfterSMEPrologue};
462void MachineSMEABI::propagateDesiredStates(FunctionInfo &FnInfo,
467 auto GetBlockState = [](BlockInfo &
Block,
bool Incoming) -> ZAState & {
472 for (
auto [BlockID, BlockInfo] :
enumerate(FnInfo.Blocks)) {
473 if (!isLegalEdgeBundleZAState(GetBlockState(BlockInfo, Forwards)))
477 while (!Worklist.
empty()) {
479 BlockInfo &
Block = FnInfo.Blocks[
MBB->getNumber()];
483 int StateCounts[ZAState::NUM_ZA_STATE] = {0};
486 BlockInfo &PredOrSuccBlock = FnInfo.Blocks[PredOrSucc->getNumber()];
487 ZAState ZAState = GetBlockState(PredOrSuccBlock, !Forwards);
488 if (isLegalEdgeBundleZAState(ZAState))
489 StateCounts[ZAState]++;
492 ZAState PropagatedState = ZAState(
max_element(StateCounts) - StateCounts);
493 ZAState &CurrentState = GetBlockState(
Block, Forwards);
494 if (PropagatedState != CurrentState) {
495 CurrentState = PropagatedState;
496 ZAState &OtherState = GetBlockState(
Block, !Forwards);
498 if (OtherState == ZAState::ANY)
499 OtherState = PropagatedState;
504 BlockInfo &SuccOrPredBlock = FnInfo.Blocks[SuccOrPred->getNumber()];
505 if (!isLegalEdgeBundleZAState(GetBlockState(SuccOrPredBlock, Forwards)))
515MachineSMEABI::assignBundleZAStates(
const EdgeBundles &Bundles,
516 const FunctionInfo &FnInfo) {
519 LLVM_DEBUG(
dbgs() <<
"Assigning ZA state for edge bundle: " <<
I <<
'\n');
524 int EdgeStateCounts[ZAState::NUM_ZA_STATE] = {0};
525 for (
unsigned BlockID : Bundles.
getBlocks(
I)) {
528 const BlockInfo &
Block = FnInfo.Blocks[BlockID];
529 bool InEdge = Bundles.
getBundle(BlockID,
false) ==
I;
530 bool OutEdge = Bundles.
getBundle(BlockID,
true) ==
I;
533 InEdge && isLegalEdgeBundleZAState(
Block.DesiredIncomingState);
535 OutEdge && isLegalEdgeBundleZAState(
Block.DesiredOutgoingState);
538 << getZAStateString(
Block.DesiredIncomingState));
539 EdgeStateCounts[
Block.DesiredIncomingState]++;
543 << getZAStateString(
Block.DesiredOutgoingState));
544 EdgeStateCounts[
Block.DesiredOutgoingState]++;
546 if (!LegalInEdge && !LegalOutEgde)
551 ZAState BundleState =
552 ZAState(
max_element(EdgeStateCounts) - EdgeStateCounts);
554 if (BundleState == ZAState::ANY)
555 BundleState = ZAState::ACTIVE;
558 dbgs() <<
"Chosen ZA state: " << getZAStateString(BundleState) <<
'\n'
561 dbgs() <<
" " << getZAStateString(ZAState(State)) <<
": " <<
Count;
565 BundleStates[
I] = BundleState;
571std::pair<MachineBasicBlock::iterator, LiveRegs>
572MachineSMEABI::findStateChangeInsertionPoint(
577 if (Inst !=
Block.Insts.end()) {
578 InsertPt = Inst->InsertPt;
579 PhysLiveRegs = Inst->PhysLiveRegs;
581 InsertPt =
MBB.getFirstTerminator();
582 PhysLiveRegs =
Block.PhysLiveRegsAtExit;
585 if (!(PhysLiveRegs & LiveRegs::NZCV))
586 return {InsertPt, PhysLiveRegs};
590 if (Inst ==
Block.Insts.begin()) {
591 PrevStateChangeI =
MBB.begin();
597 PrevStateChangeI = std::prev(Inst)->InsertPt;
602 setPhysLiveRegs(LiveUnits, PhysLiveRegs);
605 if (
I->getOpcode() ==
TII->getCallFrameDestroyOpcode() ||
I->isCall())
609 return {
I, getPhysLiveRegs(LiveUnits)};
611 return {InsertPt, PhysLiveRegs};
614void MachineSMEABI::insertStateChanges(EmitContext &Context,
615 const FunctionInfo &FnInfo,
619 const BlockInfo &
Block = FnInfo.Blocks[
MBB.getNumber()];
620 ZAState InState = BundleStates[Bundles.
getBundle(
MBB.getNumber(),
623 ZAState CurrentState =
Block.FixedEntryState;
624 if (CurrentState == ZAState::ANY)
625 CurrentState = InState;
627 for (
auto &Inst :
Block.Insts) {
628 if (CurrentState != Inst.NeededState) {
629 auto [InsertPt, PhysLiveRegs] =
630 findStateChangeInsertionPoint(
MBB,
Block, &Inst);
631 emitStateChange(Context,
MBB, InsertPt, CurrentState, Inst.NeededState,
633 CurrentState = Inst.NeededState;
637 if (
MBB.succ_empty())
642 if (CurrentState != OutState) {
643 auto [InsertPt, PhysLiveRegs] =
644 findStateChangeInsertionPoint(
MBB,
Block,
Block.Insts.end());
645 emitStateChange(Context,
MBB, InsertPt, CurrentState, OutState,
654 return MBBI->getDebugLoc();
658void MachineSMEABI::emitSetupLazySave(EmitContext &Context,
664 Register TPIDR2 =
MRI->createVirtualRegister(&AArch64::GPR64spRegClass);
665 Register TPIDR2Ptr =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
674 .
addImm(AArch64SysReg::TPIDR2_EL0)
678PhysRegSave MachineSMEABI::createPhysRegSave(
LiveRegs PhysLiveRegs,
682 PhysRegSave RegSave{PhysLiveRegs};
683 if (PhysLiveRegs & LiveRegs::NZCV) {
684 RegSave.StatusFlags =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
686 .
addImm(AArch64SysReg::NZCV)
691 if (PhysLiveRegs & LiveRegs::W0) {
692 RegSave.X0Save =
MRI->createVirtualRegister(PhysLiveRegs & LiveRegs::W0_HI
693 ? &AArch64::GPR64RegClass
694 : &AArch64::GPR32RegClass);
696 .
addReg(PhysLiveRegs & LiveRegs::W0_HI ? AArch64::X0 : AArch64::W0);
701void MachineSMEABI::restorePhyRegSave(
const PhysRegSave &RegSave,
705 if (RegSave.StatusFlags != AArch64::NoRegister)
707 .
addImm(AArch64SysReg::NZCV)
708 .
addReg(RegSave.StatusFlags)
711 if (RegSave.X0Save != AArch64::NoRegister)
713 RegSave.PhysLiveRegs & LiveRegs::W0_HI ? AArch64::X0 : AArch64::W0)
717void MachineSMEABI::emitRestoreLazySave(EmitContext &Context,
723 Register TPIDR2EL0 =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
727 PhysRegSave RegSave = createPhysRegSave(PhysLiveRegs,
MBB,
MBBI,
DL);
731 .
addImm(AArch64SVCR::SVCRZA)
735 .
addImm(AArch64SysReg::TPIDR2_EL0);
746 .
addRegMask(
TRI->SMEABISupportRoutinesCallPreservedMaskFromX0());
749 .
addImm(AArch64SysReg::TPIDR2_EL0)
752 restorePhyRegSave(RegSave,
MBB,
MBBI,
DL);
762 .
addImm(AArch64SysReg::TPIDR2_EL0)
767 .
addImm(AArch64SVCR::SVCRZA)
771void MachineSMEABI::emitAllocateLazySaveBuffer(
776 Register SP =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
777 Register SVL =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
784 if (Buffer == AArch64::NoRegister) {
792 "Lazy ZA save is not yet supported on Windows");
793 Buffer =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
814 "TPIDR2 block initialization is not supported on big-endian targets");
837 Register TPIDR2EL0 =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
840 .
addImm(AArch64SysReg::TPIDR2_EL0);
849 .
addRegMask(
TRI->SMEABISupportRoutinesCallPreservedMaskFromX0());
856 .
addImm(AArch64SVCR::SVCRZA)
868void MachineSMEABI::emitFullZASaveRestore(EmitContext &Context,
871 LiveRegs PhysLiveRegs,
bool IsSave) {
876 PhysRegSave RegSave = createPhysRegSave(PhysLiveRegs,
MBB,
MBBI,
DL);
880 .
addReg(Context.getAgnosticZABufferPtr(*MF));
886 IsSave ? RTLIB::SMEABI_SME_SAVE : RTLIB::SMEABI_SME_RESTORE))
891 restorePhyRegSave(RegSave,
MBB,
MBBI,
DL);
894void MachineSMEABI::emitAllocateFullZASaveBuffer(
902 Register BufferPtr = Context.getAgnosticZABufferPtr(*MF);
903 Register BufferSize =
MRI->createVirtualRegister(&AArch64::GPR64RegClass);
905 PhysRegSave RegSave = createPhysRegSave(PhysLiveRegs,
MBB,
MBBI,
DL);
935 restorePhyRegSave(RegSave,
MBB,
MBBI,
DL);
938void MachineSMEABI::emitStateChange(EmitContext &Context,
941 ZAState From, ZAState To,
944 if (From == ZAState::ANY || To == ZAState::ANY)
949 if (From == ZAState::ENTRY && To == ZAState::OFF)
956 if (From == ZAState::ENTRY) {
958 "ENTRY state only valid in entry block");
959 emitSMEPrologue(
MBB,
MBB.getFirstNonPHI());
960 if (To == ZAState::ACTIVE)
966 From = ZAState::ACTIVE;
969 if (From == ZAState::ACTIVE && To == ZAState::LOCAL_SAVED)
970 emitZASave(Context,
MBB, InsertPt, PhysLiveRegs);
971 else if (From == ZAState::LOCAL_SAVED && To == ZAState::ACTIVE)
972 emitZARestore(Context,
MBB, InsertPt, PhysLiveRegs);
973 else if (To == ZAState::OFF) {
974 assert(From != ZAState::ENTRY &&
975 "ENTRY to OFF should have already been handled");
977 "Should not turn ZA off in agnostic ZA function");
978 emitZAOff(
MBB, InsertPt, From == ZAState::LOCAL_SAVED);
980 dbgs() <<
"Error: Transition from " << getZAStateString(From) <<
" to "
981 << getZAStateString(To) <<
'\n';
996 SMEAttrs SMEFnAttrs = AFI->getSMEFnAttrs();
997 if (!SMEFnAttrs.hasZAState() && !SMEFnAttrs.hasZT0State() &&
998 !SMEFnAttrs.hasAgnosticZAInterface())
1001 assert(MF.getRegInfo().isSSA() &&
"Expected to be run on SSA form!");
1005 TII = Subtarget->getInstrInfo();
1006 TRI = Subtarget->getRegisterInfo();
1007 MRI = &MF.getRegInfo();
1010 getAnalysis<EdgeBundlesWrapperLegacy>().getEdgeBundles();
1012 FunctionInfo FnInfo = collectNeededZAStates(SMEFnAttrs);
1046 for (
bool Forwards : {
true,
false})
1047 propagateDesiredStates(FnInfo, Forwards);
1052 EmitContext Context;
1053 insertStateChanges(Context, FnInfo, Bundles, BundleStates);
1055 if (Context.needsSaveBuffer()) {
1056 if (FnInfo.AfterSMEProloguePt) {
1060 emitAllocateZASaveBuffer(Context, *
MBBI->getParent(),
MBBI,
1061 FnInfo.PhysLiveRegsAfterSMEPrologue);
1064 emitAllocateZASaveBuffer(
1066 FnInfo.Blocks[EntryBlock.
getNumber()].PhysLiveRegsAtEntry);
1074 return new MachineSMEABI(OptLevel);
unsigned const MachineRegisterInfo * MRI
static constexpr unsigned ZERO_ALL_ZA_MASK
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.
#define ENTRY(ASMNAME, ENUM)
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
bool hasSharedZAInterface() 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...