ExecutionDomainFix.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. //==-- llvm/CodeGen/ExecutionDomainFix.h - Execution Domain Fix -*- C++ -*--==//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. /// \file Execution Domain Fix pass.
  10. ///
  11. /// Some X86 SSE instructions like mov, and, or, xor are available in different
  12. /// variants for different operand types. These variant instructions are
  13. /// equivalent, but on Nehalem and newer cpus there is extra latency
  14. /// transferring data between integer and floating point domains. ARM cores
  15. /// have similar issues when they are configured with both VFP and NEON
  16. /// pipelines.
  17. ///
  18. /// This pass changes the variant instructions to minimize domain crossings.
  19. //
  20. //===----------------------------------------------------------------------===//
  21. #ifndef LLVM_CODEGEN_EXECUTIONDOMAINFIX_H
  22. #define LLVM_CODEGEN_EXECUTIONDOMAINFIX_H
  23. #include "llvm/ADT/SmallVector.h"
  24. #include "llvm/CodeGen/LoopTraversal.h"
  25. #include "llvm/CodeGen/MachineFunctionPass.h"
  26. #include "llvm/CodeGen/ReachingDefAnalysis.h"
  27. #include "llvm/CodeGen/TargetRegisterInfo.h"
  28. namespace llvm {
  29. class MachineInstr;
  30. class TargetInstrInfo;
  31. /// A DomainValue is a bit like LiveIntervals' ValNo, but it also keeps track
  32. /// of execution domains.
  33. ///
  34. /// An open DomainValue represents a set of instructions that can still switch
  35. /// execution domain. Multiple registers may refer to the same open
  36. /// DomainValue - they will eventually be collapsed to the same execution
  37. /// domain.
  38. ///
  39. /// A collapsed DomainValue represents a single register that has been forced
  40. /// into one of more execution domains. There is a separate collapsed
  41. /// DomainValue for each register, but it may contain multiple execution
  42. /// domains. A register value is initially created in a single execution
  43. /// domain, but if we were forced to pay the penalty of a domain crossing, we
  44. /// keep track of the fact that the register is now available in multiple
  45. /// domains.
  46. struct DomainValue {
  47. /// Basic reference counting.
  48. unsigned Refs = 0;
  49. /// Bitmask of available domains. For an open DomainValue, it is the still
  50. /// possible domains for collapsing. For a collapsed DomainValue it is the
  51. /// domains where the register is available for free.
  52. unsigned AvailableDomains;
  53. /// Pointer to the next DomainValue in a chain. When two DomainValues are
  54. /// merged, Victim.Next is set to point to Victor, so old DomainValue
  55. /// references can be updated by following the chain.
  56. DomainValue *Next;
  57. /// Twiddleable instructions using or defining these registers.
  58. SmallVector<MachineInstr *, 8> Instrs;
  59. DomainValue() { clear(); }
  60. /// A collapsed DomainValue has no instructions to twiddle - it simply keeps
  61. /// track of the domains where the registers are already available.
  62. bool isCollapsed() const { return Instrs.empty(); }
  63. /// Is domain available?
  64. bool hasDomain(unsigned domain) const {
  65. assert(domain <
  66. static_cast<unsigned>(std::numeric_limits<unsigned>::digits) &&
  67. "undefined behavior");
  68. return AvailableDomains & (1u << domain);
  69. }
  70. /// Mark domain as available.
  71. void addDomain(unsigned domain) {
  72. assert(domain <
  73. static_cast<unsigned>(std::numeric_limits<unsigned>::digits) &&
  74. "undefined behavior");
  75. AvailableDomains |= 1u << domain;
  76. }
  77. // Restrict to a single domain available.
  78. void setSingleDomain(unsigned domain) {
  79. assert(domain <
  80. static_cast<unsigned>(std::numeric_limits<unsigned>::digits) &&
  81. "undefined behavior");
  82. AvailableDomains = 1u << domain;
  83. }
  84. /// Return bitmask of domains that are available and in mask.
  85. unsigned getCommonDomains(unsigned mask) const {
  86. return AvailableDomains & mask;
  87. }
  88. /// First domain available.
  89. unsigned getFirstDomain() const {
  90. return countTrailingZeros(AvailableDomains);
  91. }
  92. /// Clear this DomainValue and point to next which has all its data.
  93. void clear() {
  94. AvailableDomains = 0;
  95. Next = nullptr;
  96. Instrs.clear();
  97. }
  98. };
  99. class ExecutionDomainFix : public MachineFunctionPass {
  100. SpecificBumpPtrAllocator<DomainValue> Allocator;
  101. SmallVector<DomainValue *, 16> Avail;
  102. const TargetRegisterClass *const RC;
  103. MachineFunction *MF;
  104. const TargetInstrInfo *TII;
  105. const TargetRegisterInfo *TRI;
  106. std::vector<SmallVector<int, 1>> AliasMap;
  107. const unsigned NumRegs;
  108. /// Value currently in each register, or NULL when no value is being tracked.
  109. /// This counts as a DomainValue reference.
  110. using LiveRegsDVInfo = std::vector<DomainValue *>;
  111. LiveRegsDVInfo LiveRegs;
  112. /// Keeps domain information for all registers. Note that this
  113. /// is different from the usual definition notion of liveness. The CPU
  114. /// doesn't care whether or not we consider a register killed.
  115. using OutRegsInfoMap = SmallVector<LiveRegsDVInfo, 4>;
  116. OutRegsInfoMap MBBOutRegsInfos;
  117. ReachingDefAnalysis *RDA;
  118. public:
  119. ExecutionDomainFix(char &PassID, const TargetRegisterClass &RC)
  120. : MachineFunctionPass(PassID), RC(&RC), NumRegs(RC.getNumRegs()) {}
  121. void getAnalysisUsage(AnalysisUsage &AU) const override {
  122. AU.setPreservesAll();
  123. AU.addRequired<ReachingDefAnalysis>();
  124. MachineFunctionPass::getAnalysisUsage(AU);
  125. }
  126. bool runOnMachineFunction(MachineFunction &MF) override;
  127. MachineFunctionProperties getRequiredProperties() const override {
  128. return MachineFunctionProperties().set(
  129. MachineFunctionProperties::Property::NoVRegs);
  130. }
  131. private:
  132. /// Translate TRI register number to a list of indices into our smaller tables
  133. /// of interesting registers.
  134. iterator_range<SmallVectorImpl<int>::const_iterator>
  135. regIndices(unsigned Reg) const;
  136. /// DomainValue allocation.
  137. DomainValue *alloc(int domain = -1);
  138. /// Add reference to DV.
  139. DomainValue *retain(DomainValue *DV) {
  140. if (DV)
  141. ++DV->Refs;
  142. return DV;
  143. }
  144. /// Release a reference to DV. When the last reference is released,
  145. /// collapse if needed.
  146. void release(DomainValue *);
  147. /// Follow the chain of dead DomainValues until a live DomainValue is reached.
  148. /// Update the referenced pointer when necessary.
  149. DomainValue *resolve(DomainValue *&);
  150. /// Set LiveRegs[rx] = dv, updating reference counts.
  151. void setLiveReg(int rx, DomainValue *DV);
  152. /// Kill register rx, recycle or collapse any DomainValue.
  153. void kill(int rx);
  154. /// Force register rx into domain.
  155. void force(int rx, unsigned domain);
  156. /// Collapse open DomainValue into given domain. If there are multiple
  157. /// registers using dv, they each get a unique collapsed DomainValue.
  158. void collapse(DomainValue *dv, unsigned domain);
  159. /// All instructions and registers in B are moved to A, and B is released.
  160. bool merge(DomainValue *A, DomainValue *B);
  161. /// Set up LiveRegs by merging predecessor live-out values.
  162. void enterBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
  163. /// Update live-out values.
  164. void leaveBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
  165. /// Process he given basic block.
  166. void processBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
  167. /// Visit given insturcion.
  168. bool visitInstr(MachineInstr *);
  169. /// Update def-ages for registers defined by MI.
  170. /// If Kill is set, also kill off DomainValues clobbered by the defs.
  171. void processDefs(MachineInstr *, bool Kill);
  172. /// A soft instruction can be changed to work in other domains given by mask.
  173. void visitSoftInstr(MachineInstr *, unsigned mask);
  174. /// A hard instruction only works in one domain. All input registers will be
  175. /// forced into that domain.
  176. void visitHardInstr(MachineInstr *, unsigned domain);
  177. };
  178. } // namespace llvm
  179. #endif // LLVM_CODEGEN_EXECUTIONDOMAINFIX_H