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