AllocationOrder.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. //===-- llvm/CodeGen/AllocationOrder.h - Allocation Order -*- 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. // This file implements an allocation order for virtual registers.
  10. //
  11. // The preferred allocation order for a virtual register depends on allocation
  12. // hints and target hooks. The AllocationOrder class encapsulates all of that.
  13. //
  14. //===----------------------------------------------------------------------===//
  15. #ifndef LLVM_LIB_CODEGEN_ALLOCATIONORDER_H
  16. #define LLVM_LIB_CODEGEN_ALLOCATIONORDER_H
  17. #include "llvm/ADT/ArrayRef.h"
  18. #include "llvm/ADT/STLExtras.h"
  19. #include "llvm/ADT/SmallVector.h"
  20. #include "llvm/CodeGen/Register.h"
  21. namespace llvm {
  22. class RegisterClassInfo;
  23. class VirtRegMap;
  24. class LiveRegMatrix;
  25. class LLVM_LIBRARY_VISIBILITY AllocationOrder {
  26. const SmallVector<MCPhysReg, 16> Hints;
  27. ArrayRef<MCPhysReg> Order;
  28. // How far into the Order we can iterate. This is 0 if the AllocationOrder is
  29. // constructed with HardHints = true, Order.size() otherwise. While
  30. // technically a size_t, it will participate in comparisons with the
  31. // Iterator's Pos, which must be signed, so it's typed here as signed, too, to
  32. // avoid warnings and under the assumption that the size of Order is
  33. // relatively small.
  34. // IterationLimit defines an invalid iterator position.
  35. const int IterationLimit;
  36. public:
  37. /// Forward iterator for an AllocationOrder.
  38. class Iterator final {
  39. const AllocationOrder &AO;
  40. int Pos = 0;
  41. public:
  42. Iterator(const AllocationOrder &AO, int Pos) : AO(AO), Pos(Pos) {}
  43. /// Return true if the curent position is that of a preferred register.
  44. bool isHint() const { return Pos < 0; }
  45. /// Return the next physical register in the allocation order.
  46. MCRegister operator*() const {
  47. if (Pos < 0)
  48. return AO.Hints.end()[Pos];
  49. assert(Pos < AO.IterationLimit);
  50. return AO.Order[Pos];
  51. }
  52. /// Advance the iterator to the next position. If that's past the Hints
  53. /// list, advance to the first value that's not also in the Hints list.
  54. Iterator &operator++() {
  55. if (Pos < AO.IterationLimit)
  56. ++Pos;
  57. while (Pos >= 0 && Pos < AO.IterationLimit && AO.isHint(AO.Order[Pos]))
  58. ++Pos;
  59. return *this;
  60. }
  61. bool operator==(const Iterator &Other) const {
  62. assert(&AO == &Other.AO);
  63. return Pos == Other.Pos;
  64. }
  65. bool operator!=(const Iterator &Other) const { return !(*this == Other); }
  66. };
  67. /// Create a new AllocationOrder for VirtReg.
  68. /// @param VirtReg Virtual register to allocate for.
  69. /// @param VRM Virtual register map for function.
  70. /// @param RegClassInfo Information about reserved and allocatable registers.
  71. static AllocationOrder create(unsigned VirtReg, const VirtRegMap &VRM,
  72. const RegisterClassInfo &RegClassInfo,
  73. const LiveRegMatrix *Matrix);
  74. /// Create an AllocationOrder given the Hits, Order, and HardHits values.
  75. /// Use the create method above - the ctor is for unittests.
  76. AllocationOrder(SmallVector<MCPhysReg, 16> &&Hints, ArrayRef<MCPhysReg> Order,
  77. bool HardHints)
  78. : Hints(std::move(Hints)), Order(Order),
  79. IterationLimit(HardHints ? 0 : static_cast<int>(Order.size())) {}
  80. Iterator begin() const {
  81. return Iterator(*this, -(static_cast<int>(Hints.size())));
  82. }
  83. Iterator end() const { return Iterator(*this, IterationLimit); }
  84. Iterator getOrderLimitEnd(unsigned OrderLimit) const {
  85. assert(OrderLimit <= Order.size());
  86. if (OrderLimit == 0)
  87. return end();
  88. Iterator Ret(*this,
  89. std::min(static_cast<int>(OrderLimit) - 1, IterationLimit));
  90. return ++Ret;
  91. }
  92. /// Get the allocation order without reordered hints.
  93. ArrayRef<MCPhysReg> getOrder() const { return Order; }
  94. /// Return true if Reg is a preferred physical register.
  95. bool isHint(Register Reg) const {
  96. assert(!Reg.isPhysical() ||
  97. Reg.id() <
  98. static_cast<uint32_t>(std::numeric_limits<MCPhysReg>::max()));
  99. return Reg.isPhysical() && is_contained(Hints, Reg.id());
  100. }
  101. };
  102. } // end namespace llvm
  103. #endif