From 606023f0d09567fa562fdadf5f42ebbc54ab8687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E9=BE=99=E6=88=90?= Date: Tue, 25 Nov 2025 20:08:04 +0800 Subject: [PATCH] remove basicblock ilist --- CMakeLists.txt | 4 ++++ include/codegen/CodeGen.hpp | 1 + include/lightir/BasicBlock.hpp | 2 +- include/lightir/Function.hpp | 7 +++--- include/lightir/Type.hpp | 8 ++++++- src/codegen/CodeGen.cpp | 10 ++++---- src/lightir/Function.cpp | 44 ++++++++++++++++------------------ 7 files changed, 43 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index addee0a..99675e8 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,10 @@ SET(CMAKE_CXX_FLAGS_ASAN "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=undefined -fsaniti set(default_build_type "Debug") +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + add_definitions(-DDEBUG_BUILD) +endif() + if(NOT(CMAKE_BUILD_TYPE_SHADOW STREQUAL CMAKE_BUILD_TYPE)) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to '${default_build_type}'") diff --git a/include/codegen/CodeGen.hpp b/include/codegen/CodeGen.hpp index 39dd622..8680a7c 100755 --- a/include/codegen/CodeGen.hpp +++ b/include/codegen/CodeGen.hpp @@ -3,6 +3,7 @@ #include "ASMInstruction.hpp" #include "Module.hpp" #include "Register.hpp" +#include class CodeGen { public: diff --git a/include/lightir/BasicBlock.hpp b/include/lightir/BasicBlock.hpp index bbd1c75..9b5555e 100755 --- a/include/lightir/BasicBlock.hpp +++ b/include/lightir/BasicBlock.hpp @@ -13,7 +13,7 @@ class Function; class Instruction; class Module; -class BasicBlock : public Value, public llvm::ilist_node { +class BasicBlock : public Value { public: ~BasicBlock() = default; static BasicBlock *create(Module *m, const std::string &name, diff --git a/include/lightir/Function.hpp b/include/lightir/Function.hpp index 0959e1f..db1d566 100755 --- a/include/lightir/Function.hpp +++ b/include/lightir/Function.hpp @@ -36,10 +36,11 @@ class Function : public Value, public llvm::ilist_node { Module *get_parent() const; + // 此处 remove 的 BasicBlock, 需要手动 delete void remove(BasicBlock *bb); - BasicBlock *get_entry_block() { return &*basic_blocks_.begin(); } + BasicBlock *get_entry_block() { return basic_blocks_.front(); } - llvm::ilist &get_basic_blocks() { return basic_blocks_; } + std::list &get_basic_blocks() { return basic_blocks_; } std::list &get_args() { return arguments_; } bool is_declaration() { return basic_blocks_.empty(); } @@ -50,7 +51,7 @@ class Function : public Value, public llvm::ilist_node { void check_for_block_relation_error(); private: - llvm::ilist basic_blocks_; + std::list basic_blocks_; std::list arguments_; Module *parent_; unsigned seq_cnt_; // print use diff --git a/include/lightir/Type.hpp b/include/lightir/Type.hpp index 5d456a7..8a06bec 100755 --- a/include/lightir/Type.hpp +++ b/include/lightir/Type.hpp @@ -23,7 +23,13 @@ class Type { }; explicit Type(TypeID tid, Module *m); - ~Type() = default; + +// 生成 vptr, 使调试时能够显示 IntegerType 等 Type 的信息 +#ifdef DEBUG_BUILD + virtual +#endif + + ~Type() = default; TypeID get_type_id() const { return tid_; } diff --git a/src/codegen/CodeGen.cpp b/src/codegen/CodeGen.cpp index f947e4c..5246146 100755 --- a/src/codegen/CodeGen.cpp +++ b/src/codegen/CodeGen.cpp @@ -14,8 +14,8 @@ void CodeGen::allocate() { } // 为指令结果分配栈空间 - for (auto &bb : context.func->get_basic_blocks()) { - for (auto &instr : bb.get_instructions()) { + for (auto bb : context.func->get_basic_blocks()) { + for (auto& instr : bb->get_instructions()) { // 每个非 void 的定值都分配栈空间 if (not instr.is_void()) { auto size = instr.get_type()->get_size(); @@ -407,10 +407,10 @@ void CodeGen::run() { // 生成 prologue gen_prologue(); - for (auto &bb : func.get_basic_blocks()) { - context.bb = &bb; + for (auto bb : func.get_basic_blocks()) { + context.bb = bb; append_inst(label_name(context.bb), ASMInstruction::Label); - for (auto &instr : bb.get_instructions()) { + for (auto &instr : bb->get_instructions()) { // For debug append_inst(instr.print(), ASMInstruction::Comment); context.inst = &instr; // 更新 context diff --git a/src/lightir/Function.cpp b/src/lightir/Function.cpp index e10fd7c..7e197f5 100755 --- a/src/lightir/Function.cpp +++ b/src/lightir/Function.cpp @@ -58,8 +58,7 @@ void Function::set_instr_name() { } } } - for (auto &bb1 : basic_blocks_) { - auto bb = &bb1; + for (auto bb : basic_blocks_) { if (seq.find(bb) == seq.end()) { auto seq_num = seq.size() + seq_cnt_; if (bb->set_name("label" + std::to_string(seq_num))) { @@ -116,8 +115,7 @@ std::string Function::print() { } else { func_ir += " {"; func_ir += "\n"; - for (auto &bb1 : this->get_basic_blocks()) { - auto bb = &bb1; + for (auto &bb : this->get_basic_blocks()) { func_ir += bb->print(); } func_ir += "}"; @@ -139,18 +137,18 @@ void Function::check_for_block_relation_error() { // 检查函数的基本块表是否包含所有且仅包含 get_parent 是本函数的基本块 std::unordered_set bbs; - for (auto& bb : basic_blocks_) + for (auto bb : basic_blocks_) { - bbs.emplace(&bb); + bbs.emplace(bb); } - for (auto& bb : basic_blocks_) + for (auto bb : basic_blocks_) { - assert((bb.get_parent() == this) && "函数 F 的基本块表中包含基本块 a, 但 a 的 get_parent 方法不返回 F"); - for (auto i: bb.get_succ_basic_blocks()) + assert((bb->get_parent() == this) && "函数 F 的基本块表中包含基本块 a, 但 a 的 get_parent 方法不返回 F"); + for (auto i: bb->get_succ_basic_blocks()) { assert((bbs.count(i)) && "函数 F 的基本块表中包含基本块 a, a 的后继块表中的某基本块 b 不在 F 的基本块表中"); } - for (auto i: bb.get_pre_basic_blocks()) + for (auto i: bb->get_pre_basic_blocks()) { assert((bbs.count(i)) && "函数 F 的基本块表中包含基本块 a, a 的前驱块表中的某基本块 b 不在 F 的基本块表中"); } @@ -171,22 +169,22 @@ void Function::check_for_block_relation_error() } */ // 检查基本块基本信息 - for (auto& bb : basic_blocks_) + for (auto bb : basic_blocks_) { - assert((!bb.get_instructions().empty()) && "发现了空基本块"); - auto b = &bb.get_instructions().back(); + assert((!bb->get_instructions().empty()) && "发现了空基本块"); + auto b = &bb->get_instructions().back(); assert((b->is_br() || b->is_ret()) && "发现了无 terminator 基本块"); - assert((b->is_br() || bb.get_succ_basic_blocks().empty()) && "某基本块末尾是 ret 指令但是后继块表不是空的, 或者末尾是 br 但后继表为空"); + assert((b->is_br() || bb->get_succ_basic_blocks().empty()) && "某基本块末尾是 ret 指令但是后继块表不是空的, 或者末尾是 br 但后继表为空"); } // 检查基本块前驱后继关系是否是与 branch 指令对应 - for (auto& bb : basic_blocks_) + for (auto bb : basic_blocks_) { - if(!bb.get_succ_basic_blocks().empty()){ + if(!bb->get_succ_basic_blocks().empty()){ std::unordered_set suc_table; std::unordered_set br_get; - for (auto suc : bb.get_succ_basic_blocks()) + for (auto suc : bb->get_succ_basic_blocks()) suc_table.emplace(suc); - auto& ops = bb.get_instructions().back().get_operands(); + auto& ops = bb->get_instructions().back().get_operands(); for (auto i : ops) { auto bb2 = dynamic_cast(i); @@ -199,7 +197,7 @@ void Function::check_for_block_relation_error() for(auto i : suc_table) { bool ok = false; for(auto j : i->get_pre_basic_blocks()) { - if(j == &bb){ + if(j == bb){ ok = true; break; } @@ -211,12 +209,12 @@ void Function::check_for_block_relation_error() // 检查基本块前驱后继关系是否是与 branch 指令对应 for (auto& bb : basic_blocks_) { - for (auto pre : bb.get_pre_basic_blocks()) + for (auto pre : bb->get_pre_basic_blocks()) { bool ok = false; for (auto i : pre->get_succ_basic_blocks()) { - if (i == &bb) + if (i == bb) { ok = true; break; @@ -229,9 +227,9 @@ void Function::check_for_block_relation_error() // 检查指令 parent 设置 for (auto& bb : basic_blocks_) { - for (auto& inst : bb.get_instructions()) + for (auto& inst : bb->get_instructions()) { - assert ((inst.get_parent() == &bb) && "基本块 A 指令表包含指令 b, 但是 b 的 get_parent 函数不返回 A"); + assert ((inst.get_parent() == bb) && "基本块 A 指令表包含指令 b, 但是 b 的 get_parent 函数不返回 A"); } } } -- GitLab