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
15namespace llvm {
16
17/// Wrapper class representing virtual and physical registers. Should be passed
18/// by value.
19class Register {
20 unsigned Reg;
21
22public:
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
150template <> 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

source code of llvm/include/llvm/CodeGen/Register.h