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: Reg(Val)23 constexpr Register(unsigned Val = 0) : Reg(Val) {} Register(MCRegister Val)24 constexpr Register(MCRegister Val) : Reg(Val.id()) {} 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 static constexpr unsigned FirstStackSlot = 1u << 30; 39 static_assert(FirstStackSlot >= MCRegister::LastPhysicalReg); 40 static constexpr unsigned VirtualRegFlag = 1u << 31; 41 42 /// Return true if this is a stack slot. isStack()43 constexpr bool isStack() const { 44 return Register::FirstStackSlot <= Reg && Reg < Register::VirtualRegFlag; 45 } 46 47 /// Convert a non-negative frame index to a stack slot register value. index2StackSlot(int FI)48 static Register index2StackSlot(int FI) { 49 assert(FI >= 0 && "Cannot hold a negative frame index."); 50 return Register(FI + Register::FirstStackSlot); 51 } 52 53 /// Return true if the specified register number is in 54 /// the physical register namespace. isPhysicalRegister(unsigned Reg)55 static constexpr bool isPhysicalRegister(unsigned Reg) { 56 return MCRegister::isPhysicalRegister(Reg); 57 } 58 59 /// Return true if the specified register number is in 60 /// the virtual register namespace. isVirtualRegister(unsigned Reg)61 static constexpr bool isVirtualRegister(unsigned Reg) { 62 return Reg & Register::VirtualRegFlag; 63 } 64 65 /// Convert a 0-based index to a virtual register number. 66 /// This is the inverse operation of VirtReg2IndexFunctor below. index2VirtReg(unsigned Index)67 static Register index2VirtReg(unsigned Index) { 68 assert(Index < (1u << 31) && "Index too large for virtual register range."); 69 return Index | Register::VirtualRegFlag; 70 } 71 72 /// Return true if the specified register number is in the virtual register 73 /// namespace. isVirtual()74 constexpr bool isVirtual() const { return isVirtualRegister(Reg); } 75 76 /// Return true if the specified register number is in the physical register 77 /// namespace. isPhysical()78 constexpr bool isPhysical() const { return isPhysicalRegister(Reg); } 79 80 /// Convert a virtual register number to a 0-based index. The first virtual 81 /// register in a function will get the index 0. virtRegIndex()82 unsigned virtRegIndex() const { 83 assert(isVirtual() && "Not a virtual register"); 84 return Reg & ~Register::VirtualRegFlag; 85 } 86 87 /// Compute the frame index from a register value representing a stack slot. stackSlotIndex()88 int stackSlotIndex() const { 89 assert(isStack() && "Not a stack slot"); 90 return static_cast<int>(Reg - Register::FirstStackSlot); 91 } 92 93 constexpr operator unsigned() const { return Reg; } 94 id()95 constexpr unsigned id() const { return Reg; } 96 MCRegister()97 constexpr operator MCRegister() const { return MCRegister(Reg); } 98 99 /// Utility to check-convert this value to a MCRegister. The caller is 100 /// expected to have already validated that this Register is, indeed, 101 /// physical. asMCReg()102 MCRegister asMCReg() const { 103 assert(!isValid() || isPhysical()); 104 return MCRegister(Reg); 105 } 106 isValid()107 constexpr bool isValid() const { return Reg != MCRegister::NoRegister; } 108 109 /// Comparisons between register objects 110 constexpr bool operator==(const Register &Other) const { 111 return Reg == Other.Reg; 112 } 113 constexpr bool operator!=(const Register &Other) const { 114 return Reg != Other.Reg; 115 } 116 constexpr bool operator==(const MCRegister &Other) const { 117 return Reg == Other.id(); 118 } 119 constexpr bool operator!=(const MCRegister &Other) const { 120 return Reg != Other.id(); 121 } 122 123 /// Comparisons against register constants. E.g. 124 /// * R == AArch64::WZR 125 /// * R == 0 126 constexpr bool operator==(unsigned Other) const { return Reg == Other; } 127 constexpr bool operator!=(unsigned Other) const { return Reg != Other; } 128 constexpr bool operator==(int Other) const { return Reg == unsigned(Other); } 129 constexpr bool operator!=(int Other) const { return Reg != unsigned(Other); } 130 // MSVC requires that we explicitly declare these two as well. 131 constexpr bool operator==(MCPhysReg Other) const { 132 return Reg == unsigned(Other); 133 } 134 constexpr bool operator!=(MCPhysReg Other) const { 135 return Reg != unsigned(Other); 136 } 137 138 /// Operators to move from one register to another nearby register by adding 139 /// an offset. 140 Register &operator++() { 141 assert(isValid()); 142 ++Reg; 143 return *this; 144 } 145 146 Register operator++(int) { 147 Register R(*this); 148 ++(*this); 149 return R; 150 } 151 152 Register &operator+=(unsigned RHS) { 153 assert(isValid()); 154 Reg += RHS; 155 return *this; 156 } 157 }; 158 159 // Provide DenseMapInfo for Register 160 template <> struct DenseMapInfo<Register> { 161 static inline Register getEmptyKey() { 162 return DenseMapInfo<unsigned>::getEmptyKey(); 163 } 164 static inline Register getTombstoneKey() { 165 return DenseMapInfo<unsigned>::getTombstoneKey(); 166 } 167 static unsigned getHashValue(const Register &Val) { 168 return DenseMapInfo<unsigned>::getHashValue(Val.id()); 169 } 170 static bool isEqual(const Register &LHS, const Register &RHS) { 171 return LHS == RHS; 172 } 173 }; 174 175 /// Wrapper class representing a virtual register or register unit. 176 class VirtRegOrUnit { 177 unsigned VRegOrUnit; 178 179 public: 180 constexpr explicit VirtRegOrUnit(MCRegUnit Unit) : VRegOrUnit(Unit) { 181 assert(!Register::isVirtualRegister(VRegOrUnit)); 182 } 183 constexpr explicit VirtRegOrUnit(Register Reg) : VRegOrUnit(Reg.id()) { 184 assert(Reg.isVirtual()); 185 } 186 187 constexpr bool isVirtualReg() const { 188 return Register::isVirtualRegister(VRegOrUnit); 189 } 190 191 constexpr MCRegUnit asMCRegUnit() const { 192 assert(!isVirtualReg() && "Not a register unit"); 193 return VRegOrUnit; 194 } 195 196 constexpr Register asVirtualReg() const { 197 assert(isVirtualReg() && "Not a virtual register"); 198 return Register(VRegOrUnit); 199 } 200 201 constexpr bool operator==(const VirtRegOrUnit &Other) const { 202 return VRegOrUnit == Other.VRegOrUnit; 203 } 204 }; 205 206 } // namespace llvm 207 208 #endif // LLVM_CODEGEN_REGISTER_H 209