refactor(dev): 统一 IR/MIR 接口命名风格
This commit is contained in:
@@ -10,10 +10,10 @@ namespace {
|
||||
|
||||
const FrameSlot& GetFrameSlot(const MachineFunction& function,
|
||||
const Operand& operand) {
|
||||
if (operand.kind() != Operand::Kind::FrameIndex) {
|
||||
if (operand.GetKind() != Operand::Kind::FrameIndex) {
|
||||
throw std::runtime_error(FormatError("mir", "期望 FrameIndex 操作数"));
|
||||
}
|
||||
return function.frame_slot(operand.frame_index());
|
||||
return function.GetFrameSlot(operand.GetFrameIndex());
|
||||
}
|
||||
|
||||
void PrintStackAccess(std::ostream& os, const char* mnemonic, PhysReg reg,
|
||||
@@ -26,44 +26,44 @@ void PrintStackAccess(std::ostream& os, const char* mnemonic, PhysReg reg,
|
||||
|
||||
void PrintAsm(const MachineFunction& function, std::ostream& os) {
|
||||
os << ".text\n";
|
||||
os << ".global " << function.name() << "\n";
|
||||
os << ".type " << function.name() << ", %function\n";
|
||||
os << function.name() << ":\n";
|
||||
os << ".global " << function.GetName() << "\n";
|
||||
os << ".type " << function.GetName() << ", %function\n";
|
||||
os << function.GetName() << ":\n";
|
||||
|
||||
for (const auto& inst : function.entry().instructions()) {
|
||||
const auto& ops = inst.operands();
|
||||
switch (inst.opcode()) {
|
||||
for (const auto& inst : function.GetEntry().GetInstructions()) {
|
||||
const auto& ops = inst.GetOperands();
|
||||
switch (inst.GetOpcode()) {
|
||||
case Opcode::Prologue:
|
||||
os << " stp x29, x30, [sp, #-16]!\n";
|
||||
os << " mov x29, sp\n";
|
||||
if (function.frame_size() > 0) {
|
||||
os << " sub sp, sp, #" << function.frame_size() << "\n";
|
||||
if (function.GetFrameSize() > 0) {
|
||||
os << " sub sp, sp, #" << function.GetFrameSize() << "\n";
|
||||
}
|
||||
break;
|
||||
case Opcode::Epilogue:
|
||||
if (function.frame_size() > 0) {
|
||||
os << " add sp, sp, #" << function.frame_size() << "\n";
|
||||
if (function.GetFrameSize() > 0) {
|
||||
os << " add sp, sp, #" << function.GetFrameSize() << "\n";
|
||||
}
|
||||
os << " ldp x29, x30, [sp], #16\n";
|
||||
break;
|
||||
case Opcode::MovImm:
|
||||
os << " mov " << PhysRegName(ops.at(0).reg()) << ", #"
|
||||
<< ops.at(1).imm() << "\n";
|
||||
os << " mov " << PhysRegName(ops.at(0).GetReg()) << ", #"
|
||||
<< ops.at(1).GetImm() << "\n";
|
||||
break;
|
||||
case Opcode::LoadStack: {
|
||||
const auto& slot = GetFrameSlot(function, ops.at(1));
|
||||
PrintStackAccess(os, "ldur", ops.at(0).reg(), slot.offset);
|
||||
PrintStackAccess(os, "ldur", ops.at(0).GetReg(), slot.offset);
|
||||
break;
|
||||
}
|
||||
case Opcode::StoreStack: {
|
||||
const auto& slot = GetFrameSlot(function, ops.at(1));
|
||||
PrintStackAccess(os, "stur", ops.at(0).reg(), slot.offset);
|
||||
PrintStackAccess(os, "stur", ops.at(0).GetReg(), slot.offset);
|
||||
break;
|
||||
}
|
||||
case Opcode::AddRR:
|
||||
os << " add " << PhysRegName(ops.at(0).reg()) << ", "
|
||||
<< PhysRegName(ops.at(1).reg()) << ", "
|
||||
<< PhysRegName(ops.at(2).reg()) << "\n";
|
||||
os << " add " << PhysRegName(ops.at(0).GetReg()) << ", "
|
||||
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
||||
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
||||
break;
|
||||
case Opcode::Ret:
|
||||
os << " ret\n";
|
||||
@@ -71,7 +71,8 @@ void PrintAsm(const MachineFunction& function, std::ostream& os) {
|
||||
}
|
||||
}
|
||||
|
||||
os << ".size " << function.name() << ", .-" << function.name() << "\n";
|
||||
os << ".size " << function.GetName() << ", .-" << function.GetName()
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
} // namespace mir
|
||||
|
||||
@@ -16,7 +16,7 @@ int AlignTo(int value, int align) {
|
||||
|
||||
void RunFrameLowering(MachineFunction& function) {
|
||||
int cursor = 0;
|
||||
for (const auto& slot : function.frame_slots()) {
|
||||
for (const auto& slot : function.GetFrameSlots()) {
|
||||
cursor += slot.size;
|
||||
if (-cursor < -256) {
|
||||
throw std::runtime_error(FormatError("mir", "暂不支持过大的栈帧"));
|
||||
@@ -24,17 +24,17 @@ void RunFrameLowering(MachineFunction& function) {
|
||||
}
|
||||
|
||||
cursor = 0;
|
||||
for (const auto& slot : function.frame_slots()) {
|
||||
for (const auto& slot : function.GetFrameSlots()) {
|
||||
cursor += slot.size;
|
||||
function.frame_slot(slot.index).offset = -cursor;
|
||||
function.GetFrameSlot(slot.index).offset = -cursor;
|
||||
}
|
||||
function.set_frame_size(AlignTo(cursor, 16));
|
||||
function.SetFrameSize(AlignTo(cursor, 16));
|
||||
|
||||
auto& insts = function.entry().instructions();
|
||||
auto& insts = function.GetEntry().GetInstructions();
|
||||
std::vector<MachineInstr> lowered;
|
||||
lowered.emplace_back(Opcode::Prologue);
|
||||
for (const auto& inst : insts) {
|
||||
if (inst.opcode() == Opcode::Ret) {
|
||||
if (inst.GetOpcode() == Opcode::Ret) {
|
||||
lowered.emplace_back(Opcode::Epilogue);
|
||||
}
|
||||
lowered.push_back(inst);
|
||||
|
||||
@@ -15,14 +15,14 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
|
||||
const ValueSlotMap& slots, MachineBasicBlock& block) {
|
||||
if (auto* constant = dynamic_cast<const ir::ConstantInt*>(value)) {
|
||||
block.Append(Opcode::MovImm,
|
||||
{Operand::Reg(target), Operand::Imm(constant->value())});
|
||||
{Operand::Reg(target), Operand::Imm(constant->GetValue())});
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = slots.find(value);
|
||||
if (it == slots.end()) {
|
||||
throw std::runtime_error(
|
||||
FormatError("mir", "找不到值对应的栈槽: " + value->name()));
|
||||
FormatError("mir", "找不到值对应的栈槽: " + value->GetName()));
|
||||
}
|
||||
|
||||
block.Append(Opcode::LoadStack,
|
||||
@@ -31,28 +31,28 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
|
||||
|
||||
void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
||||
ValueSlotMap& slots) {
|
||||
auto& block = function.entry();
|
||||
auto& block = function.GetEntry();
|
||||
|
||||
switch (inst.opcode()) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case ir::Opcode::Alloca: {
|
||||
slots.emplace(&inst, function.CreateFrameIndex());
|
||||
return;
|
||||
}
|
||||
case ir::Opcode::Store: {
|
||||
auto& store = static_cast<const ir::StoreInst&>(inst);
|
||||
auto dst = slots.find(store.ptr());
|
||||
auto dst = slots.find(store.GetPtr());
|
||||
if (dst == slots.end()) {
|
||||
throw std::runtime_error(
|
||||
FormatError("mir", "暂不支持对非栈变量地址进行写入"));
|
||||
}
|
||||
EmitValueToReg(store.value(), PhysReg::W8, slots, block);
|
||||
EmitValueToReg(store.GetValue(), PhysReg::W8, slots, block);
|
||||
block.Append(Opcode::StoreStack,
|
||||
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst->second)});
|
||||
return;
|
||||
}
|
||||
case ir::Opcode::Load: {
|
||||
auto& load = static_cast<const ir::LoadInst&>(inst);
|
||||
auto src = slots.find(load.ptr());
|
||||
auto src = slots.find(load.GetPtr());
|
||||
if (src == slots.end()) {
|
||||
throw std::runtime_error(
|
||||
FormatError("mir", "暂不支持对非栈变量地址进行读取"));
|
||||
@@ -68,8 +68,8 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
||||
case ir::Opcode::Add: {
|
||||
auto& bin = static_cast<const ir::BinaryInst&>(inst);
|
||||
int dst_slot = function.CreateFrameIndex();
|
||||
EmitValueToReg(bin.lhs(), PhysReg::W8, slots, block);
|
||||
EmitValueToReg(bin.rhs(), PhysReg::W9, slots, block);
|
||||
EmitValueToReg(bin.GetLhs(), PhysReg::W8, slots, block);
|
||||
EmitValueToReg(bin.GetRhs(), PhysReg::W9, slots, block);
|
||||
block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::W8),
|
||||
Operand::Reg(PhysReg::W8),
|
||||
Operand::Reg(PhysReg::W9)});
|
||||
@@ -80,7 +80,7 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
||||
}
|
||||
case ir::Opcode::Ret: {
|
||||
auto& ret = static_cast<const ir::ReturnInst&>(inst);
|
||||
EmitValueToReg(ret.value(), PhysReg::W0, slots, block);
|
||||
EmitValueToReg(ret.GetValue(), PhysReg::W0, slots, block);
|
||||
block.Append(Opcode::Ret);
|
||||
return;
|
||||
}
|
||||
@@ -97,23 +97,23 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
||||
std::unique_ptr<MachineFunction> LowerToMIR(const ir::Module& module) {
|
||||
DefaultContext();
|
||||
|
||||
if (module.functions().size() != 1) {
|
||||
if (module.GetFunctions().size() != 1) {
|
||||
throw std::runtime_error(FormatError("mir", "暂不支持多个函数"));
|
||||
}
|
||||
|
||||
const auto& func = *module.functions().front();
|
||||
if (func.name() != "main") {
|
||||
const auto& func = *module.GetFunctions().front();
|
||||
if (func.GetName() != "main") {
|
||||
throw std::runtime_error(FormatError("mir", "暂不支持非 main 函数"));
|
||||
}
|
||||
|
||||
auto machine_func = std::make_unique<MachineFunction>(func.name());
|
||||
auto machine_func = std::make_unique<MachineFunction>(func.GetName());
|
||||
ValueSlotMap slots;
|
||||
const auto* entry = func.entry();
|
||||
const auto* entry = func.GetEntry();
|
||||
if (!entry) {
|
||||
throw std::runtime_error(FormatError("mir", "IR 函数缺少入口基本块"));
|
||||
}
|
||||
|
||||
for (const auto& inst : entry->instructions()) {
|
||||
for (const auto& inst : entry->GetInstructions()) {
|
||||
LowerInstruction(*inst, *machine_func, slots);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,14 +16,14 @@ int MachineFunction::CreateFrameIndex(int size) {
|
||||
return index;
|
||||
}
|
||||
|
||||
FrameSlot& MachineFunction::frame_slot(int 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::frame_slot(int index) const {
|
||||
const FrameSlot& MachineFunction::GetFrameSlot(int index) const {
|
||||
if (index < 0 || index >= static_cast<int>(frame_slots_.size())) {
|
||||
throw std::runtime_error(FormatError("mir", "非法 FrameIndex"));
|
||||
}
|
||||
|
||||
@@ -23,9 +23,10 @@ bool IsAllowedReg(PhysReg reg) {
|
||||
} // namespace
|
||||
|
||||
void RunRegAlloc(MachineFunction& function) {
|
||||
for (const auto& inst : function.entry().instructions()) {
|
||||
for (const auto& operand : inst.operands()) {
|
||||
if (operand.kind() == Operand::Kind::Reg && !IsAllowedReg(operand.reg())) {
|
||||
for (const auto& inst : function.GetEntry().GetInstructions()) {
|
||||
for (const auto& operand : inst.GetOperands()) {
|
||||
if (operand.GetKind() == Operand::Kind::Reg &&
|
||||
!IsAllowedReg(operand.GetReg())) {
|
||||
throw std::runtime_error(FormatError("mir", "寄存器分配失败"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user