1 | //===-- llvm/CodeGen/Register.h ---------------------------------*- 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 | #ifndef LLVM_CODEGEN_REGISTER_H |
10 | #define LLVM_CODEGEN_REGISTER_H |
11 | |
12 | #include "llvm/MC/MCRegister.h" |
13 | #include <cassert> |
14 | |
15 | namespace llvm { |
16 | |
17 | /// Wrapper class representing virtual and physical registers. Should be passed |
18 | /// by value. |
19 | class Register { |
20 | unsigned Reg; |
21 | |
22 | public: |
23 | constexpr Register(unsigned Val = 0) : Reg(Val) {} |
24 | constexpr Register(MCRegister Val) : Reg(Val) {} |
25 | |
26 | // Register numbers can represent physical registers, virtual registers, and |
27 | // sometimes stack slots. The unsigned values are divided into these ranges: |
28 | // |
29 | // 0 Not a register, can be used as a sentinel. |
30 | // [1;2^30) Physical registers assigned by TableGen. |
31 | // [2^30;2^31) Stack slots. (Rarely used.) |
32 | // [2^31;2^32) Virtual registers assigned by MachineRegisterInfo. |
33 | // |
34 | // Further sentinels can be allocated from the small negative integers. |
35 | // DenseMapInfo<unsigned> uses -1u and -2u. |
36 | static_assert(std::numeric_limits<decltype(Reg)>::max() >= 0xFFFFFFFF, |
37 | "Reg isn't large enough to hold full range." ); |
38 | |
39 | /// isStackSlot - Sometimes it is useful to be able to store a non-negative |
40 | /// frame index in a variable that normally holds a register. isStackSlot() |
41 | /// returns true if Reg is in the range used for stack slots. |
42 | /// |
43 | /// FIXME: remove in favor of member. |
44 | static constexpr bool isStackSlot(unsigned Reg) { |
45 | return MCRegister::isStackSlot(Reg); |
46 | } |
47 | |
48 | /// Return true if this is a stack slot. |
49 | constexpr bool isStack() const { return MCRegister::isStackSlot(Reg); } |
50 | |
51 | /// Compute the frame index from a register value representing a stack slot. |
52 | static int stackSlot2Index(Register Reg) { |
53 | assert(Reg.isStack() && "Not a stack slot" ); |
54 | return int(Reg - MCRegister::FirstStackSlot); |
55 | } |
56 | |
57 | /// Convert a non-negative frame index to a stack slot register value. |
58 | static Register index2StackSlot(int FI) { |
59 | assert(FI >= 0 && "Cannot hold a negative frame index." ); |
60 | return Register(FI + MCRegister::FirstStackSlot); |
61 | } |
62 | |
63 | /// Return true if the specified register number is in |
64 | /// the physical register namespace. |
65 | static constexpr bool isPhysicalRegister(unsigned Reg) { |
66 | return MCRegister::isPhysicalRegister(Reg); |
67 | } |
68 | |
69 | /// Return true if the specified register number is in |
70 | /// the virtual register namespace. |
71 | static constexpr bool isVirtualRegister(unsigned Reg) { |
72 | return Reg & MCRegister::VirtualRegFlag; |
73 | } |
74 | |
75 | /// Convert a virtual register number to a 0-based index. |
76 | /// The first virtual register in a function will get the index 0. |
77 | static unsigned virtReg2Index(Register Reg) { |
78 | assert(Reg.isVirtual() && "Not a virtual register" ); |
79 | return Reg & ~MCRegister::VirtualRegFlag; |
80 | } |
81 | |
82 | /// Convert a 0-based index to a virtual register number. |
83 | /// This is the inverse operation of VirtReg2IndexFunctor below. |
84 | static Register index2VirtReg(unsigned Index) { |
85 | assert(Index < (1u << 31) && "Index too large for virtual register range." ); |
86 | return Index | MCRegister::VirtualRegFlag; |
87 | } |
88 | |
89 | /// Return true if the specified register number is in the virtual register |
90 | /// namespace. |
91 | constexpr bool isVirtual() const { return isVirtualRegister(Reg); } |
92 | |
93 | /// Return true if the specified register number is in the physical register |
94 | /// namespace. |
95 | constexpr bool isPhysical() const { return isPhysicalRegister(Reg); } |
96 | |
97 | /// Convert a virtual register number to a 0-based index. The first virtual |
98 | /// register in a function will get the index 0. |
99 | unsigned virtRegIndex() const { return virtReg2Index(Reg); } |
100 | |
101 | constexpr operator unsigned() const { return Reg; } |
102 | |
103 | constexpr unsigned id() const { return Reg; } |
104 | |
105 | constexpr operator MCRegister() const { return MCRegister(Reg); } |
106 | |
107 | /// Utility to check-convert this value to a MCRegister. The caller is |
108 | /// expected to have already validated that this Register is, indeed, |
109 | /// physical. |
110 | MCRegister asMCReg() const { |
111 | assert(Reg == MCRegister::NoRegister || |
112 | MCRegister::isPhysicalRegister(Reg)); |
113 | return MCRegister(Reg); |
114 | } |
115 | |
116 | constexpr bool isValid() const { return Reg != MCRegister::NoRegister; } |
117 | |
118 | /// Comparisons between register objects |
119 | constexpr bool operator==(const Register &Other) const { |
120 | return Reg == Other.Reg; |
121 | } |
122 | constexpr bool operator!=(const Register &Other) const { |
123 | return Reg != Other.Reg; |
124 | } |
125 | constexpr bool operator==(const MCRegister &Other) const { |
126 | return Reg == Other.id(); |
127 | } |
128 | constexpr bool operator!=(const MCRegister &Other) const { |
129 | return Reg != Other.id(); |
130 | } |
131 | |
132 | /// Comparisons against register constants. E.g. |
133 | /// * R == AArch64::WZR |
134 | /// * R == 0 |
135 | /// * R == VirtRegMap::NO_PHYS_REG |
136 | constexpr bool operator==(unsigned Other) const { return Reg == Other; } |
137 | constexpr bool operator!=(unsigned Other) const { return Reg != Other; } |
138 | constexpr bool operator==(int Other) const { return Reg == unsigned(Other); } |
139 | constexpr bool operator!=(int Other) const { return Reg != unsigned(Other); } |
140 | // MSVC requires that we explicitly declare these two as well. |
141 | constexpr bool operator==(MCPhysReg Other) const { |
142 | return Reg == unsigned(Other); |
143 | } |
144 | constexpr bool operator!=(MCPhysReg Other) const { |
145 | return Reg != unsigned(Other); |
146 | } |
147 | }; |
148 | |
149 | // Provide DenseMapInfo for Register |
150 | template <> struct DenseMapInfo<Register> { |
151 | static inline unsigned getEmptyKey() { |
152 | return DenseMapInfo<unsigned>::getEmptyKey(); |
153 | } |
154 | static inline unsigned getTombstoneKey() { |
155 | return DenseMapInfo<unsigned>::getTombstoneKey(); |
156 | } |
157 | static unsigned getHashValue(const Register &Val) { |
158 | return DenseMapInfo<unsigned>::getHashValue(Val: Val.id()); |
159 | } |
160 | static bool isEqual(const Register &LHS, const Register &RHS) { |
161 | return DenseMapInfo<unsigned>::isEqual(LHS: LHS.id(), RHS: RHS.id()); |
162 | } |
163 | }; |
164 | |
165 | } // namespace llvm |
166 | |
167 | #endif // LLVM_CODEGEN_REGISTER_H |
168 | |