// IR 文本输出: // - 将 IR 打印为 .ll 风格的文本 // - 支撑调试与测试对比(diff) #include "ir/IR.h" #include #include #include namespace ir { static const char* TypeToString(const Type& ty) { switch (ty.kind()) { case Type::Kind::Void: return "void"; case Type::Kind::Int32: return "i32"; case Type::Kind::PtrInt32: return "i32*"; } throw std::runtime_error("未知类型"); } static const char* OpcodeToString(Opcode op) { switch (op) { case Opcode::Add: return "add"; case Opcode::Sub: return "sub"; case Opcode::Mul: return "mul"; case Opcode::Alloca: return "alloca"; case Opcode::Load: return "load"; case Opcode::Store: return "store"; case Opcode::Ret: return "ret"; } return "?"; } static std::string ValueToString(const Value* v) { if (auto* ci = dynamic_cast(v)) { return std::to_string(ci->value()); } return v ? v->name() : ""; } void IRPrinter::Print(const Module& module, std::ostream& os) { for (const auto& func : module.functions()) { os << "define " << TypeToString(*func->type()) << " @" << func->name() << "() {\n"; for (const auto& bb : func->blocks()) { if (!bb) { continue; } os << bb->name() << ":\n"; for (const auto& instPtr : bb->instructions()) { const auto* inst = instPtr.get(); switch (inst->opcode()) { case Opcode::Add: case Opcode::Sub: case Opcode::Mul: { auto* bin = static_cast(inst); os << " " << bin->name() << " = " << OpcodeToString(bin->opcode()) << " " << TypeToString(*bin->lhs()->type()) << " " << ValueToString(bin->lhs()) << ", " << ValueToString(bin->rhs()) << "\n"; break; } case Opcode::Alloca: { auto* alloca = static_cast(inst); os << " " << alloca->name() << " = alloca i32\n"; break; } case Opcode::Load: { auto* load = static_cast(inst); os << " " << load->name() << " = load i32, i32* " << ValueToString(load->ptr()) << "\n"; break; } case Opcode::Store: { auto* store = static_cast(inst); os << " store i32 " << ValueToString(store->value()) << ", i32* " << ValueToString(store->ptr()) << "\n"; break; } case Opcode::Ret: { auto* ret = static_cast(inst); os << " ret " << TypeToString(*ret->value()->type()) << " " << ValueToString(ret->value()) << "\n"; break; } } } } os << "}\n"; } } } // namespace ir