Commit 4b7accb1 authored by 李晓奇's avatar 李晓奇

finish part2: write cpp to generate .ll file

parent a0b2bd9d
...@@ -2,5 +2,6 @@ build ...@@ -2,5 +2,6 @@ build
Documentations/1-parser/*.pdf Documentations/1-parser/*.pdf
compile_commands.json compile_commands.json
.cache .cache
todo.txt
tmp.cminus tmp.cminus
...@@ -18,11 +18,13 @@ class Argument; ...@@ -18,11 +18,13 @@ class Argument;
class Type; class Type;
class FunctionType; class FunctionType;
class Function : public Value, public llvm::ilist_node<Function> { class Function : public Value, public llvm::ilist_node<Function>
{
public: public:
Function(FunctionType *ty, const std::string &name, Module *parent); Function(FunctionType *ty, const std::string &name, Module *parent);
virtual ~Function(); 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; FunctionType *get_function_type() const;
...@@ -38,15 +40,15 @@ class Function : public Value, public llvm::ilist_node<Function> { ...@@ -38,15 +40,15 @@ class Function : public Value, public llvm::ilist_node<Function> {
std::list<Argument *>::iterator arg_begin() { return arguments_.begin(); } std::list<Argument *>::iterator arg_begin() { return arguments_.begin(); }
std::list<Argument *>::iterator arg_end() { return arguments_.end(); } std::list<Argument *>::iterator arg_end() { return arguments_.end(); }
void remove(BasicBlock *bb); void remove(BasicBlock *bb);
BasicBlock *get_entry_block() { return &*basic_blocks_.begin(); } BasicBlock *get_entry_block() { return &*basic_blocks_.begin(); }
llvm::ilist<BasicBlock> &get_basic_blocks() { return basic_blocks_; } llvm::ilist<BasicBlock> &get_basic_blocks() { return basic_blocks_; }
std::list<Argument *> &get_args() { return arguments_; } std::list<Argument *> &get_args() { return arguments_; }
bool is_declaration() { return basic_blocks_.empty(); } bool is_declaration() { return basic_blocks_.empty(); }
void set_instr_name(); void set_instr_name();
std::string print(); std::string print();
private: private:
...@@ -54,27 +56,33 @@ class Function : public Value, public llvm::ilist_node<Function> { ...@@ -54,27 +56,33 @@ class Function : public Value, public llvm::ilist_node<Function> {
private: private:
llvm::ilist<BasicBlock> basic_blocks_; // basic blocks llvm::ilist<BasicBlock> basic_blocks_; // basic blocks
std::list<Argument *> arguments_; // arguments std::list<Argument *> arguments_; // arguments
Module *parent_; Module *parent_;
unsigned seq_cnt_; unsigned seq_cnt_;
// unsigned num_args_; // unsigned num_args_;
// We don't need this, all value inside function should be unnamed // We don't need this, all value inside function should be unnamed
// std::map<std::string, Value*> sym_table_; // Symbol table of args/instructions // std::map<std::string, Value*> sym_table_; // Symbol table of
// args/instructions
}; };
// 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 constructor. /// Argument constructor.
explicit Argument(Type *ty, const std::string &name = "", Function *f = nullptr, unsigned arg_no = 0) explicit Argument(Type *ty, const std::string &name = "",
: Value(ty, name), parent_(f), arg_no_(arg_no) {} Function *f = nullptr, unsigned arg_no = 0)
: Value(ty, name), parent_(f), arg_no_(arg_no)
{
}
virtual ~Argument() {} virtual ~Argument() {}
inline const Function *get_parent() const { return parent_; } 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. /// 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"); assert(parent_ && "can't get number of unparented arg");
return arg_no_; return arg_no_;
} }
...@@ -83,7 +91,7 @@ class Argument : public Value { ...@@ -83,7 +91,7 @@ class Argument : public Value {
private: private:
Function *parent_; Function *parent_;
unsigned arg_no_; // argument No. unsigned arg_no_; // argument No.
}; };
#endif // SYSYC_FUNCTION_H #endif // SYSYC_FUNCTION_H
...@@ -6,96 +6,169 @@ ...@@ -6,96 +6,169 @@
#include "Instruction.h" #include "Instruction.h"
#include "Value.h" #include "Value.h"
class IRBuilder { class IRBuilder
{
private: private:
BasicBlock *BB_; BasicBlock *BB_;
Module *m_; Module *m_;
public: public:
IRBuilder(BasicBlock *bb, Module *m) : BB_(bb), m_(m){}; IRBuilder(BasicBlock *bb, Module *m) : BB_(bb), m_(m){};
~IRBuilder() = default; ~IRBuilder() = default;
Module *get_module() { return m_; } Module *get_module() { return m_; }
BasicBlock *get_insert_block() { return this->BB_; } BasicBlock *get_insert_block() { return this->BB_; }
void set_insert_point(BasicBlock *bb) { this->BB_ = bb; } // 在某个基本块中插入指令 void set_insert_point(BasicBlock *bb)
BinaryInst *create_iadd(Value *lhs, Value *rhs) { {
this->BB_ = bb;
} // 在某个基本块中插入指令
BinaryInst *create_iadd(Value *lhs, Value *rhs)
{
return BinaryInst::create_add(lhs, rhs, this->BB_, m_); 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_isub(Value *lhs, Value *rhs)
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_); } 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_); 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_); 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_); 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_); 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_); 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_); return CmpInst::create_cmp(CmpInst::LE, lhs, rhs, this->BB_, m_);
} }
CallInst *create_call(Value *func, std::vector<Value *> args) { CallInst *create_call(Value *func, std::vector<Value *> args)
assert(dynamic_cast<Function *>(func) && "func must be Function * type"); {
assert(dynamic_cast<Function *>(func) &&
"func must be Function * type");
return CallInst::create(static_cast<Function *>(func), args, this->BB_); return CallInst::create(static_cast<Function *>(func), args, this->BB_);
} }
BranchInst *create_br(BasicBlock *if_true) { return BranchInst::create_br(if_true, this->BB_); } BranchInst *create_br(BasicBlock *if_true)
BranchInst *create_cond_br(Value *cond, BasicBlock *if_true, BasicBlock *if_false) { {
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_); 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_ret(Value *val)
ReturnInst *create_void_ret() { return ReturnInst::create_void_ret(this->BB_); } {
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<Value *> idxs) { GetElementPtrInst *create_gep(Value *ptr, std::vector<Value *> idxs)
{
return GetElementPtrInst::create_gep(ptr, idxs, this->BB_); return GetElementPtrInst::create_gep(ptr, idxs, this->BB_);
} }
StoreInst *create_store(Value *val, Value *ptr) { return StoreInst::create_store(val, ptr, this->BB_); } StoreInst *create_store(Value *val, Value *ptr)
LoadInst *create_load(Type *ty, Value *ptr) { return LoadInst::create_load(ty, ptr, this->BB_); } {
LoadInst *create_load(Value *ptr) { return StoreInst::create_store(val, ptr, this->BB_);
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_); 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_); } AllocaInst *create_alloca(Type *ty)
ZextInst *create_zext(Value *val, Type *ty) { return ZextInst::create_zext(val, ty, this->BB_); } {
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_); } SiToFpInst *create_sitofp(Value *val, Type *ty)
FpToSiInst *create_fptosi(Value *val, Type *ty) { return FpToSiInst::create_fptosi(val, ty, this->BB_); } {
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_); 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_); 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_); 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_); 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_); 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_); 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_fadd(Value *lhs, Value *rhs)
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_); } return BinaryInst::create_fadd(lhs, rhs, this->BB_, m_);
BinaryInst *create_fdiv(Value *lhs, Value *rhs) { return BinaryInst::create_fdiv(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 #endif // SYSYC_IRBUILDER_H
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
class BasicBlock; class BasicBlock;
class Function; class Function;
class Instruction : public User, public llvm::ilist_node<Instruction> { class Instruction : public User, public llvm::ilist_node<Instruction>
{
public: public:
enum OpID { enum OpID {
// Terminator Instructions // Terminator Instructions
...@@ -47,42 +48,88 @@ class Instruction : public User, public llvm::ilist_node<Instruction> { ...@@ -47,42 +48,88 @@ class Instruction : public User, public llvm::ilist_node<Instruction> {
Instruction(Type *ty, OpID id, unsigned num_ops); Instruction(Type *ty, OpID id, unsigned num_ops);
virtual ~Instruction() = default; virtual ~Instruction() = default;
inline const BasicBlock *get_parent() const { return parent_; } 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; } void set_parent(BasicBlock *parent) { this->parent_ = parent; }
// Return the function this instruction belongs to. // Return the function this instruction belongs to.
Function *get_function(); Function *get_function();
Module *get_module(); Module *get_module();
OpID get_instr_type() const { return op_id_; } OpID get_instr_type() const { return op_id_; }
std::string get_instr_op_name() { std::string get_instr_op_name()
{
switch (op_id_) { switch (op_id_) {
case ret: return "ret"; break; case ret:
case br: return "br"; break; return "ret";
case add: return "add"; break; break;
case sub: return "sub"; break; case br:
case mul: return "mul"; break; return "br";
case sdiv: return "sdiv"; break; break;
case fadd: return "fadd"; break; case add:
case fsub: return "fsub"; break; return "add";
case fmul: return "fmul"; break; break;
case fdiv: return "fdiv"; break; case sub:
case alloca: return "alloca"; break; return "sub";
case load: return "load"; break; break;
case store: return "store"; break; case mul:
case cmp: return "cmp"; break; return "mul";
case fcmp: return "fcmp"; break; break;
case phi: return "phi"; break; case sdiv:
case call: return "call"; break; return "sdiv";
case getelementptr: return "getelementptr"; break; break;
case zext: return "zext"; break; case fadd:
case fptosi: return "fptosi"; break; return "fadd";
case sitofp: return "sitofp"; break; break;
case fsub:
default: return ""; break; 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) || return ((op_id_ == ret) || (op_id_ == br) || (op_id_ == store) ||
(op_id_ == call && this->get_type()->is_void_type())); (op_id_ == call && this->get_type()->is_void_type()));
} }
...@@ -113,42 +160,52 @@ class Instruction : public User, public llvm::ilist_node<Instruction> { ...@@ -113,42 +160,52 @@ class Instruction : public User, public llvm::ilist_node<Instruction> {
bool is_gep() { return op_id_ == getelementptr; } bool is_gep() { return op_id_ == getelementptr; }
bool is_zext() { return op_id_ == zext; } bool is_zext() { return op_id_ == zext; }
bool isBinary() { bool isBinary()
return (is_add() || is_sub() || is_mul() || is_div() || is_fadd() || is_fsub() || is_fmul() || is_fdiv()) && {
return (is_add() || is_sub() || is_mul() || is_div() || is_fadd() ||
is_fsub() || is_fmul() || is_fdiv()) &&
(get_num_operand() == 2); (get_num_operand() == 2);
} }
bool isTerminator() { return is_br() || is_ret(); } bool isTerminator() { return is_br() || is_ret(); }
private: private:
OpID op_id_; OpID op_id_;
unsigned num_ops_; unsigned num_ops_;
BasicBlock *parent_; BasicBlock *parent_;
}; };
namespace detail { namespace detail
template <typename T> {
struct tag { template <typename T>
using type = T; struct tag
}; {
template <typename... Ts> using type = T;
struct select_last { };
// Use a fold-expression to fold the comma operator over the parameter pack. template <typename... Ts>
using type = typename decltype((tag<Ts>{}, ...))::type; struct select_last
}; {
template <typename... Ts> // Use a fold-expression to fold the comma operator over the parameter
using select_last_t = typename select_last<Ts...>::type; // pack.
using type = typename decltype((tag<Ts>{}, ...))::type;
};
template <typename... Ts>
using select_last_t = typename select_last<Ts...>::type;
}; // namespace detail }; // namespace detail
template <class> template <class>
inline constexpr bool always_false_v = false; inline constexpr bool always_false_v = false;
template <typename Inst> template <typename Inst>
class BaseInst : public Instruction { class BaseInst : public Instruction
{
protected: protected:
template <typename... Args> template <typename... Args>
static Inst *create(Args &&...args) { static Inst *create(Args &&...args)
if constexpr (std::is_same_v<std::decay_t<detail::select_last_t<Args...>>, BasicBlock *>) { {
if constexpr (std::is_same_v<
std::decay_t<detail::select_last_t<Args...>>,
BasicBlock *>) {
auto ptr = new Inst(std::forward<Args>(args)...); auto ptr = new Inst(std::forward<Args>(args)...);
return ptr; return ptr;
} else } else
...@@ -156,10 +213,13 @@ class BaseInst : public Instruction { ...@@ -156,10 +213,13 @@ class BaseInst : public Instruction {
} }
template <typename... Args> template <typename... Args>
BaseInst(Args &&...args) : Instruction(std::forward<Args>(args)...) {} BaseInst(Args &&...args) : Instruction(std::forward<Args>(args)...)
{
}
}; };
class BinaryInst : public BaseInst<BinaryInst> { class BinaryInst : public BaseInst<BinaryInst>
{
friend BaseInst<BinaryInst>; friend BaseInst<BinaryInst>;
private: private:
...@@ -167,28 +227,36 @@ class BinaryInst : public BaseInst<BinaryInst> { ...@@ -167,28 +227,36 @@ class BinaryInst : public BaseInst<BinaryInst> {
public: public:
// create add instruction, auto insert to bb // 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 // 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 // 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 // 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 // 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 // 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 // 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 // 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; virtual std::string print() override;
...@@ -196,7 +264,8 @@ class BinaryInst : public BaseInst<BinaryInst> { ...@@ -196,7 +264,8 @@ class BinaryInst : public BaseInst<BinaryInst> {
void assertValid(); void assertValid();
}; };
class CmpInst : public BaseInst<CmpInst> { class CmpInst : public BaseInst<CmpInst>
{
friend BaseInst<CmpInst>; friend BaseInst<CmpInst>;
public: public:
...@@ -213,7 +282,8 @@ class CmpInst : public BaseInst<CmpInst> { ...@@ -213,7 +282,8 @@ class CmpInst : public BaseInst<CmpInst> {
CmpInst(Type *ty, CmpOp op, Value *lhs, Value *rhs, BasicBlock *bb); CmpInst(Type *ty, CmpOp op, Value *lhs, Value *rhs, BasicBlock *bb);
public: 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_; } CmpOp get_cmp_op() { return cmp_op_; }
...@@ -225,7 +295,8 @@ class CmpInst : public BaseInst<CmpInst> { ...@@ -225,7 +295,8 @@ class CmpInst : public BaseInst<CmpInst> {
void assertValid(); void assertValid();
}; };
class FCmpInst : public BaseInst<FCmpInst> { class FCmpInst : public BaseInst<FCmpInst>
{
friend BaseInst<FCmpInst>; friend BaseInst<FCmpInst>;
public: public:
...@@ -242,7 +313,8 @@ class FCmpInst : public BaseInst<FCmpInst> { ...@@ -242,7 +313,8 @@ class FCmpInst : public BaseInst<FCmpInst> {
FCmpInst(Type *ty, CmpOp op, Value *lhs, Value *rhs, BasicBlock *bb); FCmpInst(Type *ty, CmpOp op, Value *lhs, Value *rhs, BasicBlock *bb);
public: 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_; } CmpOp get_cmp_op() { return cmp_op_; }
...@@ -254,28 +326,33 @@ class FCmpInst : public BaseInst<FCmpInst> { ...@@ -254,28 +326,33 @@ class FCmpInst : public BaseInst<FCmpInst> {
void assert_valid(); void assert_valid();
}; };
class CallInst : public BaseInst<CallInst> { class CallInst : public BaseInst<CallInst>
{
friend BaseInst<CallInst>; friend BaseInst<CallInst>;
protected: protected:
CallInst(Function *func, std::vector<Value *> args, BasicBlock *bb); CallInst(Function *func, std::vector<Value *> args, BasicBlock *bb);
public: public:
static CallInst *create(Function *func, std::vector<Value *> args, BasicBlock *bb); static CallInst *create(Function *func, std::vector<Value *> args,
FunctionType *get_function_type() const; BasicBlock *bb);
FunctionType *get_function_type() const;
virtual std::string print() override; virtual std::string print() override;
}; };
class BranchInst : public BaseInst<BranchInst> { class BranchInst : public BaseInst<BranchInst>
{
friend BaseInst<BranchInst>; friend BaseInst<BranchInst>;
private: 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); BranchInst(BasicBlock *if_true, BasicBlock *bb);
public: 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); static BranchInst *create_br(BasicBlock *if_true, BasicBlock *bb);
bool is_cond_br() const; bool is_cond_br() const;
...@@ -283,7 +360,8 @@ class BranchInst : public BaseInst<BranchInst> { ...@@ -283,7 +360,8 @@ class BranchInst : public BaseInst<BranchInst> {
virtual std::string print() override; virtual std::string print() override;
}; };
class ReturnInst : public BaseInst<ReturnInst> { class ReturnInst : public BaseInst<ReturnInst>
{
friend BaseInst<ReturnInst>; friend BaseInst<ReturnInst>;
private: private:
...@@ -293,12 +371,13 @@ class ReturnInst : public BaseInst<ReturnInst> { ...@@ -293,12 +371,13 @@ class ReturnInst : public BaseInst<ReturnInst> {
public: public:
static ReturnInst *create_ret(Value *val, BasicBlock *bb); static ReturnInst *create_ret(Value *val, BasicBlock *bb);
static ReturnInst *create_void_ret(BasicBlock *bb); static ReturnInst *create_void_ret(BasicBlock *bb);
bool is_void_ret() const; bool is_void_ret() const;
virtual std::string print() override; virtual std::string print() override;
}; };
class GetElementPtrInst : public BaseInst<GetElementPtrInst> { class GetElementPtrInst : public BaseInst<GetElementPtrInst>
{
friend BaseInst<GetElementPtrInst>; friend BaseInst<GetElementPtrInst>;
private: private:
...@@ -306,8 +385,9 @@ class GetElementPtrInst : public BaseInst<GetElementPtrInst> { ...@@ -306,8 +385,9 @@ class GetElementPtrInst : public BaseInst<GetElementPtrInst> {
public: public:
static Type *get_element_type(Value *ptr, std::vector<Value *> idxs); static Type *get_element_type(Value *ptr, std::vector<Value *> idxs);
static GetElementPtrInst *create_gep(Value *ptr, std::vector<Value *> idxs, BasicBlock *bb); static GetElementPtrInst *create_gep(Value *ptr, std::vector<Value *> idxs,
Type *get_element_type() const; BasicBlock *bb);
Type *get_element_type() const;
virtual std::string print() override; virtual std::string print() override;
...@@ -315,7 +395,8 @@ class GetElementPtrInst : public BaseInst<GetElementPtrInst> { ...@@ -315,7 +395,8 @@ class GetElementPtrInst : public BaseInst<GetElementPtrInst> {
Type *element_ty_; Type *element_ty_;
}; };
class StoreInst : public BaseInst<StoreInst> { class StoreInst : public BaseInst<StoreInst>
{
friend BaseInst<StoreInst>; friend BaseInst<StoreInst>;
private: private:
...@@ -330,7 +411,8 @@ class StoreInst : public BaseInst<StoreInst> { ...@@ -330,7 +411,8 @@ class StoreInst : public BaseInst<StoreInst> {
virtual std::string print() override; virtual std::string print() override;
}; };
class LoadInst : public BaseInst<LoadInst> { class LoadInst : public BaseInst<LoadInst>
{
friend BaseInst<LoadInst>; friend BaseInst<LoadInst>;
private: private:
...@@ -338,14 +420,15 @@ class LoadInst : public BaseInst<LoadInst> { ...@@ -338,14 +420,15 @@ class LoadInst : public BaseInst<LoadInst> {
public: public:
static LoadInst *create_load(Type *ty, Value *ptr, BasicBlock *bb); 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; Type *get_load_type() const;
virtual std::string print() override; virtual std::string print() override;
}; };
class AllocaInst : public BaseInst<AllocaInst> { class AllocaInst : public BaseInst<AllocaInst>
{
friend BaseInst<AllocaInst>; friend BaseInst<AllocaInst>;
private: private:
...@@ -362,7 +445,8 @@ class AllocaInst : public BaseInst<AllocaInst> { ...@@ -362,7 +445,8 @@ class AllocaInst : public BaseInst<AllocaInst> {
Type *alloca_ty_; Type *alloca_ty_;
}; };
class ZextInst : public BaseInst<ZextInst> { class ZextInst : public BaseInst<ZextInst>
{
friend BaseInst<ZextInst>; friend BaseInst<ZextInst>;
private: private:
...@@ -379,7 +463,8 @@ class ZextInst : public BaseInst<ZextInst> { ...@@ -379,7 +463,8 @@ class ZextInst : public BaseInst<ZextInst> {
Type *dest_ty_; Type *dest_ty_;
}; };
class FpToSiInst : public BaseInst<FpToSiInst> { class FpToSiInst : public BaseInst<FpToSiInst>
{
friend BaseInst<FpToSiInst>; friend BaseInst<FpToSiInst>;
private: private:
...@@ -396,7 +481,8 @@ class FpToSiInst : public BaseInst<FpToSiInst> { ...@@ -396,7 +481,8 @@ class FpToSiInst : public BaseInst<FpToSiInst> {
Type *dest_ty_; Type *dest_ty_;
}; };
class SiToFpInst : public BaseInst<SiToFpInst> { class SiToFpInst : public BaseInst<SiToFpInst>
{
friend BaseInst<SiToFpInst>; friend BaseInst<SiToFpInst>;
private: private:
...@@ -413,19 +499,25 @@ class SiToFpInst : public BaseInst<SiToFpInst> { ...@@ -413,19 +499,25 @@ class SiToFpInst : public BaseInst<SiToFpInst> {
Type *dest_ty_; Type *dest_ty_;
}; };
class PhiInst : public BaseInst<PhiInst> { class PhiInst : public BaseInst<PhiInst>
{
friend BaseInst<PhiInst>; friend BaseInst<PhiInst>;
private: private:
PhiInst(OpID op, std::vector<Value *> vals, std::vector<BasicBlock *> val_bbs, Type *ty, BasicBlock *bb); PhiInst(OpID op, std::vector<Value *> vals,
PhiInst(Type *ty, OpID op, unsigned num_ops, BasicBlock *bb) : BaseInst<PhiInst>(ty, op, num_ops, bb) {} std::vector<BasicBlock *> val_bbs, Type *ty, BasicBlock *bb);
PhiInst(Type *ty, OpID op, unsigned num_ops, BasicBlock *bb)
: BaseInst<PhiInst>(ty, op, num_ops, bb)
{
}
Value *l_val_; Value *l_val_;
public: public:
static PhiInst *create_phi(Type *ty, BasicBlock *bb); static PhiInst *create_phi(Type *ty, BasicBlock *bb);
Value *get_lval() { return l_val_; } Value *get_lval() { return l_val_; }
void set_lval(Value *l_val) { l_val_ = l_val; } void set_lval(Value *l_val) { l_val_ = l_val; }
void add_phi_pair_operand(Value *val, Value *pre_bb) { void add_phi_pair_operand(Value *val, Value *pre_bb)
{
this->add_operand(val); this->add_operand(val);
this->add_operand(pre_bb); this->add_operand(pre_bb);
} }
......
...@@ -8,35 +8,35 @@ target_link_libraries( ...@@ -8,35 +8,35 @@ target_link_libraries(
IR_lib IR_lib
) )
# add_executable( add_executable(
# stu_assign_generator stu_assign_generator
# stu_cpp/assign_generator.cpp stu_cpp/assign_generator.cpp
# ) )
# target_link_libraries( target_link_libraries(
# stu_assign_generator stu_assign_generator
# IR_lib IR_lib
# ) )
# add_executable( add_executable(
# stu_fun_generator stu_fun_generator
# stu_cpp/fun_generator.cpp stu_cpp/fun_generator.cpp
# ) )
# target_link_libraries( target_link_libraries(
# stu_fun_generator stu_fun_generator
# IR_lib IR_lib
# ) )
# add_executable( add_executable(
# stu_if_generator stu_if_generator
# stu_cpp/if_generator.cpp stu_cpp/if_generator.cpp
# ) )
# target_link_libraries( target_link_libraries(
# stu_if_generator stu_if_generator
# IR_lib IR_lib
# ) )
# add_executable( add_executable(
# stu_while_generator stu_while_generator
# stu_cpp/while_generator.cpp stu_cpp/while_generator.cpp
# ) )
# target_link_libraries( target_link_libraries(
# stu_while_generator stu_while_generator
# IR_lib IR_lib
# ) )
#include "Module.h"
#include "IRBuilder.h"
#include "Type.h"
#include "Constant.h"
#include <iostream>
#include <vector>
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<Type *> 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;
}
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "IRBuilder.h"
#include "Module.h"
#include "Type.h"
#include <iostream>
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<Type *> 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<Value *> 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;
}
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "IRBuilder.h"
#include "Module.h"
#include "Type.h"
#include <iostream>
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;
}
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "IRBuilder.h"
#include "Module.h"
#include "Type.h"
#include <iostream>
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;
}
define dso_local i32 @main() #0 { 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 is the pointer with type i32*
%ptr = getelementptr [10 x i32], [10 x i32]* %a, i64 0, i64 0 %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 %a1 = getelementptr i32, i32* %ptr, i64 1
store i32 10, i32* %a0 store i32 10, i32* %ptr
%v1 = load i32, i32* %a0 %v1 = load i32, i32* %ptr
%v2 = mul i32 %v1, 2 %v2 = mul i32 %v1, 2
store i32 %v2, i32* %a1 store i32 %v2, i32* %a1
%r = load i32, i32* %a1 %r = load i32, i32* %a1
......
...@@ -12,12 +12,13 @@ ...@@ -12,12 +12,13 @@
* #define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; // * #define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; //
* 输出行号的简单示例 #else #define DEBUG_OUTPUT #endif */ * 输出行号的简单示例 #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_INT(num) ConstantInt::get(num, mod)
#define CONST_FP(num) \ // 得到常数值的表示,方便后面多次用到
ConstantFP::get(num, mod) // 得到常数值的表示,方便后面多次用到 #define CONST_FP(num) ConstantFP::get(num, mod)
int main() int main()
{ {
...@@ -71,9 +72,10 @@ int main() ...@@ -71,9 +72,10 @@ int main()
mod, "", gcdFun); // return分支,提前create,以便true分支可以br mod, "", gcdFun); // return分支,提前create,以便true分支可以br
auto br = builder->create_cond_br(icmp, trueBB, falseBB); // 条件BR auto br = builder->create_cond_br(icmp, trueBB, falseBB); // 条件BR
DEBUG_OUTPUT // 调试的时候故意留下来的,以醒目地提醒你这个调试用的宏定义方法 DEBUG_OUTPUT; // 调试的时候故意留下来的,以醒目地提醒你这个调试用的宏定义方法
builder->set_insert_point(
trueBB); // if true; 分支的开始需要SetInsertPoint设置 // if true; 分支的开始需要SetInsertPoint设置
builder->set_insert_point(trueBB);
auto uLoad = builder->create_load(uAlloca); auto uLoad = builder->create_load(uAlloca);
builder->create_store(uLoad, retAlloca); builder->create_store(uLoad, retAlloca);
builder->create_br(retBB); // br retBB builder->create_br(retBB); // br retBB
...@@ -106,8 +108,8 @@ int main() ...@@ -106,8 +108,8 @@ int main()
auto bAlloca = builder->create_alloca(Int32Type); // b的存放 auto bAlloca = builder->create_alloca(Int32Type); // b的存放
auto tempAlloca = builder->create_alloca(Int32Type); // temp的存放 auto tempAlloca = builder->create_alloca(Int32Type); // temp的存放
std::vector<Value *> //获取funArray函数的形参,通过Function中的iterator
args1; //获取funArrayFun函数的形参,通过Function中的iterator std::vector<Value *> args1;
for (auto arg = funArrayFun->arg_begin(); arg != funArrayFun->arg_end(); for (auto arg = funArrayFun->arg_begin(); arg != funArrayFun->arg_end();
arg++) { arg++) {
args1.push_back(*arg); // * 号运算符是从迭代器中取出迭代器当前指向的元素 args1.push_back(*arg); // * 号运算符是从迭代器中取出迭代器当前指向的元素
......
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