// 极简 IR 定义:当前只支撑 i32 和加法,演示用。 // 可在此基础上扩展更多类型/指令 #pragma once #include #include #include #include #include namespace ir { class Type; class ConstantInt; class Instruction; // IR 上下文:集中管理类型、常量等共享资源,便于复用与扩展。 class Context { public: ~Context(); const std::shared_ptr& Void(); const std::shared_ptr& Int32(); const std::shared_ptr& PtrInt32(); // 去重创建 i32 常量。 ConstantInt* GetConstInt(int v); // 生成临时名称,如 %t0、%t1 ... std::string NextTemp(); private: std::shared_ptr void_; std::shared_ptr int32_; std::shared_ptr ptr_i32_; std::unordered_map> const_ints_; int temp_index_ = -1; }; Context& DefaultContext(); class Type { public: enum class Kind { Void, Int32, PtrInt32 }; explicit Type(Kind k) : kind_(k) {} Kind kind() const { return kind_; } static std::shared_ptr Void(); static std::shared_ptr Int32(); static std::shared_ptr PtrInt32(); private: Kind kind_; }; class Value { public: Value(std::shared_ptr ty, std::string name) : type_(std::move(ty)), name_(std::move(name)) {} virtual ~Value() = default; const std::shared_ptr& 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& users() const { return users_; } protected: std::shared_ptr type_; std::string name_; std::vector users_; }; class ConstantInt : public Value { public: explicit ConstantInt(int v); int value() const { return value_; } private: int value_{}; }; enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret }; class Instruction : public Value { public: Instruction(Opcode op, std::shared_ptr ty, std::string name = "") : Value(std::move(ty), std::move(name)), opcode_(op) {} Opcode opcode() const { return opcode_; } private: Opcode opcode_; }; class BinaryInst : public Instruction { public: BinaryInst(Opcode op, std::shared_ptr ty, Value* lhs, Value* rhs, std::string name); Value* lhs() const { return lhs_; } Value* rhs() const { return rhs_; } private: Value* lhs_; Value* rhs_; }; class ReturnInst : public Instruction { public: explicit ReturnInst(Value* val); Value* value() const { return value_; } private: 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)) {} const std::string& name() const { return name_; } const std::vector>& instructions() const { return instructions_; } template T* Append(Args&&... args) { auto inst = std::make_unique(std::forward(args)...); auto* ptr = inst.get(); instructions_.push_back(std::move(inst)); return ptr; } private: std::string name_; std::vector> instructions_; }; class Function : public Value { public: // 允许显式指定返回类型,便于后续扩展多种函数签名。 Function(std::string name, std::shared_ptr ret_type); BasicBlock* entry() { return entry_.get(); } const BasicBlock* entry() const { return entry_.get(); } private: std::unique_ptr entry_; }; class Module { public: // 创建函数时显式传入返回类型,便于在 IRGen 中根据语法树信息选择类型。 Function* CreateFunction(const std::string& name, std::shared_ptr ret_type); const std::vector>& functions() const { return functions_; } private: std::vector> functions_; }; class IRBuilder { public: explicit IRBuilder(BasicBlock* bb) : insertBlock_(bb) {} void SetInsertPoint(BasicBlock* bb) { insertBlock_ = bb; } BasicBlock* GetInsertBlock() const { return insertBlock_; } // 构造常量、二元运算、返回指令的最小集合。 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); } 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: BasicBlock* insertBlock_; }; class IRPrinter { public: void Print(const Module& module); }; } // namespace ir