refactor(irgen): IR改成alloca和store形式
This commit is contained in:
@@ -28,6 +28,13 @@ const std::shared_ptr<Type>& Context::Int32() {
|
||||
return int32_;
|
||||
}
|
||||
|
||||
const std::shared_ptr<Type>& Context::PtrInt32() {
|
||||
if (!ptr_i32_) {
|
||||
ptr_i32_ = std::make_shared<Type>(Type::Kind::PtrInt32);
|
||||
}
|
||||
return ptr_i32_;
|
||||
}
|
||||
|
||||
ConstantInt* Context::GetConstInt(int v) {
|
||||
auto it = const_ints_.find(v);
|
||||
if (it != const_ints_.end()) return it->second.get();
|
||||
@@ -38,7 +45,7 @@ ConstantInt* Context::GetConstInt(int v) {
|
||||
|
||||
std::string Context::NextTemp() {
|
||||
std::ostringstream oss;
|
||||
oss << "%t" << temp_index_++;
|
||||
oss << "%" << ++temp_index_;
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
||||
35
src/ir/IR.h
35
src/ir/IR.h
@@ -19,6 +19,7 @@ class Context {
|
||||
~Context();
|
||||
const std::shared_ptr<Type>& Void();
|
||||
const std::shared_ptr<Type>& Int32();
|
||||
const std::shared_ptr<Type>& PtrInt32();
|
||||
// 去重创建 i32 常量。
|
||||
ConstantInt* GetConstInt(int v);
|
||||
// 生成临时名称,如 %t0、%t1 ...
|
||||
@@ -27,6 +28,7 @@ class Context {
|
||||
private:
|
||||
std::shared_ptr<Type> void_;
|
||||
std::shared_ptr<Type> int32_;
|
||||
std::shared_ptr<Type> ptr_i32_;
|
||||
std::unordered_map<int, std::unique_ptr<ConstantInt>> const_ints_;
|
||||
int temp_index_ = 0;
|
||||
};
|
||||
@@ -35,11 +37,12 @@ Context& DefaultContext();
|
||||
|
||||
class Type {
|
||||
public:
|
||||
enum class Kind { Void, Int32 };
|
||||
enum class Kind { Void, Int32, PtrInt32 };
|
||||
explicit Type(Kind k) : kind_(k) {}
|
||||
Kind kind() const { return kind_; }
|
||||
static std::shared_ptr<Type> Void();
|
||||
static std::shared_ptr<Type> Int32();
|
||||
static std::shared_ptr<Type> PtrInt32();
|
||||
|
||||
private:
|
||||
Kind kind_;
|
||||
@@ -68,7 +71,7 @@ class ConstantInt : public Value {
|
||||
int value_{};
|
||||
};
|
||||
|
||||
enum class Opcode { Add, Sub, Mul, Ret };
|
||||
enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret };
|
||||
|
||||
class Instruction : public Value {
|
||||
public:
|
||||
@@ -101,6 +104,31 @@ class ReturnInst : public Instruction {
|
||||
Value* value_;
|
||||
};
|
||||
|
||||
class AllocaInst : public Instruction {
|
||||
public:
|
||||
explicit AllocaInst(std::string name);
|
||||
};
|
||||
|
||||
class LoadInst : public Instruction {
|
||||
public:
|
||||
LoadInst(Value* ptr, std::string name);
|
||||
Value* ptr() const { return ptr_; }
|
||||
|
||||
private:
|
||||
Value* ptr_;
|
||||
};
|
||||
|
||||
class StoreInst : public Instruction {
|
||||
public:
|
||||
StoreInst(Value* val, Value* ptr);
|
||||
Value* value() const { return value_; }
|
||||
Value* ptr() const { return ptr_; }
|
||||
|
||||
private:
|
||||
Value* value_;
|
||||
Value* ptr_;
|
||||
};
|
||||
|
||||
class BasicBlock {
|
||||
public:
|
||||
explicit BasicBlock(std::string name) : name_(std::move(name)) {}
|
||||
@@ -158,6 +186,9 @@ class IRBuilder {
|
||||
BinaryInst* CreateAdd(Value* lhs, Value* rhs, const std::string& name) {
|
||||
return CreateBinary(Opcode::Add, lhs, rhs, name);
|
||||
}
|
||||
AllocaInst* CreateAllocaI32(const std::string& name);
|
||||
LoadInst* CreateLoad(Value* ptr, const std::string& name);
|
||||
StoreInst* CreateStore(Value* val, Value* ptr);
|
||||
ReturnInst* CreateRet(Value* v);
|
||||
|
||||
private:
|
||||
|
||||
@@ -20,6 +20,27 @@ BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs,
|
||||
return insertBlock_->Append<BinaryInst>(op, Type::Int32(), lhs, rhs, name);
|
||||
}
|
||||
|
||||
AllocaInst* IRBuilder::CreateAllocaI32(const std::string& name) {
|
||||
if (!insertBlock_) {
|
||||
throw std::runtime_error("IRBuilder 未设置插入点");
|
||||
}
|
||||
return insertBlock_->Append<AllocaInst>(name);
|
||||
}
|
||||
|
||||
LoadInst* IRBuilder::CreateLoad(Value* ptr, const std::string& name) {
|
||||
if (!insertBlock_) {
|
||||
throw std::runtime_error("IRBuilder 未设置插入点");
|
||||
}
|
||||
return insertBlock_->Append<LoadInst>(ptr, name);
|
||||
}
|
||||
|
||||
StoreInst* IRBuilder::CreateStore(Value* val, Value* ptr) {
|
||||
if (!insertBlock_) {
|
||||
throw std::runtime_error("IRBuilder 未设置插入点");
|
||||
}
|
||||
return insertBlock_->Append<StoreInst>(val, ptr);
|
||||
}
|
||||
|
||||
ReturnInst* IRBuilder::CreateRet(Value* v) {
|
||||
if (!insertBlock_) {
|
||||
throw std::runtime_error("IRBuilder 未设置插入点");
|
||||
|
||||
@@ -15,6 +15,8 @@ static const char* TypeToString(const Type& ty) {
|
||||
return "void";
|
||||
case Type::Kind::Int32:
|
||||
return "i32";
|
||||
case Type::Kind::PtrInt32:
|
||||
return "i32*";
|
||||
}
|
||||
throw std::runtime_error("未知类型");
|
||||
}
|
||||
@@ -27,6 +29,12 @@ static const char* OpcodeToString(Opcode op) {
|
||||
return "sub";
|
||||
case Opcode::Mul:
|
||||
return "mul";
|
||||
case Opcode::Alloca:
|
||||
return "alloca";
|
||||
case Opcode::Load:
|
||||
return "load";
|
||||
case Opcode::Store:
|
||||
return "store";
|
||||
case Opcode::Ret:
|
||||
return "ret";
|
||||
}
|
||||
@@ -42,6 +50,7 @@ void IRPrinter::Print(const Module& module) {
|
||||
std::cout << "}\n";
|
||||
continue;
|
||||
}
|
||||
std::cout << "entry:\n";
|
||||
for (const auto& instPtr : bb->instructions()) {
|
||||
const auto* inst = instPtr.get();
|
||||
switch (inst->opcode()) {
|
||||
@@ -54,6 +63,23 @@ void IRPrinter::Print(const Module& module) {
|
||||
<< bin->lhs()->name() << ", " << bin->rhs()->name() << "\n";
|
||||
break;
|
||||
}
|
||||
case Opcode::Alloca: {
|
||||
auto* alloca = static_cast<const AllocaInst*>(inst);
|
||||
std::cout << " " << alloca->name() << " = alloca i32\n";
|
||||
break;
|
||||
}
|
||||
case Opcode::Load: {
|
||||
auto* load = static_cast<const LoadInst*>(inst);
|
||||
std::cout << " " << load->name() << " = load i32, i32* "
|
||||
<< load->ptr()->name() << "\n";
|
||||
break;
|
||||
}
|
||||
case Opcode::Store: {
|
||||
auto* store = static_cast<const StoreInst*>(inst);
|
||||
std::cout << " store i32 " << store->value()->name() << ", i32* "
|
||||
<< store->ptr()->name() << "\n";
|
||||
break;
|
||||
}
|
||||
case Opcode::Ret: {
|
||||
auto* ret = static_cast<const ReturnInst*>(inst);
|
||||
std::cout << " ret " << TypeToString(*ret->value()->type()) << " "
|
||||
|
||||
@@ -12,4 +12,13 @@ BinaryInst::BinaryInst(Opcode op, std::shared_ptr<Type> ty, Value* lhs,
|
||||
ReturnInst::ReturnInst(Value* val)
|
||||
: Instruction(Opcode::Ret, Type::Void(), ""), value_(val) {}
|
||||
|
||||
AllocaInst::AllocaInst(std::string name)
|
||||
: Instruction(Opcode::Alloca, Type::PtrInt32(), std::move(name)) {}
|
||||
|
||||
LoadInst::LoadInst(Value* ptr, std::string name)
|
||||
: Instruction(Opcode::Load, Type::Int32(), std::move(name)), ptr_(ptr) {}
|
||||
|
||||
StoreInst::StoreInst(Value* val, Value* ptr)
|
||||
: Instruction(Opcode::Store, Type::Void(), ""), value_(val), ptr_(ptr) {}
|
||||
|
||||
} // namespace ir
|
||||
|
||||
@@ -10,4 +10,6 @@ std::shared_ptr<Type> Type::Void() { return DefaultContext().Void(); }
|
||||
|
||||
std::shared_ptr<Type> Type::Int32() { return DefaultContext().Int32(); }
|
||||
|
||||
std::shared_ptr<Type> Type::PtrInt32() { return DefaultContext().PtrInt32(); }
|
||||
|
||||
} // namespace ir
|
||||
|
||||
Reference in New Issue
Block a user