forked from NUDT-compiler/nudt-compiler-cpp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.7 KiB
94 lines
2.7 KiB
#include "mir/MIR.h"
|
|
|
|
#include <algorithm>
|
|
#include <stdexcept>
|
|
#include <utility>
|
|
|
|
#include "utils/Log.h"
|
|
|
|
namespace mir {
|
|
|
|
namespace {
|
|
|
|
PhysReg CanonicalCalleeSavedReg(PhysReg reg) {
|
|
if (reg >= PhysReg::W0 && reg <= PhysReg::W11) {
|
|
int idx = static_cast<int>(reg) - static_cast<int>(PhysReg::W0);
|
|
return static_cast<PhysReg>(static_cast<int>(PhysReg::X0) + idx);
|
|
}
|
|
if (reg == PhysReg::W19) return PhysReg::X19;
|
|
if (reg == PhysReg::W20) return PhysReg::X20;
|
|
if (reg == PhysReg::W21) return PhysReg::X21;
|
|
if (reg == PhysReg::W22) return PhysReg::X22;
|
|
if (reg == PhysReg::W23) return PhysReg::X23;
|
|
if (reg == PhysReg::W24) return PhysReg::X24;
|
|
return reg;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
MachineFunction::MachineFunction(std::string name)
|
|
: name_(std::move(name)) {
|
|
// 创建入口块
|
|
blocks_.push_back(std::make_unique<MachineBasicBlock>("entry"));
|
|
}
|
|
|
|
MachineBasicBlock* MachineFunction::CreateBlock(std::string name) {
|
|
blocks_.push_back(std::make_unique<MachineBasicBlock>(std::move(name)));
|
|
return blocks_.back().get();
|
|
}
|
|
|
|
MachineBasicBlock* MachineFunction::FindBlock(const std::string& name) {
|
|
for (auto& block : blocks_) {
|
|
if (block->GetName() == name) {
|
|
return block.get();
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
int MachineFunction::CreateFrameIndex(int size) {
|
|
int index = static_cast<int>(frame_slots_.size());
|
|
frame_slots_.push_back(FrameSlot{index, size, 0});
|
|
return index;
|
|
}
|
|
|
|
FrameSlot& MachineFunction::GetFrameSlot(int index) {
|
|
if (index < 0 || index >= static_cast<int>(frame_slots_.size())) {
|
|
throw std::runtime_error(FormatError("mir", "非法 FrameIndex"));
|
|
}
|
|
return frame_slots_[index];
|
|
}
|
|
|
|
const FrameSlot& MachineFunction::GetFrameSlot(int index) const {
|
|
if (index < 0 || index >= static_cast<int>(frame_slots_.size())) {
|
|
throw std::runtime_error(FormatError("mir", "非法 FrameIndex"));
|
|
}
|
|
return frame_slots_[index];
|
|
}
|
|
|
|
int MachineFunction::CreateVReg(VRegClass rc) {
|
|
(void)rc; // 类别信息在 Operand 中记录
|
|
return next_vreg_id_++;
|
|
}
|
|
|
|
void MachineFunction::AddUsedCalleeSaved(PhysReg reg) {
|
|
reg = CanonicalCalleeSavedReg(reg);
|
|
if (std::find(used_callee_saved_.begin(), used_callee_saved_.end(), reg) ==
|
|
used_callee_saved_.end()) {
|
|
used_callee_saved_.push_back(reg);
|
|
}
|
|
}
|
|
|
|
MachineFunction* MachineModule::CreateFunction(std::string name) {
|
|
functions_.push_back(std::make_unique<MachineFunction>(std::move(name)));
|
|
return functions_.back().get();
|
|
}
|
|
|
|
void MachineModule::AddGlobalVar(std::string name, int init_val, int count,
|
|
bool is_float, std::vector<int> init_elems) {
|
|
global_vars_.emplace_back(std::move(name), init_val, count, is_float,
|
|
std::move(init_elems));
|
|
}
|
|
|
|
} // namespace mir
|