AllocationOrder.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. //===-- llvm/CodeGen/AllocationOrder.h - Allocation Order -*- C++ -*-------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements an allocation order for virtual registers.
  11. //
  12. // The preferred allocation order for a virtual register depends on allocation
  13. // hints and target hooks. The AllocationOrder class encapsulates all of that.
  14. //
  15. //===----------------------------------------------------------------------===//
  16. #ifndef LLVM_LIB_CODEGEN_ALLOCATIONORDER_H
  17. #define LLVM_LIB_CODEGEN_ALLOCATIONORDER_H
  18. #include "llvm/ADT/ArrayRef.h"
  19. #include "llvm/MC/MCRegisterInfo.h"
  20. namespace llvm {
  21. class RegisterClassInfo;
  22. class VirtRegMap;
  23. class LLVM_LIBRARY_VISIBILITY AllocationOrder {
  24. SmallVector<MCPhysReg, 16> Hints;
  25. ArrayRef<MCPhysReg> Order;
  26. int Pos;
  27. public:
  28. /// Create a new AllocationOrder for VirtReg.
  29. /// @param VirtReg Virtual register to allocate for.
  30. /// @param VRM Virtual register map for function.
  31. /// @param RegClassInfo Information about reserved and allocatable registers.
  32. AllocationOrder(unsigned VirtReg,
  33. const VirtRegMap &VRM,
  34. const RegisterClassInfo &RegClassInfo);
  35. /// Get the allocation order without reordered hints.
  36. ArrayRef<MCPhysReg> getOrder() const { return Order; }
  37. /// Return the next physical register in the allocation order, or 0.
  38. /// It is safe to call next() again after it returned 0, it will keep
  39. /// returning 0 until rewind() is called.
  40. unsigned next(unsigned Limit = 0) {
  41. if (Pos < 0)
  42. return Hints.end()[Pos++];
  43. if (!Limit)
  44. Limit = Order.size();
  45. while (Pos < int(Limit)) {
  46. unsigned Reg = Order[Pos++];
  47. if (!isHint(Reg))
  48. return Reg;
  49. }
  50. return 0;
  51. }
  52. /// As next(), but allow duplicates to be returned, and stop before the
  53. /// Limit'th register in the RegisterClassInfo allocation order.
  54. ///
  55. /// This can produce more than Limit registers if there are hints.
  56. unsigned nextWithDups(unsigned Limit) {
  57. if (Pos < 0)
  58. return Hints.end()[Pos++];
  59. if (Pos < int(Limit))
  60. return Order[Pos++];
  61. return 0;
  62. }
  63. /// Start over from the beginning.
  64. void rewind() { Pos = -int(Hints.size()); }
  65. /// Return true if the last register returned from next() was a preferred register.
  66. bool isHint() const { return Pos <= 0; }
  67. /// Return true if PhysReg is a preferred register.
  68. bool isHint(unsigned PhysReg) const {
  69. return std::find(Hints.begin(), Hints.end(), PhysReg) != Hints.end();
  70. }
  71. };
  72. } // end namespace llvm
  73. #endif