RegAllocEvictionAdvisor.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. //===- RegAllocEvictionAdvisor.cpp - eviction advisor ---------------------===//
  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. // Implementation of the default eviction advisor and of the Analysis pass.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "RegAllocEvictionAdvisor.h"
  13. #include "AllocationOrder.h"
  14. #include "RegAllocGreedy.h"
  15. #include "llvm/CodeGen/LiveRegMatrix.h"
  16. #include "llvm/CodeGen/MachineFunction.h"
  17. #include "llvm/CodeGen/RegisterClassInfo.h"
  18. #include "llvm/CodeGen/VirtRegMap.h"
  19. #include "llvm/InitializePasses.h"
  20. #include "llvm/Pass.h"
  21. #include "llvm/Support/CommandLine.h"
  22. #include "llvm/Support/ErrorHandling.h"
  23. #include "llvm/Target/TargetMachine.h"
  24. using namespace llvm;
  25. static cl::opt<RegAllocEvictionAdvisorAnalysis::AdvisorMode> Mode(
  26. "regalloc-enable-advisor", cl::Hidden,
  27. cl::init(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default),
  28. cl::desc("Enable regalloc advisor mode"),
  29. cl::values(
  30. clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default,
  31. "default", "Default"),
  32. clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release,
  33. "release", "precompiled"),
  34. clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development,
  35. "development", "for training")));
  36. static cl::opt<bool> EnableLocalReassignment(
  37. "enable-local-reassign", cl::Hidden,
  38. cl::desc("Local reassignment can yield better allocation decisions, but "
  39. "may be compile time intensive"),
  40. cl::init(false));
  41. cl::opt<unsigned> EvictInterferenceCutoff(
  42. "regalloc-eviction-max-interference-cutoff", cl::Hidden,
  43. cl::desc("Number of interferences after which we declare "
  44. "an interference unevictable and bail out. This "
  45. "is a compilation cost-saving consideration. To "
  46. "disable, pass a very large number."),
  47. cl::init(10));
  48. #define DEBUG_TYPE "regalloc"
  49. #ifdef LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL
  50. #define LLVM_HAVE_TF_AOT
  51. #endif
  52. char RegAllocEvictionAdvisorAnalysis::ID = 0;
  53. INITIALIZE_PASS(RegAllocEvictionAdvisorAnalysis, "regalloc-evict",
  54. "Regalloc eviction policy", false, true)
  55. namespace {
  56. class DefaultEvictionAdvisorAnalysis final
  57. : public RegAllocEvictionAdvisorAnalysis {
  58. public:
  59. DefaultEvictionAdvisorAnalysis(bool NotAsRequested)
  60. : RegAllocEvictionAdvisorAnalysis(AdvisorMode::Default),
  61. NotAsRequested(NotAsRequested) {}
  62. // support for isa<> and dyn_cast.
  63. static bool classof(const RegAllocEvictionAdvisorAnalysis *R) {
  64. return R->getAdvisorMode() == AdvisorMode::Default;
  65. }
  66. private:
  67. std::unique_ptr<RegAllocEvictionAdvisor>
  68. getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
  69. return std::make_unique<DefaultEvictionAdvisor>(MF, RA);
  70. }
  71. bool doInitialization(Module &M) override {
  72. if (NotAsRequested)
  73. M.getContext().emitError("Requested regalloc eviction advisor analysis "
  74. "could be created. Using default");
  75. return RegAllocEvictionAdvisorAnalysis::doInitialization(M);
  76. }
  77. const bool NotAsRequested;
  78. };
  79. } // namespace
  80. template <> Pass *llvm::callDefaultCtor<RegAllocEvictionAdvisorAnalysis>() {
  81. Pass *Ret = nullptr;
  82. switch (Mode) {
  83. case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default:
  84. Ret = new DefaultEvictionAdvisorAnalysis(/*NotAsRequested*/ false);
  85. break;
  86. case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development:
  87. #if defined(LLVM_HAVE_TFLITE)
  88. Ret = createDevelopmentModeAdvisor();
  89. #endif
  90. break;
  91. case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release:
  92. #if defined(LLVM_HAVE_TF_AOT)
  93. Ret = createReleaseModeAdvisor();
  94. #endif
  95. break;
  96. }
  97. if (Ret)
  98. return Ret;
  99. return new DefaultEvictionAdvisorAnalysis(/*NotAsRequested*/ true);
  100. }
  101. StringRef RegAllocEvictionAdvisorAnalysis::getPassName() const {
  102. switch (getAdvisorMode()) {
  103. case AdvisorMode::Default:
  104. return "Default Regalloc Eviction Advisor";
  105. case AdvisorMode::Release:
  106. return "Release mode Regalloc Eviction Advisor";
  107. case AdvisorMode::Development:
  108. return "Development mode Regalloc Eviction Advisor";
  109. }
  110. llvm_unreachable("Unknown advisor kind");
  111. }
  112. RegAllocEvictionAdvisor::RegAllocEvictionAdvisor(const MachineFunction &MF,
  113. const RAGreedy &RA)
  114. : MF(MF), RA(RA), Matrix(RA.getInterferenceMatrix()),
  115. LIS(RA.getLiveIntervals()), VRM(RA.getVirtRegMap()),
  116. MRI(&VRM->getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()),
  117. RegClassInfo(RA.getRegClassInfo()), RegCosts(TRI->getRegisterCosts(MF)),
  118. EnableLocalReassign(EnableLocalReassignment ||
  119. MF.getSubtarget().enableRALocalReassignment(
  120. MF.getTarget().getOptLevel())) {}
  121. /// shouldEvict - determine if A should evict the assigned live range B. The
  122. /// eviction policy defined by this function together with the allocation order
  123. /// defined by enqueue() decides which registers ultimately end up being split
  124. /// and spilled.
  125. ///
  126. /// Cascade numbers are used to prevent infinite loops if this function is a
  127. /// cyclic relation.
  128. ///
  129. /// @param A The live range to be assigned.
  130. /// @param IsHint True when A is about to be assigned to its preferred
  131. /// register.
  132. /// @param B The live range to be evicted.
  133. /// @param BreaksHint True when B is already assigned to its preferred register.
  134. bool DefaultEvictionAdvisor::shouldEvict(const LiveInterval &A, bool IsHint,
  135. const LiveInterval &B,
  136. bool BreaksHint) const {
  137. bool CanSplit = RA.getExtraInfo().getStage(B) < RS_Spill;
  138. // Be fairly aggressive about following hints as long as the evictee can be
  139. // split.
  140. if (CanSplit && IsHint && !BreaksHint)
  141. return true;
  142. if (A.weight() > B.weight()) {
  143. LLVM_DEBUG(dbgs() << "should evict: " << B << " w= " << B.weight() << '\n');
  144. return true;
  145. }
  146. return false;
  147. }
  148. /// canEvictHintInterference - return true if the interference for VirtReg
  149. /// on the PhysReg, which is VirtReg's hint, can be evicted in favor of VirtReg.
  150. bool DefaultEvictionAdvisor::canEvictHintInterference(
  151. const LiveInterval &VirtReg, MCRegister PhysReg,
  152. const SmallVirtRegSet &FixedRegisters) const {
  153. EvictionCost MaxCost;
  154. MaxCost.setBrokenHints(1);
  155. return canEvictInterferenceBasedOnCost(VirtReg, PhysReg, true, MaxCost,
  156. FixedRegisters);
  157. }
  158. /// canEvictInterferenceBasedOnCost - Return true if all interferences between
  159. /// VirtReg and PhysReg can be evicted.
  160. ///
  161. /// @param VirtReg Live range that is about to be assigned.
  162. /// @param PhysReg Desired register for assignment.
  163. /// @param IsHint True when PhysReg is VirtReg's preferred register.
  164. /// @param MaxCost Only look for cheaper candidates and update with new cost
  165. /// when returning true.
  166. /// @returns True when interference can be evicted cheaper than MaxCost.
  167. bool DefaultEvictionAdvisor::canEvictInterferenceBasedOnCost(
  168. const LiveInterval &VirtReg, MCRegister PhysReg, bool IsHint,
  169. EvictionCost &MaxCost, const SmallVirtRegSet &FixedRegisters) const {
  170. // It is only possible to evict virtual register interference.
  171. if (Matrix->checkInterference(VirtReg, PhysReg) > LiveRegMatrix::IK_VirtReg)
  172. return false;
  173. bool IsLocal = VirtReg.empty() || LIS->intervalIsInOneMBB(VirtReg);
  174. // Find VirtReg's cascade number. This will be unassigned if VirtReg was never
  175. // involved in an eviction before. If a cascade number was assigned, deny
  176. // evicting anything with the same or a newer cascade number. This prevents
  177. // infinite eviction loops.
  178. //
  179. // This works out so a register without a cascade number is allowed to evict
  180. // anything, and it can be evicted by anything.
  181. unsigned Cascade = RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.reg());
  182. EvictionCost Cost;
  183. for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
  184. LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units);
  185. // If there is 10 or more interferences, chances are one is heavier.
  186. const auto &Interferences = Q.interferingVRegs(EvictInterferenceCutoff);
  187. if (Interferences.size() >= EvictInterferenceCutoff)
  188. return false;
  189. // Check if any interfering live range is heavier than MaxWeight.
  190. for (const LiveInterval *Intf : reverse(Interferences)) {
  191. assert(Intf->reg().isVirtual() &&
  192. "Only expecting virtual register interference from query");
  193. // Do not allow eviction of a virtual register if we are in the middle
  194. // of last-chance recoloring and this virtual register is one that we
  195. // have scavenged a physical register for.
  196. if (FixedRegisters.count(Intf->reg()))
  197. return false;
  198. // Never evict spill products. They cannot split or spill.
  199. if (RA.getExtraInfo().getStage(*Intf) == RS_Done)
  200. return false;
  201. // Once a live range becomes small enough, it is urgent that we find a
  202. // register for it. This is indicated by an infinite spill weight. These
  203. // urgent live ranges get to evict almost anything.
  204. //
  205. // Also allow urgent evictions of unspillable ranges from a strictly
  206. // larger allocation order.
  207. bool Urgent =
  208. !VirtReg.isSpillable() &&
  209. (Intf->isSpillable() ||
  210. RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(VirtReg.reg())) <
  211. RegClassInfo.getNumAllocatableRegs(
  212. MRI->getRegClass(Intf->reg())));
  213. // Only evict older cascades or live ranges without a cascade.
  214. unsigned IntfCascade = RA.getExtraInfo().getCascade(Intf->reg());
  215. if (Cascade == IntfCascade)
  216. return false;
  217. if (Cascade < IntfCascade) {
  218. if (!Urgent)
  219. return false;
  220. // We permit breaking cascades for urgent evictions. It should be the
  221. // last resort, though, so make it really expensive.
  222. Cost.BrokenHints += 10;
  223. }
  224. // Would this break a satisfied hint?
  225. bool BreaksHint = VRM->hasPreferredPhys(Intf->reg());
  226. // Update eviction cost.
  227. Cost.BrokenHints += BreaksHint;
  228. Cost.MaxWeight = std::max(Cost.MaxWeight, Intf->weight());
  229. // Abort if this would be too expensive.
  230. if (!(Cost < MaxCost))
  231. return false;
  232. if (Urgent)
  233. continue;
  234. // Apply the eviction policy for non-urgent evictions.
  235. if (!shouldEvict(VirtReg, IsHint, *Intf, BreaksHint))
  236. return false;
  237. // If !MaxCost.isMax(), then we're just looking for a cheap register.
  238. // Evicting another local live range in this case could lead to suboptimal
  239. // coloring.
  240. if (!MaxCost.isMax() && IsLocal && LIS->intervalIsInOneMBB(*Intf) &&
  241. (!EnableLocalReassign || !canReassign(*Intf, PhysReg))) {
  242. return false;
  243. }
  244. }
  245. }
  246. MaxCost = Cost;
  247. return true;
  248. }
  249. MCRegister DefaultEvictionAdvisor::tryFindEvictionCandidate(
  250. const LiveInterval &VirtReg, const AllocationOrder &Order,
  251. uint8_t CostPerUseLimit, const SmallVirtRegSet &FixedRegisters) const {
  252. // Keep track of the cheapest interference seen so far.
  253. EvictionCost BestCost;
  254. BestCost.setMax();
  255. MCRegister BestPhys;
  256. auto MaybeOrderLimit = getOrderLimit(VirtReg, Order, CostPerUseLimit);
  257. if (!MaybeOrderLimit)
  258. return MCRegister::NoRegister;
  259. unsigned OrderLimit = *MaybeOrderLimit;
  260. // When we are just looking for a reduced cost per use, don't break any
  261. // hints, and only evict smaller spill weights.
  262. if (CostPerUseLimit < uint8_t(~0u)) {
  263. BestCost.BrokenHints = 0;
  264. BestCost.MaxWeight = VirtReg.weight();
  265. }
  266. for (auto I = Order.begin(), E = Order.getOrderLimitEnd(OrderLimit); I != E;
  267. ++I) {
  268. MCRegister PhysReg = *I;
  269. assert(PhysReg);
  270. if (!canAllocatePhysReg(CostPerUseLimit, PhysReg) ||
  271. !canEvictInterferenceBasedOnCost(VirtReg, PhysReg, false, BestCost,
  272. FixedRegisters))
  273. continue;
  274. // Best so far.
  275. BestPhys = PhysReg;
  276. // Stop if the hint can be used.
  277. if (I.isHint())
  278. break;
  279. }
  280. return BestPhys;
  281. }