LCOV - code coverage report
Current view: top level - lib/Target/AArch64 - AArch64InstrInfo.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 31 90 34.4 %
Date: 2017-09-14 15:23:50 Functions: 4 5 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : static const MachineMemOperand::Flags MOSuppressPair =
      31             :     MachineMemOperand::MOTargetFlag1;
      32             : static const MachineMemOperand::Flags MOStridedAccess =
      33             :     MachineMemOperand::MOTargetFlag2;
      34             : 
      35             : #define FALKOR_STRIDED_ACCESS_MD "falkor.strided.access"
      36             : 
      37        3588 : class AArch64InstrInfo final : public AArch64GenInstrInfo {
      38             :   const AArch64RegisterInfo RI;
      39             :   const AArch64Subtarget &Subtarget;
      40             : 
      41             : public:
      42             :   explicit AArch64InstrInfo(const AArch64Subtarget &STI);
      43             : 
      44             :   /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
      45             :   /// such, whenever a client has an instance of instruction info, it should
      46             :   /// always be able to get register info as well (through this method).
      47     2540948 :   const AArch64RegisterInfo &getRegisterInfo() const { return RI; }
      48             : 
      49             :   unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
      50             : 
      51             :   bool isAsCheapAsAMove(const MachineInstr &MI) const override;
      52             : 
      53             :   bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg,
      54             :                              unsigned &DstReg, unsigned &SubIdx) const override;
      55             : 
      56             :   bool
      57             :   areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
      58             :                                   AliasAnalysis *AA = nullptr) const override;
      59             : 
      60             :   unsigned isLoadFromStackSlot(const MachineInstr &MI,
      61             :                                int &FrameIndex) const override;
      62             :   unsigned isStoreToStackSlot(const MachineInstr &MI,
      63             :                               int &FrameIndex) const override;
      64             : 
      65             :   /// Returns true if there is a shiftable register and that the shift value
      66             :   /// is non-zero.
      67             :   bool hasShiftedReg(const MachineInstr &MI) const;
      68             : 
      69             :   /// Returns true if there is an extendable register and that the extending
      70             :   /// value is non-zero.
      71             :   bool hasExtendedReg(const MachineInstr &MI) const;
      72             : 
      73             :   /// \brief Does this instruction set its full destination register to zero?
      74             :   bool isGPRZero(const MachineInstr &MI) const;
      75             : 
      76             :   /// \brief Does this instruction rename a GPR without modifying bits?
      77             :   bool isGPRCopy(const MachineInstr &MI) const;
      78             : 
      79             :   /// \brief Does this instruction rename an FPR without modifying bits?
      80             :   bool isFPRCopy(const MachineInstr &MI) const;
      81             : 
      82             :   /// Return true if this is load/store scales or extends its register offset.
      83             :   /// This refers to scaling a dynamic index as opposed to scaled immediates.
      84             :   /// MI should be a memory op that allows scaled addressing.
      85             :   bool isScaledAddr(const MachineInstr &MI) const;
      86             : 
      87             :   /// Return true if pairing the given load or store is hinted to be
      88             :   /// unprofitable.
      89             :   bool isLdStPairSuppressed(const MachineInstr &MI) const;
      90             : 
      91             :   /// Return true if the given load or store is a strided memory access.
      92             :   bool isStridedAccess(const MachineInstr &MI) const;
      93             : 
      94             :   /// Return true if this is an unscaled load/store.
      95             :   bool isUnscaledLdSt(unsigned Opc) const;
      96             : 
      97             :   /// Return true if this is an unscaled load/store.
      98             :   bool isUnscaledLdSt(MachineInstr &MI) const;
      99             : 
     100       57725 :   static bool isPairableLdStInst(const MachineInstr &MI) {
     101      115450 :     switch (MI.getOpcode()) {
     102             :     default:
     103             :       return false;
     104             :     // Scaled instructions.
     105        8796 :     case AArch64::STRSui:
     106             :     case AArch64::STRDui:
     107             :     case AArch64::STRQui:
     108             :     case AArch64::STRXui:
     109             :     case AArch64::STRWui:
     110             :     case AArch64::LDRSui:
     111             :     case AArch64::LDRDui:
     112             :     case AArch64::LDRQui:
     113             :     case AArch64::LDRXui:
     114             :     case AArch64::LDRWui:
     115             :     case AArch64::LDRSWui:
     116             :     // Unscaled instructions.
     117             :     case AArch64::STURSi:
     118             :     case AArch64::STURDi:
     119             :     case AArch64::STURQi:
     120             :     case AArch64::STURWi:
     121             :     case AArch64::STURXi:
     122             :     case AArch64::LDURSi:
     123             :     case AArch64::LDURDi:
     124             :     case AArch64::LDURQi:
     125             :     case AArch64::LDURWi:
     126             :     case AArch64::LDURXi:
     127             :     case AArch64::LDURSWi:
     128        8796 :       return true;
     129             :     }
     130             :   }
     131             : 
     132             :   /// \brief Return the opcode that set flags when possible.  The caller is
     133             :   /// responsible for ensuring the opc has a flag setting equivalent.
     134          21 :   static unsigned convertToFlagSettingOpc(unsigned Opc, bool &Is64Bit) {
     135          21 :     switch (Opc) {
     136           0 :     default:
     137           0 :       llvm_unreachable("Opcode has no flag setting equivalent!");
     138             :     // 32-bit cases:
     139           3 :     case AArch64::ADDWri:
     140           3 :       Is64Bit = false;
     141           3 :       return AArch64::ADDSWri;
     142           4 :     case AArch64::ADDWrr:
     143           4 :       Is64Bit = false;
     144           4 :       return AArch64::ADDSWrr;
     145           0 :     case AArch64::ADDWrs:
     146           0 :       Is64Bit = false;
     147           0 :       return AArch64::ADDSWrs;
     148           0 :     case AArch64::ADDWrx:
     149           0 :       Is64Bit = false;
     150           0 :       return AArch64::ADDSWrx;
     151           3 :     case AArch64::ANDWri:
     152           3 :       Is64Bit = false;
     153           3 :       return AArch64::ANDSWri;
     154           0 :     case AArch64::ANDWrr:
     155           0 :       Is64Bit = false;
     156           0 :       return AArch64::ANDSWrr;
     157           0 :     case AArch64::ANDWrs:
     158           0 :       Is64Bit = false;
     159           0 :       return AArch64::ANDSWrs;
     160           1 :     case AArch64::BICWrr:
     161           1 :       Is64Bit = false;
     162           1 :       return AArch64::BICSWrr;
     163           0 :     case AArch64::BICWrs:
     164           0 :       Is64Bit = false;
     165           0 :       return AArch64::BICSWrs;
     166           0 :     case AArch64::SUBWri:
     167           0 :       Is64Bit = false;
     168           0 :       return AArch64::SUBSWri;
     169           0 :     case AArch64::SUBWrr:
     170           0 :       Is64Bit = false;
     171           0 :       return AArch64::SUBSWrr;
     172           0 :     case AArch64::SUBWrs:
     173           0 :       Is64Bit = false;
     174           0 :       return AArch64::SUBSWrs;
     175           0 :     case AArch64::SUBWrx:
     176           0 :       Is64Bit = false;
     177           0 :       return AArch64::SUBSWrx;
     178             :     // 64-bit cases:
     179           8 :     case AArch64::ADDXri:
     180           8 :       Is64Bit = true;
     181           8 :       return AArch64::ADDSXri;
     182           1 :     case AArch64::ADDXrr:
     183           1 :       Is64Bit = true;
     184           1 :       return AArch64::ADDSXrr;
     185           0 :     case AArch64::ADDXrs:
     186           0 :       Is64Bit = true;
     187           0 :       return AArch64::ADDSXrs;
     188           0 :     case AArch64::ADDXrx:
     189           0 :       Is64Bit = true;
     190           0 :       return AArch64::ADDSXrx;
     191           1 :     case AArch64::ANDXri:
     192           1 :       Is64Bit = true;
     193           1 :       return AArch64::ANDSXri;
     194           0 :     case AArch64::ANDXrr:
     195           0 :       Is64Bit = true;
     196           0 :       return AArch64::ANDSXrr;
     197           0 :     case AArch64::ANDXrs:
     198           0 :       Is64Bit = true;
     199           0 :       return AArch64::ANDSXrs;
     200           0 :     case AArch64::BICXrr:
     201           0 :       Is64Bit = true;
     202           0 :       return AArch64::BICSXrr;
     203           0 :     case AArch64::BICXrs:
     204           0 :       Is64Bit = true;
     205           0 :       return AArch64::BICSXrs;
     206           0 :     case AArch64::SUBXri:
     207           0 :       Is64Bit = true;
     208           0 :       return AArch64::SUBSXri;
     209           0 :     case AArch64::SUBXrr:
     210           0 :       Is64Bit = true;
     211           0 :       return AArch64::SUBSXrr;
     212           0 :     case AArch64::SUBXrs:
     213           0 :       Is64Bit = true;
     214           0 :       return AArch64::SUBSXrs;
     215           0 :     case AArch64::SUBXrx:
     216           0 :       Is64Bit = true;
     217           0 :       return AArch64::SUBSXrx;
     218             :     }
     219             :   }
     220             : 
     221             :   /// Return true if this is a load/store that can be potentially paired/merged.
     222             :   bool isCandidateToMergeOrPair(MachineInstr &MI) const;
     223             : 
     224             :   /// Hint that pairing the given load or store is unprofitable.
     225             :   void suppressLdStPair(MachineInstr &MI) const;
     226             : 
     227             :   bool getMemOpBaseRegImmOfs(MachineInstr &LdSt, unsigned &BaseReg,
     228             :                              int64_t &Offset,
     229             :                              const TargetRegisterInfo *TRI) const override;
     230             : 
     231             :   bool getMemOpBaseRegImmOfsWidth(MachineInstr &LdSt, unsigned &BaseReg,
     232             :                                   int64_t &Offset, unsigned &Width,
     233             :                                   const TargetRegisterInfo *TRI) const;
     234             : 
     235             :   /// Return the immediate offset of the base register in a load/store \p LdSt.
     236             :   MachineOperand &getMemOpBaseRegImmOfsOffsetOperand(MachineInstr &LdSt) const;
     237             : 
     238             :   /// \brief Returns true if opcode \p Opc is a memory operation. If it is, set
     239             :   /// \p Scale, \p Width, \p MinOffset, and \p MaxOffset accordingly.
     240             :   ///
     241             :   /// For unscaled instructions, \p Scale is set to 1.
     242             :   bool getMemOpInfo(unsigned Opcode, unsigned &Scale, unsigned &Width,
     243             :                     int64_t &MinOffset, int64_t &MaxOffset) const;
     244             : 
     245             :   bool shouldClusterMemOps(MachineInstr &FirstLdSt, MachineInstr &SecondLdSt,
     246             :                            unsigned NumLoads) const override;
     247             : 
     248             :   void copyPhysRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
     249             :                         const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
     250             :                         bool KillSrc, unsigned Opcode,
     251             :                         llvm::ArrayRef<unsigned> Indices) const;
     252             :   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
     253             :                    const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
     254             :                    bool KillSrc) const override;
     255             : 
     256             :   void storeRegToStackSlot(MachineBasicBlock &MBB,
     257             :                            MachineBasicBlock::iterator MBBI, unsigned SrcReg,
     258             :                            bool isKill, int FrameIndex,
     259             :                            const TargetRegisterClass *RC,
     260             :                            const TargetRegisterInfo *TRI) const override;
     261             : 
     262             :   void loadRegFromStackSlot(MachineBasicBlock &MBB,
     263             :                             MachineBasicBlock::iterator MBBI, unsigned DestReg,
     264             :                             int FrameIndex, const TargetRegisterClass *RC,
     265             :                             const TargetRegisterInfo *TRI) const override;
     266             : 
     267             :   // This tells target independent code that it is okay to pass instructions
     268             :   // with subreg operands to foldMemoryOperandImpl.
     269         770 :   bool isSubregFoldable() const override { return true; }
     270             : 
     271             :   using TargetInstrInfo::foldMemoryOperandImpl;
     272             :   MachineInstr *
     273             :   foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI,
     274             :                         ArrayRef<unsigned> Ops,
     275             :                         MachineBasicBlock::iterator InsertPt, int FrameIndex,
     276             :                         LiveIntervals *LIS = nullptr) const override;
     277             : 
     278             :   /// \returns true if a branch from an instruction with opcode \p BranchOpc
     279             :   ///  bytes is capable of jumping to a position \p BrOffset bytes away.
     280             :   bool isBranchOffsetInRange(unsigned BranchOpc,
     281             :                              int64_t BrOffset) const override;
     282             : 
     283             :   MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
     284             : 
     285             :   bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
     286             :                      MachineBasicBlock *&FBB,
     287             :                      SmallVectorImpl<MachineOperand> &Cond,
     288             :                      bool AllowModify = false) const override;
     289             :   unsigned removeBranch(MachineBasicBlock &MBB,
     290             :                         int *BytesRemoved = nullptr) const override;
     291             :   unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
     292             :                         MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
     293             :                         const DebugLoc &DL,
     294             :                         int *BytesAdded = nullptr) const override;
     295             :   bool
     296             :   reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
     297             :   bool canInsertSelect(const MachineBasicBlock &, ArrayRef<MachineOperand> Cond,
     298             :                        unsigned, unsigned, int &, int &, int &) const override;
     299             :   void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
     300             :                     const DebugLoc &DL, unsigned DstReg,
     301             :                     ArrayRef<MachineOperand> Cond, unsigned TrueReg,
     302             :                     unsigned FalseReg) const override;
     303             :   void getNoop(MCInst &NopInst) const override;
     304             : 
     305             :   /// analyzeCompare - For a comparison instruction, return the source registers
     306             :   /// in SrcReg and SrcReg2, and the value it compares against in CmpValue.
     307             :   /// Return true if the comparison instruction can be analyzed.
     308             :   bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
     309             :                       unsigned &SrcReg2, int &CmpMask,
     310             :                       int &CmpValue) const override;
     311             :   /// optimizeCompareInstr - Convert the instruction supplying the argument to
     312             :   /// the comparison into one that sets the zero bit in the flags register.
     313             :   bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
     314             :                             unsigned SrcReg2, int CmpMask, int CmpValue,
     315             :                             const MachineRegisterInfo *MRI) const override;
     316             :   bool optimizeCondBranch(MachineInstr &MI) const override;
     317             : 
     318             :   /// Return true when a code sequence can improve throughput. It
     319             :   /// should be called only for instructions in loops.
     320             :   /// \param Pattern - combiner pattern
     321             :   bool isThroughputPattern(MachineCombinerPattern Pattern) const override;
     322             :   /// Return true when there is potentially a faster code sequence
     323             :   /// for an instruction chain ending in ``Root``. All potential patterns are
     324             :   /// listed in the ``Patterns`` array.
     325             :   bool getMachineCombinerPatterns(
     326             :       MachineInstr &Root,
     327             :       SmallVectorImpl<MachineCombinerPattern> &Patterns) const override;
     328             :   /// Return true when Inst is associative and commutative so that it can be
     329             :   /// reassociated.
     330             :   bool isAssociativeAndCommutative(const MachineInstr &Inst) const override;
     331             :   /// When getMachineCombinerPatterns() finds patterns, this function generates
     332             :   /// the instructions that could replace the original code sequence
     333             :   void genAlternativeCodeSequence(
     334             :       MachineInstr &Root, MachineCombinerPattern Pattern,
     335             :       SmallVectorImpl<MachineInstr *> &InsInstrs,
     336             :       SmallVectorImpl<MachineInstr *> &DelInstrs,
     337             :       DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const override;
     338             :   /// AArch64 supports MachineCombiner.
     339             :   bool useMachineCombiner() const override;
     340             : 
     341             :   bool expandPostRAPseudo(MachineInstr &MI) const override;
     342             : 
     343             :   std::pair<unsigned, unsigned>
     344             :   decomposeMachineOperandsTargetFlags(unsigned TF) const override;
     345             :   ArrayRef<std::pair<unsigned, const char *>>
     346             :   getSerializableDirectMachineOperandTargetFlags() const override;
     347             :   ArrayRef<std::pair<unsigned, const char *>>
     348             :   getSerializableBitmaskMachineOperandTargetFlags() const override;
     349             :   ArrayRef<std::pair<MachineMemOperand::Flags, const char *>>
     350             :   getSerializableMachineMemOperandTargetFlags() const override;
     351             : 
     352             :   bool isFunctionSafeToOutlineFrom(MachineFunction &MF) const override;
     353             :   std::pair<size_t, unsigned>
     354             :   getOutliningCallOverhead(MachineBasicBlock::iterator &StartIt,
     355             :                            MachineBasicBlock::iterator &EndIt) const override;
     356             :   std::pair<size_t, unsigned> getOutliningFrameOverhead(
     357             :       std::vector<
     358             :           std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>>
     359             :           &CandidateClass) const override;
     360             :   AArch64GenInstrInfo::MachineOutlinerInstrType
     361             :   getOutliningType(MachineInstr &MI) const override;
     362             :   void insertOutlinerEpilogue(MachineBasicBlock &MBB, MachineFunction &MF,
     363             :                               unsigned FrameClass) const override;
     364             :   void insertOutlinerPrologue(MachineBasicBlock &MBB, MachineFunction &MF,
     365             :                               unsigned FrameClass) const override;
     366             :   MachineBasicBlock::iterator
     367             :   insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
     368             :                      MachineBasicBlock::iterator &It, MachineFunction &MF,
     369             :                      unsigned CallClass) const override;
     370             :   /// Returns true if the instruction has a shift left that can be executed
     371             :   /// more efficiently.
     372             :   bool isExynosShiftLeftFast(const MachineInstr &MI) const;
     373             :   /// Returns true if the instruction has a shift by immediate that can be
     374             :   /// executed in one cycle less.
     375             :   bool isFalkorShiftExtFast(const MachineInstr &MI) const;
     376             : 
     377             : private:
     378             :   /// \brief Sets the offsets on outlined instructions in \p MBB which use SP
     379             :   /// so that they will be valid post-outlining.
     380             :   ///
     381             :   /// \param MBB A \p MachineBasicBlock in an outlined function.
     382             :   void fixupPostOutline(MachineBasicBlock &MBB) const;
     383             : 
     384             :   void instantiateCondBranch(MachineBasicBlock &MBB, const DebugLoc &DL,
     385             :                              MachineBasicBlock *TBB,
     386             :                              ArrayRef<MachineOperand> Cond) const;
     387             :   bool substituteCmpToZero(MachineInstr &CmpInstr, unsigned SrcReg,
     388             :                            const MachineRegisterInfo *MRI) const;
     389             : };
     390             : 
     391             : /// emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg
     392             : /// plus Offset.  This is intended to be used from within the prolog/epilog
     393             : /// insertion (PEI) pass, where a virtual scratch register may be allocated
     394             : /// if necessary, to be replaced by the scavenger at the end of PEI.
     395             : void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
     396             :                      const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
     397             :                      int Offset, const TargetInstrInfo *TII,
     398             :                      MachineInstr::MIFlag = MachineInstr::NoFlags,
     399             :                      bool SetNZCV = false);
     400             : 
     401             : /// rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the
     402             : /// FP. Return false if the offset could not be handled directly in MI, and
     403             : /// return the left-over portion by reference.
     404             : bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
     405             :                               unsigned FrameReg, int &Offset,
     406             :                               const AArch64InstrInfo *TII);
     407             : 
     408             : /// \brief Use to report the frame offset status in isAArch64FrameOffsetLegal.
     409             : enum AArch64FrameOffsetStatus {
     410             :   AArch64FrameOffsetCannotUpdate = 0x0, ///< Offset cannot apply.
     411             :   AArch64FrameOffsetIsLegal = 0x1,      ///< Offset is legal.
     412             :   AArch64FrameOffsetCanUpdate = 0x2     ///< Offset can apply, at least partly.
     413             : };
     414             : 
     415             : /// \brief Check if the @p Offset is a valid frame offset for @p MI.
     416             : /// The returned value reports the validity of the frame offset for @p MI.
     417             : /// It uses the values defined by AArch64FrameOffsetStatus for that.
     418             : /// If result == AArch64FrameOffsetCannotUpdate, @p MI cannot be updated to
     419             : /// use an offset.eq
     420             : /// If result & AArch64FrameOffsetIsLegal, @p Offset can completely be
     421             : /// rewritten in @p MI.
     422             : /// If result & AArch64FrameOffsetCanUpdate, @p Offset contains the
     423             : /// amount that is off the limit of the legal offset.
     424             : /// If set, @p OutUseUnscaledOp will contain the whether @p MI should be
     425             : /// turned into an unscaled operator, which opcode is in @p OutUnscaledOp.
     426             : /// If set, @p EmittableOffset contains the amount that can be set in @p MI
     427             : /// (possibly with @p OutUnscaledOp if OutUseUnscaledOp is true) and that
     428             : /// is a legal offset.
     429             : int isAArch64FrameOffsetLegal(const MachineInstr &MI, int &Offset,
     430             :                               bool *OutUseUnscaledOp = nullptr,
     431             :                               unsigned *OutUnscaledOp = nullptr,
     432             :                               int *EmittableOffset = nullptr);
     433             : 
     434             : static inline bool isUncondBranchOpcode(int Opc) { return Opc == AArch64::B; }
     435             : 
     436             : static inline bool isCondBranchOpcode(int Opc) {
     437      279405 :   switch (Opc) {
     438             :   case AArch64::Bcc:
     439             :   case AArch64::CBZW:
     440             :   case AArch64::CBZX:
     441             :   case AArch64::CBNZW:
     442             :   case AArch64::CBNZX:
     443             :   case AArch64::TBZW:
     444             :   case AArch64::TBZX:
     445             :   case AArch64::TBNZW:
     446             :   case AArch64::TBNZX:
     447             :     return true;
     448             :   default:
     449             :     return false;
     450             :   }
     451             : }
     452             : 
     453             : static inline bool isIndirectBranchOpcode(int Opc) {
     454             :   return Opc == AArch64::BR;
     455             : }
     456             : 
     457             : } // end namespace llvm
     458             : 
     459             : #endif

Generated by: LCOV version 1.13