Commit 606023f0 authored by Yang's avatar Yang

remove basicblock ilist

parent aa8e7d9f
...@@ -9,6 +9,10 @@ SET(CMAKE_CXX_FLAGS_ASAN "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=undefined -fsaniti ...@@ -9,6 +9,10 @@ SET(CMAKE_CXX_FLAGS_ASAN "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=undefined -fsaniti
set(default_build_type "Debug") 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_SHADOW STREQUAL CMAKE_BUILD_TYPE))
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${default_build_type}'") message(STATUS "Setting build type to '${default_build_type}'")
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "ASMInstruction.hpp" #include "ASMInstruction.hpp"
#include "Module.hpp" #include "Module.hpp"
#include "Register.hpp" #include "Register.hpp"
#include <unordered_map>
class CodeGen { class CodeGen {
public: public:
......
...@@ -13,7 +13,7 @@ class Function; ...@@ -13,7 +13,7 @@ class Function;
class Instruction; class Instruction;
class Module; class Module;
class BasicBlock : public Value, public llvm::ilist_node<BasicBlock> { class BasicBlock : public Value {
public: public:
~BasicBlock() = default; ~BasicBlock() = default;
static BasicBlock *create(Module *m, const std::string &name, static BasicBlock *create(Module *m, const std::string &name,
......
...@@ -36,10 +36,11 @@ class Function : public Value, public llvm::ilist_node<Function> { ...@@ -36,10 +36,11 @@ class Function : public Value, public llvm::ilist_node<Function> {
Module *get_parent() const; Module *get_parent() const;
// 此处 remove 的 BasicBlock, 需要手动 delete
void remove(BasicBlock *bb); void remove(BasicBlock *bb);
BasicBlock *get_entry_block() { return &*basic_blocks_.begin(); } BasicBlock *get_entry_block() { return basic_blocks_.front(); }
llvm::ilist<BasicBlock> &get_basic_blocks() { return basic_blocks_; } std::list<BasicBlock*> &get_basic_blocks() { return basic_blocks_; }
std::list<Argument> &get_args() { return arguments_; } std::list<Argument> &get_args() { return arguments_; }
bool is_declaration() { return basic_blocks_.empty(); } bool is_declaration() { return basic_blocks_.empty(); }
...@@ -50,7 +51,7 @@ class Function : public Value, public llvm::ilist_node<Function> { ...@@ -50,7 +51,7 @@ class Function : public Value, public llvm::ilist_node<Function> {
void check_for_block_relation_error(); void check_for_block_relation_error();
private: private:
llvm::ilist<BasicBlock> basic_blocks_; std::list<BasicBlock*> basic_blocks_;
std::list<Argument> arguments_; std::list<Argument> arguments_;
Module *parent_; Module *parent_;
unsigned seq_cnt_; // print use unsigned seq_cnt_; // print use
......
...@@ -23,6 +23,12 @@ class Type { ...@@ -23,6 +23,12 @@ class Type {
}; };
explicit Type(TypeID tid, Module *m); explicit Type(TypeID tid, Module *m);
// 生成 vptr, 使调试时能够显示 IntegerType 等 Type 的信息
#ifdef DEBUG_BUILD
virtual
#endif
~Type() = default; ~Type() = default;
TypeID get_type_id() const { return tid_; } TypeID get_type_id() const { return tid_; }
......
...@@ -14,8 +14,8 @@ void CodeGen::allocate() { ...@@ -14,8 +14,8 @@ void CodeGen::allocate() {
} }
// 为指令结果分配栈空间 // 为指令结果分配栈空间
for (auto &bb : context.func->get_basic_blocks()) { for (auto bb : context.func->get_basic_blocks()) {
for (auto &instr : bb.get_instructions()) { for (auto& instr : bb->get_instructions()) {
// 每个非 void 的定值都分配栈空间 // 每个非 void 的定值都分配栈空间
if (not instr.is_void()) { if (not instr.is_void()) {
auto size = instr.get_type()->get_size(); auto size = instr.get_type()->get_size();
...@@ -407,10 +407,10 @@ void CodeGen::run() { ...@@ -407,10 +407,10 @@ void CodeGen::run() {
// 生成 prologue // 生成 prologue
gen_prologue(); gen_prologue();
for (auto &bb : func.get_basic_blocks()) { for (auto bb : func.get_basic_blocks()) {
context.bb = &bb; context.bb = bb;
append_inst(label_name(context.bb), ASMInstruction::Label); append_inst(label_name(context.bb), ASMInstruction::Label);
for (auto &instr : bb.get_instructions()) { for (auto &instr : bb->get_instructions()) {
// For debug // For debug
append_inst(instr.print(), ASMInstruction::Comment); append_inst(instr.print(), ASMInstruction::Comment);
context.inst = &instr; // 更新 context context.inst = &instr; // 更新 context
......
...@@ -58,8 +58,7 @@ void Function::set_instr_name() { ...@@ -58,8 +58,7 @@ void Function::set_instr_name() {
} }
} }
} }
for (auto &bb1 : basic_blocks_) { for (auto bb : basic_blocks_) {
auto bb = &bb1;
if (seq.find(bb) == seq.end()) { if (seq.find(bb) == seq.end()) {
auto seq_num = seq.size() + seq_cnt_; auto seq_num = seq.size() + seq_cnt_;
if (bb->set_name("label" + std::to_string(seq_num))) { if (bb->set_name("label" + std::to_string(seq_num))) {
...@@ -116,8 +115,7 @@ std::string Function::print() { ...@@ -116,8 +115,7 @@ std::string Function::print() {
} else { } else {
func_ir += " {"; func_ir += " {";
func_ir += "\n"; func_ir += "\n";
for (auto &bb1 : this->get_basic_blocks()) { for (auto &bb : this->get_basic_blocks()) {
auto bb = &bb1;
func_ir += bb->print(); func_ir += bb->print();
} }
func_ir += "}"; func_ir += "}";
...@@ -139,18 +137,18 @@ void Function::check_for_block_relation_error() ...@@ -139,18 +137,18 @@ void Function::check_for_block_relation_error()
{ {
// 检查函数的基本块表是否包含所有且仅包含 get_parent 是本函数的基本块 // 检查函数的基本块表是否包含所有且仅包含 get_parent 是本函数的基本块
std::unordered_set<BasicBlock*> bbs; std::unordered_set<BasicBlock*> 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"); assert((bb->get_parent() == this) && "函数 F 的基本块表中包含基本块 a, 但 a 的 get_parent 方法不返回 F");
for (auto i: bb.get_succ_basic_blocks()) for (auto i: bb->get_succ_basic_blocks())
{ {
assert((bbs.count(i)) && "函数 F 的基本块表中包含基本块 a, a 的后继块表中的某基本块 b 不在 F 的基本块表中"); 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 的基本块表中"); assert((bbs.count(i)) && "函数 F 的基本块表中包含基本块 a, a 的前驱块表中的某基本块 b 不在 F 的基本块表中");
} }
...@@ -171,22 +169,22 @@ void Function::check_for_block_relation_error() ...@@ -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()) && "发现了空基本块"); assert((!bb->get_instructions().empty()) && "发现了空基本块");
auto b = &bb.get_instructions().back(); auto b = &bb->get_instructions().back();
assert((b->is_br() || b->is_ret()) && "发现了无 terminator 基本块"); 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 指令对应 // 检查基本块前驱后继关系是否是与 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<BasicBlock*> suc_table; std::unordered_set<BasicBlock*> suc_table;
std::unordered_set<BasicBlock*> br_get; std::unordered_set<BasicBlock*> br_get;
for (auto suc : bb.get_succ_basic_blocks()) for (auto suc : bb->get_succ_basic_blocks())
suc_table.emplace(suc); suc_table.emplace(suc);
auto& ops = bb.get_instructions().back().get_operands(); auto& ops = bb->get_instructions().back().get_operands();
for (auto i : ops) for (auto i : ops)
{ {
auto bb2 = dynamic_cast<BasicBlock*>(i); auto bb2 = dynamic_cast<BasicBlock*>(i);
...@@ -199,7 +197,7 @@ void Function::check_for_block_relation_error() ...@@ -199,7 +197,7 @@ void Function::check_for_block_relation_error()
for(auto i : suc_table) { for(auto i : suc_table) {
bool ok = false; bool ok = false;
for(auto j : i->get_pre_basic_blocks()) { for(auto j : i->get_pre_basic_blocks()) {
if(j == &bb){ if(j == bb){
ok = true; ok = true;
break; break;
} }
...@@ -211,12 +209,12 @@ void Function::check_for_block_relation_error() ...@@ -211,12 +209,12 @@ void Function::check_for_block_relation_error()
// 检查基本块前驱后继关系是否是与 branch 指令对应 // 检查基本块前驱后继关系是否是与 branch 指令对应
for (auto& bb : basic_blocks_) for (auto& bb : basic_blocks_)
{ {
for (auto pre : bb.get_pre_basic_blocks()) for (auto pre : bb->get_pre_basic_blocks())
{ {
bool ok = false; bool ok = false;
for (auto i : pre->get_succ_basic_blocks()) for (auto i : pre->get_succ_basic_blocks())
{ {
if (i == &bb) if (i == bb)
{ {
ok = true; ok = true;
break; break;
...@@ -229,9 +227,9 @@ void Function::check_for_block_relation_error() ...@@ -229,9 +227,9 @@ void Function::check_for_block_relation_error()
// 检查指令 parent 设置 // 检查指令 parent 设置
for (auto& bb : basic_blocks_) 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");
} }
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment