diff --git a/.gitignore b/.gitignore index 4f2cafc1a9b3b57b5760531902e7ecd51048a8e4..a450ff48d9572d4a09ee1b3d0ff20a04065634a5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ build Documentations/1-parser/*.pdf compile_commands.json .cache +todo.txt tmp.cminus diff --git a/include/lightir/Function.h b/include/lightir/Function.h index 507c59f15995c1c33ea48bb966dfb5846f56da04..079bf9df35531c201dc6643b1e91be853b9f49ef 100644 --- a/include/lightir/Function.h +++ b/include/lightir/Function.h @@ -18,11 +18,13 @@ class Argument; class Type; class FunctionType; -class Function : public Value, public llvm::ilist_node { +class Function : public Value, public llvm::ilist_node +{ public: Function(FunctionType *ty, const std::string &name, Module *parent); virtual ~Function(); - static Function *create(FunctionType *ty, const std::string &name, Module *parent); + static Function *create(FunctionType *ty, const std::string &name, + Module *parent); FunctionType *get_function_type() const; @@ -38,15 +40,15 @@ class Function : public Value, public llvm::ilist_node { std::list::iterator arg_begin() { return arguments_.begin(); } std::list::iterator arg_end() { return arguments_.end(); } - void remove(BasicBlock *bb); + void remove(BasicBlock *bb); BasicBlock *get_entry_block() { return &*basic_blocks_.begin(); } llvm::ilist &get_basic_blocks() { return basic_blocks_; } - std::list &get_args() { return arguments_; } + std::list &get_args() { return arguments_; } bool is_declaration() { return basic_blocks_.empty(); } - void set_instr_name(); + void set_instr_name(); std::string print(); private: @@ -54,27 +56,33 @@ class Function : public Value, public llvm::ilist_node { private: llvm::ilist basic_blocks_; // basic blocks - std::list arguments_; // arguments - Module *parent_; - unsigned seq_cnt_; + std::list arguments_; // arguments + Module *parent_; + unsigned seq_cnt_; // unsigned num_args_; // We don't need this, all value inside function should be unnamed - // std::map sym_table_; // Symbol table of args/instructions + // std::map sym_table_; // Symbol table of + // args/instructions }; // Argument of Function, does not contain actual value -class Argument : public Value { +class Argument : public Value +{ public: /// Argument constructor. - explicit Argument(Type *ty, const std::string &name = "", Function *f = nullptr, unsigned arg_no = 0) - : Value(ty, name), parent_(f), arg_no_(arg_no) {} + explicit Argument(Type *ty, const std::string &name = "", + Function *f = nullptr, unsigned arg_no = 0) + : Value(ty, name), parent_(f), arg_no_(arg_no) + { + } virtual ~Argument() {} inline const Function *get_parent() const { return parent_; } - inline Function *get_parent() { return parent_; } + inline Function *get_parent() { return parent_; } /// 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 + { assert(parent_ && "can't get number of unparented arg"); return arg_no_; } @@ -83,7 +91,7 @@ class Argument : public Value { private: Function *parent_; - unsigned arg_no_; // argument No. + unsigned arg_no_; // argument No. }; #endif // SYSYC_FUNCTION_H diff --git a/include/lightir/IRBuilder.h b/include/lightir/IRBuilder.h index a06b9679761ff15294803e6fe67ddc570bb06ad5..5bfd3cab7188c5a9b4e4a1cc0bcdb5d94320b847 100644 --- a/include/lightir/IRBuilder.h +++ b/include/lightir/IRBuilder.h @@ -6,96 +6,169 @@ #include "Instruction.h" #include "Value.h" -class IRBuilder { +class IRBuilder +{ private: BasicBlock *BB_; - Module *m_; + Module *m_; public: IRBuilder(BasicBlock *bb, Module *m) : BB_(bb), m_(m){}; ~IRBuilder() = default; - Module *get_module() { return m_; } + Module *get_module() { return m_; } BasicBlock *get_insert_block() { return this->BB_; } - void set_insert_point(BasicBlock *bb) { this->BB_ = bb; } // 在某个基本块中插入指令 - BinaryInst *create_iadd(Value *lhs, Value *rhs) { + void set_insert_point(BasicBlock *bb) + { + this->BB_ = bb; + } // 在某个基本块中插入指令 + BinaryInst *create_iadd(Value *lhs, Value *rhs) + { return BinaryInst::create_add(lhs, rhs, this->BB_, m_); } // 创建加法指令(以及其他算术指令) - BinaryInst *create_isub(Value *lhs, Value *rhs) { return BinaryInst::create_sub(lhs, rhs, this->BB_, m_); } - BinaryInst *create_imul(Value *lhs, Value *rhs) { return BinaryInst::create_mul(lhs, rhs, this->BB_, m_); } - BinaryInst *create_isdiv(Value *lhs, Value *rhs) { return BinaryInst::create_sdiv(lhs, rhs, this->BB_, m_); } + BinaryInst *create_isub(Value *lhs, Value *rhs) + { + return BinaryInst::create_sub(lhs, rhs, this->BB_, m_); + } + BinaryInst *create_imul(Value *lhs, Value *rhs) + { + return BinaryInst::create_mul(lhs, rhs, this->BB_, m_); + } + BinaryInst *create_isdiv(Value *lhs, Value *rhs) + { + return BinaryInst::create_sdiv(lhs, rhs, this->BB_, m_); + } - CmpInst *create_icmp_eq(Value *lhs, Value *rhs) { + CmpInst *create_icmp_eq(Value *lhs, Value *rhs) + { return CmpInst::create_cmp(CmpInst::EQ, lhs, rhs, this->BB_, m_); } - CmpInst *create_icmp_ne(Value *lhs, Value *rhs) { + CmpInst *create_icmp_ne(Value *lhs, Value *rhs) + { return CmpInst::create_cmp(CmpInst::NE, lhs, rhs, this->BB_, m_); } - CmpInst *create_icmp_gt(Value *lhs, Value *rhs) { + CmpInst *create_icmp_gt(Value *lhs, Value *rhs) + { return CmpInst::create_cmp(CmpInst::GT, lhs, rhs, this->BB_, m_); } - CmpInst *create_icmp_ge(Value *lhs, Value *rhs) { + CmpInst *create_icmp_ge(Value *lhs, Value *rhs) + { return CmpInst::create_cmp(CmpInst::GE, lhs, rhs, this->BB_, m_); } - CmpInst *create_icmp_lt(Value *lhs, Value *rhs) { + CmpInst *create_icmp_lt(Value *lhs, Value *rhs) + { return CmpInst::create_cmp(CmpInst::LT, lhs, rhs, this->BB_, m_); } - CmpInst *create_icmp_le(Value *lhs, Value *rhs) { + CmpInst *create_icmp_le(Value *lhs, Value *rhs) + { return CmpInst::create_cmp(CmpInst::LE, lhs, rhs, this->BB_, m_); } - CallInst *create_call(Value *func, std::vector args) { - assert(dynamic_cast(func) && "func must be Function * type"); + CallInst *create_call(Value *func, std::vector args) + { + assert(dynamic_cast(func) && + "func must be Function * type"); return CallInst::create(static_cast(func), args, this->BB_); } - BranchInst *create_br(BasicBlock *if_true) { return BranchInst::create_br(if_true, this->BB_); } - BranchInst *create_cond_br(Value *cond, BasicBlock *if_true, BasicBlock *if_false) { + BranchInst *create_br(BasicBlock *if_true) + { + return BranchInst::create_br(if_true, this->BB_); + } + BranchInst *create_cond_br(Value *cond, BasicBlock *if_true, + BasicBlock *if_false) + { return BranchInst::create_cond_br(cond, if_true, if_false, this->BB_); } - ReturnInst *create_ret(Value *val) { return ReturnInst::create_ret(val, this->BB_); } - ReturnInst *create_void_ret() { return ReturnInst::create_void_ret(this->BB_); } + ReturnInst *create_ret(Value *val) + { + return ReturnInst::create_ret(val, this->BB_); + } + ReturnInst *create_void_ret() + { + return ReturnInst::create_void_ret(this->BB_); + } - GetElementPtrInst *create_gep(Value *ptr, std::vector idxs) { + GetElementPtrInst *create_gep(Value *ptr, std::vector idxs) + { return GetElementPtrInst::create_gep(ptr, idxs, this->BB_); } - StoreInst *create_store(Value *val, Value *ptr) { return StoreInst::create_store(val, ptr, this->BB_); } - LoadInst *create_load(Type *ty, Value *ptr) { return LoadInst::create_load(ty, ptr, this->BB_); } - LoadInst *create_load(Value *ptr) { - assert(ptr->get_type()->is_pointer_type() && "ptr must be pointer type"); - return LoadInst::create_load(ptr->get_type()->get_pointer_element_type(), ptr, this->BB_); + StoreInst *create_store(Value *val, Value *ptr) + { + return StoreInst::create_store(val, ptr, this->BB_); + } + LoadInst *create_load(Type *ty, Value *ptr) + { + return LoadInst::create_load(ty, ptr, this->BB_); + } + LoadInst *create_load(Value *ptr) + { + assert(ptr->get_type()->is_pointer_type() && + "ptr must be pointer type"); + return LoadInst::create_load( + ptr->get_type()->get_pointer_element_type(), ptr, this->BB_); } - AllocaInst *create_alloca(Type *ty) { return AllocaInst::create_alloca(ty, this->BB_); } - ZextInst *create_zext(Value *val, Type *ty) { return ZextInst::create_zext(val, ty, this->BB_); } + AllocaInst *create_alloca(Type *ty) + { + return AllocaInst::create_alloca(ty, this->BB_); + } + ZextInst *create_zext(Value *val, Type *ty) + { + return ZextInst::create_zext(val, ty, this->BB_); + } - SiToFpInst *create_sitofp(Value *val, Type *ty) { return SiToFpInst::create_sitofp(val, ty, this->BB_); } - FpToSiInst *create_fptosi(Value *val, Type *ty) { return FpToSiInst::create_fptosi(val, ty, this->BB_); } + SiToFpInst *create_sitofp(Value *val, Type *ty) + { + return SiToFpInst::create_sitofp(val, ty, this->BB_); + } + FpToSiInst *create_fptosi(Value *val, Type *ty) + { + return FpToSiInst::create_fptosi(val, ty, this->BB_); + } - FCmpInst *create_fcmp_ne(Value *lhs, Value *rhs) { + FCmpInst *create_fcmp_ne(Value *lhs, Value *rhs) + { return FCmpInst::create_fcmp(FCmpInst::NE, lhs, rhs, this->BB_, m_); } - FCmpInst *create_fcmp_lt(Value *lhs, Value *rhs) { + FCmpInst *create_fcmp_lt(Value *lhs, Value *rhs) + { return FCmpInst::create_fcmp(FCmpInst::LT, lhs, rhs, this->BB_, m_); } - FCmpInst *create_fcmp_le(Value *lhs, Value *rhs) { + FCmpInst *create_fcmp_le(Value *lhs, Value *rhs) + { return FCmpInst::create_fcmp(FCmpInst::LE, lhs, rhs, this->BB_, m_); } - FCmpInst *create_fcmp_ge(Value *lhs, Value *rhs) { + FCmpInst *create_fcmp_ge(Value *lhs, Value *rhs) + { return FCmpInst::create_fcmp(FCmpInst::GE, lhs, rhs, this->BB_, m_); } - FCmpInst *create_fcmp_gt(Value *lhs, Value *rhs) { + FCmpInst *create_fcmp_gt(Value *lhs, Value *rhs) + { return FCmpInst::create_fcmp(FCmpInst::GT, lhs, rhs, this->BB_, m_); } - FCmpInst *create_fcmp_eq(Value *lhs, Value *rhs) { + FCmpInst *create_fcmp_eq(Value *lhs, Value *rhs) + { return FCmpInst::create_fcmp(FCmpInst::EQ, lhs, rhs, this->BB_, m_); } - BinaryInst *create_fadd(Value *lhs, Value *rhs) { return BinaryInst::create_fadd(lhs, rhs, this->BB_, m_); } - BinaryInst *create_fsub(Value *lhs, Value *rhs) { return BinaryInst::create_fsub(lhs, rhs, this->BB_, m_); } - BinaryInst *create_fmul(Value *lhs, Value *rhs) { return BinaryInst::create_fmul(lhs, rhs, this->BB_, m_); } - BinaryInst *create_fdiv(Value *lhs, Value *rhs) { return BinaryInst::create_fdiv(lhs, rhs, this->BB_, m_); } + BinaryInst *create_fadd(Value *lhs, Value *rhs) + { + return BinaryInst::create_fadd(lhs, rhs, this->BB_, m_); + } + BinaryInst *create_fsub(Value *lhs, Value *rhs) + { + return BinaryInst::create_fsub(lhs, rhs, this->BB_, m_); + } + BinaryInst *create_fmul(Value *lhs, Value *rhs) + { + return BinaryInst::create_fmul(lhs, rhs, this->BB_, m_); + } + BinaryInst *create_fdiv(Value *lhs, Value *rhs) + { + return BinaryInst::create_fdiv(lhs, rhs, this->BB_, m_); + } }; #endif // SYSYC_IRBUILDER_H diff --git a/include/lightir/Instruction.h b/include/lightir/Instruction.h index fe502e7c46c11bf6d8dbb969ee9f7e048eee8565..10913a562439c84bd6408ee4491bc0df08c30663 100644 --- a/include/lightir/Instruction.h +++ b/include/lightir/Instruction.h @@ -9,7 +9,8 @@ class BasicBlock; class Function; -class Instruction : public User, public llvm::ilist_node { +class Instruction : public User, public llvm::ilist_node +{ public: enum OpID { // Terminator Instructions @@ -47,42 +48,88 @@ class Instruction : public User, public llvm::ilist_node { Instruction(Type *ty, OpID id, unsigned num_ops); virtual ~Instruction() = default; inline const BasicBlock *get_parent() const { return parent_; } - inline BasicBlock *get_parent() { return parent_; } + inline BasicBlock *get_parent() { return parent_; } void set_parent(BasicBlock *parent) { this->parent_ = parent; } // Return the function this instruction belongs to. Function *get_function(); - Module *get_module(); + Module *get_module(); - OpID get_instr_type() const { return op_id_; } - std::string get_instr_op_name() { + OpID get_instr_type() const { return op_id_; } + std::string get_instr_op_name() + { switch (op_id_) { - case ret: return "ret"; break; - case br: return "br"; break; - case add: return "add"; break; - case sub: return "sub"; break; - case mul: return "mul"; break; - case sdiv: return "sdiv"; break; - case fadd: return "fadd"; break; - case fsub: return "fsub"; break; - case fmul: return "fmul"; break; - case fdiv: return "fdiv"; break; - case alloca: return "alloca"; break; - case load: return "load"; break; - case store: return "store"; break; - case cmp: return "cmp"; break; - case fcmp: return "fcmp"; break; - case phi: return "phi"; break; - case call: return "call"; break; - case getelementptr: return "getelementptr"; break; - case zext: return "zext"; break; - case fptosi: return "fptosi"; break; - case sitofp: return "sitofp"; break; - - default: return ""; break; + case ret: + return "ret"; + break; + case br: + return "br"; + break; + case add: + return "add"; + break; + case sub: + return "sub"; + break; + case mul: + return "mul"; + break; + case sdiv: + return "sdiv"; + break; + case fadd: + return "fadd"; + break; + case fsub: + return "fsub"; + break; + case fmul: + return "fmul"; + break; + case fdiv: + return "fdiv"; + break; + case alloca: + return "alloca"; + break; + case load: + return "load"; + break; + case store: + return "store"; + break; + case cmp: + return "cmp"; + break; + case fcmp: + return "fcmp"; + break; + case phi: + return "phi"; + break; + case call: + return "call"; + break; + case getelementptr: + return "getelementptr"; + break; + case zext: + return "zext"; + break; + case fptosi: + return "fptosi"; + break; + case sitofp: + return "sitofp"; + break; + + default: + return ""; + break; } } - bool is_void() { + bool is_void() + { return ((op_id_ == ret) || (op_id_ == br) || (op_id_ == store) || (op_id_ == call && this->get_type()->is_void_type())); } @@ -113,42 +160,52 @@ class Instruction : public User, public llvm::ilist_node { bool is_gep() { return op_id_ == getelementptr; } bool is_zext() { return op_id_ == zext; } - bool isBinary() { - return (is_add() || is_sub() || is_mul() || is_div() || is_fadd() || is_fsub() || is_fmul() || is_fdiv()) && + bool isBinary() + { + return (is_add() || is_sub() || is_mul() || is_div() || is_fadd() || + is_fsub() || is_fmul() || is_fdiv()) && (get_num_operand() == 2); } bool isTerminator() { return is_br() || is_ret(); } private: - OpID op_id_; - unsigned num_ops_; + OpID op_id_; + unsigned num_ops_; BasicBlock *parent_; }; -namespace detail { -template -struct tag { - using type = T; -}; -template -struct select_last { - // Use a fold-expression to fold the comma operator over the parameter pack. - using type = typename decltype((tag{}, ...))::type; -}; -template -using select_last_t = typename select_last::type; +namespace detail +{ + template + struct tag + { + using type = T; + }; + template + struct select_last + { + // Use a fold-expression to fold the comma operator over the parameter + // pack. + using type = typename decltype((tag{}, ...))::type; + }; + template + using select_last_t = typename select_last::type; }; // namespace detail template inline constexpr bool always_false_v = false; template -class BaseInst : public Instruction { +class BaseInst : public Instruction +{ protected: template - static Inst *create(Args &&...args) { - if constexpr (std::is_same_v>, BasicBlock *>) { + static Inst *create(Args &&...args) + { + if constexpr (std::is_same_v< + std::decay_t>, + BasicBlock *>) { auto ptr = new Inst(std::forward(args)...); return ptr; } else @@ -156,10 +213,13 @@ class BaseInst : public Instruction { } template - BaseInst(Args &&...args) : Instruction(std::forward(args)...) {} + BaseInst(Args &&...args) : Instruction(std::forward(args)...) + { + } }; -class BinaryInst : public BaseInst { +class BinaryInst : public BaseInst +{ friend BaseInst; private: @@ -167,28 +227,36 @@ class BinaryInst : public BaseInst { public: // create add instruction, auto insert to bb - static BinaryInst *create_add(Value *v1, Value *v2, BasicBlock *bb, Module *m); + static BinaryInst *create_add(Value *v1, Value *v2, BasicBlock *bb, + Module *m); // create sub instruction, auto insert to bb - static BinaryInst *create_sub(Value *v1, Value *v2, BasicBlock *bb, Module *m); + static BinaryInst *create_sub(Value *v1, Value *v2, BasicBlock *bb, + Module *m); // create mul instruction, auto insert to bb - static BinaryInst *create_mul(Value *v1, Value *v2, BasicBlock *bb, Module *m); + static BinaryInst *create_mul(Value *v1, Value *v2, BasicBlock *bb, + Module *m); // create Div instruction, auto insert to bb - static BinaryInst *create_sdiv(Value *v1, Value *v2, BasicBlock *bb, Module *m); + static BinaryInst *create_sdiv(Value *v1, Value *v2, BasicBlock *bb, + Module *m); // create fadd instruction, auto insert to bb - static BinaryInst *create_fadd(Value *v1, Value *v2, BasicBlock *bb, Module *m); + static BinaryInst *create_fadd(Value *v1, Value *v2, BasicBlock *bb, + Module *m); // create fsub instruction, auto insert to bb - static BinaryInst *create_fsub(Value *v1, Value *v2, BasicBlock *bb, Module *m); + static BinaryInst *create_fsub(Value *v1, Value *v2, BasicBlock *bb, + Module *m); // create fmul instruction, auto insert to bb - static BinaryInst *create_fmul(Value *v1, Value *v2, BasicBlock *bb, Module *m); + static BinaryInst *create_fmul(Value *v1, Value *v2, BasicBlock *bb, + Module *m); // create fDiv instruction, auto insert to bb - static BinaryInst *create_fdiv(Value *v1, Value *v2, BasicBlock *bb, Module *m); + static BinaryInst *create_fdiv(Value *v1, Value *v2, BasicBlock *bb, + Module *m); virtual std::string print() override; @@ -196,7 +264,8 @@ class BinaryInst : public BaseInst { void assertValid(); }; -class CmpInst : public BaseInst { +class CmpInst : public BaseInst +{ friend BaseInst; public: @@ -213,7 +282,8 @@ class CmpInst : public BaseInst { CmpInst(Type *ty, CmpOp op, Value *lhs, Value *rhs, BasicBlock *bb); public: - static CmpInst *create_cmp(CmpOp op, Value *lhs, Value *rhs, BasicBlock *bb, Module *m); + static CmpInst *create_cmp(CmpOp op, Value *lhs, Value *rhs, BasicBlock *bb, + Module *m); CmpOp get_cmp_op() { return cmp_op_; } @@ -225,7 +295,8 @@ class CmpInst : public BaseInst { void assertValid(); }; -class FCmpInst : public BaseInst { +class FCmpInst : public BaseInst +{ friend BaseInst; public: @@ -242,7 +313,8 @@ class FCmpInst : public BaseInst { FCmpInst(Type *ty, CmpOp op, Value *lhs, Value *rhs, BasicBlock *bb); public: - static FCmpInst *create_fcmp(CmpOp op, Value *lhs, Value *rhs, BasicBlock *bb, Module *m); + static FCmpInst *create_fcmp(CmpOp op, Value *lhs, Value *rhs, + BasicBlock *bb, Module *m); CmpOp get_cmp_op() { return cmp_op_; } @@ -254,28 +326,33 @@ class FCmpInst : public BaseInst { void assert_valid(); }; -class CallInst : public BaseInst { +class CallInst : public BaseInst +{ friend BaseInst; protected: CallInst(Function *func, std::vector args, BasicBlock *bb); public: - static CallInst *create(Function *func, std::vector args, BasicBlock *bb); - FunctionType *get_function_type() const; + static CallInst *create(Function *func, std::vector args, + BasicBlock *bb); + FunctionType *get_function_type() const; virtual std::string print() override; }; -class BranchInst : public BaseInst { +class BranchInst : public BaseInst +{ friend BaseInst; private: - BranchInst(Value *cond, BasicBlock *if_true, BasicBlock *if_false, BasicBlock *bb); + BranchInst(Value *cond, BasicBlock *if_true, BasicBlock *if_false, + BasicBlock *bb); BranchInst(BasicBlock *if_true, BasicBlock *bb); public: - static BranchInst *create_cond_br(Value *cond, BasicBlock *if_true, BasicBlock *if_false, BasicBlock *bb); + static BranchInst *create_cond_br(Value *cond, BasicBlock *if_true, + BasicBlock *if_false, BasicBlock *bb); static BranchInst *create_br(BasicBlock *if_true, BasicBlock *bb); bool is_cond_br() const; @@ -283,7 +360,8 @@ class BranchInst : public BaseInst { virtual std::string print() override; }; -class ReturnInst : public BaseInst { +class ReturnInst : public BaseInst +{ friend BaseInst; private: @@ -293,12 +371,13 @@ class ReturnInst : public BaseInst { public: static ReturnInst *create_ret(Value *val, BasicBlock *bb); static ReturnInst *create_void_ret(BasicBlock *bb); - bool is_void_ret() const; + bool is_void_ret() const; virtual std::string print() override; }; -class GetElementPtrInst : public BaseInst { +class GetElementPtrInst : public BaseInst +{ friend BaseInst; private: @@ -306,8 +385,9 @@ class GetElementPtrInst : public BaseInst { public: static Type *get_element_type(Value *ptr, std::vector idxs); - static GetElementPtrInst *create_gep(Value *ptr, std::vector idxs, BasicBlock *bb); - Type *get_element_type() const; + static GetElementPtrInst *create_gep(Value *ptr, std::vector idxs, + BasicBlock *bb); + Type *get_element_type() const; virtual std::string print() override; @@ -315,7 +395,8 @@ class GetElementPtrInst : public BaseInst { Type *element_ty_; }; -class StoreInst : public BaseInst { +class StoreInst : public BaseInst +{ friend BaseInst; private: @@ -330,7 +411,8 @@ class StoreInst : public BaseInst { virtual std::string print() override; }; -class LoadInst : public BaseInst { +class LoadInst : public BaseInst +{ friend BaseInst; private: @@ -338,14 +420,15 @@ class LoadInst : public BaseInst { public: static LoadInst *create_load(Type *ty, Value *ptr, BasicBlock *bb); - Value *get_lval() { return this->get_operand(0); } + Value *get_lval() { return this->get_operand(0); } Type *get_load_type() const; virtual std::string print() override; }; -class AllocaInst : public BaseInst { +class AllocaInst : public BaseInst +{ friend BaseInst; private: @@ -362,7 +445,8 @@ class AllocaInst : public BaseInst { Type *alloca_ty_; }; -class ZextInst : public BaseInst { +class ZextInst : public BaseInst +{ friend BaseInst; private: @@ -379,7 +463,8 @@ class ZextInst : public BaseInst { Type *dest_ty_; }; -class FpToSiInst : public BaseInst { +class FpToSiInst : public BaseInst +{ friend BaseInst; private: @@ -396,7 +481,8 @@ class FpToSiInst : public BaseInst { Type *dest_ty_; }; -class SiToFpInst : public BaseInst { +class SiToFpInst : public BaseInst +{ friend BaseInst; private: @@ -413,19 +499,25 @@ class SiToFpInst : public BaseInst { Type *dest_ty_; }; -class PhiInst : public BaseInst { +class PhiInst : public BaseInst +{ friend BaseInst; private: - PhiInst(OpID op, std::vector vals, std::vector val_bbs, Type *ty, BasicBlock *bb); - PhiInst(Type *ty, OpID op, unsigned num_ops, BasicBlock *bb) : BaseInst(ty, op, num_ops, bb) {} + PhiInst(OpID op, std::vector vals, + std::vector val_bbs, Type *ty, BasicBlock *bb); + PhiInst(Type *ty, OpID op, unsigned num_ops, BasicBlock *bb) + : BaseInst(ty, op, num_ops, bb) + { + } Value *l_val_; public: static PhiInst *create_phi(Type *ty, BasicBlock *bb); - Value *get_lval() { return l_val_; } - void set_lval(Value *l_val) { l_val_ = l_val; } - void add_phi_pair_operand(Value *val, Value *pre_bb) { + Value *get_lval() { return l_val_; } + void set_lval(Value *l_val) { l_val_ = l_val; } + void add_phi_pair_operand(Value *val, Value *pre_bb) + { this->add_operand(val); this->add_operand(pre_bb); } diff --git a/tests/2-ir-gen-warmup/CMakeLists.txt b/tests/2-ir-gen-warmup/CMakeLists.txt index e70dd2644f0f3582e78b1cd75d9fd1bad08165b0..11a7cba40cc82818b63a18bb0a5ab9c5cbb1819e 100644 --- a/tests/2-ir-gen-warmup/CMakeLists.txt +++ b/tests/2-ir-gen-warmup/CMakeLists.txt @@ -8,35 +8,35 @@ target_link_libraries( IR_lib ) -# add_executable( -# stu_assign_generator -# stu_cpp/assign_generator.cpp -# ) -# target_link_libraries( -# stu_assign_generator -# IR_lib -# ) -# add_executable( -# stu_fun_generator -# stu_cpp/fun_generator.cpp -# ) -# target_link_libraries( -# stu_fun_generator -# IR_lib -# ) -# add_executable( -# stu_if_generator -# stu_cpp/if_generator.cpp -# ) -# target_link_libraries( -# stu_if_generator -# IR_lib -# ) -# add_executable( -# stu_while_generator -# stu_cpp/while_generator.cpp -# ) -# target_link_libraries( -# stu_while_generator -# IR_lib -# ) + add_executable( + stu_assign_generator + stu_cpp/assign_generator.cpp +) +target_link_libraries( + stu_assign_generator + IR_lib +) +add_executable( + stu_fun_generator + stu_cpp/fun_generator.cpp +) +target_link_libraries( + stu_fun_generator + IR_lib +) +add_executable( + stu_if_generator + stu_cpp/if_generator.cpp +) +target_link_libraries( + stu_if_generator + IR_lib +) +add_executable( + stu_while_generator + stu_cpp/while_generator.cpp +) +target_link_libraries( + stu_while_generator + IR_lib +) diff --git a/tests/2-ir-gen-warmup/stu_cpp/assign_generator.cpp b/tests/2-ir-gen-warmup/stu_cpp/assign_generator.cpp index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8a4cef9ee499845b0bbc7b8d63c816b345e9f4cb 100644 --- a/tests/2-ir-gen-warmup/stu_cpp/assign_generator.cpp +++ b/tests/2-ir-gen-warmup/stu_cpp/assign_generator.cpp @@ -0,0 +1,38 @@ +#include "Module.h" +#include "IRBuilder.h" +#include "Type.h" +#include "Constant.h" + +#include +#include + +int main() +{ + auto mod = new Module("assign.c"); + auto bud = new IRBuilder(nullptr, mod); + auto I32Type = Type::get_int32_type(mod); + auto I32x10Type = Type::get_array_type(I32Type, 10); + + std::vector NoneArg; + auto mainTp = FunctionType::get(I32Type, NoneArg); + auto mainFunc = Function::create(mainTp, "main", mod); + + auto bb = BasicBlock::create(mod, "entry", mainFunc); + bud->set_insert_point(bb); + + auto arr_ptr = bud->create_alloca(I32x10Type); + auto a0_ptr = bud->create_gep( + arr_ptr, {ConstantInt::get(0, mod), ConstantInt::get(0, mod)}); + auto a1_ptr = bud->create_gep( + arr_ptr, {ConstantInt::get(0, mod), ConstantInt::get(0, mod)}); + bud->create_store(ConstantInt::get(10, mod), a0_ptr); + auto a0_load = bud->create_load(a0_ptr); + auto mul = bud->create_imul(a0_load, ConstantInt::get(2, mod)); + bud->create_store(mul, a1_ptr); + auto a1_load = bud->create_load(a1_ptr); + bud->create_ret(a1_load); + + std::cout << mod->print(); + delete mod; + return 0; +} diff --git a/tests/2-ir-gen-warmup/stu_cpp/fun_generator.cpp b/tests/2-ir-gen-warmup/stu_cpp/fun_generator.cpp index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..dd4649fa75bf560a4751b9862ee6ab9aa27a138b 100644 --- a/tests/2-ir-gen-warmup/stu_cpp/fun_generator.cpp +++ b/tests/2-ir-gen-warmup/stu_cpp/fun_generator.cpp @@ -0,0 +1,42 @@ +#include "BasicBlock.h" +#include "Constant.h" +#include "Function.h" +#include "IRBuilder.h" +#include "Module.h" +#include "Type.h" + +#include + +int main() +{ + + auto mod = new Module("Cminus code"); // module name是什么无关紧要 + auto bud = new IRBuilder(nullptr, mod); + Type *I32Type = Type::get_int32_type(mod); + std::vector OneIntArg(1, I32Type); + auto calleeTp = FunctionType::get(I32Type, OneIntArg); + auto calleeFunc = Function::create(calleeTp, "callee", mod); + auto bb = BasicBlock::create(mod, "entry", calleeFunc); + bud->set_insert_point(bb); + + std::vector arg_vs; + for (auto arg = calleeFunc->arg_begin(); arg != calleeFunc->arg_end(); + arg++) + arg_vs.push_back(*arg); + auto mul = bud->create_imul(arg_vs[0], ConstantInt::get(2, mod)); + bud->create_ret(mul); + + + auto mainTp = FunctionType::get(I32Type, {}); + auto mainFunc = Function::create(mainTp, "main", mod); + bb = BasicBlock::create(mod, "entry", mainFunc); + bud->set_insert_point(bb); + + auto call = bud->create_call(calleeFunc, {ConstantInt::get(110, mod)}); + bud->create_ret(call); + + + std::cout << mod->print(); + delete mod; + return 0; +} diff --git a/tests/2-ir-gen-warmup/stu_cpp/if_generator.cpp b/tests/2-ir-gen-warmup/stu_cpp/if_generator.cpp index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3436c747e412fe162422ae50d74de7593683519f 100644 --- a/tests/2-ir-gen-warmup/stu_cpp/if_generator.cpp +++ b/tests/2-ir-gen-warmup/stu_cpp/if_generator.cpp @@ -0,0 +1,38 @@ +#include "BasicBlock.h" +#include "Constant.h" +#include "Function.h" +#include "IRBuilder.h" +#include "Module.h" +#include "Type.h" + +#include + +int main() +{ + auto mod = new Module("if.c"); + auto bud = new IRBuilder(nullptr, mod); + Type *I32Type = Type::get_int32_type(mod); + Type *floatType = Type::get_float_type(mod); + + auto mainTp = FunctionType::get(I32Type, {}); + auto mainFunc = Function::create(mainTp, "main", mod); + auto bb = BasicBlock::create(mod, "entry", mainFunc); + + bud->set_insert_point(bb); + auto aAlloc = bud->create_alloca(floatType); + bud->create_store(ConstantFP::get(5.555, mod), aAlloc); + auto aValue = bud->create_load(aAlloc); + auto cond = bud->create_fcmp_gt(aValue, ConstantFP::get(1, mod)); + auto TBB = BasicBlock::create(mod, "trueCase", mainFunc); + auto FBB = BasicBlock::create(mod, "falseCase", mainFunc); + bud->create_cond_br(cond, TBB, FBB); + + bud->set_insert_point(TBB); + bud->create_ret(ConstantInt::get(233, mod)); + bud->set_insert_point(FBB); + bud->create_ret(ConstantInt::get(0, mod)); + + std::cout << mod->print(); + delete mod; + return 0; +} diff --git a/tests/2-ir-gen-warmup/stu_cpp/while_generator.cpp b/tests/2-ir-gen-warmup/stu_cpp/while_generator.cpp index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2db0dd7bc81dcabffcff6e6acc350ae3ae3b83b8 100644 --- a/tests/2-ir-gen-warmup/stu_cpp/while_generator.cpp +++ b/tests/2-ir-gen-warmup/stu_cpp/while_generator.cpp @@ -0,0 +1,53 @@ +#include "BasicBlock.h" +#include "Constant.h" +#include "Function.h" +#include "IRBuilder.h" +#include "Module.h" +#include "Type.h" + +#include + +int main() +{ + auto mod = new Module("while.c"); + auto bud = new IRBuilder(nullptr, mod); + Type *I32Type = Type::get_int32_type(mod); + + // main函数 + auto mainFunc = + Function::create(FunctionType::get(I32Type, {}), "main", mod); + auto bb = BasicBlock::create(mod, "entry", mainFunc); + auto judge = BasicBlock::create(mod, "judge", mainFunc); + auto loop = BasicBlock::create(mod, "loop", mainFunc); + auto exit = BasicBlock::create(mod, "exit", mainFunc); + + bud->set_insert_point(bb); + auto aAlloc = bud->create_alloca(I32Type); + auto iAlloc = bud->create_alloca(I32Type); + bud->create_store(ConstantInt::get(10, mod), aAlloc); + bud->create_store(ConstantInt::get(0, mod), iAlloc); + bud->create_br(judge); + + bud->set_insert_point(judge); + auto iV = bud->create_load(iAlloc); + auto cond = bud->create_icmp_lt(iV, ConstantInt::get(10, mod)); + bud->create_cond_br(cond, loop, exit); + + + bud->set_insert_point(loop); + auto add = bud->create_iadd(iV, ConstantInt::get(1, mod)); + bud->create_store(add, iAlloc); + // + auto aV = bud->create_load(aAlloc); + auto aadd = bud->create_iadd(add, aV); + bud->create_store(aadd, aAlloc); + bud->create_br(judge); + + bud->set_insert_point(exit); + aV = bud->create_load(aAlloc); + bud->create_ret(aV); + + std::cout << mod->print(); + delete mod; + return 0; +} diff --git a/tests/2-ir-gen-warmup/stu_ll/assign_hand.ll b/tests/2-ir-gen-warmup/stu_ll/assign_hand.ll index 5e427ea739f0782467b1f0499e604431a74b7418..ee50bddc6e0f72f3bbac3ea6d0d9766788a5ef79 100644 --- a/tests/2-ir-gen-warmup/stu_ll/assign_hand.ll +++ b/tests/2-ir-gen-warmup/stu_ll/assign_hand.ll @@ -1,11 +1,11 @@ define dso_local i32 @main() #0 { - %a = alloca [10 x i32], align 4 + %a = alloca [10 x i32] ; ptr is the pointer with type i32* %ptr = getelementptr [10 x i32], [10 x i32]* %a, i64 0, i64 0 - %a0 = getelementptr i32, i32* %ptr, i64 0 + ; %a0 = getelementptr i32, i32* %ptr, i64 0 %a1 = getelementptr i32, i32* %ptr, i64 1 - store i32 10, i32* %a0 - %v1 = load i32, i32* %a0 + store i32 10, i32* %ptr + %v1 = load i32, i32* %ptr %v2 = mul i32 %v1, 2 store i32 %v2, i32* %a1 %r = load i32, i32* %a1 diff --git a/tests/2-ir-gen-warmup/ta_gcd/gcd_array_generator.cpp b/tests/2-ir-gen-warmup/ta_gcd/gcd_array_generator.cpp index 8b49c52aa1bb5cde8249e80355619ae76d403399..8ff8459b2d401055c1fcd3b1f609a976b24a0814 100644 --- a/tests/2-ir-gen-warmup/ta_gcd/gcd_array_generator.cpp +++ b/tests/2-ir-gen-warmup/ta_gcd/gcd_array_generator.cpp @@ -12,12 +12,13 @@ * #define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; // * 输出行号的简单示例 #else #define DEBUG_OUTPUT #endif */ -#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; // 输出行号的简单示例 +// 输出行号的简单示例 +#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; #define CONST_INT(num) ConstantInt::get(num, mod) -#define CONST_FP(num) \ - ConstantFP::get(num, mod) // 得到常数值的表示,方便后面多次用到 +// 得到常数值的表示,方便后面多次用到 +#define CONST_FP(num) ConstantFP::get(num, mod) int main() { @@ -71,9 +72,10 @@ int main() mod, "", gcdFun); // return分支,提前create,以便true分支可以br auto br = builder->create_cond_br(icmp, trueBB, falseBB); // 条件BR - DEBUG_OUTPUT // 调试的时候故意留下来的,以醒目地提醒你这个调试用的宏定义方法 - builder->set_insert_point( - trueBB); // if true; 分支的开始需要SetInsertPoint设置 + DEBUG_OUTPUT; // 调试的时候故意留下来的,以醒目地提醒你这个调试用的宏定义方法 + + // if true; 分支的开始需要SetInsertPoint设置 + builder->set_insert_point(trueBB); auto uLoad = builder->create_load(uAlloca); builder->create_store(uLoad, retAlloca); builder->create_br(retBB); // br retBB @@ -106,8 +108,8 @@ int main() auto bAlloca = builder->create_alloca(Int32Type); // b的存放 auto tempAlloca = builder->create_alloca(Int32Type); // temp的存放 - std::vector - args1; //获取funArrayFun函数的形参,通过Function中的iterator + //获取funArray函数的形参,通过Function中的iterator + std::vector args1; for (auto arg = funArrayFun->arg_begin(); arg != funArrayFun->arg_end(); arg++) { args1.push_back(*arg); // * 号运算符是从迭代器中取出迭代器当前指向的元素