Commit e547371b authored by Yang's avatar Yang

add codegen summary

parent c396901a
{ {
"configurations": [ "configurations": [
{ {
"type": "lldb", "type": "lldb",
"request": "launch", "request": "launch",
"name": "Compile & Debug 1.ll", "name": "Compile & Gen 1.ll",
// 要调试的程序 // 要调试的程序
"program": "${workspaceFolder}/build/cminusfc", "program": "${workspaceFolder}/build/cminusfc",
// 命令行参数 // 命令行参数
"args": [ "args": [
"-o", "-emit-llvm",
"./build/1.ll", "./build/1.cminus",
"-emit-llvm", "-o",
"./build/1.cminus" "./build/1.ll"
], ],
// 程序运行的目录 // 程序运行的目录
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
// 程序运行前运行的命令(例如 build) // 程序运行前运行的命令(例如 build)
"preLaunchTask": "make cminusfc", "preLaunchTask": "make cminusfc",
"initCommands": [ "initCommands": [
"command script import ${workspaceFolder}/lldb_formatters.py" "command script import ${workspaceFolder}/lldb_formatters.py"
] ]
}, },
{ {
"type": "lldb", "type": "lldb",
"request": "launch", "request": "launch",
"name": "Debug 1.ll", "name": "Gen 1.ll",
// 要调试的程序 // 要调试的程序
"program": "${workspaceFolder}/build/cminusfc", "program": "${workspaceFolder}/build/cminusfc",
// 命令行参数 // 命令行参数
"args": [ "args": [
"-o", "-emit-llvm",
"./build/1.ll", "./build/1.cminus",
"-emit-llvm", "-o",
"./build/1.cminus" "./build/1.ll"
], ],
// 程序运行的目录 // 程序运行的目录
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"initCommands": [ "initCommands": [
"command script import ${workspaceFolder}/lldb_formatters.py" "command script import ${workspaceFolder}/lldb_formatters.py"
] ]
} },
] {
"type": "lldb",
"request": "launch",
"name": "Compile & Gen 1.s",
// 要调试的程序
"program": "${workspaceFolder}/build/cminusfc",
// 命令行参数
"args": [
"-S",
"./build/1.cminus",
"-o",
"./build/1.s"
],
// 程序运行的目录
"cwd": "${workspaceFolder}",
// 程序运行前运行的命令(例如 build)
"preLaunchTask": "make cminusfc",
"initCommands": [
"command script import ${workspaceFolder}/lldb_formatters.py"
]
}
]
} }
\ No newline at end of file
{ {
"version": "2.0.0", "version": "2.0.0",
"tasks": [ "tasks": [
{ {
"type": "shell", "type": "shell",
"label": "make cminusfc", "label": "make cminusfc",
"command": "cd build && make" "command": "cd build && make"
} }
] ]
} }
\ No newline at end of file
...@@ -12,17 +12,17 @@ SET(CMAKE_CXX_FLAGS_ASAN "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=undefined -fsaniti ...@@ -12,17 +12,17 @@ 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") if(CMAKE_BUILD_TYPE STREQUAL "Debug")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
check_cxx_compiler_flag("-fstandalone-debug" CXX_SUPPORTS_STANDALONE_DEBUG) check_cxx_compiler_flag("-fstandalone-debug" CXX_SUPPORTS_STANDALONE_DEBUG)
if(CXX_SUPPORTS_STANDALONE_DEBUG) if(CXX_SUPPORTS_STANDALONE_DEBUG)
message(STATUS "Adding -fstandalone-debug for Clang") message(STATUS "Adding -fstandalone-debug for Clang")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fstandalone-debug") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fstandalone-debug")
else() else()
message(STATUS "Clang does not support -fstandalone-debug, skipping") message(STATUS "Clang does not support -fstandalone-debug, skipping")
endif() endif()
else() else()
message(STATUS "Use Gcc") message(STATUS "Use Gcc")
endif() endif()
endif() endif()
if(CMAKE_BUILD_TYPE STREQUAL "Debug") if(CMAKE_BUILD_TYPE STREQUAL "Debug")
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <string> #include <string>
struct ASMInstruction { struct ASMInstruction {
enum InstType { Instruction, Atrribute, Label, Comment } type; enum InstType { Instruction, Attribute, Label, Comment } type;
std::string content; std::string content;
explicit ASMInstruction(std::string s, InstType ty = Instruction) explicit ASMInstruction(std::string s, InstType ty = Instruction)
...@@ -13,7 +13,7 @@ struct ASMInstruction { ...@@ -13,7 +13,7 @@ struct ASMInstruction {
std::string format() const { std::string format() const {
switch (type) { switch (type) {
case ASMInstruction::Instruction: case ASMInstruction::Instruction:
case ASMInstruction::Atrribute: case ASMInstruction::Attribute:
return "\t" + content + "\n"; return "\t" + content + "\n";
case ASMInstruction::Label: case ASMInstruction::Label:
return content + ":\n"; return content + ":\n";
...@@ -22,4 +22,7 @@ struct ASMInstruction { ...@@ -22,4 +22,7 @@ struct ASMInstruction {
} }
assert(false && "unreachable"); assert(false && "unreachable");
} }
// 用于 lldb 调试生成 summary
std::string safe_print() const;
}; };
...@@ -8,13 +8,16 @@ ...@@ -8,13 +8,16 @@
class CodeGen { class CodeGen {
public: public:
explicit CodeGen(Module *module) : m(module) {} explicit CodeGen(Module *module) : m(module) {}
~CodeGen(){
for(auto i : output) delete i;
}
std::string print() const; std::string print() const;
void run(); void run();
template <class... Args> void append_inst(Args... arg) { template <class... Args> void append_inst(Args... arg) {
output.emplace_back(arg...); output.emplace_back(new ASMInstruction(arg...));
} }
void void
...@@ -26,7 +29,7 @@ class CodeGen { ...@@ -26,7 +29,7 @@ class CodeGen {
} }
content.pop_back(); content.pop_back();
content.pop_back(); content.pop_back();
output.emplace_back(content, ty); output.emplace_back(new ASMInstruction(content, ty));
} }
private: private:
...@@ -98,5 +101,5 @@ class CodeGen { ...@@ -98,5 +101,5 @@ class CodeGen {
} context; } context;
Module *m; Module *m;
std::list<ASMInstruction> output; std::list<ASMInstruction*> output;
}; };
...@@ -32,6 +32,9 @@ struct Reg { ...@@ -32,6 +32,9 @@ struct Reg {
std::string print() const; std::string print() const;
// 用于 lldb 调试生成 summary
std::string safe_print() const;
static Reg zero() { return Reg(0); } static Reg zero() { return Reg(0); }
static Reg ra() { return Reg(1); } static Reg ra() { return Reg(1); }
static Reg sp() { return Reg(3); } static Reg sp() { return Reg(3); }
...@@ -62,17 +65,20 @@ struct FReg { ...@@ -62,17 +65,20 @@ struct FReg {
std::string print() const; std::string print() const;
static FReg fa(unsigned i) { static FReg fa(unsigned i) {
assert(0 <= i and i <= 7); assert(i <= 7);
return FReg(i); return FReg(i);
} }
static FReg ft(unsigned i) { static FReg ft(unsigned i) {
assert(0 <= i and i <= 15); assert(i <= 15);
return FReg(i + 8); return FReg(i + 8);
} }
static FReg fs(unsigned i) { static FReg fs(unsigned i) {
assert(0 <= i and i <= 7); assert(i <= 7);
return FReg(i + 24); return FReg(i + 24);
} }
// 用于 lldb 调试生成 summary
std::string safe_print() const;
}; };
struct CFReg { struct CFReg {
...@@ -82,4 +88,7 @@ struct CFReg { ...@@ -82,4 +88,7 @@ struct CFReg {
bool operator==(const CFReg &other) { return id == other.id; } bool operator==(const CFReg &other) { return id == other.id; }
std::string print() const { return "$fcc" + std::to_string(id); } std::string print() const { return "$fcc" + std::to_string(id); }
// 用于 lldb 调试生成 summary
std::string safe_print() const;
}; };
...@@ -90,23 +90,23 @@ struct ASTNode { ...@@ -90,23 +90,23 @@ struct ASTNode {
}; };
struct ASTProgram : ASTNode { struct ASTProgram : ASTNode {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
~ASTProgram() override = default; ~ASTProgram() override = default;
std::vector<std::shared_ptr<ASTDeclaration>> declarations; std::vector<std::shared_ptr<ASTDeclaration>> declarations;
}; };
struct ASTDeclaration : ASTNode { struct ASTDeclaration : ASTNode {
~ASTDeclaration() override = default; ~ASTDeclaration() override = default;
CminusType type; CminusType type;
std::string id; std::string id;
}; };
struct ASTFactor : ASTNode { struct ASTFactor : ASTNode {
~ASTFactor() override = default; ~ASTFactor() override = default;
}; };
struct ASTNum : ASTFactor { struct ASTNum : ASTFactor {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
CminusType type; CminusType type;
union { union {
int i_val; int i_val;
...@@ -115,18 +115,18 @@ struct ASTNum : ASTFactor { ...@@ -115,18 +115,18 @@ struct ASTNum : ASTFactor {
}; };
struct ASTVarDeclaration : ASTDeclaration { struct ASTVarDeclaration : ASTDeclaration {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
std::shared_ptr<ASTNum> num; std::shared_ptr<ASTNum> num;
}; };
struct ASTFunDeclaration : ASTDeclaration { struct ASTFunDeclaration : ASTDeclaration {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
std::vector<std::shared_ptr<ASTParam>> params; std::vector<std::shared_ptr<ASTParam>> params;
std::shared_ptr<ASTCompoundStmt> compound_stmt; std::shared_ptr<ASTCompoundStmt> compound_stmt;
}; };
struct ASTParam : ASTNode { struct ASTParam : ASTNode {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
CminusType type; CminusType type;
std::string id; std::string id;
// true if it is array param // true if it is array param
...@@ -134,22 +134,22 @@ struct ASTParam : ASTNode { ...@@ -134,22 +134,22 @@ struct ASTParam : ASTNode {
}; };
struct ASTStatement : ASTNode { struct ASTStatement : ASTNode {
~ASTStatement() override = default; ~ASTStatement() override = default;
}; };
struct ASTCompoundStmt : ASTStatement { struct ASTCompoundStmt : ASTStatement {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
std::vector<std::shared_ptr<ASTVarDeclaration>> local_declarations; std::vector<std::shared_ptr<ASTVarDeclaration>> local_declarations;
std::vector<std::shared_ptr<ASTStatement>> statement_list; std::vector<std::shared_ptr<ASTStatement>> statement_list;
}; };
struct ASTExpressionStmt : ASTStatement { struct ASTExpressionStmt : ASTStatement {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
std::shared_ptr<ASTExpression> expression; std::shared_ptr<ASTExpression> expression;
}; };
struct ASTSelectionStmt : ASTStatement { struct ASTSelectionStmt : ASTStatement {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
std::shared_ptr<ASTExpression> expression; std::shared_ptr<ASTExpression> expression;
std::shared_ptr<ASTStatement> if_statement; std::shared_ptr<ASTStatement> if_statement;
// should be nullptr if no else structure exists // should be nullptr if no else structure exists
...@@ -157,13 +157,13 @@ struct ASTSelectionStmt : ASTStatement { ...@@ -157,13 +157,13 @@ struct ASTSelectionStmt : ASTStatement {
}; };
struct ASTIterationStmt : ASTStatement { struct ASTIterationStmt : ASTStatement {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
std::shared_ptr<ASTExpression> expression; std::shared_ptr<ASTExpression> expression;
std::shared_ptr<ASTStatement> statement; std::shared_ptr<ASTStatement> statement;
}; };
struct ASTReturnStmt : ASTStatement { struct ASTReturnStmt : ASTStatement {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
// should be nullptr if return void // should be nullptr if return void
std::shared_ptr<ASTExpression> expression; std::shared_ptr<ASTExpression> expression;
}; };
...@@ -171,41 +171,41 @@ struct ASTReturnStmt : ASTStatement { ...@@ -171,41 +171,41 @@ struct ASTReturnStmt : ASTStatement {
struct ASTExpression : ASTFactor {}; struct ASTExpression : ASTFactor {};
struct ASTAssignExpression : ASTExpression { struct ASTAssignExpression : ASTExpression {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
std::shared_ptr<ASTVar> var; std::shared_ptr<ASTVar> var;
std::shared_ptr<ASTExpression> expression; std::shared_ptr<ASTExpression> expression;
}; };
struct ASTSimpleExpression : ASTExpression { struct ASTSimpleExpression : ASTExpression {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
std::shared_ptr<ASTAdditiveExpression> additive_expression_l; std::shared_ptr<ASTAdditiveExpression> additive_expression_l;
std::shared_ptr<ASTAdditiveExpression> additive_expression_r; std::shared_ptr<ASTAdditiveExpression> additive_expression_r;
RelOp op; RelOp op;
}; };
struct ASTVar : ASTFactor { struct ASTVar : ASTFactor {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
std::string id; std::string id;
// nullptr if var is of int type // nullptr if var is of int type
std::shared_ptr<ASTExpression> expression; std::shared_ptr<ASTExpression> expression;
}; };
struct ASTAdditiveExpression : ASTNode { struct ASTAdditiveExpression : ASTNode {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
std::shared_ptr<ASTAdditiveExpression> additive_expression; std::shared_ptr<ASTAdditiveExpression> additive_expression;
AddOp op; AddOp op;
std::shared_ptr<ASTTerm> term; std::shared_ptr<ASTTerm> term;
}; };
struct ASTTerm : ASTNode { struct ASTTerm : ASTNode {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
std::shared_ptr<ASTTerm> term; std::shared_ptr<ASTTerm> term;
MulOp op; MulOp op;
std::shared_ptr<ASTFactor> factor; std::shared_ptr<ASTFactor> factor;
}; };
struct ASTCall : ASTFactor { struct ASTCall : ASTFactor {
Value* accept(ASTVisitor &) final; Value* accept(ASTVisitor &) final;
std::string id; std::string id;
std::vector<std::shared_ptr<ASTExpression>> args; std::vector<std::shared_ptr<ASTExpression>> args;
}; };
...@@ -233,22 +233,22 @@ class ASTVisitor { ...@@ -233,22 +233,22 @@ class ASTVisitor {
class ASTPrinter : public ASTVisitor { class ASTPrinter : public ASTVisitor {
public: public:
Value* visit(ASTProgram &) final; Value* visit(ASTProgram &) final;
Value* visit(ASTNum &) final; Value* visit(ASTNum &) final;
Value* visit(ASTVarDeclaration &) final; Value* visit(ASTVarDeclaration &) final;
Value* visit(ASTFunDeclaration &) final; Value* visit(ASTFunDeclaration &) final;
Value* visit(ASTParam &) final; Value* visit(ASTParam &) final;
Value* visit(ASTCompoundStmt &) final; Value* visit(ASTCompoundStmt &) final;
Value* visit(ASTExpressionStmt &) final; Value* visit(ASTExpressionStmt &) final;
Value* visit(ASTSelectionStmt &) final; Value* visit(ASTSelectionStmt &) final;
Value* visit(ASTIterationStmt &) final; Value* visit(ASTIterationStmt &) final;
Value* visit(ASTReturnStmt &) final; Value* visit(ASTReturnStmt &) final;
Value* visit(ASTAssignExpression &) final; Value* visit(ASTAssignExpression &) final;
Value* visit(ASTSimpleExpression &) final; Value* visit(ASTSimpleExpression &) final;
Value* visit(ASTAdditiveExpression &) final; Value* visit(ASTAdditiveExpression &) final;
Value* visit(ASTVar &) final; Value* visit(ASTVar &) final;
Value* visit(ASTTerm &) final; Value* visit(ASTTerm &) final;
Value* visit(ASTCall &) final; Value* visit(ASTCall &) final;
void add_depth() { depth += 2; } void add_depth() { depth += 2; }
void remove_depth() { depth -= 2; } void remove_depth() { depth -= 2; }
......
...@@ -12,10 +12,10 @@ class Module; ...@@ -12,10 +12,10 @@ class Module;
class BasicBlock : public Value { class BasicBlock : public Value {
public: public:
BasicBlock(const BasicBlock& other) = delete; BasicBlock(const BasicBlock& other) = delete;
BasicBlock(BasicBlock&& other) noexcept = delete; BasicBlock(BasicBlock&& other) noexcept = delete;
BasicBlock& operator=(const BasicBlock& other) = delete; BasicBlock& operator=(const BasicBlock& other) = delete;
BasicBlock& operator=(BasicBlock&& other) noexcept = delete; BasicBlock& operator=(BasicBlock&& other) noexcept = delete;
~BasicBlock() override; ~BasicBlock() override;
static BasicBlock *create(Module *m, const std::string &name, static BasicBlock *create(Module *m, const std::string &name,
Function *parent) { Function *parent) {
...@@ -31,18 +31,18 @@ class BasicBlock : public Value { ...@@ -31,18 +31,18 @@ class BasicBlock : public Value {
void add_pre_basic_block(BasicBlock *bb) void add_pre_basic_block(BasicBlock *bb)
{ {
for (auto i : pre_bbs_) if (i == bb) return; for (auto i : pre_bbs_) if (i == bb) return;
pre_bbs_.push_back(bb); pre_bbs_.push_back(bb);
} }
// 自动去重 // 自动去重
void add_succ_basic_block(BasicBlock *bb) void add_succ_basic_block(BasicBlock *bb)
{ {
for (auto i : succ_bbs_) if (i == bb) return; for (auto i : succ_bbs_) if (i == bb) return;
succ_bbs_.push_back(bb); succ_bbs_.push_back(bb);
} }
void remove_pre_basic_block(BasicBlock *bb) { pre_bbs_.remove(bb); } void remove_pre_basic_block(BasicBlock *bb) { pre_bbs_.remove(bb); }
// 若你将 br label0, label0 的其中一个 label0 改为 label1,并且调用 remove_suc label0,那 suc 集合中也将不再包含 label0 // 若你将 br label0, label0 的其中一个 label0 改为 label1,并且调用 remove_suc label0,那 suc 集合中也将不再包含 label0
void remove_succ_basic_block(BasicBlock *bb) { succ_bbs_.remove(bb); } void remove_succ_basic_block(BasicBlock *bb) { succ_bbs_.remove(bb); }
BasicBlock* get_entry_block_of_same_function() const; BasicBlock* get_entry_block_of_same_function() const;
// If the Block is terminated by ret/br // If the Block is terminated by ret/br
bool is_terminated() const; bool is_terminated() const;
...@@ -77,7 +77,7 @@ class BasicBlock : public Value { ...@@ -77,7 +77,7 @@ class BasicBlock : public Value {
Module *get_module() const; Module *get_module() const;
void erase_from_parent(); void erase_from_parent();
std::string print() override; std::string print() override;
// 用于 lldb 调试生成 summary // 用于 lldb 调试生成 summary
std::string safe_print() const; std::string safe_print() const;
......
...@@ -56,7 +56,7 @@ class ConstantArray : public Constant { ...@@ -56,7 +56,7 @@ class ConstantArray : public Constant {
static ConstantArray *get(ArrayType *ty, static ConstantArray *get(ArrayType *ty,
const std::vector<Constant *> &val); const std::vector<Constant *> &val);
std::string print() override; std::string print() override;
}; };
class ConstantZero : public Constant { class ConstantZero : public Constant {
......
...@@ -16,10 +16,10 @@ class FunctionType; ...@@ -16,10 +16,10 @@ class FunctionType;
class Function : public Value { class Function : public Value {
public: public:
Function(const Function& other) = delete; Function(const Function& other) = delete;
Function(Function&& other) noexcept = delete; Function(Function&& other) noexcept = delete;
Function& operator=(const Function& other) = delete; Function& operator=(const Function& other) = delete;
Function& operator=(Function&& other) noexcept = delete; Function& operator=(Function&& other) noexcept = delete;
Function(FunctionType *ty, const std::string &name, Module *parent); Function(FunctionType *ty, const std::string &name, Module *parent);
~Function() override; ~Function() override;
static Function *create(FunctionType *ty, const std::string &name, static Function *create(FunctionType *ty, const std::string &name,
...@@ -35,18 +35,18 @@ class Function : public Value { ...@@ -35,18 +35,18 @@ class Function : public Value {
Module *get_parent() const; Module *get_parent() const;
// 此处 remove 的 BasicBlock, 需要手动 delete // 此处 remove 的 BasicBlock, 需要手动 delete
void remove(BasicBlock *bb); void remove(BasicBlock *bb);
BasicBlock *get_entry_block() const { return basic_blocks_.front(); } BasicBlock *get_entry_block() const { return basic_blocks_.front(); }
std::list<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() const { return basic_blocks_.empty(); } bool is_declaration() const { return basic_blocks_.empty(); }
void set_instr_name(); void set_instr_name();
std::string print() override; std::string print() override;
// 用于检查函数的基本块是否存在问题 // 用于检查函数的基本块是否存在问题
void check_for_block_relation_error() const; void check_for_block_relation_error() const;
// 用于 lldb 调试生成 summary // 用于 lldb 调试生成 summary
...@@ -58,7 +58,7 @@ class Function : public Value { ...@@ -58,7 +58,7 @@ class Function : public Value {
private: private:
std::list<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
}; };
...@@ -66,17 +66,17 @@ class Function : public Value { ...@@ -66,17 +66,17 @@ class Function : public Value {
// Argument of Function, does not contain actual value // Argument of Function, does not contain actual value
class Argument : public Value { class Argument : public Value {
public: public:
Argument(const Argument& other) = delete; Argument(const Argument& other) = delete;
Argument(Argument&& other) noexcept = delete; Argument(Argument&& other) noexcept = delete;
Argument& operator=(const Argument& other) = delete; Argument& operator=(const Argument& other) = delete;
Argument& operator=(Argument&& other) noexcept = delete; Argument& operator=(Argument&& other) noexcept = delete;
explicit Argument(Type *ty, const std::string &name = "", explicit Argument(Type *ty, const std::string &name = "",
Function *f = nullptr, unsigned arg_no = 0) Function *f = nullptr, unsigned arg_no = 0)
: Value(ty, name), parent_(f), arg_no_(arg_no) {} : Value(ty, name), parent_(f), arg_no_(arg_no) {}
~Argument() override = default; ~Argument() override = default;
const Function *get_parent() const { return parent_; } const Function *get_parent() const { return parent_; }
Function *get_parent() { return parent_; } Function *get_parent() { return parent_; }
/// For example in "void foo(int a, float b)" a is 0 and b is 1. /// For example in "void foo(int a, float b)" a is 0 and b is 1.
unsigned get_arg_no() const { unsigned get_arg_no() const {
...@@ -84,7 +84,7 @@ class Argument : public Value { ...@@ -84,7 +84,7 @@ class Argument : public Value {
return arg_no_; return arg_no_;
} }
std::string print() override; std::string print() override;
// 用于 lldb 调试生成 summary // 用于 lldb 调试生成 summary
std::string safe_print() const; std::string safe_print() const;
......
...@@ -277,7 +277,7 @@ class AllocaInst : public Instruction { ...@@ -277,7 +277,7 @@ class AllocaInst : public Instruction {
public: public:
// 新特性:指令表分为 {alloca, phi | other inst} 两段,创建和向基本块插入 alloca 和 phi,都只会插在第一段,它们在常规指令前面 // 新特性:指令表分为 {alloca, phi | other inst} 两段,创建和向基本块插入 alloca 和 phi,都只会插在第一段,它们在常规指令前面
static AllocaInst *create_alloca(Type *ty, BasicBlock *bb, const std::string& name = ""); static AllocaInst *create_alloca(Type *ty, BasicBlock *bb, const std::string& name = "");
Type *get_alloca_type() const { Type *get_alloca_type() const {
return get_type()->get_pointer_element_type(); return get_type()->get_pointer_element_type();
} }
......
...@@ -42,7 +42,7 @@ class Module { ...@@ -42,7 +42,7 @@ class Module {
private: private:
// The global variables in the module // The global variables in the module
std::list<GlobalVariable*> global_list_; std::list<GlobalVariable*> global_list_;
// The functions in the module // The functions in the module
std::list<Function*> function_list_; std::list<Function*> function_list_;
......
...@@ -6,22 +6,21 @@ ...@@ -6,22 +6,21 @@
class Names class Names
{ {
public: public:
explicit Names(bool use_underline, std::string prefix, std::string append) explicit Names(std::string prefix, std::string append)
: use_underline_(use_underline), default_prefix_used_count_(0), default_prefix_(std::move(prefix)), : default_prefix_used_count_(0), default_prefix_(std::move(prefix)),
appended_prefix_(std::move(append)) appended_prefix_(std::move(append))
{ {
} }
// 获得一个 Names 内唯一的名称,会保持唯一的同时尽可能的与 names 类似 // 获得一个 Names 内唯一的名称,会保持唯一的同时尽可能的与 names 类似
std::string get_name(std::string name); std::string get_name(std::string name);
// 获得一个 Names 内唯一的名称 // 获得一个 Names 内唯一的名称
std::string get_name(); std::string get_name();
private: private:
bool use_underline_; int default_prefix_used_count_;
int default_prefix_used_count_; std::string default_prefix_;
std::string default_prefix_; std::string appended_prefix_;
std::string appended_prefix_; std::unordered_map<std::string, int> allocated_;
std::unordered_map<std::string, int> allocated_;
}; };
#endif // !NAMES_HPP #endif // !NAMES_HPP
...@@ -12,12 +12,12 @@ class FloatType; ...@@ -12,12 +12,12 @@ class FloatType;
class Type { class Type {
public: public:
Type(const Type& other) = delete; Type(const Type& other) = delete;
Type(Type&& other) noexcept = delete; Type(Type&& other) noexcept = delete;
Type& operator=(const Type& other) = delete; Type& operator=(const Type& other) = delete;
Type& operator=(Type&& other) noexcept = delete; Type& operator=(Type&& other) noexcept = delete;
enum TypeID: uint8_t { enum TypeID: uint8_t {
VoidTyID, // Void VoidTyID, // Void
LabelTyID, // Labels, e.g., BasicBlock LabelTyID, // Labels, e.g., BasicBlock
IntegerTyID, // Integers, include 32 bits and 1 bit IntegerTyID, // Integers, include 32 bits and 1 bit
...@@ -63,12 +63,12 @@ class Type { ...@@ -63,12 +63,12 @@ class Type {
class IntegerType : public Type { class IntegerType : public Type {
public: public:
IntegerType(const IntegerType& other) = delete; IntegerType(const IntegerType& other) = delete;
IntegerType(IntegerType&& other) noexcept = delete; IntegerType(IntegerType&& other) noexcept = delete;
IntegerType& operator=(const IntegerType& other) = delete; IntegerType& operator=(const IntegerType& other) = delete;
IntegerType& operator=(IntegerType&& other) noexcept = delete; IntegerType& operator=(IntegerType&& other) noexcept = delete;
explicit IntegerType(unsigned num_bits, Module *m); explicit IntegerType(unsigned num_bits, Module *m);
~IntegerType() override; ~IntegerType() override;
unsigned get_num_bits() const; unsigned get_num_bits() const;
...@@ -79,12 +79,12 @@ class IntegerType : public Type { ...@@ -79,12 +79,12 @@ class IntegerType : public Type {
class FunctionType : public Type { class FunctionType : public Type {
public: public:
FunctionType(const FunctionType& other) = delete; FunctionType(const FunctionType& other) = delete;
FunctionType(FunctionType&& other) noexcept = delete; FunctionType(FunctionType&& other) noexcept = delete;
FunctionType& operator=(const FunctionType& other) = delete; FunctionType& operator=(const FunctionType& other) = delete;
FunctionType& operator=(FunctionType&& other) noexcept = delete; FunctionType& operator=(FunctionType&& other) noexcept = delete;
FunctionType(Type *result, const std::vector<Type *>& params); FunctionType(Type *result, const std::vector<Type *>& params);
~FunctionType() override; ~FunctionType() override;
static bool is_valid_return_type(const Type *ty); static bool is_valid_return_type(const Type *ty);
...@@ -106,12 +106,12 @@ class FunctionType : public Type { ...@@ -106,12 +106,12 @@ class FunctionType : public Type {
class ArrayType : public Type { class ArrayType : public Type {
public: public:
ArrayType(const ArrayType& other) = delete; ArrayType(const ArrayType& other) = delete;
ArrayType(ArrayType&& other) noexcept = delete; ArrayType(ArrayType&& other) noexcept = delete;
ArrayType& operator=(const ArrayType& other) = delete; ArrayType& operator=(const ArrayType& other) = delete;
ArrayType& operator=(ArrayType&& other) noexcept = delete; ArrayType& operator=(ArrayType&& other) noexcept = delete;
ArrayType(Type *contained, unsigned num_elements); ArrayType(Type *contained, unsigned num_elements);
~ArrayType() override; ~ArrayType() override;
static bool is_valid_element_type(const Type *ty); static bool is_valid_element_type(const Type *ty);
...@@ -128,12 +128,12 @@ class ArrayType : public Type { ...@@ -128,12 +128,12 @@ class ArrayType : public Type {
class PointerType : public Type { class PointerType : public Type {
public: public:
PointerType(const PointerType& other) = delete; PointerType(const PointerType& other) = delete;
PointerType(PointerType&& other) noexcept = delete; PointerType(PointerType&& other) noexcept = delete;
PointerType& operator=(const PointerType& other) = delete; PointerType& operator=(const PointerType& other) = delete;
PointerType& operator=(PointerType&& other) noexcept = delete; PointerType& operator=(PointerType&& other) noexcept = delete;
PointerType(Type *contained); PointerType(Type *contained);
~PointerType() override; ~PointerType() override;
Type *get_element_type() const { return contained_; } Type *get_element_type() const { return contained_; }
...@@ -145,12 +145,12 @@ class PointerType : public Type { ...@@ -145,12 +145,12 @@ class PointerType : public Type {
class FloatType : public Type { class FloatType : public Type {
public: public:
FloatType(const FloatType& other) = delete; FloatType(const FloatType& other) = delete;
FloatType(FloatType&& other) noexcept = delete; FloatType(FloatType&& other) noexcept = delete;
FloatType& operator=(const FloatType& other) = delete; FloatType& operator=(const FloatType& other) = delete;
FloatType& operator=(FloatType&& other) noexcept = delete; FloatType& operator=(FloatType&& other) noexcept = delete;
FloatType(Module *m); FloatType(Module *m);
~FloatType() override; ~FloatType() override;
static FloatType *get(Module *m); static FloatType *get(Module *m);
}; };
...@@ -6,11 +6,11 @@ ...@@ -6,11 +6,11 @@
class User : public Value { class User : public Value {
public: public:
User(const User& other) = delete; User(const User& other) = delete;
User(User&& other) noexcept = delete; User(User&& other) noexcept = delete;
User& operator=(const User& other) = delete; User& operator=(const User& other) = delete;
User& operator=(User&& other) noexcept = delete; User& operator=(User&& other) noexcept = delete;
User(Type *ty, const std::string &name = "") : Value(ty, name){} User(Type *ty, const std::string &name = "") : Value(ty, name){}
~User() override; ~User() override;
const std::vector<Value *> &get_operands() const { return operands_; } const std::vector<Value *> &get_operands() const { return operands_; }
......
...@@ -12,12 +12,12 @@ struct Use; ...@@ -12,12 +12,12 @@ struct Use;
class Value { class Value {
public: public:
Value(const Value& other) = delete; Value(const Value& other) = delete;
Value(Value&& other) noexcept = delete; Value(Value&& other) noexcept = delete;
Value& operator=(const Value& other) = delete; Value& operator=(const Value& other) = delete;
Value& operator=(Value&& other) noexcept = delete; Value& operator=(Value&& other) noexcept = delete;
explicit Value(Type *ty, std::string name = "") explicit Value(Type *ty, std::string name = "")
: type_(ty), name_(std::move(name)){} : type_(ty), name_(std::move(name)){}
virtual ~Value(); virtual ~Value();
......
...@@ -9,7 +9,13 @@ def parseString(val : lldb.SBValue): ...@@ -9,7 +9,13 @@ def parseString(val : lldb.SBValue):
return "" return ""
def SafePrintSummary(valobj: lldb.SBValue, internal_dict): def SafePrintSummary(valobj: lldb.SBValue, internal_dict):
name: lldb.SBValue = valobj.EvaluateExpression("this->safe_print()") if valobj.GetType().IsPointerType():
deref: lldb.SBValue = valobj.Dereference()
if deref.IsValid():
valobj = deref
else:
return ""
name: lldb.SBValue = valobj.EvaluateExpression("safe_print()")
return parseString(name) return parseString(name)
def __lldb_init_module(debugger: lldb.SBDebugger, internal_dict): def __lldb_init_module(debugger: lldb.SBDebugger, internal_dict):
...@@ -18,7 +24,8 @@ def __lldb_init_module(debugger: lldb.SBDebugger, internal_dict): ...@@ -18,7 +24,8 @@ def __lldb_init_module(debugger: lldb.SBDebugger, internal_dict):
, "Function", "Argument" , "Function", "Argument"
, "BasicBlock" , "BasicBlock"
, "GlobalVariable" , "GlobalVariable"
, "Instruction", "IBinaryInst", "FBinaryInst", "ICmpInst", "FCmpInst", "CallInst", "BranchInst", "ReturnInst", "GetElementPtrInst", "StoreInst", "LoadInst", "AllocaInst", "ZextInst", "FpToSiInst", "SiToFpInst", "PhiInst" ] , "Instruction", "IBinaryInst", "FBinaryInst", "ICmpInst", "FCmpInst", "CallInst", "BranchInst", "ReturnInst", "GetElementPtrInst", "StoreInst", "LoadInst", "AllocaInst", "ZextInst", "FpToSiInst", "SiToFpInst", "PhiInst"
, "ASMInstruction", "Reg", "FReg", "CFReg" ]
for i in types: for i in types:
debugger.HandleCommand( debugger.HandleCommand(
f"type summary add -F lldb_formatters.SafePrintSummary {i} -w my" f"type summary add -F lldb_formatters.SafePrintSummary {i} -w my"
......
...@@ -108,7 +108,7 @@ Value* CminusfBuilder::visit(ASTVarDeclaration &node) { ...@@ -108,7 +108,7 @@ Value* CminusfBuilder::visit(ASTVarDeclaration &node) {
} }
Value* CminusfBuilder::visit(ASTFunDeclaration &node) { Value* CminusfBuilder::visit(ASTFunDeclaration &node) {
Type *ret_type; Type *ret_type;
std::vector<Type *> param_types; std::vector<Type *> param_types;
if (node.type == TYPE_INT) if (node.type == TYPE_INT)
ret_type = INT32_T; ret_type = INT32_T;
...@@ -142,8 +142,8 @@ Value* CminusfBuilder::visit(ASTFunDeclaration &node) { ...@@ -142,8 +142,8 @@ Value* CminusfBuilder::visit(ASTFunDeclaration &node) {
scope.enter(); scope.enter();
context.pre_enter_scope = true; context.pre_enter_scope = true;
std::vector<Value *> args; std::vector<Value *> args;
for (auto &arg : func->get_args()) { for (auto arg : func->get_args()) {
args.push_back(&arg); args.push_back(arg);
} }
for (unsigned int i = 0; i < node.params.size(); ++i) { for (unsigned int i = 0; i < node.params.size(); ++i) {
if (node.params[i]->isarray) { if (node.params[i]->isarray) {
......
#include "CodeGen.hpp" #include "CodeGen.hpp"
#include "ASMInstruction.hpp"
#include "CodeGenUtil.hpp" #include "CodeGenUtil.hpp"
#include "Register.hpp"
std::string ASMInstruction::safe_print() const
{
switch (type) {
case Instruction:
case Attribute:
return content;
case Label:
return content + ":";
case Comment:
return "# " + content;
}
return "<error>";
}
void CodeGen::allocate() { void CodeGen::allocate() {
// 备份 $ra $fp // 备份 $ra $fp
...@@ -8,9 +24,9 @@ void CodeGen::allocate() { ...@@ -8,9 +24,9 @@ void CodeGen::allocate() {
// 为每个参数分配栈空间 // 为每个参数分配栈空间
for (auto &arg : context.func->get_args()) { for (auto &arg : context.func->get_args()) {
auto size = arg.get_type()->get_size(); auto size = arg->get_type()->get_size();
offset = offset + size; offset = offset + size;
context.offset_map[&arg] = -static_cast<int>(offset); context.offset_map[arg] = -static_cast<int>(offset);
} }
// 为指令结果分配栈空间 // 为指令结果分配栈空间
...@@ -205,11 +221,11 @@ void CodeGen::gen_prologue() { ...@@ -205,11 +221,11 @@ void CodeGen::gen_prologue() {
int garg_cnt = 0; int garg_cnt = 0;
int farg_cnt = 0; int farg_cnt = 0;
for (auto &arg : context.func->get_args()) { for (auto arg : context.func->get_args()) {
if (arg.get_type()->is_float_type()) { if (arg->get_type()->is_float_type()) {
store_from_freg(&arg, FReg::fa(farg_cnt++)); store_from_freg(arg, FReg::fa(farg_cnt++));
} else { // int or pointer } else { // int or pointer
store_from_greg(&arg, Reg::a(garg_cnt++)); store_from_greg(arg, Reg::a(garg_cnt++));
} }
} }
} }
...@@ -241,16 +257,16 @@ void CodeGen::gen_binary() { ...@@ -241,16 +257,16 @@ void CodeGen::gen_binary() {
load_to_greg(context.inst->get_operand(1), Reg::t(1)); load_to_greg(context.inst->get_operand(1), Reg::t(1));
switch (context.inst->get_instr_type()) { switch (context.inst->get_instr_type()) {
case Instruction::add: case Instruction::add:
output.emplace_back("add.w $t2, $t0, $t1"); append_inst("add.w $t2, $t0, $t1");
break; break;
case Instruction::sub: case Instruction::sub:
output.emplace_back("sub.w $t2, $t0, $t1"); append_inst("sub.w $t2, $t0, $t1");
break; break;
case Instruction::mul: case Instruction::mul:
output.emplace_back("mul.w $t2, $t0, $t1"); append_inst("mul.w $t2, $t0, $t1");
break; break;
case Instruction::sdiv: case Instruction::sdiv:
output.emplace_back("div.w $t2, $t0, $t1"); append_inst("div.w $t2, $t0, $t1");
break; break;
default: default:
assert(false); assert(false);
...@@ -370,26 +386,26 @@ void CodeGen::run() { ...@@ -370,26 +386,26 @@ void CodeGen::run() {
* - 支持更旧版本的 GNU 汇编器, 因为 `.bss` 伪指令是应该相对较新的指令, * - 支持更旧版本的 GNU 汇编器, 因为 `.bss` 伪指令是应该相对较新的指令,
* GNU 汇编器在 2023 年 2 月的 2.37 版本才将其引入 * GNU 汇编器在 2023 年 2 月的 2.37 版本才将其引入
*/ */
append_inst(".text", ASMInstruction::Atrribute); append_inst(".text", ASMInstruction::Attribute);
append_inst(".section", {".bss", "\"aw\"", "@nobits"}, append_inst(".section", {".bss", "\"aw\"", "@nobits"},
ASMInstruction::Atrribute); ASMInstruction::Attribute);
for (auto global : m->get_global_variable()) { for (auto global : m->get_global_variable()) {
auto size = auto size =
global->get_type()->get_pointer_element_type()->get_size(); global->get_type()->get_pointer_element_type()->get_size();
append_inst(".globl", {global->get_name()}, append_inst(".globl", {global->get_name()},
ASMInstruction::Atrribute); ASMInstruction::Attribute);
append_inst(".type", {global->get_name(), "@object"}, append_inst(".type", {global->get_name(), "@object"},
ASMInstruction::Atrribute); ASMInstruction::Attribute);
append_inst(".size", {global->get_name(), std::to_string(size)}, append_inst(".size", {global->get_name(), std::to_string(size)},
ASMInstruction::Atrribute); ASMInstruction::Attribute);
append_inst(global->get_name(), ASMInstruction::Label); append_inst(global->get_name(), ASMInstruction::Label);
append_inst(".space", {std::to_string(size)}, append_inst(".space", {std::to_string(size)},
ASMInstruction::Atrribute); ASMInstruction::Attribute);
} }
} }
// 函数代码段 // 函数代码段
output.emplace_back(".text", ASMInstruction::Atrribute); output.emplace_back(new ASMInstruction(".text", ASMInstruction::Attribute));
for (auto func : m->get_functions()) { for (auto func : m->get_functions()) {
if (not func->is_declaration()) { if (not func->is_declaration()) {
// 更新 context // 更新 context
...@@ -397,9 +413,9 @@ void CodeGen::run() { ...@@ -397,9 +413,9 @@ void CodeGen::run() {
context.func = func; context.func = func;
// 函数信息 // 函数信息
append_inst(".globl", {func->get_name()}, ASMInstruction::Atrribute); append_inst(".globl", {func->get_name()}, ASMInstruction::Attribute);
append_inst(".type", {func->get_name(), "@function"}, append_inst(".type", {func->get_name(), "@function"},
ASMInstruction::Atrribute); ASMInstruction::Attribute);
append_inst(func->get_name(), ASMInstruction::Label); append_inst(func->get_name(), ASMInstruction::Label);
// 分配函数栈帧 // 分配函数栈帧
...@@ -495,8 +511,8 @@ void CodeGen::run() { ...@@ -495,8 +511,8 @@ void CodeGen::run() {
std::string CodeGen::print() const { std::string CodeGen::print() const {
std::string result; std::string result;
for (const auto &inst : output) { for (const auto inst : output) {
result += inst.format(); result += inst->format();
} }
return result; return result;
} }
...@@ -26,9 +26,35 @@ std::string Reg::print() const { ...@@ -26,9 +26,35 @@ std::string Reg::print() const {
assert(false); assert(false);
} }
std::string Reg::safe_print() const
{
if (id == 0) {
return "$zero";
}
if (id == 1) {
return "$ra";
}
if (id == 2) {
return "$tp";
}
if (id == 3) {
return "$sp";
}
if (4 <= id and id <= 11) {
return "$a" + std::to_string(id - 4);
}
if (12 <= id and id <= 20) {
return "$t" + std::to_string(id - 12);
}
if (id == 22) {
return "$fp";
}
return "<error id " + std::to_string(id) + ">";
}
std::string FReg::print() const { std::string FReg::print() const {
if (0 <= id and id <= 7) { if (id <= 7) {
return "$fa" + std::to_string(id); return "$fa" + std::to_string(id);
} }
if (8 <= id and id <= 23) { if (8 <= id and id <= 23) {
...@@ -39,3 +65,22 @@ std::string FReg::print() const { ...@@ -39,3 +65,22 @@ std::string FReg::print() const {
} }
assert(false); assert(false);
} }
std::string FReg::safe_print() const
{
if (id <= 7) {
return "$fa" + std::to_string(id);
}
if (8 <= id and id <= 23) {
return "$ft" + std::to_string(id - 8);
}
if (24 <= id and id <= 31) {
return "$fs" + std::to_string(id - 24);
}
return "<error id " + std::to_string(id) + ">";
}
std::string CFReg::safe_print() const
{
return "$fcc" + std::to_string(id);
}
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
std::string ptr_to_str(const void* ptr) std::string ptr_to_str(const void* ptr)
{ {
const char* translate = "0123456789abcdef"; const char* translate = "0123456789abcdef";
uintptr_t addr = reinterpret_cast<uintptr_t>(ptr); uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
uintptr_t a = addr & 0xF; uintptr_t a = addr & 0xF;
uintptr_t b = (addr >> 4) & 0xF; uintptr_t b = (addr >> 4) & 0xF;
uintptr_t c = (addr >> 8) & 0xF; uintptr_t c = (addr >> 8) & 0xF;
uintptr_t d = (addr >> 12) & 0xF; uintptr_t d = (addr >> 12) & 0xF;
return {'<', translate[d], translate[c], translate[b], translate[a], '>'}; return {'<', translate[d], translate[c], translate[b], translate[a], '>'};
} }
...@@ -47,7 +47,7 @@ void BasicBlock::add_instruction(Instruction *instr) { ...@@ -47,7 +47,7 @@ void BasicBlock::add_instruction(Instruction *instr) {
auto it = instr_list_.begin(); auto it = instr_list_.begin();
for (; it != instr_list_.end() && ((*it)->is_alloca() || (*it)->is_phi()); ++it){} for (; it != instr_list_.end() && ((*it)->is_alloca() || (*it)->is_phi()); ++it){}
instr_list_.emplace(it, instr); instr_list_.emplace(it, instr);
return; return;
} }
assert(not is_terminated() && "Inserting instruction to terminated bb"); assert(not is_terminated() && "Inserting instruction to terminated bb");
instr_list_.push_back(instr); instr_list_.push_back(instr);
...@@ -56,7 +56,7 @@ void BasicBlock::add_instruction(Instruction *instr) { ...@@ -56,7 +56,7 @@ void BasicBlock::add_instruction(Instruction *instr) {
void BasicBlock::add_instr_begin(Instruction* instr) void BasicBlock::add_instr_begin(Instruction* instr)
{ {
if (instr->is_alloca() || instr->is_phi()) if (instr->is_alloca() || instr->is_phi())
instr_list_.push_front(instr); instr_list_.push_front(instr);
else else
{ {
auto it = instr_list_.begin(); auto it = instr_list_.begin();
...@@ -121,8 +121,8 @@ BasicBlock::~BasicBlock() ...@@ -121,8 +121,8 @@ BasicBlock::~BasicBlock()
BasicBlock* BasicBlock::get_entry_block_of_same_function() const BasicBlock* BasicBlock::get_entry_block_of_same_function() const
{ {
assert(parent_ != nullptr && "bb have no parent function"); assert(parent_ != nullptr && "bb have no parent function");
return parent_->get_entry_block(); return parent_->get_entry_block();
} }
Names GLOBAL_BASICBLOCK_NAMES_{false, "label", ""}; Names GLOBAL_BASICBLOCK_NAMES_{"label", "_"};
\ No newline at end of file \ No newline at end of file
...@@ -168,7 +168,7 @@ std::string ConstantFP::print() { ...@@ -168,7 +168,7 @@ std::string ConstantFP::print() {
ConstantZero *ConstantZero::get(Type *ty, Module *m) { ConstantZero *ConstantZero::get(Type *ty, Module *m) {
if (not cached_zero[ty]) if (not cached_zero[ty])
{ {
cached_zero[ty] = std::unique_ptr<ConstantZero>(new ConstantZero(ty)); cached_zero[ty] = std::unique_ptr<ConstantZero>(new ConstantZero(ty));
} }
return cached_zero[ty].get(); return cached_zero[ty].get();
} }
......
...@@ -3,31 +3,33 @@ ...@@ -3,31 +3,33 @@
#include "Module.hpp" #include "Module.hpp"
#include "Instruction.hpp" #include "Instruction.hpp"
#include <cassert> #include <cassert>
#include <string>
#include <unordered_set> #include <unordered_set>
#include <queue> #include <queue>
namespace namespace
{ {
std::string chopName(std::string name) std::string chopName(std::string name)
{ {
if (name.size() > 4) return { name.begin(), name.begin() + 4 }; if (name.size() > 3) return { name.begin(), name.begin() + 3 };
return name; return name;
} }
} }
Function::Function(FunctionType* ty, const std::string& name, Module* parent) Function::Function(FunctionType* ty, const std::string& name, Module* parent)
: Value(ty, name), names4blocks_(false, "label", chopName(name)), names4insts_(true, "op", ""), parent_(parent), seq_cnt_(0) { : Value(ty, name), names4blocks_("label", chopName(name) + "_"), names4insts_("op", ""), parent_(parent), seq_cnt_(0) {
// num_args_ = ty->getNumParams(); // num_args_ = ty->getNumParams();
parent->add_function(this); parent->add_function(this);
// build args // build args
for (unsigned i = 0; i < get_num_of_args(); i++) { for (unsigned i = 0; i < get_num_of_args(); i++) {
arguments_.emplace_back(ty->get_param_type(i), "", this, i); arguments_.emplace_back(new Argument(ty->get_param_type(i), "arg" + std::to_string(i), this, i));
} }
} }
Function::~Function() Function::~Function()
{ {
for (auto bb : basic_blocks_) delete bb; for (auto bb : basic_blocks_) delete bb;
for(auto arg: arguments_) delete arg;
} }
Function* Function::create(FunctionType* ty, const std::string& name, Function* Function::create(FunctionType* ty, const std::string& name,
...@@ -66,10 +68,10 @@ void Function::add_basic_block(BasicBlock* bb) { basic_blocks_.push_back(bb); } ...@@ -66,10 +68,10 @@ void Function::add_basic_block(BasicBlock* bb) { basic_blocks_.push_back(bb); }
void Function::set_instr_name() { void Function::set_instr_name() {
std::map<Value*, int> seq; std::map<Value*, int> seq;
for (auto& arg : this->get_args()) { for (auto& arg : this->get_args()) {
if (seq.find(&arg) == seq.end()) { if (seq.find(arg) == seq.end()) {
auto seq_num = seq.size() + seq_cnt_; auto seq_num = seq.size() + seq_cnt_;
if (arg.set_name("arg" + std::to_string(seq_num))) { if (arg->set_name("arg" + std::to_string(seq_num))) {
seq.insert({ &arg, seq_num }); seq.insert({ arg, seq_num });
} }
} }
} }
...@@ -121,7 +123,7 @@ std::string Function::print() { ...@@ -121,7 +123,7 @@ std::string Function::print() {
for (auto& arg : get_args()) { for (auto& arg : get_args()) {
if (&arg != &*get_args().begin()) if (&arg != &*get_args().begin())
func_ir += ", "; func_ir += ", ";
func_ir += arg.print(); func_ir += arg->print();
} }
} }
func_ir += ")"; func_ir += ")";
...@@ -160,7 +162,7 @@ std::string Argument::safe_print() const ...@@ -160,7 +162,7 @@ std::string Argument::safe_print() const
auto ty = parent->get_function_type(); auto ty = parent->get_function_type();
if (ty == nullptr || ty->get_num_of_args() <= arg_no_) return "@" + parent->get_name() + " arg" + std::to_string(arg_no_) + " <unknow type>"; if (ty == nullptr || ty->get_num_of_args() <= arg_no_) return "@" + parent->get_name() + " arg" + std::to_string(arg_no_) + " <unknow type>";
auto ty2 = ty->get_param_type(arg_no_); auto ty2 = ty->get_param_type(arg_no_);
return "@" + parent->get_name() + " arg" + std::to_string(arg_no_) + " " + (ty2 == nullptr ? "<null>" : ty2->safe_print()); return (ty2 == nullptr ? "<null>" : ty2->safe_print()) + " @" + parent->get_name() + " arg" + std::to_string(arg_no_);
} }
......
...@@ -217,7 +217,7 @@ std::string Instruction::safe_print() const ...@@ -217,7 +217,7 @@ std::string Instruction::safe_print() const
switch (op_id_) switch (op_id_)
{ {
case ret: case ret:
{ {
std::string instr_ir; std::string instr_ir;
instr_ir += get_instr_op_name(); instr_ir += get_instr_op_name();
instr_ir += " "; instr_ir += " ";
...@@ -230,9 +230,9 @@ std::string Instruction::safe_print() const ...@@ -230,9 +230,9 @@ std::string Instruction::safe_print() const
instr_ir += "void"; instr_ir += "void";
} }
return instr_ir; return instr_ir;
} }
case br: case br:
{ {
std::string instr_ir; std::string instr_ir;
instr_ir += safe_print_instr_op_name(get_instr_type()); instr_ir += safe_print_instr_op_name(get_instr_type());
instr_ir += " "; instr_ir += " ";
...@@ -244,7 +244,7 @@ std::string Instruction::safe_print() const ...@@ -244,7 +244,7 @@ std::string Instruction::safe_print() const
instr_ir += safe_print_op_as_op(this, 2, true); instr_ir += safe_print_op_as_op(this, 2, true);
} }
return instr_ir; return instr_ir;
} }
case add: case add:
case sub: case sub:
case mul: case mul:
...@@ -265,7 +265,7 @@ std::string Instruction::safe_print() const ...@@ -265,7 +265,7 @@ std::string Instruction::safe_print() const
return instr_ir; return instr_ir;
} }
case alloca: case alloca:
{ {
std::string instr_ir; std::string instr_ir;
instr_ir += safe_print_as_op(this, true); instr_ir += safe_print_as_op(this, true);
instr_ir += " = "; instr_ir += " = ";
...@@ -284,9 +284,9 @@ std::string Instruction::safe_print() const ...@@ -284,9 +284,9 @@ std::string Instruction::safe_print() const
else instr_ir += ty2->safe_print(); else instr_ir += ty2->safe_print();
} }
return instr_ir; return instr_ir;
} }
case load: case load:
{ {
std::string instr_ir; std::string instr_ir;
instr_ir += safe_print_as_op(this, true); instr_ir += safe_print_as_op(this, true);
instr_ir += " = "; instr_ir += " = ";
...@@ -294,9 +294,9 @@ std::string Instruction::safe_print() const ...@@ -294,9 +294,9 @@ std::string Instruction::safe_print() const
instr_ir += " "; instr_ir += " ";
instr_ir += safe_print_op_as_op(this, 0, true); instr_ir += safe_print_op_as_op(this, 0, true);
return instr_ir; return instr_ir;
} }
case store: case store:
{ {
std::string instr_ir; std::string instr_ir;
instr_ir += safe_print_instr_op_name(get_instr_type()); instr_ir += safe_print_instr_op_name(get_instr_type());
instr_ir += " "; instr_ir += " ";
...@@ -304,7 +304,7 @@ std::string Instruction::safe_print() const ...@@ -304,7 +304,7 @@ std::string Instruction::safe_print() const
instr_ir += ", "; instr_ir += ", ";
instr_ir += safe_print_op_as_op(this, 1, true); instr_ir += safe_print_op_as_op(this, 1, true);
return instr_ir; return instr_ir;
} }
case ge: case ge:
case gt: case gt:
case le: case le:
...@@ -340,8 +340,8 @@ std::string Instruction::safe_print() const ...@@ -340,8 +340,8 @@ std::string Instruction::safe_print() const
return instr_ir; return instr_ir;
} }
case phi: case phi:
{ {
std::string instr_ir; std::string instr_ir;
instr_ir += safe_print_as_op(this, true); instr_ir += safe_print_as_op(this, true);
instr_ir += " = "; instr_ir += " = ";
instr_ir += safe_print_instr_op_name(get_instr_type()); instr_ir += safe_print_instr_op_name(get_instr_type());
...@@ -356,7 +356,7 @@ std::string Instruction::safe_print() const ...@@ -356,7 +356,7 @@ std::string Instruction::safe_print() const
instr_ir += " ]"; instr_ir += " ]";
} }
return instr_ir; return instr_ir;
} }
case call: case call:
{ {
std::string instr_ir; std::string instr_ir;
...@@ -410,7 +410,7 @@ std::string Instruction::safe_print() const ...@@ -410,7 +410,7 @@ std::string Instruction::safe_print() const
return instr_ir; return instr_ir;
} }
case getelementptr: case getelementptr:
{ {
std::string instr_ir; std::string instr_ir;
instr_ir += safe_print_as_op(this, true); instr_ir += safe_print_as_op(this, true);
instr_ir += " = "; instr_ir += " = ";
...@@ -422,11 +422,11 @@ std::string Instruction::safe_print() const ...@@ -422,11 +422,11 @@ std::string Instruction::safe_print() const
instr_ir += safe_print_op_as_op(this, i, true); instr_ir += safe_print_op_as_op(this, i, true);
} }
return instr_ir; return instr_ir;
} }
case zext: case zext:
case fptosi: case fptosi:
case sitofp: case sitofp:
{ {
std::string instr_ir; std::string instr_ir;
instr_ir += safe_print_as_op(this, true); instr_ir += safe_print_as_op(this, true);
instr_ir += " = "; instr_ir += " = ";
...@@ -434,7 +434,7 @@ std::string Instruction::safe_print() const ...@@ -434,7 +434,7 @@ std::string Instruction::safe_print() const
instr_ir += " "; instr_ir += " ";
instr_ir += safe_print_op_as_op(this, 0, true); instr_ir += safe_print_op_as_op(this, 0, true);
return instr_ir; return instr_ir;
} }
} }
std::string str; std::string str;
str += safe_print_as_op(this, true); str += safe_print_as_op(this, true);
...@@ -538,10 +538,12 @@ std::string BranchInst::print() { ...@@ -538,10 +538,12 @@ std::string BranchInst::print() {
std::string ReturnInst::print() { std::string ReturnInst::print() {
std::string instr_ir; std::string instr_ir;
instr_ir += safe_print_instr_op_name(get_instr_type()); instr_ir += get_instr_op_name();
instr_ir += " "; instr_ir += " ";
if (!is_void_ret()) { if (!is_void_ret()) {
instr_ir += safe_print_op_as_op(this, 0, true); instr_ir += this->get_operand(0)->get_type()->print();
instr_ir += " ";
instr_ir += print_as_op(this->get_operand(0), false);
} else { } else {
instr_ir += "void"; instr_ir += "void";
} }
......
...@@ -15,7 +15,7 @@ Instruction::Instruction(Type *ty, OpID id, const std::string& name, BasicBlock ...@@ -15,7 +15,7 @@ Instruction::Instruction(Type *ty, OpID id, const std::string& name, BasicBlock
assert(ty != nullptr && "Instruction have null type"); assert(ty != nullptr && "Instruction have null type");
assert(((!ty->is_void_type()) || name.empty()) && "Void Type Instruction should not have name"); assert(((!ty->is_void_type()) || name.empty()) && "Void Type Instruction should not have name");
if (parent) if (parent)
parent->add_instruction(this); parent->add_instruction(this);
if (!ty->is_void_type() && parent && parent->get_parent()) if (!ty->is_void_type() && parent && parent->get_parent())
set_name(parent_->get_parent()->names4insts_.get_name(name)); set_name(parent_->get_parent()->names4insts_.get_name(name));
} }
...@@ -226,7 +226,7 @@ GetElementPtrInst::GetElementPtrInst(Value *ptr, const std::vector<Value *>& idx ...@@ -226,7 +226,7 @@ GetElementPtrInst::GetElementPtrInst(Value *ptr, const std::vector<Value *>& idx
add_operand(ptr); add_operand(ptr);
for (auto idx : idxs) for (auto idx : idxs)
{ {
assert(idx->get_type()->is_integer_type() && "Index is not integer"); assert(idx->get_type()->is_integer_type() && "Index is not integer");
add_operand(idx); add_operand(idx);
} }
} }
...@@ -309,7 +309,7 @@ ZextInst::ZextInst(Value *val, Type *ty, BasicBlock *bb, const std::string& name ...@@ -309,7 +309,7 @@ ZextInst::ZextInst(Value *val, Type *ty, BasicBlock *bb, const std::string& name
"ZextInst operand is not integer"); "ZextInst operand is not integer");
assert(ty->is_integer_type() && "ZextInst destination type is not integer"); assert(ty->is_integer_type() && "ZextInst destination type is not integer");
assert((dynamic_cast<IntegerType *>(val->get_type())->get_num_bits() < assert((dynamic_cast<IntegerType *>(val->get_type())->get_num_bits() <
dynamic_cast<IntegerType *>(ty)->get_num_bits()) && dynamic_cast<IntegerType *>(ty)->get_num_bits()) &&
"ZextInst operand bit size is not smaller than destination type bit " "ZextInst operand bit size is not smaller than destination type bit "
"size"); "size");
add_operand(val); add_operand(val);
...@@ -368,4 +368,4 @@ PhiInst *PhiInst::create_phi(Type *ty, BasicBlock *bb, ...@@ -368,4 +368,4 @@ PhiInst *PhiInst::create_phi(Type *ty, BasicBlock *bb,
return new PhiInst(ty, vals, val_bbs, bb, name); return new PhiInst(ty, vals, val_bbs, bb, name);
} }
Names GLOBAL_INSTRUCTION_NAMES_{ true, "op", "" }; Names GLOBAL_INSTRUCTION_NAMES_{"op", "_" };
\ No newline at end of file \ No newline at end of file
...@@ -23,7 +23,7 @@ Module::~Module() ...@@ -23,7 +23,7 @@ Module::~Module()
for (auto& i : pointer_map_) delete i.second; for (auto& i : pointer_map_) delete i.second;
for (auto& i : array_map_) delete i.second; for (auto& i : array_map_) delete i.second;
for (auto& i : function_map_) delete i.second; for (auto& i : function_map_) delete i.second;
for (auto i : function_list_) delete i; for (auto i : function_list_) delete i;
for (auto i : global_list_) delete i; for (auto i : global_list_) delete i;
} }
......
...@@ -2,25 +2,31 @@ ...@@ -2,25 +2,31 @@
std::string Names::get_name(std::string name) std::string Names::get_name(std::string name)
{ {
int ed = static_cast<int>(name.size()); int ed = static_cast<int>(name.size());
while (ed > 0) int bg = 0;
{ while (bg < ed)
char ch = name[ed - 1]; {
if ((use_underline_ && ch == '_') || (ch >= '0' && ch <= '9')) ed--; char ch = name[bg];
else break; if (ch == '_' || (ch >= '0' && ch <= '9')) bg++;
} else break;
if (ed == 0) return get_name(); }
std::string name1 = {name.begin(), name.begin() + ed}; while (ed > bg)
if (name1 == default_prefix_) return get_name(); {
auto get = appended_prefix_ + name1; char ch = name[ed - 1];
auto idx = allocated_[name1]++; if (ch == '_' || (ch >= '0' && ch <= '9')) ed--;
if (idx == 0) return get; else break;
if (use_underline_) get += "_"; }
return get + std::to_string(idx); if (bg == ed) return get_name();
std::string name1 = {name.begin() + bg, name.begin() + ed};
if (name1 == default_prefix_) return get_name();
auto get = appended_prefix_ + name1;
auto idx = allocated_[name1]++;
if (idx == 0) return get;
return get + std::to_string(idx);
} }
std::string Names::get_name() std::string Names::get_name()
{ {
auto get = appended_prefix_ + default_prefix_; auto get = appended_prefix_ + default_prefix_;
return get + std::to_string(++default_prefix_used_count_); return get + std::to_string(++default_prefix_used_count_);
} }
...@@ -72,11 +72,11 @@ std::string Type::print() const { ...@@ -72,11 +72,11 @@ std::string Type::print() const {
case IntegerTyID: case IntegerTyID:
type_ir += "i"; type_ir += "i";
type_ir += std::to_string( type_ir += std::to_string(
dynamic_cast<const IntegerType *>(this)->get_num_bits()); dynamic_cast<const IntegerType *>(this)->get_num_bits());
break; break;
case FunctionTyID: case FunctionTyID:
type_ir += type_ir +=
dynamic_cast<const FunctionType *>(this)->get_return_type()->print(); dynamic_cast<const FunctionType *>(this)->get_return_type()->print();
type_ir += " ("; type_ir += " (";
for (unsigned i = 0; for (unsigned i = 0;
i < dynamic_cast<const FunctionType *>(this)->get_num_of_args(); i < dynamic_cast<const FunctionType *>(this)->get_num_of_args();
...@@ -96,10 +96,10 @@ std::string Type::print() const { ...@@ -96,10 +96,10 @@ std::string Type::print() const {
case ArrayTyID: case ArrayTyID:
type_ir += "["; type_ir += "[";
type_ir += std::to_string( type_ir += std::to_string(
dynamic_cast<const ArrayType *>(this)->get_num_of_elements()); dynamic_cast<const ArrayType *>(this)->get_num_of_elements());
type_ir += " x "; type_ir += " x ";
type_ir += type_ir +=
dynamic_cast<const ArrayType *>(this)->get_element_type()->print(); dynamic_cast<const ArrayType *>(this)->get_element_type()->print();
type_ir += "]"; type_ir += "]";
break; break;
case FloatTyID: case FloatTyID:
...@@ -119,38 +119,38 @@ std::string Type::safe_print() const ...@@ -119,38 +119,38 @@ std::string Type::safe_print() const
case LabelTyID: case LabelTyID:
return "label"; return "label";
case IntegerTyID: case IntegerTyID:
{ {
auto ty = dynamic_cast<const IntegerType*>(this); auto ty = dynamic_cast<const IntegerType*>(this);
if (ty == nullptr) return "<not IntegerType>"; if (ty == nullptr) return "<not IntegerType>";
return "i" + std::to_string(ty->get_num_bits()); return "i" + std::to_string(ty->get_num_bits());
} }
case FunctionTyID: case FunctionTyID:
{ {
auto ty = dynamic_cast<const FunctionType*>(this); auto ty = dynamic_cast<const FunctionType*>(this);
if (ty == nullptr) return "<not FunctionType>"; if (ty == nullptr) return "<not FunctionType>";
auto ty2 = ty->get_return_type(); auto ty2 = ty->get_return_type();
std::string type_ir = (ty2 == nullptr ? "<null>" : ty2->safe_print()) + " ("; std::string type_ir = (ty2 == nullptr ? "<null>" : ty2->safe_print()) + " (";
for (unsigned i = 0; i < ty->get_num_of_args(); i++) { for (unsigned i = 0; i < ty->get_num_of_args(); i++) {
if (i) type_ir += ", "; if (i) type_ir += ", ";
ty2 = ty->get_param_type(i); ty2 = ty->get_param_type(i);
type_ir += (ty2 == nullptr ? "<null>" : ty2->safe_print()); type_ir += (ty2 == nullptr ? "<null>" : ty2->safe_print());
} }
return type_ir + ")"; return type_ir + ")";
} }
case PointerTyID: case PointerTyID:
{ {
auto ty = dynamic_cast<const PointerType*>(this); auto ty = dynamic_cast<const PointerType*>(this);
if (ty == nullptr) return "<not PointerType>"; if (ty == nullptr) return "<not PointerType>";
auto ty2 = ty->get_element_type(); auto ty2 = ty->get_element_type();
return (ty2 == nullptr ? "<null>" : ty2->safe_print()) + "*"; return (ty2 == nullptr ? "<null>" : ty2->safe_print()) + "*";
} }
case ArrayTyID: case ArrayTyID:
{ {
auto ty = dynamic_cast<const ArrayType*>(this); auto ty = dynamic_cast<const ArrayType*>(this);
if (ty == nullptr) return "<not ArrayType>"; if (ty == nullptr) return "<not ArrayType>";
auto ty2 = ty->get_element_type(); auto ty2 = ty->get_element_type();
return "[" + std::to_string(ty->get_num_of_elements()) + "x" + (ty2 == nullptr ? "<null>" : ty2->safe_print()) + "]"; return "[" + std::to_string(ty->get_num_of_elements()) + "x" + (ty2 == nullptr ? "<null>" : ty2->safe_print()) + "]";
} }
case FloatTyID: case FloatTyID:
return "float"; return "float";
} }
......
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