|
|
|
|
@ -122,54 +122,54 @@ std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
|
|
|
|
|
for (size_t i = 0; i < args.size() && i < param_tys.size(); ++i) {
|
|
|
|
|
auto* arg = args[i];
|
|
|
|
|
const auto& pty = param_tys[i];
|
|
|
|
|
if (pty->IsPointer() && arg && arg->GetType() && arg->GetType()->IsPointer()) {
|
|
|
|
|
bool param_elem_array = pty->GetElementType()->IsArray();
|
|
|
|
|
bool arg_elem_array = arg->GetType()->GetElementType()->IsArray();
|
|
|
|
|
if (!param_elem_array && arg_elem_array) {
|
|
|
|
|
std::vector<ir::Value*> idx = {builder_.CreateConstInt(0),
|
|
|
|
|
builder_.CreateConstInt(0)};
|
|
|
|
|
args[i] = builder_.CreateGep(arg, std::move(idx),
|
|
|
|
|
module_.GetContext().NextTemp());
|
|
|
|
|
arg = args[i];
|
|
|
|
|
} else if (param_elem_array && arg_elem_array) {
|
|
|
|
|
auto* param_elem = pty->GetElementType().get();
|
|
|
|
|
auto* arg_elem = arg->GetType()->GetElementType().get();
|
|
|
|
|
if (param_elem && arg_elem && arg_elem->IsArray() &&
|
|
|
|
|
arg_elem->GetElementType()->Equals(*param_elem)) {
|
|
|
|
|
std::vector<ir::Value*> idx = {builder_.CreateConstInt(0)};
|
|
|
|
|
if (pty->IsPointer()) {
|
|
|
|
|
if (arg && arg->GetType() && arg->GetType()->IsPointer()) {
|
|
|
|
|
bool param_elem_array = pty->GetElementType()->IsArray();
|
|
|
|
|
bool arg_elem_array = arg->GetType()->GetElementType()->IsArray();
|
|
|
|
|
if (!param_elem_array && arg_elem_array) {
|
|
|
|
|
std::vector<ir::Value*> idx = {builder_.CreateConstInt(0),
|
|
|
|
|
builder_.CreateConstInt(0)};
|
|
|
|
|
args[i] = builder_.CreateGep(arg, std::move(idx),
|
|
|
|
|
module_.GetContext().NextTemp());
|
|
|
|
|
arg = args[i];
|
|
|
|
|
} else if (param_elem_array && arg_elem_array) {
|
|
|
|
|
auto* param_elem = pty->GetElementType().get();
|
|
|
|
|
auto* arg_elem = arg->GetType()->GetElementType().get();
|
|
|
|
|
if (param_elem && arg_elem && arg_elem->IsArray() &&
|
|
|
|
|
arg_elem->GetElementType()->Equals(*param_elem)) {
|
|
|
|
|
std::vector<ir::Value*> idx = {builder_.CreateConstInt(0)};
|
|
|
|
|
args[i] = builder_.CreateGep(arg, std::move(idx),
|
|
|
|
|
module_.GetContext().NextTemp());
|
|
|
|
|
arg = args[i];
|
|
|
|
|
}
|
|
|
|
|
} else if (param_elem_array && !arg_elem_array) {
|
|
|
|
|
if (auto* gep = dynamic_cast<ir::GepInst*>(arg)) {
|
|
|
|
|
const auto& idx = gep->GetIndices();
|
|
|
|
|
auto is_zero = [](ir::Value* v) {
|
|
|
|
|
auto* ci = dynamic_cast<ir::ConstantInt*>(v);
|
|
|
|
|
return ci && ci->GetValue() == 0;
|
|
|
|
|
};
|
|
|
|
|
if (idx.size() == 2 && is_zero(idx[0]) && is_zero(idx[1])) {
|
|
|
|
|
auto* base = gep->GetBasePtr();
|
|
|
|
|
if (base && base->GetType() && base->GetType()->IsPointer() &&
|
|
|
|
|
base->GetType()->GetElementType()->IsArray()) {
|
|
|
|
|
args[i] = base;
|
|
|
|
|
arg = base;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (param_elem_array && !arg_elem_array) {
|
|
|
|
|
if (auto* gep = dynamic_cast<ir::GepInst*>(arg)) {
|
|
|
|
|
const auto& idx = gep->GetIndices();
|
|
|
|
|
auto is_zero = [](ir::Value* v) {
|
|
|
|
|
auto* ci = dynamic_cast<ir::ConstantInt*>(v);
|
|
|
|
|
return ci && ci->GetValue() == 0;
|
|
|
|
|
};
|
|
|
|
|
if (idx.size() == 2 && is_zero(idx[0]) && is_zero(idx[1])) {
|
|
|
|
|
auto* base = gep->GetBasePtr();
|
|
|
|
|
if (base && base->GetType() && base->GetType()->IsPointer() &&
|
|
|
|
|
base->GetType()->GetElementType()->IsArray()) {
|
|
|
|
|
} else if (arg && arg->GetType() && arg->GetType()->IsInt32()) {
|
|
|
|
|
if (auto* load = dynamic_cast<ir::LoadInst*>(arg)) {
|
|
|
|
|
auto* base = load->GetPtr();
|
|
|
|
|
if (base && base->GetType() && base->GetType()->IsPointer()) {
|
|
|
|
|
auto* elem = base->GetType()->GetElementType().get();
|
|
|
|
|
if (elem && elem->IsPointer() &&
|
|
|
|
|
elem->GetElementType()->Equals(*pty->GetElementType())) {
|
|
|
|
|
args[i] = base;
|
|
|
|
|
arg = base;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (auto* gep = dynamic_cast<ir::GepInst*>(arg)) {
|
|
|
|
|
auto* base = gep->GetBasePtr();
|
|
|
|
|
if (base && base->GetType() && base->GetType()->IsPointer() &&
|
|
|
|
|
base->GetType()->GetElementType()->IsArray()) {
|
|
|
|
|
auto* base_elem = base->GetType()->GetElementType().get();
|
|
|
|
|
auto* param_elem = pty->GetElementType().get();
|
|
|
|
|
if (base_elem && base_elem->IsArray() && param_elem &&
|
|
|
|
|
base_elem->GetElementType()->Equals(*param_elem)) {
|
|
|
|
|
std::vector<ir::Value*> idx2 = {builder_.CreateConstInt(0)};
|
|
|
|
|
args[i] = builder_.CreateGep(base, std::move(idx2),
|
|
|
|
|
module_.GetContext().NextTemp());
|
|
|
|
|
arg = args[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -329,8 +329,11 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "无法解析左值类型"));
|
|
|
|
|
}
|
|
|
|
|
bool as_rvalue = true;
|
|
|
|
|
if (!ty->dims.empty() && ctx->LBRACK().empty()) {
|
|
|
|
|
as_rvalue = false;
|
|
|
|
|
if (!ty->dims.empty()) {
|
|
|
|
|
const size_t index_count = ctx->exp().size();
|
|
|
|
|
if (index_count == 0 || index_count < ty->dims.size()) {
|
|
|
|
|
as_rvalue = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return static_cast<ir::Value*>(LoadIfNeeded(addr, *ty, as_rvalue));
|
|
|
|
|
}
|
|
|
|
|
@ -648,6 +651,18 @@ ir::Value* IRGenImpl::DefaultValue(const TypeDesc& ty) {
|
|
|
|
|
return builder_.CreateConstInt(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ir::AllocaInst* IRGenImpl::CreateEntryAlloca(std::shared_ptr<ir::Type> ty,
|
|
|
|
|
const std::string& name) {
|
|
|
|
|
if (!func_) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "CreateEntryAlloca 缺少函数"));
|
|
|
|
|
}
|
|
|
|
|
auto* entry = func_->GetEntry();
|
|
|
|
|
if (!entry) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "CreateEntryAlloca 缺少入口块"));
|
|
|
|
|
}
|
|
|
|
|
return entry->Prepend<ir::AllocaInst>(std::move(ty), name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t IRGenImpl::ArrayStride(const TypeDesc& ty, size_t dim) const {
|
|
|
|
|
size_t stride = 1;
|
|
|
|
|
for (size_t i = dim + 1; i < ty.dims.size(); ++i) {
|
|
|
|
|
@ -749,10 +764,14 @@ void IRGenImpl::InitArray(ir::Value* base_ptr, const TypeDesc& ty,
|
|
|
|
|
ir::Value* addr = builder_.CreateGep(base_ptr, std::move(indices),
|
|
|
|
|
module_.GetContext().NextTemp());
|
|
|
|
|
ir::Value* value = values[idx];
|
|
|
|
|
if (ty.base == BaseTypeKind::Float && (value->IsInt1() || value->IsInt32())) {
|
|
|
|
|
value = CastToFloat(value);
|
|
|
|
|
if (ty.base == BaseTypeKind::Float) {
|
|
|
|
|
if (value->IsInt1() || value->IsInt32()) {
|
|
|
|
|
value = CastToFloat(value->IsInt1() ? CastToInt(value) : value);
|
|
|
|
|
}
|
|
|
|
|
} else if (ty.base == BaseTypeKind::Int && value->IsFloat()) {
|
|
|
|
|
value = CastToInt(value);
|
|
|
|
|
} else if (ty.base == BaseTypeKind::Int && value->IsInt1()) {
|
|
|
|
|
value = CastToInt(value);
|
|
|
|
|
}
|
|
|
|
|
builder_.CreateStore(value, addr);
|
|
|
|
|
}
|
|
|
|
|
@ -777,10 +796,14 @@ void IRGenImpl::InitConstArray(ir::Value* base_ptr, const TypeDesc& ty,
|
|
|
|
|
ir::Value* addr = builder_.CreateGep(base_ptr, std::move(indices),
|
|
|
|
|
module_.GetContext().NextTemp());
|
|
|
|
|
ir::Value* value = values[idx];
|
|
|
|
|
if (ty.base == BaseTypeKind::Float && (value->IsInt1() || value->IsInt32())) {
|
|
|
|
|
value = CastToFloat(value);
|
|
|
|
|
if (ty.base == BaseTypeKind::Float) {
|
|
|
|
|
if (value->IsInt1() || value->IsInt32()) {
|
|
|
|
|
value = CastToFloat(value->IsInt1() ? CastToInt(value) : value);
|
|
|
|
|
}
|
|
|
|
|
} else if (ty.base == BaseTypeKind::Int && value->IsFloat()) {
|
|
|
|
|
value = CastToInt(value);
|
|
|
|
|
} else if (ty.base == BaseTypeKind::Int && value->IsInt1()) {
|
|
|
|
|
value = CastToInt(value);
|
|
|
|
|
}
|
|
|
|
|
builder_.CreateStore(value, addr);
|
|
|
|
|
}
|
|
|
|
|
|