diff --git a/include/ir/IR.h b/include/ir/IR.h index b961192..739185d 100644 --- a/include/ir/IR.h +++ b/include/ir/IR.h @@ -41,6 +41,8 @@ namespace ir { class Type; +class ArrayType; +class FunctionType; class Value; class User; class ConstantValue; @@ -93,23 +95,79 @@ class Context { class Type { public: - enum class Kind { Void, Int32, PtrInt32 }; - explicit Type(Kind k); + enum class Kind { Void, Int32, PtrInt32, Array, Function }; + + virtual ~Type() = default; + // 使用静态共享对象获取类型。 // 同一类型可直接比较返回值是否相等,例如: // 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; + static std::shared_ptr GetArrayType(std::shared_ptr elem, std::vector dims); + static std::shared_ptr GetFunctionType(std::shared_ptr ret, std::vector> params); + + // 类型判断 + Kind GetKind() const { return kind_; } + bool IsVoid() const { return kind_ == Kind::Void; } + bool IsInt32() const { return kind_ == Kind::Int32; } + bool IsPtrInt32() const { return kind_ == Kind::PtrInt32; } + bool IsArray() const { return kind_ == Kind::Array; } + bool IsFunction() const { return kind_ == Kind::Function; } + + // 类型属性 + 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); diff --git a/src/ir/Type.cpp b/src/ir/Type.cpp index 3e1684d..6c220fb 100644 --- a/src/ir/Type.cpp +++ b/src/ir/Type.cpp @@ -1,31 +1,188 @@ // 当前仅支持 void、i32 和 i32*。 #include "ir/IR.h" +#include namespace ir { Type::Type(Kind k) : kind_(k) {} +size_t Type::Size() const { + switch (kind_) { + case Kind::Void: return 0; + case Kind::Int32: return 4; + case Kind::PtrInt32: return 8; // 假设 64 位平台 + default: return 0; // 派生类应重写 + } +} + +size_t Type::Alignment() const { + switch (kind_) { + case Kind::Int32: return 4; + case Kind::PtrInt32: return 8; + default: return 1; // void 和复合类型由派生类处理 + } +} + +bool Type::IsComplete() const { + // void 视为完整类型(但不能有对象),int 和指针都是完整类型 + return kind_ != Kind::Void; +} const std::shared_ptr& Type::GetVoidType() { - static const std::shared_ptr type = std::make_shared(Kind::Void); + static const std::shared_ptr type = std::shared_ptr(new Type(Kind::Void)); return type; } const std::shared_ptr& Type::GetInt32Type() { - static const std::shared_ptr type = std::make_shared(Kind::Int32); + static const std::shared_ptr type = std::shared_ptr(new Type(Kind::Int32)); return type; } const std::shared_ptr& Type::GetPtrInt32Type() { - static const std::shared_ptr type = std::make_shared(Kind::PtrInt32); + static const std::shared_ptr type = std::shared_ptr(new Type(Kind::PtrInt32)); return type; } -Type::Kind Type::GetKind() const { return kind_; } +// ---------- 数组类型缓存 ---------- +// 使用自定义键类型保证唯一性:元素类型指针 + 维度向量 +struct ArrayKey { + const Type* elem_type; + std::vector dims; + + bool operator==(const ArrayKey& other) const { + return elem_type == other.elem_type && dims == other.dims; + } +}; + +struct ArrayKeyHash { + std::size_t operator()(const ArrayKey& key) const { + std::size_t h = std::hash{}(key.elem_type); + for (int d : key.dims) { + h ^= std::hash{}(d) + 0x9e3779b9 + (h << 6) + (h >> 2); + } + return h; + } +}; + +static std::unordered_map, ArrayKeyHash>& GetArrayCache() { + static std::unordered_map, ArrayKeyHash> cache; + return cache; +} + +std::shared_ptr Type::GetArrayType(std::shared_ptr elem, + std::vector dims) { + // 检查维度合法性 + for (int d : dims) { + if (d <= 0) { + // SysY 数组维度必须为正整数常量表达式,这里假设已检查 + return nullptr; + } + } + + ArrayKey key{elem.get(), dims}; + auto& cache = GetArrayCache(); + auto it = cache.find(key); + if (it != cache.end()) { + auto ptr = it->second.lock(); + if (ptr) return ptr; + } + + auto arr = std::shared_ptr(new ArrayType(std::move(elem), std::move(dims))); + cache[key] = arr; + return arr; +} + +// ---------- 函数类型缓存 ---------- +struct FunctionKey { + const Type* return_type; + std::vector param_types; + + bool operator==(const FunctionKey& other) const { + return return_type == other.return_type && param_types == other.param_types; + } +}; + +struct FunctionKeyHash { + std::size_t operator()(const FunctionKey& key) const { + std::size_t h = std::hash{}(key.return_type); + for (const Type* t : key.param_types) { + h ^= std::hash{}(t) + 0x9e3779b9 + (h << 6) + (h >> 2); + } + return h; + } +}; + +static std::unordered_map, FunctionKeyHash>& GetFunctionCache() { + static std::unordered_map, FunctionKeyHash> cache; + return cache; +} + +std::shared_ptr Type::GetFunctionType(std::shared_ptr ret, + std::vector> params) { + // 提取裸指针用于键(保证唯一性,因为 shared_ptr 指向同一对象) + std::vector param_ptrs; + param_ptrs.reserve(params.size()); + for (const auto& p : params) { + param_ptrs.push_back(p.get()); + } + + FunctionKey key{ret.get(), std::move(param_ptrs)}; + auto& cache = GetFunctionCache(); + auto it = cache.find(key); + if (it != cache.end()) { + auto ptr = it->second.lock(); + if (ptr) return ptr; + } + + auto func = std::shared_ptr(new FunctionType(std::move(ret), std::move(params))); + cache[key] = func; + return func; +} + +// ---------- ArrayType 实现 ---------- +ArrayType::ArrayType(std::shared_ptr elem, std::vector dims) + : Type(Kind::Array), elem_type_(std::move(elem)), dims_(std::move(dims)) { + // 数组元素类型必须是完整类型 + assert(elem_type_ && elem_type_->IsComplete()); +} + +size_t ArrayType::GetElementCount() const { + size_t count = 1; + for (int d : dims_) count *= d; + return count; +} + +size_t ArrayType::Size() const { + return GetElementCount() * elem_type_->Size(); +} -bool Type::IsVoid() const { return kind_ == Kind::Void; } +size_t ArrayType::Alignment() const { + // 数组对齐等于其元素对齐 + return elem_type_->Alignment(); +} -bool Type::IsInt32() const { return kind_ == Kind::Int32; } +bool ArrayType::IsComplete() const { + // 维度已确定且元素类型完整,则数组完整 + return !dims_.empty() && elem_type_->IsComplete(); +} -bool Type::IsPtrInt32() const { return kind_ == Kind::PtrInt32; } +// ---------- FunctionType 实现 ---------- +FunctionType::FunctionType(std::shared_ptr ret, + std::vector> params) + : Type(Kind::Function), return_type_(std::move(ret)), param_types_(std::move(params)) {} + +size_t FunctionType::Size() const { + // 函数类型没有运行时大小,通常用于类型检查,返回 0 + return 0; +} + +size_t FunctionType::Alignment() const { + // 不对齐 + return 1; +} + +bool FunctionType::IsComplete() const { + // 函数类型总是完整的(只要返回类型完整,但 SysY 中 void 也视为完整) + return true; +} } // namespace ir