You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nudt-compiler-cpp/include/ir/IR.h

895 lines
29 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// 当前只支撑 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 <iosfwd>
#include <memory>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
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<ArrayType> ty,
std::vector<ConstantValue*> elements);
// 获取零常量(按类型缓存)
ConstantZero* GetZeroConstant(std::shared_ptr<Type> ty);
// 获取聚合类型的零常量
ConstantAggregateZero* GetAggregateZero(std::shared_ptr<Type> ty);
std::string NextTemp();
private:
std::unordered_map<int, std::unique_ptr<ConstantInt>> const_ints_;
// 浮点常量:使用整数表示浮点数位模式作为键(避免浮点精度问题)
std::unordered_map<uint32_t, std::unique_ptr<ConstantFloat>> const_floats_;
// 零常量缓存(按类型指针)
std::unordered_map<Type*, std::unique_ptr<ConstantZero>> zero_constants_;
std::unordered_map<Type*, std::unique_ptr<ConstantAggregateZero>> aggregate_zeros_;
// 数组常量简单存储,不去重(因为数组常量通常组合多样,去重成本高)
std::vector<std::unique_ptr<ConstantArray>> 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<Type>& GetVoidType();
static const std::shared_ptr<Type>& GetInt32Type();
static const std::shared_ptr<Type>& GetFloatType();
static const std::shared_ptr<Type>& GetPtrInt32Type();
static const std::shared_ptr<Type>& GetPtrFloatType();
static const std::shared_ptr<Type>& GetLabelType();
static std::shared_ptr<ArrayType> GetArrayType(std::shared_ptr<Type> elem, std::vector<int> dims);
static std::shared_ptr<FunctionType> GetFunctionType(std::shared_ptr<Type> ret, std::vector<std::shared_ptr<Type>> params);
static const std::shared_ptr<Type>& GetInt1Type();
static const std::shared_ptr<Type>& 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<Type>& GetElementType() const { return elem_type_; }
const std::vector<int>& 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<Type> elem, std::vector<int> dims);
friend class Type; // 允许 Type::GetArrayType 构造
private:
std::shared_ptr<Type> elem_type_;
std::vector<int> dims_;
};
// 函数类型
class FunctionType : public Type {
public:
const std::shared_ptr<Type>& GetReturnType() const { return return_type_; }
const std::vector<std::shared_ptr<Type>>& 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<Type> ret, std::vector<std::shared_ptr<Type>> params);
friend class Type;
private:
std::shared_ptr<Type> return_type_;
std::vector<std::shared_ptr<Type>> param_types_;
};
class Value {
public:
Value(std::shared_ptr<Type> ty, std::string name);
virtual ~Value() = default;
const std::shared_ptr<Type>& 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<Use>& GetUses() const;
void ReplaceAllUsesWith(Value* new_value);
protected:
std::shared_ptr<Type> type_;
std::string name_;
std::vector<Use> uses_;
};
// ConstantValue 是常量体系的基类。
// 当前只实现了 ConstantInt后续可继续扩展更多常量种类。
class ConstantValue : public Value {
public:
ConstantValue(std::shared_ptr<Type> ty, std::string name = "");
};
class ConstantInt : public ConstantValue {
public:
ConstantInt(std::shared_ptr<Type> ty, int v);
int GetValue() const { return value_; }
private:
int value_{};
};
// 在 ConstantInt 类之后添加以下类
// ConstantFloat - 浮点常量
class ConstantFloat : public ConstantValue {
public:
ConstantFloat(std::shared_ptr<Type> ty, float v);
float GetValue() const { return value_; }
private:
float value_{};
};
// ConstantArray - 数组常量
class ConstantArray : public ConstantValue {
public:
// 构造函数:接收数组类型和常量元素列表
ConstantArray(std::shared_ptr<ArrayType> ty, std::vector<ConstantValue*> elements);
// 获取元素数量
size_t GetNumElements() const { return elements_.size(); }
// 获取指定索引的元素
ConstantValue* GetElement(size_t index) const { return elements_[index]; }
// 获取所有元素
const std::vector<ConstantValue*>& GetElements() const { return elements_; }
// 验证常量数组的类型是否正确
bool IsValid() const;
private:
std::vector<ConstantValue*> elements_;
};
// ConstantZero - 零常量(用于零初始化)
class ConstantZero : public ConstantValue {
public:
explicit ConstantZero(std::shared_ptr<Type> ty);
// 工厂方法:创建特定类型的零常量
static std::unique_ptr<ConstantZero> GetZero(std::shared_ptr<Type> ty);
};
// ConstantAggregateZero - 聚合类型的零常量(数组、结构体等)
class ConstantAggregateZero : public ConstantValue {
public:
explicit ConstantAggregateZero(std::shared_ptr<Type> ty);
// 获取聚合类型
std::shared_ptr<Type> GetAggregateType() const { return GetType(); }
// 工厂方法:创建聚合类型的零常量
static std::unique_ptr<ConstantAggregateZero> GetZero(std::shared_ptr<Type> ty);
};
//function 参数占位类,目前仅保存类型和名字,后续可扩展更多属性(例如是否为数组参数、数组维度等)。
class Argument : public Value {
public:
Argument(std::shared_ptr<Type> 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<Type> ty, std::string name);
size_t GetNumOperands() const;
Value* GetOperand(size_t index) const;
void SetOperand(size_t index, Value* value);
// 添加模板方法,支持派生类自动转换
template<typename T>
void SetOperand(size_t index, T* value) {
SetOperand(index, static_cast<Value*>(value));
}
template<typename T>
void AddOperand(T* value) {
AddOperand(static_cast<Value*>(value));
}
protected:
// 统一的 operand 入口。
void AddOperand(Value* value);
private:
std::vector<Value*> operands_;
};
// GlobalValue 是全局值/全局变量体系的空壳占位类。
// 当前只补齐类层次,具体初始化器、打印和链接语义后续再补。
// ir/IR.h - 修正 GlobalValue 定义
// ir/IR.h - 修正 GlobalValue 定义
class GlobalValue : public User {
private:
std::vector<ConstantValue*> initializer_; // 初始化值列表
bool is_constant_ = false; // 是否为常量如const变量
bool is_extern_ = false; // 是否为外部声明
public:
GlobalValue(std::shared_ptr<Type> ty, std::string name);
// 初始化器相关 - 使用 ConstantValue*
void SetInitializer(ConstantValue* init);
void SetInitializer(const std::vector<ConstantValue*>& init);
const std::vector<ConstantValue*>& 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<ArrayType*>(GetType().get())) {
return array_ty->GetElementCount();
}
return 0;
}
};
class Instruction : public User {
public:
Instruction(Opcode op, std::shared_ptr<Type> 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<Type> ty, Value* lhs, Value* rhs,
std::string name);
Value* GetLhs() const;
Value* GetRhs() const;
};
class ReturnInst : public Instruction {
public:
ReturnInst(std::shared_ptr<Type> void_ty, Value* val);
Value* GetValue() const;
};
class AllocaInst : public Instruction {
public:
AllocaInst(std::shared_ptr<Type> ptr_ty, std::string name);
};
class LoadInst : public Instruction {
public:
LoadInst(std::shared_ptr<Type> val_ty, Value* ptr, std::string name);
Value* GetPtr() const;
};
class StoreInst : public Instruction {
public:
StoreInst(std::shared_ptr<Type> void_ty, Value* val, Value* ptr);
Value* GetValue() const;
Value* GetPtr() const;
};
// 在 IR.h 中修改 BranchInst 类定义
class BranchInst : public Instruction {
public:
// 无条件跳转构造函数
BranchInst(std::shared_ptr<Type> 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<Type> 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<Type> 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<Type> 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<Type> target_ty, std::string name = "")
: Instruction(Opcode::ZExt, target_ty, name) {
AddOperand(value);
}
// 获取被扩展的值
Value* GetValue() const {
return GetOperand(0);
}
// 获取源类型
std::shared_ptr<Type> GetSourceType() const {
return GetValue()->GetType();
}
// 获取目标类型
std::shared_ptr<Type> GetTargetType() const {
return GetType();
}
// 设置被扩展的值
void SetValue(Value* value) {
SetOperand(0, value);
}
};
// TruncInst - 截断指令
class TruncInst : public Instruction {
public:
TruncInst(Value* value, std::shared_ptr<Type> target_ty, std::string name = "")
: Instruction(Opcode::Trunc, target_ty, name) {
AddOperand(value);
}
// 获取被截断的值
Value* GetValue() const {
return GetOperand(0);
}
// 获取源类型
std::shared_ptr<Type> GetSourceType() const {
return GetValue()->GetType();
}
// 获取目标类型
std::shared_ptr<Type> GetTargetType() const {
return GetType();
}
// 设置被截断的值
void SetValue(Value* value) {
SetOperand(0, value);
}
};
class GEPInst : public Instruction {
public:
GEPInst(std::shared_ptr<Type> ptr_ty,
Value* base,
const std::vector<Value*>& indices,
const std::string& name);
Value* GetBase() const;
const std::vector<Value*>& GetIndices() const;
};
// Function 当前也采用了最小实现。
// 需要特别注意:由于项目里还没有单独的 FunctionType
// Function 继承自 Value 后,其 type_ 目前只保存“返回类型”,
// 并不能完整表达“返回类型 + 形参列表”这一整套函数签名。
// 这对当前只支持 int main() 的最小 IR 足够,但后续若补普通函数、
// 形参和调用,通常需要引入专门的函数类型表示。
class Function : public Value {
public:
// 当前构造函数接收完整的 FunctionType。
Function(std::string name, std::shared_ptr<FunctionType> func_type);
BasicBlock* CreateBlock(const std::string& name);
BasicBlock* GetEntry();
const BasicBlock* GetEntry() const;
const std::vector<std::unique_ptr<BasicBlock>>& GetBlocks() const;
// 函数增加参数的接口,目前仅保存参数类型和名字,后续可扩展更多属性(例如是否为数组参数、数组维度等)。注意这里是直接在 Function 上管理参数列表,而不是通过一个单独的 FunctionType 来表达完整函数签名,这也是当前最小实现的一个简化点。
Argument* AddArgument(std::unique_ptr<Argument> arg);
const std::vector<std::unique_ptr<Argument>>& GetArguments() const;
private:
BasicBlock* entry_ = nullptr;
std::vector<std::unique_ptr<BasicBlock>> blocks_;
std::vector<std::unique_ptr<Argument>> arguments_;
};
class CallInst : public Instruction {
public:
CallInst(std::shared_ptr<Type> ret_ty,
Function* callee,
const std::vector<Value*>& args,
const std::string& name);
Function* GetCallee() const;
const std::vector<Value*>& GetArgs() const;
private:
Function* callee_;
std::vector<Value*> 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<std::unique_ptr<Instruction>>& GetInstructions() const;
const std::vector<BasicBlock*>& GetPredecessors() const;
const std::vector<BasicBlock*>& GetSuccessors() const;
template <typename T, typename... Args>
T* Append(Args&&... args) {
if (HasTerminator()) {
throw std::runtime_error("BasicBlock 已有 terminator不能继续追加指令: " +
name_);
}
auto inst = std::make_unique<T>(std::forward<Args>(args)...);
auto* ptr = inst.get();
ptr->SetParent(this);
instructions_.push_back(std::move(inst));
return ptr;
}
private:
Function* parent_ = nullptr;
std::vector<std::unique_ptr<Instruction>> instructions_;
std::vector<BasicBlock*> predecessors_;
std::vector<BasicBlock*> successors_;
};
class Module {
public:
Module() = default;
Context& GetContext();
const Context& GetContext() const;
// 创建函数时传入完整的 FunctionType。
Function* CreateFunction(const std::string& name,
std::shared_ptr<FunctionType> func_type);
GlobalValue* CreateGlobal(const std::string& name,
std::shared_ptr<Type> ty);
Function* FindFunction(const std::string& name) const;
const std::vector<std::unique_ptr<Function>>& GetFunctions() const;
const std::vector<std::unique_ptr<GlobalValue>>& GetGlobals() const;
private:
Context context_;
std::vector<std::unique_ptr<Function>> functions_;
std::vector<std::unique_ptr<GlobalValue>> globals_;
};
// SIToFP - 整数转浮点
class SIToFPInst : public Instruction {
public:
SIToFPInst(Value* value, std::shared_ptr<Type> 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<Type> 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<ArrayType> ty,
std::vector<ConstantValue*> elements); // 新增
ConstantZero* CreateZeroConstant(std::shared_ptr<Type> 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<Value*>& 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<Type> target_ty,
const std::string& name = "");
TruncInst* CreateTrunc(Value* value, std::shared_ptr<Type> 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<Value*>& 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<Type> target_ty,
const std::string& name = "");
FPToSIInst* CreateFPToSI(Value* value, std::shared_ptr<Type> 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