AllocationOrder.h 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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/MC/MCRegisterInfo.h"
  20. namespace llvm {
  21. class RegisterClassInfo;
  22. class VirtRegMap;
  23. class LiveRegMatrix;
  24. class LLVM_LIBRARY_VISIBILITY AllocationOrder {
  25. SmallVector<MCPhysReg, 16> Hints;
  26. ArrayRef<MCPhysReg> Order;
  27. int Pos;
  28. // If HardHints is true, *only* Hints will be returned.
  29. bool HardHints;
  30. public:
  31. /// Create a new AllocationOrder for VirtReg.
  32. /// @param VirtReg Virtual register to allocate for.
  33. /// @param VRM Virtual register map for function.
  34. /// @param RegClassInfo Information about reserved and allocatable registers.
  35. AllocationOrder(unsigned VirtReg,
  36. const VirtRegMap &VRM,
  37. const RegisterClassInfo &RegClassInfo,
  38. const LiveRegMatrix *Matrix);
  39. /// Get the allocation order without reordered hints.
  40. ArrayRef<MCPhysReg> getOrder() const { return Order; }
  41. /// Return the next physical register in the allocation order, or 0.
  42. /// It is safe to call next() again after it returned 0, it will keep
  43. /// returning 0 until rewind() is called.
  44. unsigned next(unsigned Limit = 0) {
  45. if (Pos < 0)
  46. return Hints.end()[Pos++];
  47. if (HardHints)
  48. return 0;
  49. if (!Limit)
  50. Limit = Order.size();
  51. while (Pos < int(Limit)) {
  52. unsigned Reg = Order[Pos++];
  53. if (!isHint(Reg))
  54. return Reg;
  55. }
  56. return 0;
  57. }
  58. /// As next(), but allow duplicates to be returned, and stop before the
  59. /// Limit'th register in the RegisterClassInfo allocation order.
  60. ///
  61. /// This can produce more than Limit registers if there are hints.
  62. unsigned nextWithDups(unsigned Limit) {
  63. if (Pos < 0)
  64. return Hints.end()[Pos++];
  65. if (HardHints)
  66. return 0;
  67. if (Pos < int(Limit))
  68. return Order[Pos++];
  69. return 0;
  70. }
  71. /// Start over from the beginning.
  72. void rewind() { Pos = -int(Hints.size()); }
  73. /// Return true if the last register returned from next() was a preferred register.
  74. bool isHint() const { return Pos <= 0; }
  75. /// Return true if PhysReg is a preferred register.
  76. bool isHint(unsigned PhysReg) const { return is_contained(Hints, PhysReg); }
  77. };
  78. } // end namespace llvm
  79. #endif