runtime/register-state.cpp (63 lines of code) (raw):
// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
#include "register-state.h"
#include <cstring>
namespace py {
namespace x64 {
RegisterState::RegisterState() { memset(assignment_, 0, sizeof(assignment_)); }
void RegisterState::assign(VirtualRegister* vreg, Register reg) {
VirtualRegister* previous_assignment = assignment_[reg];
if (previous_assignment != nullptr) {
previous_assignment->free();
}
assignment_[reg] = vreg;
vreg->assign(reg);
}
void RegisterState::free(VirtualRegister* vreg) {
Register reg = static_cast<Register>(*vreg);
CHECK(reg != kNoRegister, "no register assigned");
CHECK(assignment_[reg] == vreg, "inconsistent assignment");
vreg->free();
assignment_[reg] = nullptr;
}
void RegisterState::allocate(VirtualRegister* vreg, View<Register> candidates) {
for (Register reg : candidates) {
if (assignment_[reg] == nullptr) {
assign(vreg, reg);
return;
}
}
UNREACHABLE("no free register left");
}
void RegisterState::clobber(View<Register> registers) {
for (Register reg : registers) {
VirtualRegister* vreg = assignment_[reg];
if (vreg != nullptr) {
vreg->free();
assignment_[reg] = nullptr;
}
}
}
void RegisterState::reset() {
for (word i = 0; i < kNumRegisters; i++) {
VirtualRegister* vreg = assignment_[i];
if (vreg != nullptr) {
vreg->free();
assignment_[i] = nullptr;
}
}
}
void RegisterState::resetTo(View<RegisterAssignment> assignment) {
reset();
for (word i = 0, length = assignment.length(); i < length; i++) {
VirtualRegister* vreg = assignment.get(i).vreg;
assign(vreg, assignment.get(i).reg);
}
}
void RegisterState::check(View<RegisterAssignment> assignment) {
for (word i = 0, length = assignment.length(); i < length; i++) {
VirtualRegister* vreg = assignment.get(i).vreg;
CHECK(static_cast<Register>(*vreg) == assignment.get(i).reg,
"unexpected assignment");
}
}
} // namespace x64
} // namespace py