MachineOutliner.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===---- MachineOutliner.h - Outliner data structures ------*- 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. /// \file
  15. /// Contains all data structures shared between the outliner implemented in
  16. /// MachineOutliner.cpp and target implementations of the outliner.
  17. ///
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_CODEGEN_MACHINEOUTLINER_H
  20. #define LLVM_CODEGEN_MACHINEOUTLINER_H
  21. #include "llvm/CodeGen/LivePhysRegs.h"
  22. #include "llvm/CodeGen/LiveRegUnits.h"
  23. #include "llvm/CodeGen/MachineFunction.h"
  24. #include "llvm/CodeGen/MachineRegisterInfo.h"
  25. #include "llvm/CodeGen/TargetRegisterInfo.h"
  26. namespace llvm {
  27. namespace outliner {
  28. /// Represents how an instruction should be mapped by the outliner.
  29. /// \p Legal instructions are those which are safe to outline.
  30. /// \p LegalTerminator instructions are safe to outline, but only as the
  31. /// last instruction in a sequence.
  32. /// \p Illegal instructions are those which cannot be outlined.
  33. /// \p Invisible instructions are instructions which can be outlined, but
  34. /// shouldn't actually impact the outlining result.
  35. enum InstrType { Legal, LegalTerminator, Illegal, Invisible };
  36. /// An individual sequence of instructions to be replaced with a call to
  37. /// an outlined function.
  38. struct Candidate {
  39. private:
  40. /// The start index of this \p Candidate in the instruction list.
  41. unsigned StartIdx = 0;
  42. /// The number of instructions in this \p Candidate.
  43. unsigned Len = 0;
  44. // The first instruction in this \p Candidate.
  45. MachineBasicBlock::iterator FirstInst;
  46. // The last instruction in this \p Candidate.
  47. MachineBasicBlock::iterator LastInst;
  48. // The basic block that contains this Candidate.
  49. MachineBasicBlock *MBB = nullptr;
  50. /// Cost of calling an outlined function from this point as defined by the
  51. /// target.
  52. unsigned CallOverhead = 0;
  53. public:
  54. /// The index of this \p Candidate's \p OutlinedFunction in the list of
  55. /// \p OutlinedFunctions.
  56. unsigned FunctionIdx = 0;
  57. /// Identifier denoting the instructions to emit to call an outlined function
  58. /// from this point. Defined by the target.
  59. unsigned CallConstructionID = 0;
  60. /// Contains physical register liveness information for the MBB containing
  61. /// this \p Candidate.
  62. ///
  63. /// This is optionally used by the target to calculate more fine-grained
  64. /// cost model information.
  65. LiveRegUnits LRU;
  66. /// Contains the accumulated register liveness information for the
  67. /// instructions in this \p Candidate.
  68. ///
  69. /// This is optionally used by the target to determine which registers have
  70. /// been used across the sequence.
  71. LiveRegUnits UsedInSequence;
  72. /// Target-specific flags for this Candidate's MBB.
  73. unsigned Flags = 0x0;
  74. /// True if initLRU has been called on this Candidate.
  75. bool LRUWasSet = false;
  76. /// Return the number of instructions in this Candidate.
  77. unsigned getLength() const { return Len; }
  78. /// Return the start index of this candidate.
  79. unsigned getStartIdx() const { return StartIdx; }
  80. /// Return the end index of this candidate.
  81. unsigned getEndIdx() const { return StartIdx + Len - 1; }
  82. /// Set the CallConstructionID and CallOverhead of this candidate to CID and
  83. /// CO respectively.
  84. void setCallInfo(unsigned CID, unsigned CO) {
  85. CallConstructionID = CID;
  86. CallOverhead = CO;
  87. }
  88. /// Returns the call overhead of this candidate if it is in the list.
  89. unsigned getCallOverhead() const { return CallOverhead; }
  90. MachineBasicBlock::iterator &front() { return FirstInst; }
  91. MachineBasicBlock::iterator &back() { return LastInst; }
  92. MachineFunction *getMF() const { return MBB->getParent(); }
  93. MachineBasicBlock *getMBB() const { return MBB; }
  94. /// The number of instructions that would be saved by outlining every
  95. /// candidate of this type.
  96. ///
  97. /// This is a fixed value which is not updated during the candidate pruning
  98. /// process. It is only used for deciding which candidate to keep if two
  99. /// candidates overlap. The true benefit is stored in the OutlinedFunction
  100. /// for some given candidate.
  101. unsigned Benefit = 0;
  102. Candidate(unsigned StartIdx, unsigned Len,
  103. MachineBasicBlock::iterator &FirstInst,
  104. MachineBasicBlock::iterator &LastInst, MachineBasicBlock *MBB,
  105. unsigned FunctionIdx, unsigned Flags)
  106. : StartIdx(StartIdx), Len(Len), FirstInst(FirstInst), LastInst(LastInst),
  107. MBB(MBB), FunctionIdx(FunctionIdx), Flags(Flags) {}
  108. Candidate() = default;
  109. /// Used to ensure that \p Candidates are outlined in an order that
  110. /// preserves the start and end indices of other \p Candidates.
  111. bool operator<(const Candidate &RHS) const {
  112. return getStartIdx() > RHS.getStartIdx();
  113. }
  114. /// Compute the registers that are live across this Candidate.
  115. /// Used by targets that need this information for cost model calculation.
  116. /// If a target does not need this information, then this should not be
  117. /// called.
  118. void initLRU(const TargetRegisterInfo &TRI) {
  119. assert(MBB->getParent()->getRegInfo().tracksLiveness() &&
  120. "Candidate's Machine Function must track liveness");
  121. // Only initialize once.
  122. if (LRUWasSet)
  123. return;
  124. LRUWasSet = true;
  125. LRU.init(TRI);
  126. LRU.addLiveOuts(*MBB);
  127. // Compute liveness from the end of the block up to the beginning of the
  128. // outlining candidate.
  129. std::for_each(MBB->rbegin(), (MachineBasicBlock::reverse_iterator)front(),
  130. [this](MachineInstr &MI) { LRU.stepBackward(MI); });
  131. // Walk over the sequence itself and figure out which registers were used
  132. // in the sequence.
  133. UsedInSequence.init(TRI);
  134. std::for_each(front(), std::next(back()),
  135. [this](MachineInstr &MI) { UsedInSequence.accumulate(MI); });
  136. }
  137. };
  138. /// The information necessary to create an outlined function for some
  139. /// class of candidate.
  140. struct OutlinedFunction {
  141. public:
  142. std::vector<Candidate> Candidates;
  143. /// The actual outlined function created.
  144. /// This is initialized after we go through and create the actual function.
  145. MachineFunction *MF = nullptr;
  146. /// Represents the size of a sequence in bytes. (Some instructions vary
  147. /// widely in size, so just counting the instructions isn't very useful.)
  148. unsigned SequenceSize = 0;
  149. /// Target-defined overhead of constructing a frame for this function.
  150. unsigned FrameOverhead = 0;
  151. /// Target-defined identifier for constructing a frame for this function.
  152. unsigned FrameConstructionID = 0;
  153. /// Return the number of candidates for this \p OutlinedFunction.
  154. unsigned getOccurrenceCount() const { return Candidates.size(); }
  155. /// Return the number of bytes it would take to outline this
  156. /// function.
  157. unsigned getOutliningCost() const {
  158. unsigned CallOverhead = 0;
  159. for (const Candidate &C : Candidates)
  160. CallOverhead += C.getCallOverhead();
  161. return CallOverhead + SequenceSize + FrameOverhead;
  162. }
  163. /// Return the size in bytes of the unoutlined sequences.
  164. unsigned getNotOutlinedCost() const {
  165. return getOccurrenceCount() * SequenceSize;
  166. }
  167. /// Return the number of instructions that would be saved by outlining
  168. /// this function.
  169. unsigned getBenefit() const {
  170. unsigned NotOutlinedCost = getNotOutlinedCost();
  171. unsigned OutlinedCost = getOutliningCost();
  172. return (NotOutlinedCost < OutlinedCost) ? 0
  173. : NotOutlinedCost - OutlinedCost;
  174. }
  175. /// Return the number of instructions in this sequence.
  176. unsigned getNumInstrs() const { return Candidates[0].getLength(); }
  177. OutlinedFunction(std::vector<Candidate> &Candidates, unsigned SequenceSize,
  178. unsigned FrameOverhead, unsigned FrameConstructionID)
  179. : Candidates(Candidates), SequenceSize(SequenceSize),
  180. FrameOverhead(FrameOverhead), FrameConstructionID(FrameConstructionID) {
  181. const unsigned B = getBenefit();
  182. for (Candidate &C : Candidates)
  183. C.Benefit = B;
  184. }
  185. OutlinedFunction() = default;
  186. };
  187. } // namespace outliner
  188. } // namespace llvm
  189. #endif
  190. #ifdef __GNUC__
  191. #pragma GCC diagnostic pop
  192. #endif