fix(irgen): 规范irgen实现
This commit is contained in:
@@ -78,3 +78,7 @@ WS
|
|||||||
COMMENT
|
COMMENT
|
||||||
: '//' ~[\r\n]* -> skip
|
: '//' ~[\r\n]* -> skip
|
||||||
;
|
;
|
||||||
|
|
||||||
|
BLOCK_COMMENT
|
||||||
|
: '/*' .*? '*/' -> skip
|
||||||
|
;
|
||||||
|
|||||||
@@ -53,47 +53,47 @@ void IRPrinter::Print(const Module& module) {
|
|||||||
for (const auto& func : module.functions()) {
|
for (const auto& func : module.functions()) {
|
||||||
std::cout << "define " << TypeToString(*func->type()) << " @"
|
std::cout << "define " << TypeToString(*func->type()) << " @"
|
||||||
<< func->name() << "() {\n";
|
<< func->name() << "() {\n";
|
||||||
const auto* bb = func->entry();
|
for (const auto& bb : func->blocks()) {
|
||||||
if (!bb) {
|
if (!bb) {
|
||||||
std::cout << "}\n";
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
std::cout << bb->name() << ":\n";
|
||||||
std::cout << "entry:\n";
|
for (const auto& instPtr : bb->instructions()) {
|
||||||
for (const auto& instPtr : bb->instructions()) {
|
const auto* inst = instPtr.get();
|
||||||
const auto* inst = instPtr.get();
|
switch (inst->opcode()) {
|
||||||
switch (inst->opcode()) {
|
case Opcode::Add:
|
||||||
case Opcode::Add:
|
case Opcode::Sub:
|
||||||
case Opcode::Sub:
|
case Opcode::Mul: {
|
||||||
case Opcode::Mul: {
|
auto* bin = static_cast<const BinaryInst*>(inst);
|
||||||
auto* bin = static_cast<const BinaryInst*>(inst);
|
std::cout << " " << bin->name() << " = " << OpcodeToString(bin->opcode())
|
||||||
std::cout << " " << bin->name() << " = " << OpcodeToString(bin->opcode())
|
<< " " << TypeToString(*bin->lhs()->type()) << " "
|
||||||
<< " " << TypeToString(*bin->lhs()->type()) << " "
|
<< ValueToString(bin->lhs()) << ", "
|
||||||
<< ValueToString(bin->lhs()) << ", "
|
<< ValueToString(bin->rhs()) << "\n";
|
||||||
<< ValueToString(bin->rhs()) << "\n";
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case Opcode::Alloca: {
|
||||||
case Opcode::Alloca: {
|
auto* alloca = static_cast<const AllocaInst*>(inst);
|
||||||
auto* alloca = static_cast<const AllocaInst*>(inst);
|
std::cout << " " << alloca->name() << " = alloca i32\n";
|
||||||
std::cout << " " << alloca->name() << " = alloca i32\n";
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case Opcode::Load: {
|
||||||
case Opcode::Load: {
|
auto* load = static_cast<const LoadInst*>(inst);
|
||||||
auto* load = static_cast<const LoadInst*>(inst);
|
std::cout << " " << load->name() << " = load i32, i32* "
|
||||||
std::cout << " " << load->name() << " = load i32, i32* "
|
<< ValueToString(load->ptr()) << "\n";
|
||||||
<< ValueToString(load->ptr()) << "\n";
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case Opcode::Store: {
|
||||||
case Opcode::Store: {
|
auto* store = static_cast<const StoreInst*>(inst);
|
||||||
auto* store = static_cast<const StoreInst*>(inst);
|
std::cout << " store i32 " << ValueToString(store->value()) << ", i32* "
|
||||||
std::cout << " store i32 " << ValueToString(store->value()) << ", i32* "
|
<< ValueToString(store->ptr()) << "\n";
|
||||||
<< ValueToString(store->ptr()) << "\n";
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case Opcode::Ret: {
|
||||||
case Opcode::Ret: {
|
auto* ret = static_cast<const ReturnInst*>(inst);
|
||||||
auto* ret = static_cast<const ReturnInst*>(inst);
|
std::cout << " ret " << TypeToString(*ret->value()->type()) << " "
|
||||||
std::cout << " ret " << TypeToString(*ret->value()->type()) << " "
|
<< ValueToString(ret->value()) << "\n";
|
||||||
<< ValueToString(ret->value()) << "\n";
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,6 @@
|
|||||||
|
|
||||||
namespace ir {
|
namespace ir {
|
||||||
|
|
||||||
ConstantInt::ConstantInt(int v) : Value(Type::Int32(), ""), value_(v) {
|
ConstantInt::ConstantInt(int v) : Value(Type::Int32(), ""), value_(v) {}
|
||||||
set_name(std::to_string(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ir
|
} // namespace ir
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class IRGenImpl {
|
|||||||
ir::Module& module_;
|
ir::Module& module_;
|
||||||
ir::Function* func_;
|
ir::Function* func_;
|
||||||
ir::IRBuilder builder_;
|
ir::IRBuilder builder_;
|
||||||
|
// 当前只维护函数级局部变量表;若后续引入嵌套块作用域,需要改成作用域栈。
|
||||||
std::unordered_map<std::string, ir::Value*> locals_;
|
std::unordered_map<std::string, ir::Value*> locals_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ void IRGenImpl::GenBlock(SysYParser::BlockContext& block) {
|
|||||||
for (auto* item : block.blockItem()) {
|
for (auto* item : block.blockItem()) {
|
||||||
if (item) {
|
if (item) {
|
||||||
if (GenBlockItem(*item)) {
|
if (GenBlockItem(*item)) {
|
||||||
|
// 当前语法要求 return 为块内最后一条语句;命中后可停止生成。
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ ir::Value* IRGenImpl::GenExpr(SysYParser::ExpContext& expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ir::Value* IRGenImpl::GenAddExpr(SysYParser::AddExpContext& add) {
|
ir::Value* IRGenImpl::GenAddExpr(SysYParser::AddExpContext& add) {
|
||||||
|
// 当前表达式层次仍是最小实现,直接贴合 addExp -> primary 的语法形状。
|
||||||
const auto& terms = add.primary();
|
const auto& terms = add.primary();
|
||||||
if (terms.empty()) {
|
if (terms.empty()) {
|
||||||
throw std::runtime_error("[irgen] 空加法表达式");
|
throw std::runtime_error("[irgen] 空加法表达式");
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void VerifyFunctionStructure(const ir::Function& func) {
|
void VerifyFunctionStructure(const ir::Function& func) {
|
||||||
|
// 当前 IRGen 仍是单入口、顺序生成;这里在生成结束后补一层块终结校验。
|
||||||
for (const auto& bb : func.blocks()) {
|
for (const auto& bb : func.blocks()) {
|
||||||
if (!bb || !bb->HasTerminator()) {
|
if (!bb || !bb->HasTerminator()) {
|
||||||
throw std::runtime_error("[irgen] 基本块未正确终结: " +
|
throw std::runtime_error("[irgen] 基本块未正确终结: " +
|
||||||
@@ -41,5 +42,6 @@ void IRGenImpl::GenFuncDef(SysYParser::FuncDefContext& func) {
|
|||||||
locals_.clear();
|
locals_.clear();
|
||||||
|
|
||||||
GenBlock(*func.block());
|
GenBlock(*func.block());
|
||||||
|
// 语义正确性主要由 sema 保证,这里只兜底检查 IR 结构是否合法。
|
||||||
VerifyFunctionStructure(*func_);
|
VerifyFunctionStructure(*func_);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user