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