Go to the documentation of this file.
13 #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64INSTRINFO_H
14 #define LLVM_LIB_TARGET_AARCH64_AARCH64INSTRINFO_H
23 #define GET_INSTRINFO_HEADER
24 #include "AArch64GenInstrInfo.inc"
28 class AArch64Subtarget;
35 #define FALKOR_STRIDED_ACCESS_MD "falkor.strided.access"
54 Register &DstReg,
unsigned &SubIdx)
const override;
143 int64_t &Offset,
bool &OffsetIsScalable,
unsigned &
Width,
152 int64_t &Offset,
bool &OffsetIsScalable,
164 int64_t &MinOffset, int64_t &MaxOffset);
168 unsigned NumLoads,
unsigned NumBytes)
const override;
172 MCRegister SrcReg,
bool KillSrc,
unsigned Opcode,
175 DebugLoc DL,
unsigned DestReg,
unsigned SrcReg,
176 bool KillSrc,
unsigned Opcode,
unsigned ZeroReg,
180 bool KillSrc)
const override;
208 int64_t BrOffset)
const override;
215 bool AllowModify =
false)
const override;
217 MachineBranchPredicate &MBP,
218 bool AllowModify)
const override;
220 int *BytesRemoved =
nullptr)
const override;
224 int *BytesAdded =
nullptr)
const override;
229 int &)
const override;
244 Register &SrcReg2, int64_t &CmpMask,
245 int64_t &CmpValue)
const override;
249 Register SrcReg2, int64_t CmpMask, int64_t CmpValue,
263 bool DoRegPressureReduce)
const override;
279 std::pair<unsigned, unsigned>
289 bool OutlineFromLinkOnceODRs)
const override;
291 std::vector<outliner::Candidate> &RepeatedSequenceLocs)
const override;
295 unsigned &Flags)
const override;
331 int64_t &NumPredicateVectors,
332 int64_t &NumDataVectors);
336 #define GET_INSTRINFO_HELPER_DECLS
337 #include "AArch64GenInstrInfo.inc"
343 Optional<DestSourcePair>
347 unsigned getInstBundleLength(
const MachineInstr &
MI)
const;
353 void fixupPostOutline(MachineBasicBlock &
MBB)
const;
355 void instantiateCondBranch(MachineBasicBlock &
MBB,
const DebugLoc &
DL,
356 MachineBasicBlock *TBB,
357 ArrayRef<MachineOperand>
Cond)
const;
358 bool substituteCmpToZero(MachineInstr &CmpInstr,
unsigned SrcReg,
359 const MachineRegisterInfo &
MRI)
const;
360 bool removeCmpToZeroOrOne(MachineInstr &CmpInstr,
unsigned SrcReg,
361 int CmpValue,
const MachineRegisterInfo &
MRI)
const;
365 Register findRegisterToSaveLRTo(outliner::Candidate &
C)
const;
369 bool optimizePTestInstr(MachineInstr *PTest,
unsigned MaskReg,
371 const MachineRegisterInfo *
MRI)
const;
383 this->N |= UsedFlags.
N;
384 this->Z |= UsedFlags.
Z;
385 this->C |= UsedFlags.
C;
386 this->V |= UsedFlags.
V;
398 const TargetRegisterInfo &
TRI,
399 SmallVectorImpl<MachineInstr *> *CCUseInstrs =
nullptr);
404 const MachineInstr &
UseMI,
405 const TargetRegisterInfo *
TRI);
407 MCCFIInstruction
createDefCFA(
const TargetRegisterInfo &
TRI,
unsigned FrameReg,
408 unsigned Reg,
const StackOffset &Offset,
409 bool LastAdjustmentWasScalable =
true);
411 const StackOffset &OffsetFromDefCFA);
418 const DebugLoc &
DL,
unsigned DestReg,
unsigned SrcReg,
419 StackOffset Offset,
const TargetInstrInfo *
TII,
421 bool SetNZCV =
false,
bool NeedsWinCFI =
false,
422 bool *HasWinCFI =
nullptr,
bool EmitCFAOffset =
false,
423 StackOffset InitialOffset = {},
424 unsigned FrameReg = AArch64::SP);
430 unsigned FrameReg, StackOffset &Offset,
431 const AArch64InstrInfo *
TII);
455 bool *OutUseUnscaledOp =
nullptr,
456 unsigned *OutUnscaledOp =
nullptr,
457 int64_t *EmittableOffset =
nullptr);
492 case AArch64::PTRUE_B:
493 case AArch64::PTRUE_H:
494 case AArch64::PTRUE_S:
495 case AArch64::PTRUE_D:
506 #define TSFLAG_ELEMENT_SIZE_TYPE(X) (X) // 3-bits
507 #define TSFLAG_DESTRUCTIVE_INST_TYPE(X) ((X) << 3) // 4-bits
508 #define TSFLAG_FALSE_LANE_TYPE(X) ((X) << 7) // 2-bits
509 #define TSFLAG_INSTR_FLAGS(X) ((X) << 9) // 2-bits
547 #undef TSFLAG_ELEMENT_SIZE_TYPE
548 #undef TSFLAG_DESTRUCTIVE_INST_TYPE
549 #undef TSFLAG_FALSE_LANE_TYPE
550 #undef TSFLAG_INSTR_FLAGS
unsigned int getTailDuplicateSize(CodeGenOpt::Level OptLevel) const override
Optional< ParamLoadedValue > describeLoadedValue(const MachineInstr &MI, Register Reg) const override
static void suppressLdStPair(MachineInstr &MI)
Hint that pairing the given load or store is unprofitable.
bool isThroughputPattern(MachineCombinerPattern Pattern) const override
Return true when a code sequence can improve throughput.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder & UseMI
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override
#define TSFLAG_DESTRUCTIVE_INST_TYPE(X)
bool expandPostRAPseudo(MachineInstr &MI) const override
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Return the number of bytes of code the specified instruction may be.
Optional< ExtAddrMode > getAddrModeFromMemoryOp(const MachineInstr &MemI, const TargetRegisterInfo *TRI) const override
@ AArch64FrameOffsetCanUpdate
Offset can apply, at least partly.
bool getMemOperandWithOffsetWidth(const MachineInstr &MI, const MachineOperand *&BaseOp, int64_t &Offset, bool &OffsetIsScalable, unsigned &Width, const TargetRegisterInfo *TRI) const
If OffsetIsScalable is set to 'true', the offset is scaled by vscale.
static const uint64_t InstrFlagIsPTestLike
bool getMemOperandsWithOffsetWidth(const MachineInstr &MI, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, unsigned &Width, const TargetRegisterInfo *TRI) const override
unsigned getBLRCallOpcode(const MachineFunction &MF)
Return opcode to be used for indirect calls.
Reg
All possible values of the reg field in the ModR/M byte.
Optional< UsedNZCV > examineCFlagsUse(MachineInstr &MI, MachineInstr &CmpInstr, const TargetRegisterInfo &TRI, SmallVectorImpl< MachineInstr * > *CCUseInstrs=nullptr)
static bool isPreLdSt(const MachineInstr &MI)
Returns whether the instruction is a pre-indexed load/store.
static int getMemScale(const MachineInstr &MI)
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
InstrType
Represents how an instruction should be mapped by the outliner.
MachineBasicBlock::iterator insertOutlinedCall(Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, MachineFunction &MF, outliner::Candidate &C) const override
uint64_t getElementSizeForOpcode(unsigned Opc) const
Returns the vector element size (B, H, S or D) of an SVE opcode.
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
static bool isCondBranchOpcode(int Opc)
bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, StackOffset &Offset, const AArch64InstrInfo *TII)
rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the FP.
UsedNZCV & operator|=(const UsedNZCV &UsedFlags)
static bool isFpOrNEON(const MachineInstr &MI)
Returns whether the instruction is FP or NEON.
@ DestructiveTernaryCommWithRev
static bool isUncondBranchOpcode(int Opc)
Instances of this class represent a single low-level machine instruction.
The information necessary to create an outlined function for some class of candidate.
void copyGPRRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc, unsigned Opcode, unsigned ZeroReg, llvm::ArrayRef< unsigned > Indices) const
unsigned const TargetRegisterInfo * TRI
void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, const outliner::OutlinedFunction &OF) const override
@ AArch64FrameOffsetCannotUpdate
Offset cannot apply.
static bool isPairableLdStInst(const MachineInstr &MI)
Return true if pairing the given load or store may be paired with another.
int getSVERevInstr(uint16_t Opcode)
In x86 we generate this spiffy xmm0 xmm0 ret in x86 we generate this which could be xmm1 movss xmm1 xmm0 ret In sse4 we could use insertps to make both better Here s another testcase that could use x3
static unsigned getLoadStoreImmIdx(unsigned Opc)
Returns the index for the immediate for a given instruction.
bool isWhileOpcode(unsigned Opc) const
Returns true if the opcode is for an SVE WHILE## instruction.
static const MachineMemOperand::Flags MOStridedAccess
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
(vector float) vec_cmpeq(*A, *B) C
static bool isGPRZero(const MachineInstr &MI)
Does this instruction set its full destination register to zero?
static const uint64_t InstrFlagIsWhile
bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override
bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< MachineCombinerPattern > &Patterns, bool DoRegPressureReduce) const override
Return true when there is potentially a faster code sequence for an instruction chain ending in Root.
const HexagonInstrInfo * TII
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineOperand class - Representation of each machine instruction operand.
static bool isStridedAccess(const MachineInstr &MI)
Return true if the given load or store is a strided memory access.
@ DestructiveUnaryPassthru
void copyPhysRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc, unsigned Opcode, llvm::ArrayRef< unsigned > Indices) const
static bool isFPRCopy(const MachineInstr &MI)
Does this instruction rename an FPR without modifying bits?
bool useMachineCombiner() const override
AArch64 supports MachineCombiner.
MCCFIInstruction createDefCFA(const TargetRegisterInfo &TRI, unsigned FrameReg, unsigned Reg, const StackOffset &Offset, bool LastAdjustmentWasScalable=true)
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
bool isCoalescableExtInstr(const MachineInstr &MI, Register &SrcReg, Register &DstReg, unsigned &SubIdx) const override
@ AArch64FrameOffsetIsLegal
Offset is legal.
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)
gcc mainline compiles it x2(%rip)
Representation of each machine instruction.
static bool isPreLd(const MachineInstr &MI)
Returns whether the instruction is a pre-indexed load.
static const MachineMemOperand::Flags MOSuppressPair
#define TSFLAG_INSTR_FLAGS(X)
An individual sequence of instructions to be replaced with a call to an outlined function.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
#define TSFLAG_ELEMENT_SIZE_TYPE(X)
outliner::InstrType getOutliningType(MachineBasicBlock::iterator &MIT, unsigned Flags) const override
bool isFunctionSafeToOutlineFrom(MachineFunction &MF, bool OutlineFromLinkOnceODRs) const override
void genAlternativeCodeSequence(MachineInstr &Root, MachineCombinerPattern Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< unsigned, unsigned > &InstrIdxForVirtReg) const override
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
MCInst getNop() const override
bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const override
Flags
Flags values. These may be or'd together.
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 ...
outliner::OutlinedFunction getOutliningCandidateInfo(std::vector< outliner::Candidate > &RepeatedSequenceLocs) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableBitmaskMachineOperandTargetFlags() const override
MachineOperand & getMemOpBaseRegImmOfsOffsetOperand(MachineInstr &LdSt) const
Return the immediate offset of the base register in a load/store LdSt.
AArch64InstrInfo(const AArch64Subtarget &STI)
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.
Optional< RegImmPair > isAddImmediate(const MachineInstr &MI, Register Reg) const override
static Optional< unsigned > getUnscaledLdSt(unsigned Opc)
Returns the unscaled load/store for the scaled load/store opcode, if there is a corresponding unscale...
A Module instance is used to store all the information related to an LLVM module.
MachineInstrBundleIterator< MachineInstr > iterator
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool shouldClusterMemOps(ArrayRef< const MachineOperand * > BaseOps1, ArrayRef< const MachineOperand * > BaseOps2, unsigned NumLoads, unsigned NumBytes) const override
Detect opportunities for ldp/stp formation.
static bool isGPRCopy(const MachineInstr &MI)
Does this instruction rename a GPR without modifying bits?
SmallVector< MachineOperand, 4 > Cond
bool isPTestLikeOpcode(unsigned Opc) const
Returns true if the opcode is for an SVE instruction that sets the condition codes as if it's results...
MachineBasicBlock MachineBasicBlock::iterator MBBI
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...
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
StackOffset is a class to represent an offset with 2 dimensions, named fixed and scalable,...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, Register, Register, Register, int &, int &, int &) const override
unsigned const MachineRegisterInfo * MRI
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
Wrapper class representing virtual and physical registers.
ArrayRef< std::pair< MachineMemOperand::Flags, const char * > > getSerializableMachineMemOperandTargetFlags() const override
static void decomposeStackOffsetForFrameOffsets(const StackOffset &Offset, int64_t &NumBytes, int64_t &NumPredicateVectors, int64_t &NumDataVectors)
Returns the offset in parts to which this frame offset can be decomposed for the purpose of describin...
static bool hasUnscaledLdStOffset(unsigned Opc)
Return true if it has an unscaled load/store offset.
static const MachineOperand & getLdStBaseOp(const MachineInstr &MI)
Returns the base register operator of a load/store.
const AArch64RegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
static bool isPairedLdSt(const MachineInstr &MI)
Returns whether the instruction is a paired load/store.
@ DestructiveBinaryShImmUnpred
static unsigned convertToFlagSettingOpc(unsigned Opc, bool &Is64Bit)
Return the opcode that set flags when possible.
@ BR
Control flow instructions. These all have token chains.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
static bool getMemOpInfo(unsigned Opcode, TypeSize &Scale, unsigned &Width, int64_t &MinOffset, int64_t &MaxOffset)
Returns true if opcode Opc is a memory operation.
@ DestructiveInstTypeMask
static bool isLdStPairSuppressed(const MachineInstr &MI)
Return true if pairing the given load or store is hinted to be unprofitable.
static void decomposeStackOffsetForDwarfOffsets(const StackOffset &Offset, int64_t &ByteSized, int64_t &VGSized)
bool analyzeBranchPredicate(MachineBasicBlock &MBB, MachineBranchPredicate &MBP, bool AllowModify) const override
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DstReg, ArrayRef< MachineOperand > Cond, Register TrueReg, Register FalseReg) const override
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...
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
#define TSFLAG_FALSE_LANE_TYPE(X)
AArch64FrameOffsetStatus
Use to report the frame offset status in isAArch64FrameOffsetLegal.
virtual MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const
Target-dependent implementation for foldMemoryOperand.
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
static bool isQForm(const MachineInstr &MI)
Returns whether the instruction is in Q form (128 bit operands)
MachineInstrBuilder MachineInstrBuilder & DefMI
int getSVEPseudoMap(uint16_t Opcode)
bool isExtendLikelyToBeFolded(MachineInstr &ExtMI, MachineRegisterInfo &MRI) const override
static const MachineOperand & getLdStOffsetOp(const MachineInstr &MI)
Returns the the immediate offset operator of a load/store.
static bool hasUnscaledLdStOffset(MachineInstr &MI)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
@ DestructiveBinaryCommWithRev
static int getMemScale(unsigned Opc)
Scaling factor for (scaled or unscaled) load or store.
bool optimizeCondBranch(MachineInstr &MI) const override
Replace csincr-branch sequence by simple conditional branch.
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,...
static bool isFalkorShiftExtFast(const MachineInstr &MI)
Returns true if the instruction has a shift by immediate that can be executed in one cycle less.
static bool isPTrueOpcode(unsigned Opc)
bool isCandidateToMergeOrPair(const MachineInstr &MI) const
Return true if this is a load/store that can be potentially paired/merged.
MCCFIInstruction createCFAOffset(const TargetRegisterInfo &MRI, unsigned Reg, const StackOffset &OffsetFromDefCFA)
int getSVENonRevInstr(uint16_t Opcode)
static bool isPreSt(const MachineInstr &MI)
Returns whether the instruction is a pre-indexed store.
bool isAssociativeAndCommutative(const MachineInstr &Inst) const override
Return true when Inst is associative and commutative so that it can be reassociated.
bool isSubregFoldable() const override
bool isAsCheapAsAMove(const MachineInstr &MI) const override
static bool isSEHInstruction(const MachineInstr &MI)
Return true if the instructions is a SEH instruciton used for unwinding on Windows.
unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
Wrapper class representing physical registers. Should be passed by value.
MachineCombinerPattern
These are instruction patterns matched by the machine combiner pass.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override