// 当前只支撑 i32、i32*、void 以及最小的内存/算术指令,演示用。 // // 当前已经实现: // 1. 基础类型系统:void / i32 / i32* // 2. Value 体系:Value / ConstantValue / ConstantInt / Function / BasicBlock / User / GlobalValue / Instruction // 3. 最小指令集:Add / Alloca / Load / Store / Ret // 4. BasicBlock / Function / Module 三层组织结构 // 5. IRBuilder:便捷创建常量和最小指令 // 6. def-use 关系的轻量实现: // - Instruction 保存 operand 列表 // - Value 保存 uses // - 支持 ReplaceAllUsesWith 的简化实现 // // 当前尚未实现或只做了最小占位: // 1. 完整类型系统:数组、函数类型、label 类型等 // 2. 更完整的指令系统:br / condbr / call / phi / gep 等 // 3. 更成熟的 Use 管理(例如 LLVM 风格的双向链式结构) // 4. 更完整的 IR verifier 和优化基础设施 // // 当前需要特别说明的两个简化点: // 1. BasicBlock 虽然已经纳入 Value 体系,但其类型目前仍用 void 作为占位, // 后续如果补 label type,可以再改成更合理的块标签类型。 // 2. ConstantValue 体系目前只实现了 ConstantInt,后续可以继续补 ConstantFloat、 // ConstantArray等更完整的常量种类。 // // 建议的扩展顺序: // 1. 先补更多指令和类型 // 2. 再补控制流相关 IR // 3. 最后再考虑把 Value/User/Use 进一步抽象成更完整的框架 #pragma once #include #include #include #include #include #include #include namespace ir { class Type; class Value; class User; class ConstantValue; class ConstantInt; class GlobalValue; class Instruction; class BasicBlock; class Function; // Use 表示一个 Value 的一次使用记录。 // 当前实现设计: // - value:被使用的值 // - user:使用该值的 User // - operand_index:该值在 user 操作数列表中的位置 class Use { public: Use() = default; Use(Value* value, User* user, size_t operand_index) : value_(value), user_(user), operand_index_(operand_index) {} Value* GetValue() const { return value_; } User* GetUser() const { return user_; } size_t GetOperandIndex() const { return operand_index_; } void SetValue(Value* value) { value_ = value; } void SetUser(User* user) { user_ = user; } void SetOperandIndex(size_t operand_index) { operand_index_ = operand_index; } private: Value* value_ = nullptr; User* user_ = nullptr; size_t operand_index_ = 0; }; // IR 上下文:集中管理类型、常量等共享资源,便于复用与扩展。 class Context { public: Context() = default; ~Context(); // 去重创建 i32 常量。 ConstantInt* GetConstInt(int v); std::string NextTemp(); private: std::unordered_map> const_ints_; int temp_index_ = -1; }; class Type { public: enum class Kind { Void, Int32, PtrInt32 }; explicit Type(Kind k); // 使用静态共享对象获取类型。 // 同一类型可直接比较返回值是否相等,例如: // Type::GetInt32Type() == Type::GetInt32Type() static const std::shared_ptr& GetVoidType(); static const std::shared_ptr& GetInt32Type(); static const std::shared_ptr& GetPtrInt32Type(); Kind GetKind() const; bool IsVoid() const; bool IsInt32() const; bool IsPtrInt32() const; private: Kind kind_; }; class Value { public: Value(std::shared_ptr ty, std::string name); virtual ~Value() = default; const std::shared_ptr& GetType() const; const std::string& GetName() const; void SetName(std::string n); bool IsVoid() const; bool IsInt32() const; bool IsPtrInt32() const; bool IsConstant() const; bool IsInstruction() const; bool IsUser() const; bool IsFunction() const; void AddUse(User* user, size_t operand_index); void RemoveUse(User* user, size_t operand_index); const std::vector& GetUses() const; void ReplaceAllUsesWith(Value* new_value); protected: std::shared_ptr type_; std::string name_; std::vector uses_; }; // ConstantValue 是常量体系的基类。 // 当前只实现了 ConstantInt,后续可继续扩展更多常量种类。 class ConstantValue : public Value { public: ConstantValue(std::shared_ptr ty, std::string name = ""); }; class ConstantInt : public ConstantValue { public: ConstantInt(std::shared_ptr ty, int v); int GetValue() const { return value_; } private: int value_{}; }; // 后续还需要扩展更多指令类型。 enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret }; // User 是所有“会使用其他 Value 作为输入”的 IR 对象的抽象基类。 // 当前实现中只有 Instruction 继承自 User。 class User : public Value { public: User(std::shared_ptr ty, std::string name); size_t GetNumOperands() const; Value* GetOperand(size_t index) const; void SetOperand(size_t index, Value* value); protected: // 统一的 operand 入口。 void AddOperand(Value* value); private: std::vector operands_; }; // GlobalValue 是全局值/全局变量体系的空壳占位类。 // 当前只补齐类层次,具体初始化器、打印和链接语义后续再补。 class GlobalValue : public User { public: GlobalValue(std::shared_ptr ty, std::string name); }; class Instruction : public User { public: Instruction(Opcode op, std::shared_ptr ty, std::string name = ""); Opcode GetOpcode() const; bool IsTerminator() const; BasicBlock* GetParent() const; void SetParent(BasicBlock* parent); private: Opcode opcode_; BasicBlock* parent_ = nullptr; }; class BinaryInst : public Instruction { public: BinaryInst(Opcode op, std::shared_ptr ty, Value* lhs, Value* rhs, std::string name); Value* GetLhs() const; Value* GetRhs() const; }; class ReturnInst : public Instruction { public: ReturnInst(std::shared_ptr void_ty, Value* val); Value* GetValue() const; }; class AllocaInst : public Instruction { public: AllocaInst(std::shared_ptr ptr_ty, std::string name); }; class LoadInst : public Instruction { public: LoadInst(std::shared_ptr val_ty, Value* ptr, std::string name); Value* GetPtr() const; }; class StoreInst : public Instruction { public: StoreInst(std::shared_ptr void_ty, Value* val, Value* ptr); Value* GetValue() const; Value* GetPtr() const; }; // BasicBlock 已纳入 Value 体系,便于后续向更完整 IR 类图靠拢。 // 当前其类型仍使用 void 作为占位,后续可替换为专门的 label type。 class BasicBlock : public Value { public: explicit BasicBlock(std::string name); Function* GetParent() const; void SetParent(Function* parent); bool HasTerminator() const; const std::vector>& GetInstructions() const; const std::vector& GetPredecessors() const; const std::vector& GetSuccessors() const; template T* Append(Args&&... args) { if (HasTerminator()) { throw std::runtime_error("BasicBlock 已有 terminator,不能继续追加指令: " + name_); } auto inst = std::make_unique(std::forward(args)...); auto* ptr = inst.get(); ptr->SetParent(this); instructions_.push_back(std::move(inst)); return ptr; } private: Function* parent_ = nullptr; std::vector> instructions_; std::vector predecessors_; std::vector successors_; }; // Function 当前也采用了最小实现。 // 需要特别注意:由于项目里还没有单独的 FunctionType, // Function 继承自 Value 后,其 type_ 目前只保存“返回类型”, // 并不能完整表达“返回类型 + 形参列表”这一整套函数签名。 // 这对当前只支持 int main() 的最小 IR 足够,但后续若补普通函数、 // 形参和调用,通常需要引入专门的函数类型表示。 class Function : public Value { public: // 当前构造函数接收的也是返回类型,而不是完整函数类型。 Function(std::string name, std::shared_ptr ret_type); BasicBlock* CreateBlock(const std::string& name); BasicBlock* GetEntry(); const BasicBlock* GetEntry() const; const std::vector>& GetBlocks() const; private: BasicBlock* entry_ = nullptr; std::vector> blocks_; }; class Module { public: Module() = default; Context& GetContext(); const Context& GetContext() const; // 创建函数时当前只显式传入返回类型,尚未接入完整的 FunctionType。 Function* CreateFunction(const std::string& name, std::shared_ptr ret_type); const std::vector>& GetFunctions() const; private: Context context_; std::vector> functions_; }; class IRBuilder { public: IRBuilder(Context& ctx, 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); 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: Context& ctx_; BasicBlock* insert_block_; }; class IRPrinter { public: void Print(const Module& module, std::ostream& os); }; } // namespace ir