// 当前只支撑 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 ArrayType; class FunctionType; class Value; class User; class ConstantValue; class ConstantInt; class ConstantFloat; class ConstantArray; class ConstantZero; class ConstantAggregateZero; 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 上下文:集中管理类型、常量等共享资源,便于复用与扩展。 // ir/IR.h - 修改 Context 类定义 class Context { public: Context() = default; ~Context(); // 去重创建 i32 常量 ConstantInt* GetConstInt(int v); // 去重创建浮点常量 ConstantFloat* GetConstFloat(float v); // 创建数组常量(不去重,因为数组常量通常比较复杂且组合多样) ConstantArray* GetConstArray(std::shared_ptr ty, std::vector elements); // 获取零常量(按类型缓存) ConstantZero* GetZeroConstant(std::shared_ptr ty); // 获取聚合类型的零常量 ConstantAggregateZero* GetAggregateZero(std::shared_ptr ty); std::string NextTemp(); private: std::unordered_map> const_ints_; // 浮点常量:使用整数表示浮点数位模式作为键(避免浮点精度问题) std::unordered_map> const_floats_; // 零常量缓存(按类型指针) std::unordered_map> zero_constants_; std::unordered_map> aggregate_zeros_; // 数组常量简单存储,不去重(因为数组常量通常组合多样,去重成本高) std::vector> const_arrays_; int temp_index_ = -1; }; class Type { public: enum class Kind { Void, Int32, Float, PtrInt32, PtrFloat, Label, Array, Function, Int1, PtrInt1}; virtual ~Type() = default; // 使用静态共享对象获取类型。 // 同一类型可直接比较返回值是否相等,例如: // Type::GetInt32Type() == Type::GetInt32Type() static const std::shared_ptr& GetVoidType(); static const std::shared_ptr& GetInt32Type(); static const std::shared_ptr& GetFloatType(); static const std::shared_ptr& GetPtrInt32Type(); static const std::shared_ptr& GetPtrFloatType(); static const std::shared_ptr& GetLabelType(); static std::shared_ptr GetArrayType(std::shared_ptr elem, std::vector dims); static std::shared_ptr GetFunctionType(std::shared_ptr ret, std::vector> params); static const std::shared_ptr& GetInt1Type(); static const std::shared_ptr& GetPtrInt1Type(); // 类型判断 Kind GetKind() const { return kind_; } bool IsVoid() const { return kind_ == Kind::Void; } bool IsInt32() const { return kind_ == Kind::Int32; } bool IsFloat() const { return kind_ == Kind::Float; } bool IsPtrInt32() const { return kind_ == Kind::PtrInt32; } bool IsPtrFloat() const { return kind_ == Kind::PtrFloat; } bool IsLabel() const { return kind_ == Kind::Label; } bool IsArray() const { return kind_ == Kind::Array; } bool IsFunction() const { return kind_ == Kind::Function; } bool IsInt1() const { return kind_ == Kind::Int1; } bool IsPtrInt1() const { return kind_ == Kind::PtrInt1; } // 类型属性 virtual size_t Size() const; // 字节大小 virtual size_t Alignment() const; // 对齐要求 virtual bool IsComplete() const; // 是否为完整类型(非 void,数组维度已知等) protected: explicit Type(Kind k); // 构造函数 protected,只能由工厂和派生类调用 private: Kind kind_; }; // 数组类型 class ArrayType : public Type { public: // 获取元素类型和维度 const std::shared_ptr& GetElementType() const { return elem_type_; } const std::vector& GetDimensions() const { return dims_; } size_t GetElementCount() const; // 总元素个数 size_t Size() const override; size_t Alignment() const override; bool IsComplete() const override; protected: ArrayType(std::shared_ptr elem, std::vector dims); friend class Type; // 允许 Type::GetArrayType 构造 private: std::shared_ptr elem_type_; std::vector dims_; }; // 函数类型 class FunctionType : public Type { public: const std::shared_ptr& GetReturnType() const { return return_type_; } const std::vector>& GetParamTypes() const { return param_types_; } size_t Size() const override; // 函数类型没有大小,通常返回 0 size_t Alignment() const override; // 无对齐要求 bool IsComplete() const override; // 函数类型视为完整 protected: FunctionType(std::shared_ptr ret, std::vector> params); friend class Type; private: std::shared_ptr return_type_; std::vector> param_types_; }; 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_{}; }; // 在 ConstantInt 类之后添加以下类 // ConstantFloat - 浮点常量 class ConstantFloat : public ConstantValue { public: ConstantFloat(std::shared_ptr ty, float v); float GetValue() const { return value_; } private: float value_{}; }; // ConstantArray - 数组常量 class ConstantArray : public ConstantValue { public: // 构造函数:接收数组类型和常量元素列表 ConstantArray(std::shared_ptr ty, std::vector elements); // 获取元素数量 size_t GetNumElements() const { return elements_.size(); } // 获取指定索引的元素 ConstantValue* GetElement(size_t index) const { return elements_[index]; } // 获取所有元素 const std::vector& GetElements() const { return elements_; } // 验证常量数组的类型是否正确 bool IsValid() const; private: std::vector elements_; }; // ConstantZero - 零常量(用于零初始化) class ConstantZero : public ConstantValue { public: explicit ConstantZero(std::shared_ptr ty); // 工厂方法:创建特定类型的零常量 static std::unique_ptr GetZero(std::shared_ptr ty); }; // ConstantAggregateZero - 聚合类型的零常量(数组、结构体等) class ConstantAggregateZero : public ConstantValue { public: explicit ConstantAggregateZero(std::shared_ptr ty); // 获取聚合类型 std::shared_ptr GetAggregateType() const { return GetType(); } // 工厂方法:创建聚合类型的零常量 static std::unique_ptr GetZero(std::shared_ptr ty); }; //function 参数占位类,目前仅保存类型和名字,后续可扩展更多属性(例如是否为数组参数、数组维度等)。 class Argument : public Value { public: Argument(std::shared_ptr ty, std::string name); }; // 后续还需要扩展更多指令类型。add call instruction 只是最小占位,后续可以继续补 sub/mul/div/rem、br/condbr、phi、gep 等指令。 enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret, Call, Br, CondBr, Icmp, ZExt, Trunc, Div, Mod, And, Or, Not, GEP, FAdd, FSub, FMul, FDiv, FCmp, SIToFP, // 整数转浮点 FPToSI, // 浮点转整数 FPExt, // 浮点扩展 FPTrunc, // 浮点截断 }; // ZExt 和 Trunc 是零扩展和截断指令,SysY 的 int (i32) vs LLVM IR 的比较结果 (i1)。 // 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); // 添加模板方法,支持派生类自动转换 template void SetOperand(size_t index, T* value) { SetOperand(index, static_cast(value)); } template void AddOperand(T* value) { AddOperand(static_cast(value)); } protected: // 统一的 operand 入口。 void AddOperand(Value* value); private: std::vector operands_; }; // GlobalValue 是全局值/全局变量体系的空壳占位类。 // 当前只补齐类层次,具体初始化器、打印和链接语义后续再补。 // ir/IR.h - 修正 GlobalValue 定义 // ir/IR.h - 修正 GlobalValue 定义 class GlobalValue : public User { private: std::vector initializer_; // 初始化值列表 bool is_constant_ = false; // 是否为常量(如const变量) bool is_extern_ = false; // 是否为外部声明 public: GlobalValue(std::shared_ptr ty, std::string name); // 初始化器相关 - 使用 ConstantValue* void SetInitializer(ConstantValue* init); void SetInitializer(const std::vector& init); const std::vector& GetInitializer() const { return initializer_; } bool HasInitializer() const { return !initializer_.empty(); } // 常量属性 void SetConstant(bool is_const) { is_constant_ = is_const; } bool IsConstant() const { return is_constant_; } // 外部声明 void SetExtern(bool is_extern) { is_extern_ = is_extern; } bool IsExtern() const { return is_extern_; } // 类型判断 - 使用 Type 的方法 bool IsArray() const { return GetType()->IsArray(); } bool IsScalar() const { return GetType()->IsInt32() || GetType()->IsFloat(); } // 获取数组大小(如果是数组类型) int GetArraySize() const { if (auto* array_ty = dynamic_cast(GetType().get())) { return array_ty->GetElementCount(); } return 0; } }; 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; }; // 在 IR.h 中修改 BranchInst 类定义 class BranchInst : public Instruction { public: // 无条件跳转构造函数 BranchInst(std::shared_ptr void_ty, BasicBlock* target) : Instruction(Opcode::Br, void_ty, ""), is_conditional_(false), cond_(nullptr), target_(target), true_target_(nullptr), false_target_(nullptr) {} // 条件跳转构造函数 BranchInst(std::shared_ptr void_ty, Value* cond, BasicBlock* true_target, BasicBlock* false_target) : Instruction(Opcode::CondBr, void_ty, ""), is_conditional_(true), cond_(cond), target_(nullptr), true_target_(true_target), false_target_(false_target) { // 添加操作数以便维护 def-use 关系 AddOperand(cond); // 注意:BasicBlock 也是 Value,也需要添加到操作数中 // 但 BasicBlock 继承自 Value,所以可以添加 AddOperand(true_target); AddOperand(false_target); } // 判断是否为条件跳转 bool IsConditional() const { return is_conditional_; } // 获取无条件跳转的目标(仅适用于无条件跳转) BasicBlock* GetTarget() const { if (is_conditional_) { throw std::runtime_error("GetTarget called on conditional branch"); } return target_; } // 获取条件值(仅适用于条件跳转) Value* GetCondition() const { if (!is_conditional_) { throw std::runtime_error("GetCondition called on unconditional branch"); } return cond_; } // 获取真分支目标(仅适用于条件跳转) BasicBlock* GetTrueTarget() const { if (!is_conditional_) { throw std::runtime_error("GetTrueTarget called on unconditional branch"); } return true_target_; } // 获取假分支目标(仅适用于条件跳转) BasicBlock* GetFalseTarget() const { if (!is_conditional_) { throw std::runtime_error("GetFalseTarget called on unconditional branch"); } return false_target_; } // 设置无条件跳转目标 void SetTarget(BasicBlock* target) { if (is_conditional_) { throw std::runtime_error("SetTarget called on conditional branch"); } target_ = target; } // 设置条件跳转的分支目标 void SetTrueTarget(BasicBlock* target) { if (!is_conditional_) { throw std::runtime_error("SetTrueTarget called on unconditional branch"); } true_target_ = target; // 更新操作数 SetOperand(1, target); } void SetFalseTarget(BasicBlock* target) { if (!is_conditional_) { throw std::runtime_error("SetFalseTarget called on unconditional branch"); } false_target_ = target; // 更新操作数 SetOperand(2, target); } void SetCondition(Value* cond) { if (!is_conditional_) { throw std::runtime_error("SetCondition called on unconditional branch"); } cond_ = cond; // 更新操作数 SetOperand(0, cond); } private: bool is_conditional_; Value* cond_; // 条件值(条件跳转使用) BasicBlock* target_; // 无条件跳转目标 BasicBlock* true_target_; // 真分支目标(条件跳转使用) BasicBlock* false_target_; // 假分支目标(条件跳转使用) }; // 创建整数比较指令 class IcmpInst : public Instruction { public: enum class Predicate { EQ, // equal NE, // not equal LT, // less than LE, // less than or equal GT, // greater than GE // greater than or equal }; IcmpInst(Predicate pred, Value* lhs, Value* rhs, std::shared_ptr i1_ty, std::string name) : Instruction(Opcode::Icmp, i1_ty, name), pred_(pred) { AddOperand(lhs); AddOperand(rhs); } Predicate GetPredicate() const { return pred_; } Value* GetLhs() const { return GetOperand(0); } Value* GetRhs() const { return GetOperand(1); } private: Predicate pred_; }; class FcmpInst : public Instruction { public: enum class Predicate { FALSE, // Always false OEQ, // Ordered and equal OGT, // Ordered and greater than OGE, // Ordered and greater than or equal OLT, // Ordered and less than OLE, // Ordered and less than or equal ONE, // Ordered and not equal ORD, // Ordered (no nans) UNO, // Unordered (isnan(x) || isnan(y)) UEQ, // Unordered or equal UGT, // Unordered or greater than UGE, // Unordered or greater than or equal ULT, // Unordered or less than ULE, // Unordered or less than or equal UNE, // Unordered or not equal TRUE // Always true }; FcmpInst(Predicate pred, Value* lhs, Value* rhs, std::shared_ptr i1_ty, std::string name) : Instruction(Opcode::FCmp, i1_ty, name), pred_(pred) { AddOperand(lhs); AddOperand(rhs); } Predicate GetPredicate() const { return pred_; } Value* GetLhs() const { return GetOperand(0); } Value* GetRhs() const { return GetOperand(1); } private: Predicate pred_; }; // ZExtInst - 零扩展指令 class ZExtInst : public Instruction { public: ZExtInst(Value* value, std::shared_ptr target_ty, std::string name = "") : Instruction(Opcode::ZExt, target_ty, name) { AddOperand(value); } // 获取被扩展的值 Value* GetValue() const { return GetOperand(0); } // 获取源类型 std::shared_ptr GetSourceType() const { return GetValue()->GetType(); } // 获取目标类型 std::shared_ptr GetTargetType() const { return GetType(); } // 设置被扩展的值 void SetValue(Value* value) { SetOperand(0, value); } }; // TruncInst - 截断指令 class TruncInst : public Instruction { public: TruncInst(Value* value, std::shared_ptr target_ty, std::string name = "") : Instruction(Opcode::Trunc, target_ty, name) { AddOperand(value); } // 获取被截断的值 Value* GetValue() const { return GetOperand(0); } // 获取源类型 std::shared_ptr GetSourceType() const { return GetValue()->GetType(); } // 获取目标类型 std::shared_ptr GetTargetType() const { return GetType(); } // 设置被截断的值 void SetValue(Value* value) { SetOperand(0, value); } }; class GEPInst : public Instruction { public: GEPInst(std::shared_ptr ptr_ty, Value* base, const std::vector& indices, const std::string& name); Value* GetBase() const; const std::vector& GetIndices() const; }; // Function 当前也采用了最小实现。 // 需要特别注意:由于项目里还没有单独的 FunctionType, // Function 继承自 Value 后,其 type_ 目前只保存“返回类型”, // 并不能完整表达“返回类型 + 形参列表”这一整套函数签名。 // 这对当前只支持 int main() 的最小 IR 足够,但后续若补普通函数、 // 形参和调用,通常需要引入专门的函数类型表示。 class Function : public Value { public: // 当前构造函数接收完整的 FunctionType。 Function(std::string name, std::shared_ptr func_type); BasicBlock* CreateBlock(const std::string& name); BasicBlock* GetEntry(); const BasicBlock* GetEntry() const; const std::vector>& GetBlocks() const; // 函数增加参数的接口,目前仅保存参数类型和名字,后续可扩展更多属性(例如是否为数组参数、数组维度等)。注意这里是直接在 Function 上管理参数列表,而不是通过一个单独的 FunctionType 来表达完整函数签名,这也是当前最小实现的一个简化点。 Argument* AddArgument(std::unique_ptr arg); const std::vector>& GetArguments() const; private: BasicBlock* entry_ = nullptr; std::vector> blocks_; std::vector> arguments_; }; class CallInst : public Instruction { public: CallInst(std::shared_ptr ret_ty, Function* callee, const std::vector& args, const std::string& name); Function* GetCallee() const; const std::vector& GetArgs() const; private: Function* callee_; std::vector args_; }; // 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_; }; class Module { public: Module() = default; Context& GetContext(); const Context& GetContext() const; // 创建函数时传入完整的 FunctionType。 Function* CreateFunction(const std::string& name, std::shared_ptr func_type); GlobalValue* CreateGlobal(const std::string& name, std::shared_ptr ty); Function* FindFunction(const std::string& name) const; const std::vector>& GetFunctions() const; const std::vector>& GetGlobals() const; private: Context context_; std::vector> functions_; std::vector> globals_; }; // SIToFP - 整数转浮点 class SIToFPInst : public Instruction { public: SIToFPInst(Value* value, std::shared_ptr target_ty, std::string name = "") : Instruction(Opcode::SIToFP, target_ty, name) { AddOperand(value); } Value* GetValue() const { return GetOperand(0); } }; // FPToSI - 浮点转整数 class FPToSIInst : public Instruction { public: FPToSIInst(Value* value, std::shared_ptr target_ty, std::string name = "") : Instruction(Opcode::FPToSI, target_ty, name) { AddOperand(value); } Value* GetValue() const { return GetOperand(0); } }; class IRBuilder { public: IRBuilder(Context& ctx, BasicBlock* bb); void SetInsertPoint(BasicBlock* bb); BasicBlock* GetInsertBlock() const; // 构造常量、二元运算、返回指令的最小集合。 ConstantInt* CreateConstInt(int v); ConstantFloat* CreateConstFloat(float v); // 新增 ConstantArray* CreateConstArray(std::shared_ptr ty, std::vector elements); // 新增 ConstantZero* CreateZeroConstant(std::shared_ptr ty); // 新增 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); AllocaInst* CreateAllocaFloat(const std::string& name); LoadInst* CreateLoad(Value* ptr, const std::string& name); StoreInst* CreateStore(Value* val, Value* ptr); ReturnInst* CreateRet(Value* v); CallInst* CreateCall(Function* callee, const std::vector& args, const std::string& name); // 创建无条件跳转 BranchInst* CreateBr(BasicBlock* target); // 创建条件跳转 BranchInst* CreateCondBr(Value* cond, BasicBlock* true_target, BasicBlock* false_target); // 创建整数比较指令 IcmpInst* CreateICmpEQ(Value* lhs, Value* rhs, const std::string& name); IcmpInst* CreateICmpNE(Value* lhs, Value* rhs, const std::string& name); IcmpInst* CreateICmpLT(Value* lhs, Value* rhs, const std::string& name); IcmpInst* CreateICmpLE(Value* lhs, Value* rhs, const std::string& name); IcmpInst* CreateICmpGT(Value* lhs, Value* rhs, const std::string& name); IcmpInst* CreateICmpGE(Value* lhs, Value* rhs, const std::string& name); // 创建类型转换指令 ZExtInst* CreateZExt(Value* value, std::shared_ptr target_ty, const std::string& name = ""); TruncInst* CreateTrunc(Value* value, std::shared_ptr target_ty, const std::string& name = ""); // 便捷方法 ZExtInst* CreateZExtI1ToI32(Value* value, const std::string& name = "zext"); TruncInst* CreateTruncI32ToI1(Value* value, const std::string& name = "trunc"); BinaryInst* CreateDiv(Value* lhs, Value* rhs, const std::string& name); BinaryInst* CreateMod(Value* lhs, Value* rhs, const std::string& name); BinaryInst* CreateMul(Value* lhs, Value* rhs, const std::string& name); BinaryInst* CreateSub(Value* lhs, Value* rhs, const std::string& name); // 比较运算接口 BinaryInst* CreateAnd(Value* lhs, Value* rhs, const std::string& name); BinaryInst* CreateOr(Value* lhs, Value* rhs, const std::string& name); IcmpInst* CreateNot(Value* val, const std::string& name); GEPInst* CreateGEP(Value* base, const std::vector& indices, const std::string& name); // 浮点运算 BinaryInst* CreateFAdd(Value* lhs, Value* rhs, const std::string& name); BinaryInst* CreateFSub(Value* lhs, Value* rhs, const std::string& name); BinaryInst* CreateFMul(Value* lhs, Value* rhs, const std::string& name); BinaryInst* CreateFDiv(Value* lhs, Value* rhs, const std::string& name); // 浮点比较 FcmpInst* CreateFCmpOEQ(Value* lhs, Value* rhs, const std::string& name); FcmpInst* CreateFCmpONE(Value* lhs, Value* rhs, const std::string& name); FcmpInst* CreateFCmpOLT(Value* lhs, Value* rhs, const std::string& name); FcmpInst* CreateFCmpOLE(Value* lhs, Value* rhs, const std::string& name); FcmpInst* CreateFCmpOGT(Value* lhs, Value* rhs, const std::string& name); FcmpInst* CreateFCmpOGE(Value* lhs, Value* rhs, const std::string& name); // 类型转换 SIToFPInst* CreateSIToFP(Value* value, std::shared_ptr target_ty, const std::string& name = ""); FPToSIInst* CreateFPToSI(Value* value, std::shared_ptr target_ty, const std::string& name = ""); private: Context& ctx_; BasicBlock* insert_block_; }; class IRPrinter { public: void Print(const Module& module, std::ostream& os); private: void PrintConstant(const ConstantValue* constant, std::ostream& os); }; } // namespace ir