AArch64InstrInfo.h revision cd81d94322a39503e4a3e87b6ee03d4fcb3465fb
1//===- AArch64InstrInfo.h - AArch64 Instruction Information -----*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the AArch64 implementation of the TargetInstrInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_TARGET_AArch64INSTRINFO_H 15#define LLVM_TARGET_AArch64INSTRINFO_H 16 17#include "AArch64.h" 18#include "AArch64RegisterInfo.h" 19#include "llvm/Target/TargetInstrInfo.h" 20 21#define GET_INSTRINFO_HEADER 22#include "AArch64GenInstrInfo.inc" 23 24namespace llvm { 25 26class AArch64Subtarget; 27class AArch64TargetMachine; 28 29class AArch64InstrInfo : public AArch64GenInstrInfo { 30 // Reserve bits in the MachineMemOperand target hint flags, starting at 1. 31 // They will be shifted into MOTargetHintStart when accessed. 32 enum TargetMemOperandFlags { 33 MOSuppressPair = 1 34 }; 35 36 const AArch64RegisterInfo RI; 37 const AArch64Subtarget &Subtarget; 38 39public: 40 explicit AArch64InstrInfo(const AArch64Subtarget &STI); 41 42 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As 43 /// such, whenever a client has an instance of instruction info, it should 44 /// always be able to get register info as well (through this method). 45 const AArch64RegisterInfo &getRegisterInfo() const { return RI; } 46 47 unsigned GetInstSizeInBytes(const MachineInstr *MI) const; 48 49 bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg, 50 unsigned &DstReg, unsigned &SubIdx) const override; 51 52 unsigned isLoadFromStackSlot(const MachineInstr *MI, 53 int &FrameIndex) const override; 54 unsigned isStoreToStackSlot(const MachineInstr *MI, 55 int &FrameIndex) const override; 56 57 /// Returns true if there is a shiftable register and that the shift value 58 /// is non-zero. 59 bool hasShiftedReg(const MachineInstr *MI) const; 60 61 /// Returns true if there is an extendable register and that the extending 62 /// value is non-zero. 63 bool hasExtendedReg(const MachineInstr *MI) const; 64 65 /// \brief Does this instruction set its full destination register to zero? 66 bool isGPRZero(const MachineInstr *MI) const; 67 68 /// \brief Does this instruction rename a GPR without modifying bits? 69 bool isGPRCopy(const MachineInstr *MI) const; 70 71 /// \brief Does this instruction rename an FPR without modifying bits? 72 bool isFPRCopy(const MachineInstr *MI) const; 73 74 /// Return true if this is load/store scales or extends its register offset. 75 /// This refers to scaling a dynamic index as opposed to scaled immediates. 76 /// MI should be a memory op that allows scaled addressing. 77 bool isScaledAddr(const MachineInstr *MI) const; 78 79 /// Return true if pairing the given load or store is hinted to be 80 /// unprofitable. 81 bool isLdStPairSuppressed(const MachineInstr *MI) const; 82 83 /// Hint that pairing the given load or store is unprofitable. 84 void suppressLdStPair(MachineInstr *MI) const; 85 86 bool getLdStBaseRegImmOfs(MachineInstr *LdSt, unsigned &BaseReg, 87 unsigned &Offset, 88 const TargetRegisterInfo *TRI) const override; 89 90 bool enableClusterLoads() const override { return true; } 91 92 bool shouldClusterLoads(MachineInstr *FirstLdSt, MachineInstr *SecondLdSt, 93 unsigned NumLoads) const override; 94 95 bool shouldScheduleAdjacent(MachineInstr *First, 96 MachineInstr *Second) const override; 97 98 MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, 99 uint64_t Offset, const MDNode *MDPtr, 100 DebugLoc DL) const; 101 void copyPhysRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 102 DebugLoc DL, unsigned DestReg, unsigned SrcReg, 103 bool KillSrc, unsigned Opcode, 104 llvm::ArrayRef<unsigned> Indices) const; 105 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 106 DebugLoc DL, unsigned DestReg, unsigned SrcReg, 107 bool KillSrc) const override; 108 109 void storeRegToStackSlot(MachineBasicBlock &MBB, 110 MachineBasicBlock::iterator MBBI, unsigned SrcReg, 111 bool isKill, int FrameIndex, 112 const TargetRegisterClass *RC, 113 const TargetRegisterInfo *TRI) const override; 114 115 void loadRegFromStackSlot(MachineBasicBlock &MBB, 116 MachineBasicBlock::iterator MBBI, unsigned DestReg, 117 int FrameIndex, const TargetRegisterClass *RC, 118 const TargetRegisterInfo *TRI) const override; 119 120 MachineInstr * 121 foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, 122 const SmallVectorImpl<unsigned> &Ops, 123 int FrameIndex) const override; 124 125 bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 126 MachineBasicBlock *&FBB, 127 SmallVectorImpl<MachineOperand> &Cond, 128 bool AllowModify = false) const override; 129 unsigned RemoveBranch(MachineBasicBlock &MBB) const override; 130 unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 131 MachineBasicBlock *FBB, 132 const SmallVectorImpl<MachineOperand> &Cond, 133 DebugLoc DL) const override; 134 bool 135 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; 136 bool canInsertSelect(const MachineBasicBlock &, 137 const SmallVectorImpl<MachineOperand> &Cond, unsigned, 138 unsigned, int &, int &, int &) const override; 139 void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 140 DebugLoc DL, unsigned DstReg, 141 const SmallVectorImpl<MachineOperand> &Cond, 142 unsigned TrueReg, unsigned FalseReg) const override; 143 void getNoopForMachoTarget(MCInst &NopInst) const override; 144 145 /// analyzeCompare - For a comparison instruction, return the source registers 146 /// in SrcReg and SrcReg2, and the value it compares against in CmpValue. 147 /// Return true if the comparison instruction can be analyzed. 148 bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg, 149 unsigned &SrcReg2, int &CmpMask, 150 int &CmpValue) const override; 151 /// optimizeCompareInstr - Convert the instruction supplying the argument to 152 /// the comparison into one that sets the zero bit in the flags register. 153 bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, 154 unsigned SrcReg2, int CmpMask, int CmpValue, 155 const MachineRegisterInfo *MRI) const override; 156 157private: 158 void instantiateCondBranch(MachineBasicBlock &MBB, DebugLoc DL, 159 MachineBasicBlock *TBB, 160 const SmallVectorImpl<MachineOperand> &Cond) const; 161}; 162 163/// emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg 164/// plus Offset. This is intended to be used from within the prolog/epilog 165/// insertion (PEI) pass, where a virtual scratch register may be allocated 166/// if necessary, to be replaced by the scavenger at the end of PEI. 167void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 168 DebugLoc DL, unsigned DestReg, unsigned SrcReg, int Offset, 169 const TargetInstrInfo *TII, 170 MachineInstr::MIFlag = MachineInstr::NoFlags, 171 bool SetNZCV = false); 172 173/// rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the 174/// FP. Return false if the offset could not be handled directly in MI, and 175/// return the left-over portion by reference. 176bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 177 unsigned FrameReg, int &Offset, 178 const AArch64InstrInfo *TII); 179 180/// \brief Use to report the frame offset status in isAArch64FrameOffsetLegal. 181enum AArch64FrameOffsetStatus { 182 AArch64FrameOffsetCannotUpdate = 0x0, ///< Offset cannot apply. 183 AArch64FrameOffsetIsLegal = 0x1, ///< Offset is legal. 184 AArch64FrameOffsetCanUpdate = 0x2 ///< Offset can apply, at least partly. 185}; 186 187/// \brief Check if the @p Offset is a valid frame offset for @p MI. 188/// The returned value reports the validity of the frame offset for @p MI. 189/// It uses the values defined by AArch64FrameOffsetStatus for that. 190/// If result == AArch64FrameOffsetCannotUpdate, @p MI cannot be updated to 191/// use an offset.eq 192/// If result & AArch64FrameOffsetIsLegal, @p Offset can completely be 193/// rewriten in @p MI. 194/// If result & AArch64FrameOffsetCanUpdate, @p Offset contains the 195/// amount that is off the limit of the legal offset. 196/// If set, @p OutUseUnscaledOp will contain the whether @p MI should be 197/// turned into an unscaled operator, which opcode is in @p OutUnscaledOp. 198/// If set, @p EmittableOffset contains the amount that can be set in @p MI 199/// (possibly with @p OutUnscaledOp if OutUseUnscaledOp is true) and that 200/// is a legal offset. 201int isAArch64FrameOffsetLegal(const MachineInstr &MI, int &Offset, 202 bool *OutUseUnscaledOp = nullptr, 203 unsigned *OutUnscaledOp = nullptr, 204 int *EmittableOffset = nullptr); 205 206static inline bool isUncondBranchOpcode(int Opc) { return Opc == AArch64::B; } 207 208static inline bool isCondBranchOpcode(int Opc) { 209 switch (Opc) { 210 case AArch64::Bcc: 211 case AArch64::CBZW: 212 case AArch64::CBZX: 213 case AArch64::CBNZW: 214 case AArch64::CBNZX: 215 case AArch64::TBZW: 216 case AArch64::TBZX: 217 case AArch64::TBNZW: 218 case AArch64::TBNZX: 219 return true; 220 default: 221 return false; 222 } 223} 224 225static inline bool isIndirectBranchOpcode(int Opc) { return Opc == AArch64::BR; } 226 227} // end namespace llvm 228 229#endif 230