LLVM 24.0.0git
AArch64InstrInfo.h
Go to the documentation of this file.
1//===- AArch64InstrInfo.h - AArch64 Instruction Information -----*- 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 contains the AArch64 implementation of the TargetInstrInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64INSTRINFO_H
14#define LLVM_LIB_TARGET_AARCH64_AARCH64INSTRINFO_H
15
16#include "AArch64.h"
17#include "AArch64RegisterInfo.h"
21#include <optional>
22
23#define GET_INSTRINFO_HEADER
24#include "AArch64GenInstrInfo.inc"
25
26namespace llvm {
27
28class AArch64Subtarget;
29
34
35#define FALKOR_STRIDED_ACCESS_MD "falkor.strided.access"
36
37// AArch64 MachineCombiner patterns
39 // These are patterns used to reduce the length of dependence chain.
42
43 // These are multiply-add patterns matched by the AArch64 machine combiner.
56 // NEON integers vectors
69
82
91
100
101 // Floating Point
163
174
176
180};
182 const AArch64RegisterInfo RI;
183 const AArch64Subtarget &Subtarget;
184
185public:
186 explicit AArch64InstrInfo(const AArch64Subtarget &STI);
187
188 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
189 /// such, whenever a client has an instance of instruction info, it should
190 /// always be able to get register info as well (through this method).
191 const AArch64RegisterInfo &getRegisterInfo() const { return RI; }
192
194 InlineAsm::ConstraintCode C) const override {
195 return &AArch64::GPR64spRegClass;
196 }
197
198 unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
199
200 bool isAsCheapAsAMove(const MachineInstr &MI) const override;
201
202 bool isCoalescableExtInstr(const MachineInstr &MI, Register &SrcReg,
203 Register &DstReg, unsigned &SubIdx) const override;
204
205 bool
207 const MachineInstr &MIb) const override;
208
210 int &FrameIndex) const override;
212 int &FrameIndex) const override;
213
214 /// Check for post-frame ptr elimination stack locations as well. This uses a
215 /// heuristic so it isn't reliable for correctness.
217 int &FrameIndex) const override;
218 /// Check for post-frame ptr elimination stack locations as well. This uses a
219 /// heuristic so it isn't reliable for correctness.
221 int &FrameIndex) const override;
222
223 /// Does this instruction set its full destination register to zero?
224 static bool isGPRZero(const MachineInstr &MI);
225
226 /// Does this instruction rename a GPR without modifying bits?
227 static bool isGPRCopy(const MachineInstr &MI);
228
229 /// Does this instruction rename an FPR without modifying bits?
230 static bool isFPRCopy(const MachineInstr &MI);
231
232 /// Return true if pairing the given load or store is hinted to be
233 /// unprofitable.
234 static bool isLdStPairSuppressed(const MachineInstr &MI);
235
236 /// Return true if the given load or store is a strided memory access.
237 static bool isStridedAccess(const MachineInstr &MI);
238
239 /// Return true if it has an unscaled load/store offset.
240 static bool hasUnscaledLdStOffset(unsigned Opc);
242 return hasUnscaledLdStOffset(MI.getOpcode());
243 }
244
245 /// Returns the unscaled load/store for the scaled load/store opcode,
246 /// if there is a corresponding unscaled variant available.
247 static std::optional<unsigned> getUnscaledLdSt(unsigned Opc);
248
249 /// Scaling factor for (scaled or unscaled) load or store.
250 static int getMemScale(unsigned Opc);
251 static int getMemScale(const MachineInstr &MI) {
252 return getMemScale(MI.getOpcode());
253 }
254
255 /// Returns whether the instruction is a pre-indexed load.
256 static bool isPreLd(const MachineInstr &MI);
257
258 /// Returns whether the instruction is a pre-indexed store.
259 static bool isPreSt(const MachineInstr &MI);
260
261 /// Returns whether the instruction is a pre-indexed load/store.
262 static bool isPreLdSt(const MachineInstr &MI);
263
264 /// Returns whether the instruction is a zero-extending load.
265 static bool isZExtLoad(const MachineInstr &MI);
266
267 /// Returns whether the instruction is a sign-extending load.
268 static bool isSExtLoad(const MachineInstr &MI);
269
270 /// Returns whether the instruction is a paired load/store.
271 static bool isPairedLdSt(const MachineInstr &MI);
272
273 /// Returns the base register operator of a load/store.
274 static const MachineOperand &getLdStBaseOp(const MachineInstr &MI);
275
276 /// Returns the immediate offset operator of a load/store.
277 static const MachineOperand &getLdStOffsetOp(const MachineInstr &MI);
278
279 /// Returns whether the physical register is FP or NEON.
280 static bool isFpOrNEON(Register Reg);
281
282 /// Returns the shift amount operator of a load/store.
283 static const MachineOperand &getLdStAmountOp(const MachineInstr &MI);
284
285 /// Returns whether the instruction is FP or NEON.
286 static bool isFpOrNEON(const MachineInstr &MI);
287
288 /// Returns whether the instruction is in H form (16 bit operands)
289 static bool isHForm(const MachineInstr &MI);
290
291 /// Returns whether the instruction is in Q form (128 bit operands)
292 static bool isQForm(const MachineInstr &MI);
293
294 /// Returns whether the instruction can be compatible with non-zero BTYPE.
295 static bool hasBTISemantics(const MachineInstr &MI);
296
297 /// Returns the index for the immediate for a given instruction.
298 static unsigned getLoadStoreImmIdx(unsigned Opc);
299
300 /// Return true if pairing the given load or store may be paired with another.
301 static bool isPairableLdStInst(const MachineInstr &MI);
302
303 /// Returns true if MI is one of the TCRETURN* instructions.
304 static bool isTailCallReturnInst(const MachineInstr &MI);
305
306 /// Return the opcode that set flags when possible. The caller is
307 /// responsible for ensuring the opc has a flag setting equivalent.
308 static unsigned convertToFlagSettingOpc(unsigned Opc);
309
310 /// Return true if this is a load/store that can be potentially paired/merged.
311 bool isCandidateToMergeOrPair(const MachineInstr &MI) const;
312
313 /// Hint that pairing the given load or store is unprofitable.
314 static void suppressLdStPair(MachineInstr &MI);
315
316 std::optional<ExtAddrMode>
318 const TargetRegisterInfo *TRI) const override;
319
321 const MachineInstr &AddrI,
322 ExtAddrMode &AM) const override;
323
325 const ExtAddrMode &AM) const override;
326
329 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
330 const TargetRegisterInfo *TRI) const override;
331
332 /// If \p OffsetIsScalable is set to 'true', the offset is scaled by `vscale`.
333 /// This is true for some SVE instructions like ldr/str that have a
334 /// 'reg + imm' addressing mode where the immediate is an index to the
335 /// scalable vector located at 'reg + imm * vscale x #bytes'.
337 const MachineOperand *&BaseOp,
338 int64_t &Offset, bool &OffsetIsScalable,
339 TypeSize &Width,
340 const TargetRegisterInfo *TRI) const;
341
342 /// Return the immediate offset of the base register in a load/store \p LdSt.
344
345 /// Returns true if opcode \p Opc is a memory operation. If it is, set
346 /// \p Scale, \p Width, \p MinOffset, and \p MaxOffset accordingly.
347 ///
348 /// For unscaled instructions, \p Scale is set to 1. All values are in bytes.
349 /// MinOffset/MaxOffset are the un-scaled limits of the immediate in the
350 /// instruction, the actual offset limit is [MinOffset*Scale,
351 /// MaxOffset*Scale].
352 static bool getMemOpInfo(unsigned Opcode, TypeSize &Scale, TypeSize &Width,
353 int64_t &MinOffset, int64_t &MaxOffset);
354
356 int64_t Offset1, bool OffsetIsScalable1,
358 int64_t Offset2, bool OffsetIsScalable2,
359 unsigned ClusterSize,
360 unsigned NumBytes) const override;
361
363 const DebugLoc &DL, MCRegister DestReg,
364 MCRegister SrcReg, bool KillSrc,
365 llvm::ArrayRef<unsigned> Indices) const;
367 const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
368 bool KillSrc, unsigned Opcode, unsigned ZeroReg,
369 llvm::ArrayRef<unsigned> Indices) const;
371 const DebugLoc &DL, Register DestReg, Register SrcReg,
372 bool KillSrc, bool RenamableDest = false,
373 bool RenamableSrc = false) const;
375 const DebugLoc &DL, Register DestReg, Register SrcReg,
376 bool KillSrc, bool RenamableDest = false,
377 bool RenamableSrc = false) const override;
378
381 bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg,
382 MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;
383
386 Register DestReg, int FrameIndex, const TargetRegisterClass *RC,
387 Register VReg, unsigned SubReg = 0,
388 MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;
389
390 // This tells target independent code that it is okay to pass instructions
391 // with subreg operands to foldMemoryOperandImpl.
392 bool isSubregFoldable() const override { return true; }
393
396 ArrayRef<unsigned> Ops, int FrameIndex,
397 MachineInstr *&CopyMI,
398 LiveIntervals *LIS = nullptr,
399 VirtRegMap *VRM = nullptr) const override;
400
401 /// \returns true if a branch from an instruction with opcode \p BranchOpc
402 /// bytes is capable of jumping to a position \p BrOffset bytes away.
403 bool isBranchOffsetInRange(unsigned BranchOpc,
404 int64_t BrOffset) const override;
405
406 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
407
409 MachineBasicBlock &NewDestBB,
410 MachineBasicBlock &RestoreBB, const DebugLoc &DL,
411 int64_t BrOffset, RegScavenger *RS) const override;
412
414 MachineBasicBlock *&FBB,
416 bool AllowModify = false) const override;
418 MachineBranchPredicate &MBP,
419 bool AllowModify) const override;
421 int *BytesRemoved = nullptr) const override;
424 const DebugLoc &DL,
425 int *BytesAdded = nullptr) const override;
426
427 /// Inserts the compare instruction needed to un-fuse a fused conditional
428 /// branch instruction and returns the condition code of the original fused
429 /// branch.
432 const DebugLoc &DL,
434
435 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
436 analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override;
437
438 bool
441 Register, Register, Register, int &, int &,
442 int &) const override;
444 const DebugLoc &DL, Register DstReg,
446 Register FalseReg) const override;
447
449 MachineBasicBlock::iterator MI) const override;
450
451 MCInst getNop() const override;
452
454 const MachineBasicBlock *MBB,
455 const MachineFunction &MF) const override;
456
457 /// analyzeCompare - For a comparison instruction, return the source registers
458 /// in SrcReg and SrcReg2, and the value it compares against in CmpValue.
459 /// Return true if the comparison instruction can be analyzed.
460 bool analyzeCompare(const MachineInstr &MI, Register &SrcReg,
461 Register &SrcReg2, int64_t &CmpMask,
462 int64_t &CmpValue) const override;
463 /// optimizeCompareInstr - Convert the instruction supplying the argument to
464 /// the comparison into one that sets the zero bit in the flags register.
465 bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
466 Register SrcReg2, int64_t CmpMask, int64_t CmpValue,
467 const MachineRegisterInfo *MRI) const override;
468 bool optimizeCondBranch(MachineInstr &MI) const override;
469
470 CombinerObjective getCombinerObjective(unsigned Pattern) const override;
471 /// Return true when a code sequence can improve throughput. It
472 /// should be called only for instructions in loops.
473 /// \param Pattern - combiner pattern
474 bool isThroughputPattern(unsigned Pattern) const override;
475 /// Return true when there is potentially a faster code sequence
476 /// for an instruction chain ending in ``Root``. All potential patterns are
477 /// listed in the ``Patterns`` array.
478 bool getMachineCombinerPatterns(MachineInstr &Root,
480 bool DoRegPressureReduce) const override;
481 /// Return true when Inst is associative and commutative so that it can be
482 /// reassociated. If Invert is true, then the inverse of Inst operation must
483 /// be checked.
484 bool isAssociativeAndCommutative(const MachineInstr &Inst,
485 bool Invert) const override;
486
487 /// Returns true if \P Opcode is an instruction which performs accumulation
488 /// into a destination register.
489 bool isAccumulationOpcode(unsigned Opcode) const override;
490
491 /// Returns an opcode which defines the accumulator used by \P Opcode.
492 unsigned getAccumulationStartOpcode(unsigned Opcode) const override;
493
494 unsigned
495 getReduceOpcodeForAccumulator(unsigned int AccumulatorOpCode) const override;
496
497 /// When getMachineCombinerPatterns() finds patterns, this function
498 /// generates the instructions that could replace the original code
499 /// sequence
500 void genAlternativeCodeSequence(
501 MachineInstr &Root, unsigned Pattern,
504 DenseMap<Register, unsigned> &InstrIdxForVirtReg) const override;
505 /// AArch64 supports MachineCombiner.
506 bool useMachineCombiner() const override;
507
508 bool expandPostRAPseudo(MachineInstr &MI) const override;
509
510 std::pair<unsigned, unsigned>
511 decomposeMachineOperandsTargetFlags(unsigned TF) const override;
513 getSerializableDirectMachineOperandTargetFlags() const override;
515 getSerializableBitmaskMachineOperandTargetFlags() const override;
517 getSerializableMachineMemOperandTargetFlags() const override;
518
519 bool isFunctionSafeToOutlineFrom(MachineFunction &MF,
520 bool OutlineFromLinkOnceODRs) const override;
521 std::optional<std::unique_ptr<outliner::OutlinedFunction>>
522 getOutliningCandidateInfo(
523 const MachineModuleInfo &MMI,
524 std::vector<outliner::Candidate> &RepeatedSequenceLocs,
525 unsigned MinRepeats) const override;
526 void mergeOutliningCandidateAttributes(
527 Function &F, std::vector<outliner::Candidate> &Candidates) const override;
528 outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI,
530 unsigned Flags) const override;
532 std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>>
533 getOutlinableRanges(MachineBasicBlock &MBB, unsigned &Flags) const override;
534 void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF,
535 const outliner::OutlinedFunction &OF) const override;
537 insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
539 outliner::Candidate &C) const override;
540 bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override;
541
542 void buildClearRegister(Register Reg, MachineBasicBlock &MBB,
544 bool AllowSideEffects = true) const override;
545
546 /// Returns the vector element size (B, H, S or D) of an SVE opcode.
547 uint64_t getElementSizeForOpcode(unsigned Opc) const;
548 /// Returns true if the opcode is for an SVE instruction that sets the
549 /// condition codes as if it's results had been fed to a PTEST instruction
550 /// along with the same general predicate.
551 bool isPTestLikeOpcode(unsigned Opc) const;
552 /// Returns true if the opcode is for an SVE WHILE## instruction.
553 bool isWhileOpcode(unsigned Opc) const;
554 /// Returns true if the instruction has a shift by immediate that can be
555 /// executed in one cycle less.
556 static bool isFalkorShiftExtFast(const MachineInstr &MI);
557 /// Return true if the instructions is a SEH instruction used for unwinding
558 /// on Windows.
559 static bool isSEHInstruction(const MachineInstr &MI);
560
561 std::optional<RegImmPair> isAddImmediate(const MachineInstr &MI,
562 Register Reg) const override;
563
564 bool isFunctionSafeToSplit(const MachineFunction &MF) const override;
565
566 bool isMBBSafeToSplitToCold(const MachineBasicBlock &MBB) const override;
567
568 std::optional<ParamLoadedValue>
569 describeLoadedValue(const MachineInstr &MI, Register Reg) const override;
570
571 unsigned int getTailDuplicateSize(CodeGenOptLevel OptLevel) const override;
572
573 bool isExtendLikelyToBeFolded(MachineInstr &ExtMI,
574 MachineRegisterInfo &MRI) const override;
575
576 static void decomposeStackOffsetForFrameOffsets(const StackOffset &Offset,
577 int64_t &NumBytes,
578 int64_t &NumPredicateVectors,
579 int64_t &NumDataVectors);
580 static void decomposeStackOffsetForDwarfOffsets(const StackOffset &Offset,
581 int64_t &ByteSized,
582 int64_t &VGSized);
583
584 // Return true if address of the form BaseReg + Scale * ScaledReg + Offset can
585 // be used for a load/store of NumBytes. BaseReg is always present and
586 // implicit.
587 bool isLegalAddressingMode(unsigned NumBytes, int64_t Offset,
588 unsigned Scale) const;
589
590 // Decrement the SP, issuing probes along the way. `TargetReg` is the new top
591 // of the stack. `FrameSetup` is passed as true, if the allocation is a part
592 // of constructing the activation frame of a function.
594 Register TargetReg,
595 bool FrameSetup) const;
596
597 static int
598 findCondCodeUseOperandIdxForBranchOrSelect(const MachineInstr &Instr);
599
600 /// Insert a `PAUTH_EPILOGUE` pseudo before the first terminator in \p MBB to
601 /// authenticate the return address. Adds an implicit def of X16 when the
602 /// branch protection uses PAuthLR but the subtarget lacks PAuthLR
603 /// instructions. If the epilogue has callee-popped argument stack to restore,
604 /// it additionally implicit defines X15 and X17 to cover clobbered registers
605 /// for the required sequence on subtargets both with and without PAuthLR
606 /// instructions.
608
609#define GET_INSTRINFO_HELPER_DECLS
610#include "AArch64GenInstrInfo.inc"
611
612protected:
613 /// If the specific machine instruction is an instruction that moves/copies
614 /// value from one register to another register return destination and source
615 /// registers as machine operands.
616 std::optional<DestSourcePair>
617 isCopyInstrImpl(const MachineInstr &MI) const override;
618 std::optional<DestSourcePair>
619 isCopyLikeInstrImpl(const MachineInstr &MI) const override;
620
621private:
622 /// Sets the offsets on outlined instructions in \p MBB which use SP
623 /// so that they will be valid post-outlining.
624 ///
625 /// \param MBB A \p MachineBasicBlock in an outlined function.
626 void fixupPostOutline(MachineBasicBlock &MBB) const;
627
628 void instantiateCondBranch(MachineBasicBlock &MBB, const DebugLoc &DL,
629 MachineBasicBlock *TBB,
631 bool substituteCmpToZero(MachineInstr &CmpInstr, unsigned SrcReg,
632 const MachineRegisterInfo &MRI) const;
633 bool removeCmpToZeroOrOne(MachineInstr &CmpInstr, unsigned SrcReg,
634 int CmpValue, const MachineRegisterInfo &MRI) const;
635
636 /// Returns an unused general-purpose register which can be used for
637 /// constructing an outlined call if one exists. Returns 0 otherwise.
638 Register findRegisterToSaveLRTo(outliner::Candidate &C) const;
639
640 /// Remove a ptest of a predicate-generating operation that already sets, or
641 /// can be made to set, the condition codes in an identical manner
642 bool optimizePTestInstr(MachineInstr *PTest, unsigned MaskReg,
643 unsigned PredReg,
644 const MachineRegisterInfo *MRI) const;
645 std::optional<unsigned>
646 canRemovePTestInstr(MachineInstr *PTest, MachineInstr *Mask,
647 MachineInstr *Pred, const MachineRegisterInfo *MRI) const;
648
649 /// verifyInstruction - Perform target specific instruction verification.
650 bool verifyInstruction(const MachineInstr &MI,
651 StringRef &ErrInfo) const override;
652};
653
654struct UsedNZCV {
655 bool N = false;
656 bool Z = false;
657 bool C = false;
658 bool V = false;
659
660 UsedNZCV() = default;
661
662 UsedNZCV &operator|=(const UsedNZCV &UsedFlags) {
663 this->N |= UsedFlags.N;
664 this->Z |= UsedFlags.Z;
665 this->C |= UsedFlags.C;
666 this->V |= UsedFlags.V;
667 return *this;
668 }
669};
670
671/// \returns Conditions flags used after \p CmpInstr in its MachineBB if NZCV
672/// flags are not alive in successors of the same \p CmpInstr and \p MI parent.
673/// \returns std::nullopt otherwise.
674///
675/// Collect instructions using that flags in \p CCUseInstrs if provided.
676std::optional<UsedNZCV>
677examineCFlagsUse(MachineInstr &MI, MachineInstr &CmpInstr,
678 const TargetRegisterInfo &TRI,
679 SmallVectorImpl<MachineInstr *> *CCUseInstrs = nullptr);
680
681/// Return true if there is an instruction /after/ \p DefMI and before \p UseMI
682/// which either reads or clobbers NZCV.
683bool isNZCVTouchedInInstructionRange(const MachineInstr &DefMI,
684 const MachineInstr &UseMI,
685 const TargetRegisterInfo *TRI);
686
687MCCFIInstruction createDefCFA(const TargetRegisterInfo &TRI, unsigned FrameReg,
688 unsigned Reg, const StackOffset &Offset,
689 bool LastAdjustmentWasScalable = true);
690MCCFIInstruction
691createCFAOffset(const TargetRegisterInfo &MRI, unsigned Reg,
692 const StackOffset &OffsetFromDefCFA,
693 std::optional<int64_t> IncomingVGOffsetFromDefCFA);
694
695/// emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg
696/// plus Offset. This is intended to be used from within the prolog/epilog
697/// insertion (PEI) pass, where a virtual scratch register may be allocated
698/// if necessary, to be replaced by the scavenger at the end of PEI.
699void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
700 const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
701 StackOffset Offset, const TargetInstrInfo *TII,
703 bool SetNZCV = false, bool NeedsWinCFI = false,
704 bool *HasWinCFI = nullptr, bool EmitCFAOffset = false,
705 StackOffset InitialOffset = {},
706 unsigned FrameReg = AArch64::SP);
707
708/// rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the
709/// FP. Return false if the offset could not be handled directly in MI, and
710/// return the left-over portion by reference.
711bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
712 unsigned FrameReg, StackOffset &Offset,
713 const AArch64InstrInfo *TII);
714
715/// Use to report the frame offset status in isAArch64FrameOffsetLegal.
717 AArch64FrameOffsetCannotUpdate = 0x0, ///< Offset cannot apply.
718 AArch64FrameOffsetIsLegal = 0x1, ///< Offset is legal.
719 AArch64FrameOffsetCanUpdate = 0x2 ///< Offset can apply, at least partly.
720};
721
722/// Check if the @p Offset is a valid frame offset for @p MI.
723/// The returned value reports the validity of the frame offset for @p MI.
724/// It uses the values defined by AArch64FrameOffsetStatus for that.
725/// If result == AArch64FrameOffsetCannotUpdate, @p MI cannot be updated to
726/// use an offset.eq
727/// If result & AArch64FrameOffsetIsLegal, @p Offset can completely be
728/// rewritten in @p MI.
729/// If result & AArch64FrameOffsetCanUpdate, @p Offset contains the
730/// amount that is off the limit of the legal offset.
731/// If set, @p OutUseUnscaledOp will contain the whether @p MI should be
732/// turned into an unscaled operator, which opcode is in @p OutUnscaledOp.
733/// If set, @p EmittableOffset contains the amount that can be set in @p MI
734/// (possibly with @p OutUnscaledOp if OutUseUnscaledOp is true) and that
735/// is a legal offset.
736int isAArch64FrameOffsetLegal(const MachineInstr &MI, StackOffset &Offset,
737 bool *OutUseUnscaledOp = nullptr,
738 unsigned *OutUnscaledOp = nullptr,
739 int64_t *EmittableOffset = nullptr);
740
741bool optimizeTerminators(MachineBasicBlock *MBB, const TargetInstrInfo &TII);
742
743static inline bool isUncondBranchOpcode(int Opc) { return Opc == AArch64::B; }
744
745static inline bool isCondBranchOpcode(int Opc) {
746 switch (Opc) {
747 case AArch64::Bcc:
748 case AArch64::CBZW:
749 case AArch64::CBZX:
750 case AArch64::CBNZW:
751 case AArch64::CBNZX:
752 case AArch64::TBZW:
753 case AArch64::TBZX:
754 case AArch64::TBNZW:
755 case AArch64::TBNZX:
756 case AArch64::CBWPri:
757 case AArch64::CBXPri:
758 case AArch64::CBBAssertExt:
759 case AArch64::CBHAssertExt:
760 case AArch64::CBWPrr:
761 case AArch64::CBXPrr:
762 return true;
763 default:
764 return false;
765 }
766}
767
768static inline bool isIndirectBranchOpcode(int Opc) {
769 switch (Opc) {
770 case AArch64::BR:
771 case AArch64::BRAA:
772 case AArch64::BRAB:
773 case AArch64::BRAAZ:
774 case AArch64::BRABZ:
775 return true;
776 }
777 return false;
778}
779
780static inline bool isIndirectCallOpcode(unsigned Opc) {
781 switch (Opc) {
782 case AArch64::BLR:
783 case AArch64::BLRAA:
784 case AArch64::BLRAB:
785 case AArch64::BLRAAZ:
786 case AArch64::BLRABZ:
787 return true;
788 default:
789 return false;
790 }
791}
792
793static inline bool isPTrueOpcode(unsigned Opc) {
794 switch (Opc) {
795 case AArch64::PTRUE_B:
796 case AArch64::PTRUE_H:
797 case AArch64::PTRUE_S:
798 case AArch64::PTRUE_D:
799 return true;
800 default:
801 return false;
802 }
803}
804
805/// Return opcode to be used for indirect calls.
806unsigned getBLRCallOpcode(const MachineFunction &MF);
807
808/// Return XPAC opcode to be used for a ptrauth strip using the given key.
809static inline unsigned getXPACOpcodeForKey(AArch64PACKey::ID K) {
810 using namespace AArch64PACKey;
811 switch (K) {
812 case IA: case IB: return AArch64::XPACI;
813 case DA: case DB: return AArch64::XPACD;
814 }
815 llvm_unreachable("Unhandled AArch64PACKey::ID enum");
816}
817
818/// Return AUT opcode to be used for a ptrauth auth using the given key, or its
819/// AUT*Z variant that doesn't take a discriminator operand, using zero instead.
820static inline unsigned getAUTOpcodeForKey(AArch64PACKey::ID K, bool Zero) {
821 using namespace AArch64PACKey;
822 switch (K) {
823 case IA: return Zero ? AArch64::AUTIZA : AArch64::AUTIA;
824 case IB: return Zero ? AArch64::AUTIZB : AArch64::AUTIB;
825 case DA: return Zero ? AArch64::AUTDZA : AArch64::AUTDA;
826 case DB: return Zero ? AArch64::AUTDZB : AArch64::AUTDB;
827 }
828 llvm_unreachable("Unhandled AArch64PACKey::ID enum");
829}
830
831/// Return PAC opcode to be used for a ptrauth sign using the given key, or its
832/// PAC*Z variant that doesn't take a discriminator operand, using zero instead.
833static inline unsigned getPACOpcodeForKey(AArch64PACKey::ID K, bool Zero) {
834 using namespace AArch64PACKey;
835 switch (K) {
836 case IA: return Zero ? AArch64::PACIZA : AArch64::PACIA;
837 case IB: return Zero ? AArch64::PACIZB : AArch64::PACIB;
838 case DA: return Zero ? AArch64::PACDZA : AArch64::PACDA;
839 case DB: return Zero ? AArch64::PACDZB : AArch64::PACDB;
840 }
841 llvm_unreachable("Unhandled AArch64PACKey::ID enum");
842}
843
844/// Return B(L)RA opcode to be used for an authenticated branch or call using
845/// the given key, or its B(L)RA*Z variant that doesn't take a discriminator
846/// operand, using zero instead.
847static inline unsigned getBranchOpcodeForKey(bool IsCall, AArch64PACKey::ID K,
848 bool Zero) {
849 using namespace AArch64PACKey;
850 static const unsigned BranchOpcode[2][2] = {
851 {AArch64::BRAA, AArch64::BRAAZ},
852 {AArch64::BRAB, AArch64::BRABZ},
853 };
854 static const unsigned CallOpcode[2][2] = {
855 {AArch64::BLRAA, AArch64::BLRAAZ},
856 {AArch64::BLRAB, AArch64::BLRABZ},
857 };
858
859 assert((K == IA || K == IB) && "B(L)RA* instructions require IA or IB key");
860 if (IsCall)
861 return CallOpcode[K == IB][Zero];
862 return BranchOpcode[K == IB][Zero];
863}
864
865// struct TSFlags {
866#define TSFLAG_ELEMENT_SIZE_TYPE(X) (X) // 3-bits
867#define TSFLAG_DESTRUCTIVE_INST_TYPE(X) ((X) << 3) // 4-bits
868#define TSFLAG_FALSE_LANE_TYPE(X) ((X) << 7) // 2-bits
869#define TSFLAG_INSTR_FLAGS(X) ((X) << 9) // 2-bits
870#define TSFLAG_SME_MATRIX_TYPE(X) ((X) << 11) // 3-bits
871// }
872
873namespace AArch64 {
874
875// clang-format off
884
901
907
908// clang-format on
909
910// NOTE: This is a bit field.
913
924
925#undef TSFLAG_ELEMENT_SIZE_TYPE
926#undef TSFLAG_DESTRUCTIVE_INST_TYPE
927#undef TSFLAG_FALSE_LANE_TYPE
928#undef TSFLAG_INSTR_FLAGS
929#undef TSFLAG_SME_MATRIX_TYPE
930
931int32_t getSVEPseudoMap(uint32_t Opcode);
932int32_t getSVERevInstr(uint32_t Opcode);
934
935int32_t getSMEPseudoMap(uint32_t Opcode);
936}
937
938} // end namespace llvm
939
940#endif
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
#define TSFLAG_DESTRUCTIVE_INST_TYPE(X)
#define TSFLAG_SME_MATRIX_TYPE(X)
#define TSFLAG_FALSE_LANE_TYPE(X)
#define TSFLAG_INSTR_FLAGS(X)
#define TSFLAG_ELEMENT_SIZE_TYPE(X)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static bool isHForm(const MachineInstr &MI)
Returns whether the instruction is in H form (16 bit operands)
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DstReg, ArrayRef< MachineOperand > Cond, Register TrueReg, Register FalseReg) const override
static bool hasBTISemantics(const MachineInstr &MI)
Returns whether the instruction can be compatible with non-zero BTYPE.
static bool isQForm(const MachineInstr &MI)
Returns whether the instruction is in Q form (128 bit operands)
static bool getMemOpInfo(unsigned Opcode, TypeSize &Scale, TypeSize &Width, int64_t &MinOffset, int64_t &MaxOffset)
Returns true if opcode Opc is a memory operation.
static bool isTailCallReturnInst(const MachineInstr &MI)
Returns true if MI is one of the TCRETURN* instructions.
static bool isFPRCopy(const MachineInstr &MI)
Does this instruction rename an FPR without modifying bits?
MachineInstr * emitLdStWithAddr(MachineInstr &MemI, const ExtAddrMode &AM) const override
std::optional< DestSourcePair > isCopyInstrImpl(const MachineInstr &MI) const override
If the specific machine instruction is an instruction that moves/copies value from one register to an...
static int getMemScale(const MachineInstr &MI)
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
bool isSubregFoldable() const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Return the number of bytes of code the specified instruction may be.
static bool isZExtLoad(const MachineInstr &MI)
Returns whether the instruction is a zero-extending load.
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
void copyPhysRegImpl(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
static bool isGPRCopy(const MachineInstr &MI)
Does this instruction rename a GPR without modifying bits?
static unsigned convertToFlagSettingOpc(unsigned Opc)
Return the opcode that set flags when possible.
void createPauthEpilogueInstr(MachineBasicBlock &MBB, DebugLoc DL) const
Return true when there is potentially a faster code sequence for an instruction chain ending in Root.
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, Register, Register, Register, int &, int &, int &) const override
Register isLoadFromStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
Check for post-frame ptr elimination stack locations as well.
static const MachineOperand & getLdStOffsetOp(const MachineInstr &MI)
Returns the immediate offset operator of a load/store.
bool isCoalescableExtInstr(const MachineInstr &MI, Register &SrcReg, Register &DstReg, unsigned &SubIdx) const override
static std::optional< unsigned > getUnscaledLdSt(unsigned Opc)
Returns the unscaled load/store for the scaled load/store opcode, if there is a corresponding unscale...
static bool hasUnscaledLdStOffset(unsigned Opc)
Return true if it has an unscaled load/store offset.
static const MachineOperand & getLdStAmountOp(const MachineInstr &MI)
Returns the shift amount operator of a load/store.
static bool hasUnscaledLdStOffset(MachineInstr &MI)
static bool isPreLdSt(const MachineInstr &MI)
Returns whether the instruction is a pre-indexed load/store.
std::optional< ExtAddrMode > getAddrModeFromMemoryOp(const MachineInstr &MemI, const TargetRegisterInfo *TRI) const override
bool getMemOperandsWithOffsetWidth(const MachineInstr &MI, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
bool analyzeBranchPredicate(MachineBasicBlock &MBB, MachineBranchPredicate &MBP, bool AllowModify) const override
void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset, RegScavenger *RS) const override
const TargetRegisterClass * getInlineAsmMemoryOperandRegClass(InlineAsm::ConstraintCode C) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
static bool isPairableLdStInst(const MachineInstr &MI)
Return true if pairing the given load or store may be paired with another.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
static bool isSExtLoad(const MachineInstr &MI)
Returns whether the instruction is a sign-extending load.
const AArch64RegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
static bool isPreSt(const MachineInstr &MI)
Returns whether the instruction is a pre-indexed store.
void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
AArch64InstrInfo(const AArch64Subtarget &STI)
static bool isPairedLdSt(const MachineInstr &MI)
Returns whether the instruction is a paired load/store.
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, int FrameIndex, MachineInstr *&CopyMI, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
bool getMemOperandWithOffsetWidth(const MachineInstr &MI, const MachineOperand *&BaseOp, int64_t &Offset, bool &OffsetIsScalable, TypeSize &Width, const TargetRegisterInfo *TRI) const
If OffsetIsScalable is set to 'true', the offset is scaled by vscale.
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
static bool isStridedAccess(const MachineInstr &MI)
Return true if the given load or store is a strided memory access.
bool shouldClusterMemOps(ArrayRef< const MachineOperand * > BaseOps1, int64_t Offset1, bool OffsetIsScalable1, ArrayRef< const MachineOperand * > BaseOps2, int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize, unsigned NumBytes) const override
Detect opportunities for ldp/stp formation.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
bool isThroughputPattern(unsigned Pattern) const override
Return true when a code sequence can improve throughput.
MachineOperand & getMemOpBaseRegImmOfsOffsetOperand(MachineInstr &LdSt) const
Return the immediate offset of the base register in a load/store LdSt.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override
bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg, const MachineInstr &AddrI, ExtAddrMode &AM) const override
static bool isLdStPairSuppressed(const MachineInstr &MI)
Return true if pairing the given load or store is hinted to be unprofitable.
Register isStoreToStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
Check for post-frame ptr elimination stack locations as well.
std::unique_ptr< TargetInstrInfo::PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override
void copyPhysRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc, llvm::ArrayRef< unsigned > Indices) const
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
AArch64CC::CondCode insertCmpForCondBr(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, ArrayRef< MachineOperand > Cond) const
Inserts the compare instruction needed to un-fuse a fused conditional branch instruction and returns ...
bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t CmpMask, int64_t CmpValue, const MachineRegisterInfo *MRI) const override
optimizeCompareInstr - Convert the instruction supplying the argument to the comparison into one that...
static unsigned getLoadStoreImmIdx(unsigned Opc)
Returns the index for the immediate for a given instruction.
static bool isGPRZero(const MachineInstr &MI)
Does this instruction set its full destination register to zero?
void copyGPRRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc, unsigned Opcode, unsigned ZeroReg, llvm::ArrayRef< unsigned > Indices) const
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &CmpMask, int64_t &CmpValue) const override
analyzeCompare - For a comparison instruction, return the source registers in SrcReg and SrcReg2,...
CombinerObjective getCombinerObjective(unsigned Pattern) const override
static bool isFpOrNEON(Register Reg)
Returns whether the physical register is FP or NEON.
bool isAsCheapAsAMove(const MachineInstr &MI) const override
std::optional< DestSourcePair > isCopyLikeInstrImpl(const MachineInstr &MI) const override
static void suppressLdStPair(MachineInstr &MI)
Hint that pairing the given load or store is unprofitable.
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
static bool isPreLd(const MachineInstr &MI)
Returns whether the instruction is a pre-indexed load.
bool optimizeCondBranch(MachineInstr &MI) const override
Replace csincr-branch sequence by simple conditional branch.
static int getMemScale(unsigned Opc)
Scaling factor for (scaled or unscaled) load or store.
bool isCandidateToMergeOrPair(const MachineInstr &MI) const
Return true if this is a load/store that can be potentially paired/merged.
MCInst getNop() const override
static const MachineOperand & getLdStBaseOp(const MachineInstr &MI)
Returns the base register operator of a load/store.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
A debug info location.
Definition DebugLoc.h:126
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
MachineInstrBundleIterator< MachineInstr > iterator
Representation of each machine instruction.
Flags
Flags values. These may be or'd together.
This class contains meta information specific to a module.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
Wrapper class representing virtual and physical registers.
Definition Register.h:20
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:30
virtual MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, int FrameIndex, MachineInstr *&CopyMI, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const
Target-dependent implementation for foldMemoryOperand.
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 const uint64_t InstrFlagIsWhile
static const uint64_t InstrFlagIsPTestLike
int32_t getSVERevInstr(uint32_t Opcode)
int32_t getSMEPseudoMap(uint32_t Opcode)
int32_t getSVENonRevInstr(uint32_t Opcode)
int32_t getSVEPseudoMap(uint32_t Opcode)
InstrType
Represents how an instruction should be mapped by the outliner.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
static bool isCondBranchOpcode(int Opc)
MCCFIInstruction createDefCFA(const TargetRegisterInfo &TRI, unsigned FrameReg, unsigned Reg, const StackOffset &Offset, bool LastAdjustmentWasScalable=true)
static bool isPTrueOpcode(unsigned Opc)
int isAArch64FrameOffsetLegal(const MachineInstr &MI, StackOffset &Offset, bool *OutUseUnscaledOp=nullptr, unsigned *OutUnscaledOp=nullptr, int64_t *EmittableOffset=nullptr)
Check if the Offset is a valid frame offset for MI.
static bool isIndirectBranchOpcode(int Opc)
static unsigned getXPACOpcodeForKey(AArch64PACKey::ID K)
Return XPAC opcode to be used for a ptrauth strip using the given key.
unsigned getBLRCallOpcode(const MachineFunction &MF)
Return opcode to be used for indirect calls.
AArch64FrameOffsetStatus
Use to report the frame offset status in isAArch64FrameOffsetLegal.
@ AArch64FrameOffsetIsLegal
Offset is legal.
@ AArch64FrameOffsetCanUpdate
Offset can apply, at least partly.
@ AArch64FrameOffsetCannotUpdate
Offset cannot apply.
static unsigned getBranchOpcodeForKey(bool IsCall, AArch64PACKey::ID K, bool Zero)
Return B(L)RA opcode to be used for an authenticated branch or call using the given key,...
static bool isSEHInstruction(const MachineInstr &MI)
static bool isIndirectCallOpcode(unsigned Opc)
AArch64MachineCombinerPattern
@ MULSUBv8i16_OP2
@ FMULv4i16_indexed_OP1
@ FMLSv1i32_indexed_OP2
@ MULSUBv2i32_indexed_OP1
@ FMLAv2i32_indexed_OP2
@ MULADDv4i16_indexed_OP2
@ FMLAv1i64_indexed_OP1
@ MULSUBv16i8_OP1
@ FMLAv8i16_indexed_OP2
@ FMULv2i32_indexed_OP1
@ MULSUBv8i16_indexed_OP2
@ FMLAv1i64_indexed_OP2
@ MULSUBv4i16_indexed_OP2
@ FMLAv1i32_indexed_OP1
@ FMLAv2i64_indexed_OP2
@ FMLSv8i16_indexed_OP1
@ MULSUBv2i32_OP1
@ FMULv4i16_indexed_OP2
@ MULSUBv4i32_indexed_OP2
@ FMULv2i64_indexed_OP2
@ FMLAv4i32_indexed_OP1
@ MULADDv4i16_OP2
@ FMULv8i16_indexed_OP2
@ MULSUBv4i16_OP1
@ MULADDv4i32_OP2
@ MULADDv2i32_OP2
@ MULADDv16i8_OP2
@ FMLSv4i16_indexed_OP1
@ MULADDv16i8_OP1
@ FMLAv2i64_indexed_OP1
@ FMLAv1i32_indexed_OP2
@ FMLSv2i64_indexed_OP2
@ MULADDv2i32_OP1
@ MULADDv4i32_OP1
@ MULADDv2i32_indexed_OP1
@ MULSUBv16i8_OP2
@ MULADDv4i32_indexed_OP1
@ MULADDv2i32_indexed_OP2
@ FMLAv4i16_indexed_OP2
@ MULSUBv8i16_OP1
@ FMULv2i32_indexed_OP2
@ FMLSv2i32_indexed_OP2
@ FMLSv4i32_indexed_OP1
@ FMULv2i64_indexed_OP1
@ MULSUBv4i16_OP2
@ FMLSv4i16_indexed_OP2
@ FMLAv2i32_indexed_OP1
@ FMLSv2i32_indexed_OP1
@ FMLAv8i16_indexed_OP1
@ MULSUBv4i16_indexed_OP1
@ FMLSv4i32_indexed_OP2
@ MULADDv4i32_indexed_OP2
@ MULSUBv4i32_OP2
@ MULSUBv8i16_indexed_OP1
@ MULADDv8i16_OP2
@ MULSUBv2i32_indexed_OP2
@ FMULv4i32_indexed_OP2
@ FMLSv2i64_indexed_OP1
@ MULADDv4i16_OP1
@ FMLAv4i32_indexed_OP2
@ MULADDv8i16_indexed_OP1
@ FMULv4i32_indexed_OP1
@ FMLAv4i16_indexed_OP1
@ FMULv8i16_indexed_OP1
@ MULADDv8i16_OP1
@ MULSUBv4i32_indexed_OP1
@ MULSUBv4i32_OP1
@ FMLSv8i16_indexed_OP2
@ MULADDv8i16_indexed_OP2
@ MULSUBv2i32_OP2
@ FMLSv1i64_indexed_OP2
@ MULADDv4i16_indexed_OP1
void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, StackOffset Offset, const TargetInstrInfo *TII, MachineInstr::MIFlag=MachineInstr::NoFlags, bool SetNZCV=false, bool NeedsWinCFI=false, bool *HasWinCFI=nullptr, bool EmitCFAOffset=false, StackOffset InitialOffset={}, unsigned FrameReg=AArch64::SP)
emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg plus Offset.
CombinerObjective
The combiner's goal may differ based on which pattern it is attempting to optimize.
std::optional< UsedNZCV > examineCFlagsUse(MachineInstr &MI, MachineInstr &CmpInstr, const TargetRegisterInfo &TRI, SmallVectorImpl< MachineInstr * > *CCUseInstrs=nullptr)
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:227
MCCFIInstruction createCFAOffset(const TargetRegisterInfo &MRI, unsigned Reg, const StackOffset &OffsetFromDefCFA, std::optional< int64_t > IncomingVGOffsetFromDefCFA)
ArrayRef(const T &OneElt) -> ArrayRef< T >
static bool isUncondBranchOpcode(int Opc)
static unsigned getPACOpcodeForKey(AArch64PACKey::ID K, bool Zero)
Return PAC opcode to be used for a ptrauth sign using the given key, or its PAC*Z variant that doesn'...
bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, StackOffset &Offset, const AArch64InstrInfo *TII)
rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the FP.
static const MachineMemOperand::Flags MOSuppressPair
bool optimizeTerminators(MachineBasicBlock *MBB, const TargetInstrInfo &TII)
bool isNZCVTouchedInInstructionRange(const MachineInstr &DefMI, const MachineInstr &UseMI, const TargetRegisterInfo *TRI)
Return true if there is an instruction /after/ DefMI and before UseMI which either reads or clobbers ...
static const MachineMemOperand::Flags MOStridedAccess
static unsigned getAUTOpcodeForKey(AArch64PACKey::ID K, bool Zero)
Return AUT opcode to be used for a ptrauth auth using the given key, or its AUT*Z variant that doesn'...
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
Used to describe addressing mode similar to ExtAddrMode in CodeGenPrepare.
UsedNZCV & operator|=(const UsedNZCV &UsedFlags)
UsedNZCV()=default
An individual sequence of instructions to be replaced with a call to an outlined function.
The information necessary to create an outlined function for some class of candidate.