forked from NUDT-compiler/nudt-compiler-cpp
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.
141 lines
4.2 KiB
141 lines
4.2 KiB
// SSA 值体系抽象:
|
|
// - 常量、参数、指令结果等统一为 Value
|
|
// - 提供类型信息与使用/被使用关系(按需要实现)
|
|
#include "ir/IR.h"
|
|
|
|
#include <algorithm>
|
|
|
|
namespace ir {
|
|
|
|
Value::Value(std::shared_ptr<Type> ty, std::string name)
|
|
: type_(std::move(ty)), name_(std::move(name)) {}
|
|
|
|
const std::shared_ptr<Type>& Value::GetType() const { return type_; }
|
|
|
|
const std::string& Value::GetName() const { return name_; }
|
|
|
|
void Value::SetName(std::string n) { name_ = std::move(n); }
|
|
|
|
bool Value::IsVoid() const { return type_ && type_->IsVoid(); }
|
|
|
|
bool Value::IsInt32() const { return type_ && type_->IsInt32(); }
|
|
|
|
bool Value::IsPtrInt32() const { return type_ && type_->IsPtrInt32(); }
|
|
|
|
bool Value::IsConstant() const {
|
|
return dynamic_cast<const ConstantValue*>(this) != nullptr;
|
|
}
|
|
|
|
bool Value::IsInstruction() const {
|
|
return dynamic_cast<const Instruction*>(this) != nullptr;
|
|
}
|
|
|
|
bool Value::IsUser() const {
|
|
return dynamic_cast<const User*>(this) != nullptr;
|
|
}
|
|
|
|
bool Value::IsFunction() const {
|
|
return dynamic_cast<const Function*>(this) != nullptr;
|
|
}
|
|
|
|
void Value::AddUse(User* user, size_t operand_index) {
|
|
if (!user) return;
|
|
uses_.push_back(Use(this, user, operand_index));
|
|
}
|
|
|
|
void Value::RemoveUse(User* user, size_t operand_index) {
|
|
uses_.erase(
|
|
std::remove_if(uses_.begin(), uses_.end(),
|
|
[&](const Use& use) {
|
|
return use.GetUser() == user &&
|
|
use.GetOperandIndex() == operand_index;
|
|
}),
|
|
uses_.end());
|
|
}
|
|
|
|
const std::vector<Use>& Value::GetUses() const { return uses_; }
|
|
|
|
void Value::ReplaceAllUsesWith(Value* new_value) {
|
|
if (!new_value) {
|
|
throw std::runtime_error("ReplaceAllUsesWith 缺少 new_value");
|
|
}
|
|
if (new_value == this) {
|
|
return;
|
|
}
|
|
|
|
auto uses = uses_;
|
|
for (const auto& use : uses) {
|
|
auto* user = use.GetUser();
|
|
if (!user) continue;
|
|
size_t operand_index = use.GetOperandIndex();
|
|
if (user->GetOperand(operand_index) == this) {
|
|
user->SetOperand(operand_index, new_value);
|
|
}
|
|
}
|
|
}
|
|
|
|
ConstantValue::ConstantValue(std::shared_ptr<Type> ty, std::string name)
|
|
: Value(std::move(ty), std::move(name)) {}
|
|
// 建一个 Argument 对象,用给定的类型和名称初始化它,并继承 Value 的所有属性和方法。
|
|
Argument::Argument(std::shared_ptr<Type> ty, std::string name)
|
|
: Value(std::move(ty), std::move(name)) {}
|
|
|
|
ConstantInt::ConstantInt(std::shared_ptr<Type> ty, int v)
|
|
: ConstantValue(std::move(ty), ""), value_(v) {}
|
|
|
|
// ConstantFloat 实现
|
|
ConstantFloat::ConstantFloat(std::shared_ptr<Type> ty, float v)
|
|
: ConstantValue(ty, ""), value_(v) {
|
|
if (!ty->IsFloat()) {
|
|
throw std::runtime_error("ConstantFloat requires Float type");
|
|
}
|
|
}
|
|
|
|
// ConstantArray 实现
|
|
ConstantArray::ConstantArray(std::shared_ptr<ArrayType> ty,
|
|
std::vector<ConstantValue*> elements)
|
|
: ConstantValue(ty, ""), elements_(std::move(elements)) {
|
|
if (!IsValid()) {
|
|
throw std::runtime_error("Invalid constant array initialization");
|
|
}
|
|
}
|
|
|
|
bool ConstantArray::IsValid() const {
|
|
auto* array_ty = dynamic_cast<ArrayType*>(GetType().get());
|
|
if (!array_ty) return false;
|
|
|
|
// 检查元素数量是否匹配
|
|
if (elements_.size() != array_ty->GetElementCount()) return false;
|
|
|
|
// 检查每个元素的类型是否匹配数组元素类型
|
|
auto& elem_ty = array_ty->GetElementType();
|
|
for (auto* elem : elements_) {
|
|
if (elem->GetType() != elem_ty) return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// ConstantZero 实现
|
|
ConstantZero::ConstantZero(std::shared_ptr<Type> ty)
|
|
: ConstantValue(ty, "zero") {
|
|
// 零常量可以用于任何类型
|
|
}
|
|
|
|
std::unique_ptr<ConstantZero> ConstantZero::GetZero(std::shared_ptr<Type> ty) {
|
|
return std::make_unique<ConstantZero>(ty);
|
|
}
|
|
|
|
// ConstantAggregateZero 实现
|
|
ConstantAggregateZero::ConstantAggregateZero(std::shared_ptr<Type> ty)
|
|
: ConstantValue(ty, "zero") {
|
|
if (!ty->IsArray()) {
|
|
throw std::runtime_error("ConstantAggregateZero requires aggregate type");
|
|
}
|
|
}
|
|
|
|
std::unique_ptr<ConstantAggregateZero> ConstantAggregateZero::GetZero(std::shared_ptr<Type> ty) {
|
|
return std::make_unique<ConstantAggregateZero>(ty);
|
|
}
|
|
} // namespace ir
|