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"
20#include <optional>
21
22#define GET_INSTRINFO_HEADER
23#include "AArch64GenInstrInfo.inc"
24
25namespace llvm {
26
27class AArch64Subtarget;
28
33
34#define FALKOR_STRIDED_ACCESS_MD "falkor.strided.access"
35
36// AArch64 MachineCombiner patterns
38 // These are patterns used to reduce the length of dependence chain.
41
42 // These are multiply-add patterns matched by the AArch64 machine combiner.
55 // NEON integers vectors
68
81
90
99
100 // Floating Point
162
173
175
179};
181 const AArch64RegisterInfo RI;
182 const AArch64Subtarget &Subtarget;
183
184public:
185 explicit AArch64InstrInfo(const AArch64Subtarget &STI);
186
187 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
188 /// such, whenever a client has an instance of instruction info, it should
189 /// always be able to get register info as well (through this method).
190 const AArch64RegisterInfo &getRegisterInfo() const { return RI; }
191
192 unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
193
194 bool isAsCheapAsAMove(const MachineInstr &MI) const override;
195
196 bool isCoalescableExtInstr(const MachineInstr &MI, Register &SrcReg,
197 Register &DstReg, unsigned &SubIdx) const override;
198
199 bool
201 const MachineInstr &MIb) const override;
202
204 int &FrameIndex) const override;
206 int &FrameIndex) const override;
207
208 /// Check for post-frame ptr elimination stack locations as well. This uses a
209 /// heuristic so it isn't reliable for correctness.
211 int &FrameIndex) const override;
212 /// Check for post-frame ptr elimination stack locations as well. This uses a
213 /// heuristic so it isn't reliable for correctness.
215 int &FrameIndex) const override;
216
217 /// Does this instruction set its full destination register to zero?
218 static bool isGPRZero(const MachineInstr &MI);
219
220 /// Does this instruction rename a GPR without modifying bits?
221 static bool isGPRCopy(const MachineInstr &MI);
222
223 /// Does this instruction rename an FPR without modifying bits?
224 static bool isFPRCopy(const MachineInstr &MI);
225
226 /// Return true if pairing the given load or store is hinted to be
227 /// unprofitable.
228 static bool isLdStPairSuppressed(const MachineInstr &MI);
229
230 /// Return true if the given load or store is a strided memory access.
231 static bool isStridedAccess(const MachineInstr &MI);
232
233 /// Return true if it has an unscaled load/store offset.
234 static bool hasUnscaledLdStOffset(unsigned Opc);
236 return hasUnscaledLdStOffset(MI.getOpcode());
237 }
238
239 /// Returns the unscaled load/store for the scaled load/store opcode,
240 /// if there is a corresponding unscaled variant available.
241 static std::optional<unsigned> getUnscaledLdSt(unsigned Opc);
242
243 /// Scaling factor for (scaled or unscaled) load or store.
244 static int getMemScale(unsigned Opc);
245 static int getMemScale(const MachineInstr &MI) {
246 return getMemScale(MI.getOpcode());
247 }
248
249 /// Returns whether the instruction is a pre-indexed load.
250 static bool isPreLd(const MachineInstr &MI);
251
252 /// Returns whether the instruction is a pre-indexed store.
253 static bool isPreSt(const MachineInstr &MI);
254
255 /// Returns whether the instruction is a pre-indexed load/store.
256 static bool isPreLdSt(const MachineInstr &MI);
257
258 /// Returns whether the instruction is a zero-extending load.
259 static bool isZExtLoad(const MachineInstr &MI);
260
261 /// Returns whether the instruction is a sign-extending load.
262 static bool isSExtLoad(const MachineInstr &MI);
263
264 /// Returns whether the instruction is a paired load/store.
265 static bool isPairedLdSt(const MachineInstr &MI);
266
267 /// Returns the base register operator of a load/store.
268 static const MachineOperand &getLdStBaseOp(const MachineInstr &MI);
269
270 /// Returns the immediate offset operator of a load/store.
271 static const MachineOperand &getLdStOffsetOp(const MachineInstr &MI);
272
273 /// Returns whether the physical register is FP or NEON.
274 static bool isFpOrNEON(Register Reg);
275
276 /// Returns the shift amount operator of a load/store.
277 static const MachineOperand &getLdStAmountOp(const MachineInstr &MI);
278
279 /// Returns whether the instruction is FP or NEON.
280 static bool isFpOrNEON(const MachineInstr &MI);
281
282 /// Returns whether the instruction is in H form (16 bit operands)
283 static bool isHForm(const MachineInstr &MI);
284
285 /// Returns whether the instruction is in Q form (128 bit operands)
286 static bool isQForm(const MachineInstr &MI);
287
288 /// Returns whether the instruction can be compatible with non-zero BTYPE.
289 static bool hasBTISemantics(const MachineInstr &MI);
290
291 /// Returns the index for the immediate for a given instruction.
292 static unsigned getLoadStoreImmIdx(unsigned Opc);
293
294 /// Return true if pairing the given load or store may be paired with another.
295 static bool isPairableLdStInst(const MachineInstr &MI);
296
297 /// Returns true if MI is one of the TCRETURN* instructions.
298 static bool isTailCallReturnInst(const MachineInstr &MI);
299
300 /// Return the opcode that set flags when possible. The caller is
301 /// responsible for ensuring the opc has a flag setting equivalent.
302 static unsigned convertToFlagSettingOpc(unsigned Opc);
303
304 /// Return true if this is a load/store that can be potentially paired/merged.
305 bool isCandidateToMergeOrPair(const MachineInstr &MI) const;
306
307 /// Hint that pairing the given load or store is unprofitable.
308 static void suppressLdStPair(MachineInstr &MI);
309
310 std::optional<ExtAddrMode>
312 const TargetRegisterInfo *TRI) const override;
313
315 const MachineInstr &AddrI,
316 ExtAddrMode &AM) const override;
317
319 const ExtAddrMode &AM) const override;
320
323 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
324 const TargetRegisterInfo *TRI) const override;
325
326 /// If \p OffsetIsScalable is set to 'true', the offset is scaled by `vscale`.
327 /// This is true for some SVE instructions like ldr/str that have a
328 /// 'reg + imm' addressing mode where the immediate is an index to the
329 /// scalable vector located at 'reg + imm * vscale x #bytes'.
331 const MachineOperand *&BaseOp,
332 int64_t &Offset, bool &OffsetIsScalable,
333 TypeSize &Width,
334 const TargetRegisterInfo *TRI) const;
335
336 /// Return the immediate offset of the base register in a load/store \p LdSt.
338
339 /// Returns true if opcode \p Opc is a memory operation. If it is, set
340 /// \p Scale, \p Width, \p MinOffset, and \p MaxOffset accordingly.
341 ///
342 /// For unscaled instructions, \p Scale is set to 1. All values are in bytes.
343 /// MinOffset/MaxOffset are the un-scaled limits of the immediate in the
344 /// instruction, the actual offset limit is [MinOffset*Scale,
345 /// MaxOffset*Scale].
346 static bool getMemOpInfo(unsigned Opcode, TypeSize &Scale, TypeSize &Width,
347 int64_t &MinOffset, int64_t &MaxOffset);
348
350 int64_t Offset1, bool OffsetIsScalable1,
352 int64_t Offset2, bool OffsetIsScalable2,
353 unsigned ClusterSize,
354 unsigned NumBytes) const override;
355
357 const DebugLoc &DL, MCRegister DestReg,
358 MCRegister SrcReg, bool KillSrc,
359 llvm::ArrayRef<unsigned> Indices) const;
361 const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
362 bool KillSrc, unsigned Opcode, unsigned ZeroReg,
363 llvm::ArrayRef<unsigned> Indices) const;
365 const DebugLoc &DL, Register DestReg, Register SrcReg,
366 bool KillSrc, bool RenamableDest = false,
367 bool RenamableSrc = false) const;
369 const DebugLoc &DL, Register DestReg, Register SrcReg,
370 bool KillSrc, bool RenamableDest = false,
371 bool RenamableSrc = false) const override;
372
375 bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg,
376 MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;
377
380 Register DestReg, int FrameIndex, const TargetRegisterClass *RC,
381 Register VReg, unsigned SubReg = 0,
382 MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;
383
384 // This tells target independent code that it is okay to pass instructions
385 // with subreg operands to foldMemoryOperandImpl.
386 bool isSubregFoldable() const override { return true; }
387
390 ArrayRef<unsigned> Ops, int FrameIndex,
391 MachineInstr *&CopyMI,
392 LiveIntervals *LIS = nullptr,
393 VirtRegMap *VRM = nullptr) const override;
394
395 /// \returns true if a branch from an instruction with opcode \p BranchOpc
396 /// bytes is capable of jumping to a position \p BrOffset bytes away.
397 bool isBranchOffsetInRange(unsigned BranchOpc,
398 int64_t BrOffset) const override;
399
400 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
401
403 MachineBasicBlock &NewDestBB,
404 MachineBasicBlock &RestoreBB, const DebugLoc &DL,
405 int64_t BrOffset, RegScavenger *RS) const override;
406
408 MachineBasicBlock *&FBB,
410 bool AllowModify = false) const override;
412 MachineBranchPredicate &MBP,
413 bool AllowModify) const override;
415 int *BytesRemoved = nullptr) const override;
418 const DebugLoc &DL,
419 int *BytesAdded = nullptr) const override;
420
421 /// Inserts the compare instruction needed to un-fuse a fused conditional
422 /// branch instruction and returns the condition code of the original fused
423 /// branch.
426 const DebugLoc &DL,
428
429 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
430 analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override;
431
432 bool
435 Register, Register, Register, int &, int &,
436 int &) const override;
438 const DebugLoc &DL, Register DstReg,
440 Register FalseReg) const override;
441
443 MachineBasicBlock::iterator MI) const override;
444
445 MCInst getNop() const override;
446
448 const MachineBasicBlock *MBB,
449 const MachineFunction &MF) const override;
450
451 /// analyzeCompare - For a comparison instruction, return the source registers
452 /// in SrcReg and SrcReg2, and the value it compares against in CmpValue.
453 /// Return true if the comparison instruction can be analyzed.
454 bool analyzeCompare(const MachineInstr &MI, Register &SrcReg,
455 Register &SrcReg2, int64_t &CmpMask,
456 int64_t &CmpValue) const override;
457 /// optimizeCompareInstr - Convert the instruction supplying the argument to
458 /// the comparison into one that sets the zero bit in the flags register.
459 bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
460 Register SrcReg2, int64_t CmpMask, int64_t CmpValue,
461 const MachineRegisterInfo *MRI) const override;
462 bool optimizeCondBranch(MachineInstr &MI) const override;
463
464 CombinerObjective getCombinerObjective(unsigned Pattern) const override;
465 /// Return true when a code sequence can improve throughput. It
466 /// should be called only for instructions in loops.
467 /// \param Pattern - combiner pattern
468 bool isThroughputPattern(unsigned Pattern) const override;
469 /// Return true when there is potentially a faster code sequence
470 /// for an instruction chain ending in ``Root``. All potential patterns are
471 /// listed in the ``Patterns`` array.
472 bool getMachineCombinerPatterns(MachineInstr &Root,
474 bool DoRegPressureReduce) const override;
475 /// Return true when Inst is associative and commutative so that it can be
476 /// reassociated. If Invert is true, then the inverse of Inst operation must
477 /// be checked.
478 bool isAssociativeAndCommutative(const MachineInstr &Inst,
479 bool Invert) const override;
480
481 /// Returns true if \P Opcode is an instruction which performs accumulation
482 /// into a destination register.
483 bool isAccumulationOpcode(unsigned Opcode) const override;
484
485 /// Returns an opcode which defines the accumulator used by \P Opcode.
486 unsigned getAccumulationStartOpcode(unsigned Opcode) const override;
487
488 unsigned
489 getReduceOpcodeForAccumulator(unsigned int AccumulatorOpCode) const override;
490
491 /// When getMachineCombinerPatterns() finds patterns, this function
492 /// generates the instructions that could replace the original code
493 /// sequence
494 void genAlternativeCodeSequence(
495 MachineInstr &Root, unsigned Pattern,
498 DenseMap<Register, unsigned> &InstrIdxForVirtReg) const override;
499 /// AArch64 supports MachineCombiner.
500 bool useMachineCombiner() const override;
501
502 bool expandPostRAPseudo(MachineInstr &MI) const override;
503
504 std::pair<unsigned, unsigned>
505 decomposeMachineOperandsTargetFlags(unsigned TF) const override;
507 getSerializableDirectMachineOperandTargetFlags() const override;
509 getSerializableBitmaskMachineOperandTargetFlags() const override;
511 getSerializableMachineMemOperandTargetFlags() const override;
512
513 bool isFunctionSafeToOutlineFrom(MachineFunction &MF,
514 bool OutlineFromLinkOnceODRs) const override;
515 std::optional<std::unique_ptr<outliner::OutlinedFunction>>
516 getOutliningCandidateInfo(
517 const MachineModuleInfo &MMI,
518 std::vector<outliner::Candidate> &RepeatedSequenceLocs,
519 unsigned MinRepeats) const override;
520 void mergeOutliningCandidateAttributes(
521 Function &F, std::vector<outliner::Candidate> &Candidates) const override;
522 outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI,
524 unsigned Flags) const override;
526 std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>>
527 getOutlinableRanges(MachineBasicBlock &MBB, unsigned &Flags) const override;
528 void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF,
529 const outliner::OutlinedFunction &OF) const override;
531 insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
533 outliner::Candidate &C) const override;
534 bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override;
535
536 void buildClearRegister(Register Reg, MachineBasicBlock &MBB,
538 bool AllowSideEffects = true) const override;
539
540 /// Returns the vector element size (B, H, S or D) of an SVE opcode.
541 uint64_t getElementSizeForOpcode(unsigned Opc) const;
542 /// Returns true if the opcode is for an SVE instruction that sets the
543 /// condition codes as if it's results had been fed to a PTEST instruction
544 /// along with the same general predicate.
545 bool isPTestLikeOpcode(unsigned Opc) const;
546 /// Returns true if the opcode is for an SVE WHILE## instruction.
547 bool isWhileOpcode(unsigned Opc) const;
548 /// Returns true if the instruction has a shift by immediate that can be
549 /// executed in one cycle less.
550 static bool isFalkorShiftExtFast(const MachineInstr &MI);
551 /// Return true if the instructions is a SEH instruction used for unwinding
552 /// on Windows.
553 static bool isSEHInstruction(const MachineInstr &MI);
554
555 std::optional<RegImmPair> isAddImmediate(const MachineInstr &MI,
556 Register Reg) const override;
557
558 bool isFunctionSafeToSplit(const MachineFunction &MF) const override;
559
560 bool isMBBSafeToSplitToCold(const MachineBasicBlock &MBB) const override;
561
562 std::optional<ParamLoadedValue>
563 describeLoadedValue(const MachineInstr &MI, Register Reg) const override;
564
565 unsigned int getTailDuplicateSize(CodeGenOptLevel OptLevel) const override;
566
567 bool isExtendLikelyToBeFolded(MachineInstr &ExtMI,
568 MachineRegisterInfo &MRI) const override;
569
570 static void decomposeStackOffsetForFrameOffsets(const StackOffset &Offset,
571 int64_t &NumBytes,
572 int64_t &NumPredicateVectors,
573 int64_t &NumDataVectors);
574 static void decomposeStackOffsetForDwarfOffsets(const StackOffset &Offset,
575 int64_t &ByteSized,
576 int64_t &VGSized);
577
578 // Return true if address of the form BaseReg + Scale * ScaledReg + Offset can
579 // be used for a load/store of NumBytes. BaseReg is always present and
580 // implicit.
581 bool isLegalAddressingMode(unsigned NumBytes, int64_t Offset,
582 unsigned Scale) const;
583
584 // Decrement the SP, issuing probes along the way. `TargetReg` is the new top
585 // of the stack. `FrameSetup` is passed as true, if the allocation is a part
586 // of constructing the activation frame of a function.
588 Register TargetReg,
589 bool FrameSetup) const;
590
591 static int
592 findCondCodeUseOperandIdxForBranchOrSelect(const MachineInstr &Instr);
593
594 /// Insert a `PAUTH_EPILOGUE` pseudo before the first terminator in \p MBB to
595 /// authenticate the return address. Adds an implicit def of X16 when the
596 /// branch protection uses PAuthLR but the subtarget lacks PAuthLR
597 /// instructions. If the epilogue has callee-popped argument stack to restore,
598 /// it additionally implicit defines X15 and X17 to cover clobbered registers
599 /// for the required sequence on subtargets both with and without PAuthLR
600 /// instructions.
602
603#define GET_INSTRINFO_HELPER_DECLS
604#include "AArch64GenInstrInfo.inc"
605
606protected:
607 /// If the specific machine instruction is an instruction that moves/copies
608 /// value from one register to another register return destination and source
609 /// registers as machine operands.
610 std::optional<DestSourcePair>
611 isCopyInstrImpl(const MachineInstr &MI) const override;
612 std::optional<DestSourcePair>
613 isCopyLikeInstrImpl(const MachineInstr &MI) const override;
614
615private:
616 /// Sets the offsets on outlined instructions in \p MBB which use SP
617 /// so that they will be valid post-outlining.
618 ///
619 /// \param MBB A \p MachineBasicBlock in an outlined function.
620 void fixupPostOutline(MachineBasicBlock &MBB) const;
621
622 void instantiateCondBranch(MachineBasicBlock &MBB, const DebugLoc &DL,
623 MachineBasicBlock *TBB,
625 bool substituteCmpToZero(MachineInstr &CmpInstr, unsigned SrcReg,
626 const MachineRegisterInfo &MRI) const;
627 bool removeCmpToZeroOrOne(MachineInstr &CmpInstr, unsigned SrcReg,
628 int CmpValue, const MachineRegisterInfo &MRI) const;
629
630 /// Returns an unused general-purpose register which can be used for
631 /// constructing an outlined call if one exists. Returns 0 otherwise.
632 Register findRegisterToSaveLRTo(outliner::Candidate &C) const;
633
634 /// Remove a ptest of a predicate-generating operation that already sets, or
635 /// can be made to set, the condition codes in an identical manner
636 bool optimizePTestInstr(MachineInstr *PTest, unsigned MaskReg,
637 unsigned PredReg,
638 const MachineRegisterInfo *MRI) const;
639 std::optional<unsigned>
640 canRemovePTestInstr(MachineInstr *PTest, MachineInstr *Mask,
641 MachineInstr *Pred, const MachineRegisterInfo *MRI) const;
642
643 /// verifyInstruction - Perform target specific instruction verification.
644 bool verifyInstruction(const MachineInstr &MI,
645 StringRef &ErrInfo) const override;
646};
647
648struct UsedNZCV {
649 bool N = false;
650 bool Z = false;
651 bool C = false;
652 bool V = false;
653
654 UsedNZCV() = default;
655
656 UsedNZCV &operator|=(const UsedNZCV &UsedFlags) {
657 this->N |= UsedFlags.N;
658 this->Z |= UsedFlags.Z;
659 this->C |= UsedFlags.C;
660 this->V |= UsedFlags.V;
661 return *this;
662 }
663};
664
665/// \returns Conditions flags used after \p CmpInstr in its MachineBB if NZCV
666/// flags are not alive in successors of the same \p CmpInstr and \p MI parent.
667/// \returns std::nullopt otherwise.
668///
669/// Collect instructions using that flags in \p CCUseInstrs if provided.
670std::optional<UsedNZCV>
671examineCFlagsUse(MachineInstr &MI, MachineInstr &CmpInstr,
672 const TargetRegisterInfo &TRI,
673 SmallVectorImpl<MachineInstr *> *CCUseInstrs = nullptr);
674
675/// Return true if there is an instruction /after/ \p DefMI and before \p UseMI
676/// which either reads or clobbers NZCV.
677bool isNZCVTouchedInInstructionRange(const MachineInstr &DefMI,
678 const MachineInstr &UseMI,
679 const TargetRegisterInfo *TRI);
680
681MCCFIInstruction createDefCFA(const TargetRegisterInfo &TRI, unsigned FrameReg,
682 unsigned Reg, const StackOffset &Offset,
683 bool LastAdjustmentWasScalable = true);
684MCCFIInstruction
685createCFAOffset(const TargetRegisterInfo &MRI, unsigned Reg,
686 const StackOffset &OffsetFromDefCFA,
687 std::optional<int64_t> IncomingVGOffsetFromDefCFA);
688
689/// emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg
690/// plus Offset. This is intended to be used from within the prolog/epilog
691/// insertion (PEI) pass, where a virtual scratch register may be allocated
692/// if necessary, to be replaced by the scavenger at the end of PEI.
693void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
694 const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
695 StackOffset Offset, const TargetInstrInfo *TII,
697 bool SetNZCV = false, bool NeedsWinCFI = false,
698 bool *HasWinCFI = nullptr, bool EmitCFAOffset = false,
699 StackOffset InitialOffset = {},
700 unsigned FrameReg = AArch64::SP);
701
702/// rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the
703/// FP. Return false if the offset could not be handled directly in MI, and
704/// return the left-over portion by reference.
705bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
706 unsigned FrameReg, StackOffset &Offset,
707 const AArch64InstrInfo *TII);
708
709/// Use to report the frame offset status in isAArch64FrameOffsetLegal.
711 AArch64FrameOffsetCannotUpdate = 0x0, ///< Offset cannot apply.
712 AArch64FrameOffsetIsLegal = 0x1, ///< Offset is legal.
713 AArch64FrameOffsetCanUpdate = 0x2 ///< Offset can apply, at least partly.
714};
715
716/// Check if the @p Offset is a valid frame offset for @p MI.
717/// The returned value reports the validity of the frame offset for @p MI.
718/// It uses the values defined by AArch64FrameOffsetStatus for that.
719/// If result == AArch64FrameOffsetCannotUpdate, @p MI cannot be updated to
720/// use an offset.eq
721/// If result & AArch64FrameOffsetIsLegal, @p Offset can completely be
722/// rewritten in @p MI.
723/// If result & AArch64FrameOffsetCanUpdate, @p Offset contains the
724/// amount that is off the limit of the legal offset.
725/// If set, @p OutUseUnscaledOp will contain the whether @p MI should be
726/// turned into an unscaled operator, which opcode is in @p OutUnscaledOp.
727/// If set, @p EmittableOffset contains the amount that can be set in @p MI
728/// (possibly with @p OutUnscaledOp if OutUseUnscaledOp is true) and that
729/// is a legal offset.
730int isAArch64FrameOffsetLegal(const MachineInstr &MI, StackOffset &Offset,
731 bool *OutUseUnscaledOp = nullptr,
732 unsigned *OutUnscaledOp = nullptr,
733 int64_t *EmittableOffset = nullptr);
734
735bool optimizeTerminators(MachineBasicBlock *MBB, const TargetInstrInfo &TII);
736
737static inline bool isUncondBranchOpcode(int Opc) { return Opc == AArch64::B; }
738
739static inline bool isCondBranchOpcode(int Opc) {
740 switch (Opc) {
741 case AArch64::Bcc:
742 case AArch64::CBZW:
743 case AArch64::CBZX:
744 case AArch64::CBNZW:
745 case AArch64::CBNZX:
746 case AArch64::TBZW:
747 case AArch64::TBZX:
748 case AArch64::TBNZW:
749 case AArch64::TBNZX:
750 case AArch64::CBWPri:
751 case AArch64::CBXPri:
752 case AArch64::CBBAssertExt:
753 case AArch64::CBHAssertExt:
754 case AArch64::CBWPrr:
755 case AArch64::CBXPrr:
756 return true;
757 default:
758 return false;
759 }
760}
761
762static inline bool isIndirectBranchOpcode(int Opc) {
763 switch (Opc) {
764 case AArch64::BR:
765 case AArch64::BRAA:
766 case AArch64::BRAB:
767 case AArch64::BRAAZ:
768 case AArch64::BRABZ:
769 return true;
770 }
771 return false;
772}
773
774static inline bool isIndirectCallOpcode(unsigned Opc) {
775 switch (Opc) {
776 case AArch64::BLR:
777 case AArch64::BLRAA:
778 case AArch64::BLRAB:
779 case AArch64::BLRAAZ:
780 case AArch64::BLRABZ:
781 return true;
782 default:
783 return false;
784 }
785}
786
787static inline bool isPTrueOpcode(unsigned Opc) {
788 switch (Opc) {
789 case AArch64::PTRUE_B:
790 case AArch64::PTRUE_H:
791 case AArch64::PTRUE_S:
792 case AArch64::PTRUE_D:
793 return true;
794 default:
795 return false;
796 }
797}
798
799/// Return opcode to be used for indirect calls.
800unsigned getBLRCallOpcode(const MachineFunction &MF);
801
802/// Return XPAC opcode to be used for a ptrauth strip using the given key.
803static inline unsigned getXPACOpcodeForKey(AArch64PACKey::ID K) {
804 using namespace AArch64PACKey;
805 switch (K) {
806 case IA: case IB: return AArch64::XPACI;
807 case DA: case DB: return AArch64::XPACD;
808 }
809 llvm_unreachable("Unhandled AArch64PACKey::ID enum");
810}
811
812/// Return AUT opcode to be used for a ptrauth auth using the given key, or its
813/// AUT*Z variant that doesn't take a discriminator operand, using zero instead.
814static inline unsigned getAUTOpcodeForKey(AArch64PACKey::ID K, bool Zero) {
815 using namespace AArch64PACKey;
816 switch (K) {
817 case IA: return Zero ? AArch64::AUTIZA : AArch64::AUTIA;
818 case IB: return Zero ? AArch64::AUTIZB : AArch64::AUTIB;
819 case DA: return Zero ? AArch64::AUTDZA : AArch64::AUTDA;
820 case DB: return Zero ? AArch64::AUTDZB : AArch64::AUTDB;
821 }
822 llvm_unreachable("Unhandled AArch64PACKey::ID enum");
823}
824
825/// Return PAC opcode to be used for a ptrauth sign using the given key, or its
826/// PAC*Z variant that doesn't take a discriminator operand, using zero instead.
827static inline unsigned getPACOpcodeForKey(AArch64PACKey::ID K, bool Zero) {
828 using namespace AArch64PACKey;
829 switch (K) {
830 case IA: return Zero ? AArch64::PACIZA : AArch64::PACIA;
831 case IB: return Zero ? AArch64::PACIZB : AArch64::PACIB;
832 case DA: return Zero ? AArch64::PACDZA : AArch64::PACDA;
833 case DB: return Zero ? AArch64::PACDZB : AArch64::PACDB;
834 }
835 llvm_unreachable("Unhandled AArch64PACKey::ID enum");
836}
837
838/// Return B(L)RA opcode to be used for an authenticated branch or call using
839/// the given key, or its B(L)RA*Z variant that doesn't take a discriminator
840/// operand, using zero instead.
841static inline unsigned getBranchOpcodeForKey(bool IsCall, AArch64PACKey::ID K,
842 bool Zero) {
843 using namespace AArch64PACKey;
844 static const unsigned BranchOpcode[2][2] = {
845 {AArch64::BRAA, AArch64::BRAAZ},
846 {AArch64::BRAB, AArch64::BRABZ},
847 };
848 static const unsigned CallOpcode[2][2] = {
849 {AArch64::BLRAA, AArch64::BLRAAZ},
850 {AArch64::BLRAB, AArch64::BLRABZ},
851 };
852
853 assert((K == IA || K == IB) && "B(L)RA* instructions require IA or IB key");
854 if (IsCall)
855 return CallOpcode[K == IB][Zero];
856 return BranchOpcode[K == IB][Zero];
857}
858
859// struct TSFlags {
860#define TSFLAG_ELEMENT_SIZE_TYPE(X) (X) // 3-bits
861#define TSFLAG_DESTRUCTIVE_INST_TYPE(X) ((X) << 3) // 4-bits
862#define TSFLAG_FALSE_LANE_TYPE(X) ((X) << 7) // 2-bits
863#define TSFLAG_INSTR_FLAGS(X) ((X) << 9) // 2-bits
864#define TSFLAG_SME_MATRIX_TYPE(X) ((X) << 11) // 3-bits
865// }
866
867namespace AArch64 {
868
869// clang-format off
878
895
901
902// clang-format on
903
904// NOTE: This is a bit field.
907
918
919#undef TSFLAG_ELEMENT_SIZE_TYPE
920#undef TSFLAG_DESTRUCTIVE_INST_TYPE
921#undef TSFLAG_FALSE_LANE_TYPE
922#undef TSFLAG_INSTR_FLAGS
923#undef TSFLAG_SME_MATRIX_TYPE
924
925int32_t getSVEPseudoMap(uint32_t Opcode);
926int32_t getSVERevInstr(uint32_t Opcode);
928
929int32_t getSMEPseudoMap(uint32_t Opcode);
930}
931
932} // end namespace llvm
933
934#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
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:149
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.