|
|
|
|
@ -41,8 +41,8 @@ Context& DefaultContext();
|
|
|
|
|
class Type {
|
|
|
|
|
public:
|
|
|
|
|
enum class Kind { Void, Int32, PtrInt32 };
|
|
|
|
|
explicit Type(Kind k) : kind_(k) {}
|
|
|
|
|
Kind kind() const { return kind_; }
|
|
|
|
|
explicit Type(Kind k);
|
|
|
|
|
Kind kind() const;
|
|
|
|
|
static std::shared_ptr<Type> Void();
|
|
|
|
|
static std::shared_ptr<Type> Int32();
|
|
|
|
|
static std::shared_ptr<Type> PtrInt32();
|
|
|
|
|
@ -53,14 +53,13 @@ class Type {
|
|
|
|
|
|
|
|
|
|
class Value {
|
|
|
|
|
public:
|
|
|
|
|
Value(std::shared_ptr<Type> ty, std::string name)
|
|
|
|
|
: type_(std::move(ty)), name_(std::move(name)) {}
|
|
|
|
|
Value(std::shared_ptr<Type> ty, std::string name);
|
|
|
|
|
virtual ~Value() = default;
|
|
|
|
|
const std::shared_ptr<Type>& type() const { return type_; }
|
|
|
|
|
const std::string& name() const { return name_; }
|
|
|
|
|
void set_name(std::string n) { name_ = std::move(n); }
|
|
|
|
|
void AddUser(Instruction* user) { users_.push_back(user); }
|
|
|
|
|
const std::vector<Instruction*>& users() const { return users_; }
|
|
|
|
|
const std::shared_ptr<Type>& type() const;
|
|
|
|
|
const std::string& name() const;
|
|
|
|
|
void set_name(std::string n);
|
|
|
|
|
void AddUser(Instruction* user);
|
|
|
|
|
const std::vector<Instruction*>& users() const;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
std::shared_ptr<Type> type_;
|
|
|
|
|
@ -77,16 +76,16 @@ class ConstantInt : public Value {
|
|
|
|
|
int value_{};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 后续还需要扩展更多指令类型。
|
|
|
|
|
enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret };
|
|
|
|
|
|
|
|
|
|
class Instruction : public Value {
|
|
|
|
|
public:
|
|
|
|
|
Instruction(Opcode op, std::shared_ptr<Type> ty, std::string name = "")
|
|
|
|
|
: Value(std::move(ty), std::move(name)), opcode_(op) {}
|
|
|
|
|
Opcode opcode() const { return opcode_; }
|
|
|
|
|
bool IsTerminator() const { return opcode_ == Opcode::Ret; }
|
|
|
|
|
BasicBlock* parent() const { return parent_; }
|
|
|
|
|
void set_parent(BasicBlock* parent) { parent_ = parent; }
|
|
|
|
|
Instruction(Opcode op, std::shared_ptr<Type> ty, std::string name = "");
|
|
|
|
|
Opcode opcode() const;
|
|
|
|
|
bool IsTerminator() const;
|
|
|
|
|
BasicBlock* parent() const;
|
|
|
|
|
void set_parent(BasicBlock* parent);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Opcode opcode_;
|
|
|
|
|
@ -97,8 +96,8 @@ class BinaryInst : public Instruction {
|
|
|
|
|
public:
|
|
|
|
|
BinaryInst(Opcode op, std::shared_ptr<Type> ty, Value* lhs, Value* rhs,
|
|
|
|
|
std::string name);
|
|
|
|
|
Value* lhs() const { return lhs_; }
|
|
|
|
|
Value* rhs() const { return rhs_; }
|
|
|
|
|
Value* lhs() const;
|
|
|
|
|
Value* rhs() const;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Value* lhs_;
|
|
|
|
|
@ -108,7 +107,7 @@ class BinaryInst : public Instruction {
|
|
|
|
|
class ReturnInst : public Instruction {
|
|
|
|
|
public:
|
|
|
|
|
explicit ReturnInst(Value* val);
|
|
|
|
|
Value* value() const { return value_; }
|
|
|
|
|
Value* value() const;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Value* value_;
|
|
|
|
|
@ -122,7 +121,7 @@ class AllocaInst : public Instruction {
|
|
|
|
|
class LoadInst : public Instruction {
|
|
|
|
|
public:
|
|
|
|
|
LoadInst(Value* ptr, std::string name);
|
|
|
|
|
Value* ptr() const { return ptr_; }
|
|
|
|
|
Value* ptr() const;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Value* ptr_;
|
|
|
|
|
@ -131,8 +130,8 @@ class LoadInst : public Instruction {
|
|
|
|
|
class StoreInst : public Instruction {
|
|
|
|
|
public:
|
|
|
|
|
StoreInst(Value* val, Value* ptr);
|
|
|
|
|
Value* value() const { return value_; }
|
|
|
|
|
Value* ptr() const { return ptr_; }
|
|
|
|
|
Value* value() const;
|
|
|
|
|
Value* ptr() const;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Value* value_;
|
|
|
|
|
@ -141,14 +140,10 @@ class StoreInst : public Instruction {
|
|
|
|
|
|
|
|
|
|
class BasicBlock {
|
|
|
|
|
public:
|
|
|
|
|
explicit BasicBlock(std::string name) : name_(std::move(name)) {}
|
|
|
|
|
const std::string& name() const { return name_; }
|
|
|
|
|
bool HasTerminator() const {
|
|
|
|
|
return !instructions_.empty() && instructions_.back()->IsTerminator();
|
|
|
|
|
}
|
|
|
|
|
const std::vector<std::unique_ptr<Instruction>>& instructions() const {
|
|
|
|
|
return instructions_;
|
|
|
|
|
}
|
|
|
|
|
explicit BasicBlock(std::string name);
|
|
|
|
|
const std::string& name() const;
|
|
|
|
|
bool HasTerminator() const;
|
|
|
|
|
const std::vector<std::unique_ptr<Instruction>>& instructions() const;
|
|
|
|
|
template <typename T, typename... Args>
|
|
|
|
|
T* Append(Args&&... args) {
|
|
|
|
|
if (HasTerminator()) {
|
|
|
|
|
@ -172,11 +167,9 @@ class Function : public Value {
|
|
|
|
|
// 允许显式指定返回类型,便于后续扩展多种函数签名。
|
|
|
|
|
Function(std::string name, std::shared_ptr<Type> ret_type);
|
|
|
|
|
BasicBlock* CreateBlock(const std::string& name);
|
|
|
|
|
BasicBlock* entry() { return entry_; }
|
|
|
|
|
const BasicBlock* entry() const { return entry_; }
|
|
|
|
|
const std::vector<std::unique_ptr<BasicBlock>>& blocks() const {
|
|
|
|
|
return blocks_;
|
|
|
|
|
}
|
|
|
|
|
BasicBlock* entry();
|
|
|
|
|
const BasicBlock* entry() const;
|
|
|
|
|
const std::vector<std::unique_ptr<BasicBlock>>& blocks() const;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
BasicBlock* entry_ = nullptr;
|
|
|
|
|
@ -188,9 +181,7 @@ class Module {
|
|
|
|
|
// 创建函数时显式传入返回类型,便于在 IRGen 中根据语法树信息选择类型。
|
|
|
|
|
Function* CreateFunction(const std::string& name,
|
|
|
|
|
std::shared_ptr<Type> ret_type);
|
|
|
|
|
const std::vector<std::unique_ptr<Function>>& functions() const {
|
|
|
|
|
return functions_;
|
|
|
|
|
}
|
|
|
|
|
const std::vector<std::unique_ptr<Function>>& functions() const;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
std::vector<std::unique_ptr<Function>> functions_;
|
|
|
|
|
@ -198,17 +189,15 @@ class Module {
|
|
|
|
|
|
|
|
|
|
class IRBuilder {
|
|
|
|
|
public:
|
|
|
|
|
explicit IRBuilder(BasicBlock* bb) : insertBlock_(bb) {}
|
|
|
|
|
void SetInsertPoint(BasicBlock* bb) { insertBlock_ = bb; }
|
|
|
|
|
BasicBlock* GetInsertBlock() const { return insertBlock_; }
|
|
|
|
|
explicit IRBuilder(BasicBlock* bb);
|
|
|
|
|
void SetInsertPoint(BasicBlock* bb);
|
|
|
|
|
BasicBlock* GetInsertBlock() const;
|
|
|
|
|
|
|
|
|
|
// 构造常量、二元运算、返回指令的最小集合。
|
|
|
|
|
ConstantInt* CreateConstInt(int v);
|
|
|
|
|
BinaryInst* CreateBinary(Opcode op, Value* lhs, Value* rhs,
|
|
|
|
|
const std::string& name);
|
|
|
|
|
BinaryInst* CreateAdd(Value* lhs, Value* rhs, const std::string& name) {
|
|
|
|
|
return CreateBinary(Opcode::Add, lhs, rhs, name);
|
|
|
|
|
}
|
|
|
|
|
BinaryInst* CreateAdd(Value* lhs, Value* rhs, const std::string& name);
|
|
|
|
|
AllocaInst* CreateAllocaI32(const std::string& name);
|
|
|
|
|
LoadInst* CreateLoad(Value* ptr, const std::string& name);
|
|
|
|
|
StoreInst* CreateStore(Value* val, Value* ptr);
|
|
|
|
|
|