LLVM API Documentation

AArch64InstrInfo.h
Go to the documentation of this file.
00001 //===- AArch64InstrInfo.h - AArch64 Instruction Information -----*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the AArch64 implementation of the TargetInstrInfo class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64INSTRINFO_H
00015 #define LLVM_LIB_TARGET_AARCH64_AARCH64INSTRINFO_H
00016 
00017 #include "AArch64.h"
00018 #include "AArch64RegisterInfo.h"
00019 #include "llvm/Target/TargetInstrInfo.h"
00020 #include "llvm/CodeGen/MachineCombinerPattern.h"
00021 
00022 #define GET_INSTRINFO_HEADER
00023 #include "AArch64GenInstrInfo.inc"
00024 
00025 namespace llvm {
00026 
00027 class AArch64Subtarget;
00028 class AArch64TargetMachine;
00029 
00030 class AArch64InstrInfo : public AArch64GenInstrInfo {
00031   // Reserve bits in the MachineMemOperand target hint flags, starting at 1.
00032   // They will be shifted into MOTargetHintStart when accessed.
00033   enum TargetMemOperandFlags {
00034     MOSuppressPair = 1
00035   };
00036 
00037   const AArch64RegisterInfo RI;
00038   const AArch64Subtarget &Subtarget;
00039 
00040 public:
00041   explicit AArch64InstrInfo(const AArch64Subtarget &STI);
00042 
00043   /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
00044   /// such, whenever a client has an instance of instruction info, it should
00045   /// always be able to get register info as well (through this method).
00046   const AArch64RegisterInfo &getRegisterInfo() const { return RI; }
00047 
00048   unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
00049 
00050   bool isAsCheapAsAMove(const MachineInstr *MI) const override;
00051 
00052   bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg,
00053                              unsigned &DstReg, unsigned &SubIdx) const override;
00054 
00055   bool
00056   areMemAccessesTriviallyDisjoint(MachineInstr *MIa, MachineInstr *MIb,
00057                                   AliasAnalysis *AA = nullptr) const override;
00058 
00059   unsigned isLoadFromStackSlot(const MachineInstr *MI,
00060                                int &FrameIndex) const override;
00061   unsigned isStoreToStackSlot(const MachineInstr *MI,
00062                               int &FrameIndex) const override;
00063 
00064   /// Returns true if there is a shiftable register and that the shift value
00065   /// is non-zero.
00066   bool hasShiftedReg(const MachineInstr *MI) const;
00067 
00068   /// Returns true if there is an extendable register and that the extending
00069   /// value is non-zero.
00070   bool hasExtendedReg(const MachineInstr *MI) const;
00071 
00072   /// \brief Does this instruction set its full destination register to zero?
00073   bool isGPRZero(const MachineInstr *MI) const;
00074 
00075   /// \brief Does this instruction rename a GPR without modifying bits?
00076   bool isGPRCopy(const MachineInstr *MI) const;
00077 
00078   /// \brief Does this instruction rename an FPR without modifying bits?
00079   bool isFPRCopy(const MachineInstr *MI) const;
00080 
00081   /// Return true if this is load/store scales or extends its register offset.
00082   /// This refers to scaling a dynamic index as opposed to scaled immediates.
00083   /// MI should be a memory op that allows scaled addressing.
00084   bool isScaledAddr(const MachineInstr *MI) const;
00085 
00086   /// Return true if pairing the given load or store is hinted to be
00087   /// unprofitable.
00088   bool isLdStPairSuppressed(const MachineInstr *MI) const;
00089 
00090   /// Hint that pairing the given load or store is unprofitable.
00091   void suppressLdStPair(MachineInstr *MI) const;
00092 
00093   bool getLdStBaseRegImmOfs(MachineInstr *LdSt, unsigned &BaseReg,
00094                             unsigned &Offset,
00095                             const TargetRegisterInfo *TRI) const override;
00096 
00097   bool getLdStBaseRegImmOfsWidth(MachineInstr *LdSt, unsigned &BaseReg,
00098                                  int &Offset, int &Width,
00099                                  const TargetRegisterInfo *TRI) const;
00100 
00101   bool enableClusterLoads() const override { return true; }
00102 
00103   bool shouldClusterLoads(MachineInstr *FirstLdSt, MachineInstr *SecondLdSt,
00104                           unsigned NumLoads) const override;
00105 
00106   bool shouldScheduleAdjacent(MachineInstr *First,
00107                               MachineInstr *Second) const override;
00108 
00109   MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx,
00110                                          uint64_t Offset, const MDNode *MDPtr,
00111                                          DebugLoc DL) const;
00112   void copyPhysRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
00113                         DebugLoc DL, unsigned DestReg, unsigned SrcReg,
00114                         bool KillSrc, unsigned Opcode,
00115                         llvm::ArrayRef<unsigned> Indices) const;
00116   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
00117                    DebugLoc DL, unsigned DestReg, unsigned SrcReg,
00118                    bool KillSrc) const override;
00119 
00120   void storeRegToStackSlot(MachineBasicBlock &MBB,
00121                            MachineBasicBlock::iterator MBBI, unsigned SrcReg,
00122                            bool isKill, int FrameIndex,
00123                            const TargetRegisterClass *RC,
00124                            const TargetRegisterInfo *TRI) const override;
00125 
00126   void loadRegFromStackSlot(MachineBasicBlock &MBB,
00127                             MachineBasicBlock::iterator MBBI, unsigned DestReg,
00128                             int FrameIndex, const TargetRegisterClass *RC,
00129                             const TargetRegisterInfo *TRI) const override;
00130 
00131   using TargetInstrInfo::foldMemoryOperandImpl;
00132   MachineInstr *
00133   foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
00134                         const SmallVectorImpl<unsigned> &Ops,
00135                         int FrameIndex) const override;
00136 
00137   bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
00138                      MachineBasicBlock *&FBB,
00139                      SmallVectorImpl<MachineOperand> &Cond,
00140                      bool AllowModify = false) const override;
00141   unsigned RemoveBranch(MachineBasicBlock &MBB) const override;
00142   unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
00143                         MachineBasicBlock *FBB,
00144                         const SmallVectorImpl<MachineOperand> &Cond,
00145                         DebugLoc DL) const override;
00146   bool
00147   ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
00148   bool canInsertSelect(const MachineBasicBlock &,
00149                        const SmallVectorImpl<MachineOperand> &Cond, unsigned,
00150                        unsigned, int &, int &, int &) const override;
00151   void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
00152                     DebugLoc DL, unsigned DstReg,
00153                     const SmallVectorImpl<MachineOperand> &Cond,
00154                     unsigned TrueReg, unsigned FalseReg) const override;
00155   void getNoopForMachoTarget(MCInst &NopInst) const override;
00156 
00157   /// analyzeCompare - For a comparison instruction, return the source registers
00158   /// in SrcReg and SrcReg2, and the value it compares against in CmpValue.
00159   /// Return true if the comparison instruction can be analyzed.
00160   bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
00161                       unsigned &SrcReg2, int &CmpMask,
00162                       int &CmpValue) const override;
00163   /// optimizeCompareInstr - Convert the instruction supplying the argument to
00164   /// the comparison into one that sets the zero bit in the flags register.
00165   bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg,
00166                             unsigned SrcReg2, int CmpMask, int CmpValue,
00167                             const MachineRegisterInfo *MRI) const override;
00168   /// hasPattern - return true when there is potentially a faster code sequence
00169   /// for an instruction chain ending in <Root>. All potential patterns are
00170   /// listed
00171   /// in the <Pattern> array.
00172   bool hasPattern(MachineInstr &Root,
00173                   SmallVectorImpl<MachineCombinerPattern::MC_PATTERN> &Pattern)
00174       const override;
00175 
00176   /// genAlternativeCodeSequence - when hasPattern() finds a pattern
00177   /// this function generates the instructions that could replace the
00178   /// original code sequence
00179   void genAlternativeCodeSequence(
00180       MachineInstr &Root, MachineCombinerPattern::MC_PATTERN P,
00181       SmallVectorImpl<MachineInstr *> &InsInstrs,
00182       SmallVectorImpl<MachineInstr *> &DelInstrs,
00183       DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const override;
00184   /// useMachineCombiner - AArch64 supports MachineCombiner
00185   bool useMachineCombiner() const override;
00186 
00187   bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override;
00188 private:
00189   void instantiateCondBranch(MachineBasicBlock &MBB, DebugLoc DL,
00190                              MachineBasicBlock *TBB,
00191                              const SmallVectorImpl<MachineOperand> &Cond) const;
00192 };
00193 
00194 /// emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg
00195 /// plus Offset.  This is intended to be used from within the prolog/epilog
00196 /// insertion (PEI) pass, where a virtual scratch register may be allocated
00197 /// if necessary, to be replaced by the scavenger at the end of PEI.
00198 void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
00199                      DebugLoc DL, unsigned DestReg, unsigned SrcReg, int Offset,
00200                      const TargetInstrInfo *TII,
00201                      MachineInstr::MIFlag = MachineInstr::NoFlags,
00202                      bool SetNZCV = false);
00203 
00204 /// rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the
00205 /// FP. Return false if the offset could not be handled directly in MI, and
00206 /// return the left-over portion by reference.
00207 bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
00208                             unsigned FrameReg, int &Offset,
00209                             const AArch64InstrInfo *TII);
00210 
00211 /// \brief Use to report the frame offset status in isAArch64FrameOffsetLegal.
00212 enum AArch64FrameOffsetStatus {
00213   AArch64FrameOffsetCannotUpdate = 0x0, ///< Offset cannot apply.
00214   AArch64FrameOffsetIsLegal = 0x1,      ///< Offset is legal.
00215   AArch64FrameOffsetCanUpdate = 0x2     ///< Offset can apply, at least partly.
00216 };
00217 
00218 /// \brief Check if the @p Offset is a valid frame offset for @p MI.
00219 /// The returned value reports the validity of the frame offset for @p MI.
00220 /// It uses the values defined by AArch64FrameOffsetStatus for that.
00221 /// If result == AArch64FrameOffsetCannotUpdate, @p MI cannot be updated to
00222 /// use an offset.eq
00223 /// If result & AArch64FrameOffsetIsLegal, @p Offset can completely be
00224 /// rewriten in @p MI.
00225 /// If result & AArch64FrameOffsetCanUpdate, @p Offset contains the
00226 /// amount that is off the limit of the legal offset.
00227 /// If set, @p OutUseUnscaledOp will contain the whether @p MI should be
00228 /// turned into an unscaled operator, which opcode is in @p OutUnscaledOp.
00229 /// If set, @p EmittableOffset contains the amount that can be set in @p MI
00230 /// (possibly with @p OutUnscaledOp if OutUseUnscaledOp is true) and that
00231 /// is a legal offset.
00232 int isAArch64FrameOffsetLegal(const MachineInstr &MI, int &Offset,
00233                             bool *OutUseUnscaledOp = nullptr,
00234                             unsigned *OutUnscaledOp = nullptr,
00235                             int *EmittableOffset = nullptr);
00236 
00237 static inline bool isUncondBranchOpcode(int Opc) { return Opc == AArch64::B; }
00238 
00239 static inline bool isCondBranchOpcode(int Opc) {
00240   switch (Opc) {
00241   case AArch64::Bcc:
00242   case AArch64::CBZW:
00243   case AArch64::CBZX:
00244   case AArch64::CBNZW:
00245   case AArch64::CBNZX:
00246   case AArch64::TBZW:
00247   case AArch64::TBZX:
00248   case AArch64::TBNZW:
00249   case AArch64::TBNZX:
00250     return true;
00251   default:
00252     return false;
00253   }
00254 }
00255 
00256 static inline bool isIndirectBranchOpcode(int Opc) { return Opc == AArch64::BR; }
00257 
00258 } // end namespace llvm
00259 
00260 #endif