[backend-IRC]修复了后端不适配中端全局变量定义的问题
This commit is contained in:
@ -12,6 +12,39 @@ std::string RISCv64CodeGen::code_gen() {
|
|||||||
return module_gen();
|
return module_gen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned RISCv64CodeGen::getTypeSizeInBytes(Type* type) {
|
||||||
|
if (!type) {
|
||||||
|
assert(false && "Cannot get size of a null type.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type->getKind()) {
|
||||||
|
// 对于SysY语言,基本类型int和float都占用4字节
|
||||||
|
case Type::kInt:
|
||||||
|
case Type::kFloat:
|
||||||
|
return 4;
|
||||||
|
|
||||||
|
// 指针类型在RISC-V 64位架构下占用8字节
|
||||||
|
// 虽然SysY没有'int*'语法,但数组变量在IR层面本身就是指针类型
|
||||||
|
case Type::kPointer:
|
||||||
|
return 8;
|
||||||
|
|
||||||
|
// 数组类型的总大小 = 元素数量 * 单个元素的大小
|
||||||
|
case Type::kArray: {
|
||||||
|
auto arrayType = type->as<ArrayType>();
|
||||||
|
// 递归调用以计算元素大小
|
||||||
|
return arrayType->getNumElements() * getTypeSizeInBytes(arrayType->getElementType());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他类型,如Void, Label等不占用栈空间,或者不应该出现在这里
|
||||||
|
default:
|
||||||
|
// 如果遇到未处理的类型,触发断言,方便调试
|
||||||
|
// assert(false && "Unsupported type for size calculation.");
|
||||||
|
return 0; // 对于像Label或Void这样的类型,返回0是合理的
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void printInitializer(std::stringstream& ss, const ValueCounter& init_values) {
|
void printInitializer(std::stringstream& ss, const ValueCounter& init_values) {
|
||||||
for (size_t i = 0; i < init_values.getValues().size(); ++i) {
|
for (size_t i = 0; i < init_values.getValues().size(); ++i) {
|
||||||
auto val = init_values.getValues()[i];
|
auto val = init_values.getValues()[i];
|
||||||
@ -39,18 +72,36 @@ std::string RISCv64CodeGen::module_gen() {
|
|||||||
|
|
||||||
for (const auto& global_ptr : module->getGlobals()) {
|
for (const auto& global_ptr : module->getGlobals()) {
|
||||||
GlobalValue* global = global_ptr.get();
|
GlobalValue* global = global_ptr.get();
|
||||||
|
|
||||||
|
// [核心修改] 使用更健壮的逻辑来判断是否为大型零初始化数组
|
||||||
|
bool is_all_zeros = true;
|
||||||
const auto& init_values = global->getInitValues();
|
const auto& init_values = global->getInitValues();
|
||||||
|
|
||||||
// 判断是否为大型零初始化数组,以便放入.bss段
|
// 检查初始化值是否全部为0
|
||||||
bool is_large_zero_array = false;
|
if (init_values.getValues().empty()) {
|
||||||
if (init_values.getValues().size() == 1) {
|
// 如果 ValueCounter 为空,GlobalValue 的构造函数会确保它是零初始化的
|
||||||
if (auto const_val = dynamic_cast<ConstantValue*>(init_values.getValues()[0])) {
|
is_all_zeros = true;
|
||||||
if (const_val->isInt() && const_val->getInt() == 0 && init_values.getNumbers()[0] > 16) {
|
} else {
|
||||||
is_large_zero_array = true;
|
for (auto val : init_values.getValues()) {
|
||||||
|
if (auto const_val = dynamic_cast<ConstantValue*>(val)) {
|
||||||
|
if (!const_val->isZero()) {
|
||||||
|
is_all_zeros = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果初始值包含非常量(例如,另一个全局变量的地址),则不认为是纯零初始化
|
||||||
|
is_all_zeros = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 使用 getTypeSizeInBytes 检查总大小是否超过阈值 (16个整数 = 64字节)
|
||||||
|
Type* allocated_type = global->getType()->as<PointerType>()->getBaseType();
|
||||||
|
unsigned total_size = getTypeSizeInBytes(allocated_type);
|
||||||
|
|
||||||
|
bool is_large_zero_array = is_all_zeros && (total_size > 64);
|
||||||
|
|
||||||
if (is_large_zero_array) {
|
if (is_large_zero_array) {
|
||||||
bss_globals.push_back(global);
|
bss_globals.push_back(global);
|
||||||
} else {
|
} else {
|
||||||
@ -58,12 +109,12 @@ std::string RISCv64CodeGen::module_gen() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 步骤2:生成 .bss 段的代码 (这部分不变) ---
|
// --- 步骤2:生成 .bss 段的代码 ---
|
||||||
if (!bss_globals.empty()) {
|
if (!bss_globals.empty()) {
|
||||||
ss << ".bss\n";
|
ss << ".bss\n";
|
||||||
for (GlobalValue* global : bss_globals) {
|
for (GlobalValue* global : bss_globals) {
|
||||||
unsigned count = global->getInitValues().getNumbers()[0];
|
Type* allocated_type = global->getType()->as<PointerType>()->getBaseType();
|
||||||
unsigned total_size = count * 4; // 假设元素都是4字节
|
unsigned total_size = getTypeSizeInBytes(allocated_type);
|
||||||
|
|
||||||
ss << " .align 3\n";
|
ss << " .align 3\n";
|
||||||
ss << ".globl " << global->getName() << "\n";
|
ss << ".globl " << global->getName() << "\n";
|
||||||
@ -74,33 +125,45 @@ std::string RISCv64CodeGen::module_gen() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- [修改] 步骤3:生成 .data 段的代码 ---
|
// --- 步骤3:生成 .data 段的代码 ---
|
||||||
// 我们需要检查 data_globals 和 常量列表是否都为空
|
|
||||||
if (!data_globals.empty() || !module->getConsts().empty()) {
|
if (!data_globals.empty() || !module->getConsts().empty()) {
|
||||||
ss << ".data\n";
|
ss << ".data\n";
|
||||||
|
|
||||||
// a. 先处理普通的全局变量 (GlobalValue)
|
// a. 处理普通的全局变量 (GlobalValue)
|
||||||
for (GlobalValue* global : data_globals) {
|
for (GlobalValue* global : data_globals) {
|
||||||
|
Type* allocated_type = global->getType()->as<PointerType>()->getBaseType();
|
||||||
|
unsigned total_size = getTypeSizeInBytes(allocated_type);
|
||||||
|
|
||||||
|
ss << " .align 3\n";
|
||||||
ss << ".globl " << global->getName() << "\n";
|
ss << ".globl " << global->getName() << "\n";
|
||||||
|
ss << ".type " << global->getName() << ", @object\n";
|
||||||
|
ss << ".size " << global->getName() << ", " << total_size << "\n";
|
||||||
ss << global->getName() << ":\n";
|
ss << global->getName() << ":\n";
|
||||||
printInitializer(ss, global->getInitValues());
|
printInitializer(ss, global->getInitValues());
|
||||||
}
|
}
|
||||||
|
|
||||||
// b. [新增] 再处理全局常量 (ConstantVariable)
|
// b. 处理全局常量 (ConstantVariable)
|
||||||
for (const auto& const_ptr : module->getConsts()) {
|
for (const auto& const_ptr : module->getConsts()) {
|
||||||
ConstantVariable* cnst = const_ptr.get();
|
ConstantVariable* cnst = const_ptr.get();
|
||||||
|
Type* allocated_type = cnst->getType()->as<PointerType>()->getBaseType();
|
||||||
|
unsigned total_size = getTypeSizeInBytes(allocated_type);
|
||||||
|
|
||||||
|
ss << " .align 3\n";
|
||||||
ss << ".globl " << cnst->getName() << "\n";
|
ss << ".globl " << cnst->getName() << "\n";
|
||||||
|
ss << ".type " << cnst->getName() << ", @object\n";
|
||||||
|
ss << ".size " << cnst->getName() << ", " << total_size << "\n";
|
||||||
ss << cnst->getName() << ":\n";
|
ss << cnst->getName() << ":\n";
|
||||||
printInitializer(ss, cnst->getInitValues());
|
printInitializer(ss, cnst->getInitValues());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 处理函数 (.text段) 的逻辑保持不变 ---
|
// --- 步骤4:处理函数 (.text段) 的逻辑 ---
|
||||||
if (!module->getFunctions().empty()) {
|
if (!module->getFunctions().empty()) {
|
||||||
ss << ".text\n";
|
ss << ".text\n";
|
||||||
for (const auto& func_pair : module->getFunctions()) {
|
for (const auto& func_pair : module->getFunctions()) {
|
||||||
if (func_pair.second.get()) {
|
if (func_pair.second.get() && !func_pair.second->getBasicBlocks().empty()) {
|
||||||
ss << function_gen(func_pair.second.get());
|
ss << function_gen(func_pair.second.get());
|
||||||
|
if (DEBUG) std::cerr << "Function: " << func_pair.first << " generated.\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,10 +224,10 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
|
|||||||
RISCv64RegAlloc reg_alloc(mfunc.get());
|
RISCv64RegAlloc reg_alloc(mfunc.get());
|
||||||
reg_alloc.run();
|
reg_alloc.run();
|
||||||
|
|
||||||
DEBUG = 0;
|
// DEBUG = 0;
|
||||||
DEEPDEBUG = 0;
|
// DEEPDEBUG = 0;
|
||||||
// DEBUG = 1;
|
DEBUG = 1;
|
||||||
// DEEPDEBUG = 1;
|
DEEPDEBUG = 1;
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
std::cerr << "====== stack info after reg alloc ======\n";
|
std::cerr << "====== stack info after reg alloc ======\n";
|
||||||
mfunc->dumpStackFrameInfo(std::cerr);
|
mfunc->dumpStackFrameInfo(std::cerr);
|
||||||
@ -207,6 +270,8 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
|
|||||||
ss << "\n\n; --- Intermediate Representation after Instruction Selection ---\n"
|
ss << "\n\n; --- Intermediate Representation after Instruction Selection ---\n"
|
||||||
<< ss_after_isel.str();
|
<< ss_after_isel.str();
|
||||||
}
|
}
|
||||||
|
DEBUG = 1;
|
||||||
|
DEEPDEBUG = 1;
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,9 @@ private:
|
|||||||
// 函数级代码生成 (实现新的流水线)
|
// 函数级代码生成 (实现新的流水线)
|
||||||
std::string function_gen(Function* func);
|
std::string function_gen(Function* func);
|
||||||
|
|
||||||
|
// 私有辅助函数,用于根据类型计算其占用的字节数。
|
||||||
|
unsigned getTypeSizeInBytes(Type* type);
|
||||||
|
|
||||||
Module* module;
|
Module* module;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user