MCInstrAnalysis.h 7.2 KB

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