MCInstrAnalysis.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- llvm/MC/MCInstrAnalysis.h - InstrDesc target hooks -------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines the MCInstrAnalysis class which the MCTargetDescs can
  15. // derive from to give additional information to MC.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_MC_MCINSTRANALYSIS_H
  19. #define LLVM_MC_MCINSTRANALYSIS_H
  20. #include "llvm/MC/MCInst.h"
  21. #include "llvm/MC/MCInstrDesc.h"
  22. #include "llvm/MC/MCInstrInfo.h"
  23. #include <cstdint>
  24. namespace llvm {
  25. class MCRegisterInfo;
  26. class Triple;
  27. class MCInstrAnalysis {
  28. protected:
  29. friend class Target;
  30. const MCInstrInfo *Info;
  31. public:
  32. MCInstrAnalysis(const MCInstrInfo *Info) : Info(Info) {}
  33. virtual ~MCInstrAnalysis() = default;
  34. virtual bool isBranch(const MCInst &Inst) const {
  35. return Info->get(Inst.getOpcode()).isBranch();
  36. }
  37. virtual bool isConditionalBranch(const MCInst &Inst) const {
  38. return Info->get(Inst.getOpcode()).isConditionalBranch();
  39. }
  40. virtual bool isUnconditionalBranch(const MCInst &Inst) const {
  41. return Info->get(Inst.getOpcode()).isUnconditionalBranch();
  42. }
  43. virtual bool isIndirectBranch(const MCInst &Inst) const {
  44. return Info->get(Inst.getOpcode()).isIndirectBranch();
  45. }
  46. virtual bool isCall(const MCInst &Inst) const {
  47. return Info->get(Inst.getOpcode()).isCall();
  48. }
  49. virtual bool isReturn(const MCInst &Inst) const {
  50. return Info->get(Inst.getOpcode()).isReturn();
  51. }
  52. virtual bool isTerminator(const MCInst &Inst) const {
  53. return Info->get(Inst.getOpcode()).isTerminator();
  54. }
  55. /// Returns true if at least one of the register writes performed by
  56. /// \param Inst implicitly clears the upper portion of all super-registers.
  57. ///
  58. /// Example: on X86-64, a write to EAX implicitly clears the upper half of
  59. /// RAX. Also (still on x86) an XMM write perfomed by an AVX 128-bit
  60. /// instruction implicitly clears the upper portion of the correspondent
  61. /// YMM register.
  62. ///
  63. /// This method also updates an APInt which is used as mask of register
  64. /// writes. There is one bit for every explicit/implicit write performed by
  65. /// the instruction. If a write implicitly clears its super-registers, then
  66. /// the corresponding bit is set (vic. the corresponding bit is cleared).
  67. ///
  68. /// The first bits in the APint are related to explicit writes. The remaining
  69. /// bits are related to implicit writes. The sequence of writes follows the
  70. /// machine operand sequence. For implicit writes, the sequence is defined by
  71. /// the MCInstrDesc.
  72. ///
  73. /// The assumption is that the bit-width of the APInt is correctly set by
  74. /// the caller. The default implementation conservatively assumes that none of
  75. /// the writes clears the upper portion of a super-register.
  76. virtual bool clearsSuperRegisters(const MCRegisterInfo &MRI,
  77. const MCInst &Inst,
  78. APInt &Writes) const;
  79. /// Returns true if MI is a dependency breaking zero-idiom for the given
  80. /// subtarget.
  81. ///
  82. /// Mask is used to identify input operands that have their dependency
  83. /// broken. Each bit of the mask is associated with a specific input operand.
  84. /// Bits associated with explicit input operands are laid out first in the
  85. /// mask; implicit operands come after explicit operands.
  86. ///
  87. /// Dependencies are broken only for operands that have their corresponding bit
  88. /// set. Operands that have their bit cleared, or that don't have a
  89. /// corresponding bit in the mask don't have their dependency broken. Note
  90. /// that Mask may not be big enough to describe all operands. The assumption
  91. /// for operands that don't have a correspondent bit in the mask is that those
  92. /// are still data dependent.
  93. ///
  94. /// The only exception to the rule is for when Mask has all zeroes.
  95. /// A zero mask means: dependencies are broken for all explicit register
  96. /// operands.
  97. virtual bool isZeroIdiom(const MCInst &MI, APInt &Mask,
  98. unsigned CPUID) const {
  99. return false;
  100. }
  101. /// Returns true if MI is a dependency breaking instruction for the
  102. /// subtarget associated with CPUID .
  103. ///
  104. /// The value computed by a dependency breaking instruction is not dependent
  105. /// on the inputs. An example of dependency breaking instruction on X86 is
  106. /// `XOR %eax, %eax`.
  107. ///
  108. /// If MI is a dependency breaking instruction for subtarget CPUID, then Mask
  109. /// can be inspected to identify independent operands.
  110. ///
  111. /// Essentially, each bit of the mask corresponds to an input operand.
  112. /// Explicit operands are laid out first in the mask; implicit operands follow
  113. /// explicit operands. Bits are set for operands that are independent.
  114. ///
  115. /// Note that the number of bits in Mask may not be equivalent to the sum of
  116. /// explicit and implicit operands in MI. Operands that don't have a
  117. /// corresponding bit in Mask are assumed "not independente".
  118. ///
  119. /// The only exception is for when Mask is all zeroes. That means: explicit
  120. /// input operands of MI are independent.
  121. virtual bool isDependencyBreaking(const MCInst &MI, APInt &Mask,
  122. unsigned CPUID) const {
  123. return isZeroIdiom(MI, Mask, CPUID);
  124. }
  125. /// Returns true if MI is a candidate for move elimination.
  126. ///
  127. /// Different subtargets may apply different constraints to optimizable
  128. /// register moves. For example, on most X86 subtargets, a candidate for move
  129. /// elimination cannot specify the same register for both source and
  130. /// destination.
  131. virtual bool isOptimizableRegisterMove(const MCInst &MI,
  132. unsigned CPUID) const {
  133. return false;
  134. }
  135. /// Given a branch instruction try to get the address the branch
  136. /// targets. Return true on success, and the address in Target.
  137. virtual bool
  138. evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
  139. uint64_t &Target) const;
  140. /// Given an instruction tries to get the address of a memory operand. Returns
  141. /// the address on success.
  142. virtual Optional<uint64_t>
  143. evaluateMemoryOperandAddress(const MCInst &Inst, const MCSubtargetInfo *STI,
  144. uint64_t Addr, uint64_t Size) const;
  145. /// Given an instruction with a memory operand that could require relocation,
  146. /// returns the offset within the instruction of that relocation.
  147. virtual Optional<uint64_t>
  148. getMemoryOperandRelocationOffset(const MCInst &Inst, uint64_t Size) const;
  149. /// Returns (PLT virtual address, GOT virtual address) pairs for PLT entries.
  150. virtual std::vector<std::pair<uint64_t, uint64_t>>
  151. findPltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents,
  152. uint64_t GotPltSectionVA, const Triple &TargetTriple) const {
  153. return {};
  154. }
  155. };
  156. } // end namespace llvm
  157. #endif // LLVM_MC_MCINSTRANALYSIS_H
  158. #ifdef __GNUC__
  159. #pragma GCC diagnostic pop
  160. #endif