diff --git a/src/backend/RISCv64/RISCv64Backend.cpp b/src/backend/RISCv64/RISCv64Backend.cpp index 84eac98..1f552cf 100644 --- a/src/backend/RISCv64/RISCv64Backend.cpp +++ b/src/backend/RISCv64/RISCv64Backend.cpp @@ -26,7 +26,6 @@ std::string RISCv64CodeGen::module_gen() { // 判断是否为大型零初始化数组,以便放入.bss段 bool is_large_zero_array = false; - // 规则:初始化列表只有一项,且该项是值为0的整数,且数量大于一个阈值(例如16) if (init_values.getValues().size() == 1) { if (auto const_val = dynamic_cast(init_values.getValues()[0])) { if (const_val->isInt() && const_val->getInt() == 0 && init_values.getNumbers()[0] > 16) { @@ -44,19 +43,16 @@ std::string RISCv64CodeGen::module_gen() { // --- 步骤2:生成 .bss 段的代码 --- if (!bss_globals.empty()) { - ss << ".bss\n"; // 切换到 .bss 段 + ss << ".bss\n"; for (GlobalValue* global : bss_globals) { - // 获取数组总大小(元素个数 * 元素大小) - // 在SysY中,我们假设元素都是4字节(int或float) unsigned count = global->getInitValues().getNumbers()[0]; - unsigned total_size = count * 4; + unsigned total_size = count * 4; // 假设元素都是4字节 - ss << " .align 3\n"; // 8字节对齐 (2^3) + ss << " .align 3\n"; ss << ".globl " << global->getName() << "\n"; ss << ".type " << global->getName() << ", @object\n"; ss << ".size " << global->getName() << ", " << total_size << "\n"; ss << global->getName() << ":\n"; - // 使用 .space 指令来预留指定大小的零填充空间 ss << " .space " << total_size << "\n"; } } @@ -84,6 +80,30 @@ std::string RISCv64CodeGen::module_gen() { } } } + + // b. [新增] 再处理全局常量 (ConstantVariable) + for (const auto& const_ptr : module->getConsts()) { + ConstantVariable* cnst = const_ptr.get(); + ss << ".globl " << cnst->getName() << "\n"; + ss << cnst->getName() << ":\n"; + const auto& init_values = cnst->getInitValues(); + // 这部分逻辑和处理 GlobalValue 完全相同 + for (size_t i = 0; i < init_values.getValues().size(); ++i) { + auto val = init_values.getValues()[i]; + auto count = init_values.getNumbers()[i]; + if (auto constant = dynamic_cast(val)) { + for (unsigned j = 0; j < count; ++j) { + if (constant->isInt()) { + ss << " .word " << constant->getInt() << "\n"; + } else { + float f = constant->getFloat(); + uint32_t float_bits = *(uint32_t*)&f; + ss << " .word " << float_bits << "\n"; + } + } + } + } + } } // --- 处理函数 (.text段) --- diff --git a/src/backend/RISCv64/RISCv64ISel.cpp b/src/backend/RISCv64/RISCv64ISel.cpp index 49ce60d..f1b6497 100644 --- a/src/backend/RISCv64/RISCv64ISel.cpp +++ b/src/backend/RISCv64/RISCv64ISel.cpp @@ -1221,6 +1221,11 @@ void RISCv64ISel::selectNode(DAGNode* node) { la_instr->addOperand(std::make_unique(current_addr_vreg)); la_instr->addOperand(std::make_unique(global_base->getName())); CurMBB->addInstruction(std::move(la_instr)); + } else if (auto const_global_base = dynamic_cast(base_ptr_node->value)) { + auto la_instr = std::make_unique(RVOpcodes::LA); + la_instr->addOperand(std::make_unique(current_addr_vreg)); + la_instr->addOperand(std::make_unique(const_global_base->getName())); + CurMBB->addInstruction(std::move(la_instr)); } else { auto base_vreg = getVReg(base_ptr_node->value); auto mv = std::make_unique(RVOpcodes::MV); diff --git a/src/include/midend/IR.h b/src/include/midend/IR.h index 8828a79..901a3b7 100644 --- a/src/include/midend/IR.h +++ b/src/include/midend/IR.h @@ -1351,7 +1351,7 @@ protected: }; //! Global value declared at file scope -class GlobalValue : public User { +class GlobalValue : public Value { friend class Module; protected: @@ -1363,9 +1363,10 @@ protected: GlobalValue(Module *parent, Type *type, const std::string &name, const std::vector &dims = {}, ValueCounter init = {}) - : User(type, name), parent(parent) { + : Value(type, name), parent(parent) { assert(type->isPointer()); - addOperands(dims); + // addOperands(dims); + // 维度信息已经被记录到Type中,dim只是为了方便初始化 numDims = dims.size(); if (init.size() == 0) { unsigned num = 1; @@ -1385,20 +1386,34 @@ protected: } public: - unsigned getNumDims() const { return numDims; } ///< 获取维度数量 - Value* getDim(unsigned index) const { return getOperand(index); } ///< 获取位置为index的维度 - auto getDims() const { return getOperands(); } ///< 获取维度列表 + // unsigned getNumDims() const { return numDims; } ///< 获取维度数量 + // Value* getDim(unsigned index) const { return getOperand(index); } ///< 获取位置为index的维度 + // auto getDims() const { return getOperands(); } ///< 获取维度列表 + unsigned getNumIndices() const { + return numDims; + } ///< 获取维度数量 + unsigned getIndex(unsigned index) const { + assert(index < getNumIndices() && "Index out of bounds for GlobalValue!"); + Type *GlobalValueType = getType()->as()->getBaseType(); + for (unsigned i = 0; i < index; i++) { + GlobalValueType = GlobalValueType->as()->getElementType(); + } + return GlobalValueType->as()->getNumElements(); + } ///< 获取维度大小(从第0个开始) Value* getByIndex(unsigned index) const { return initValues.getValue(index); } ///< 通过一维偏移量index获取初始值 - Value* getByIndices(const std::vector &indices) const { + Value* getByIndices(const std::vector &indices) const { int index = 0; + Type *GlobalValueType = getType()->as()->getBaseType(); for (size_t i = 0; i < indices.size(); i++) { // Ensure dims[i] and indices[i] are ConstantInteger and retrieve their values correctly - auto dim_val = dynamic_cast(getDim(i)); + // GlobalValueType->as()->getNumElements(); + auto dim_val = GlobalValueType->as()->getNumElements(); auto idx_val = dynamic_cast(indices[i]); assert(dim_val && idx_val && "Dims and indices must be constant integers"); - index = dim_val->getInt() * index + idx_val->getInt(); + index = dim_val * index + idx_val->getInt(); + GlobalValueType = GlobalValueType->as()->getElementType(); } return getByIndex(index); } ///< 通过多维索引indices获取初始值 @@ -1406,7 +1421,7 @@ public: }; // class GlobalValue -class ConstantVariable : public User { +class ConstantVariable : public Value { friend class Module; protected: @@ -1417,31 +1432,45 @@ class ConstantVariable : public User { protected: ConstantVariable(Module *parent, Type *type, const std::string &name, const ValueCounter &init, const std::vector &dims = {}) - : User(type, name), parent(parent) { + : Value(type, name), parent(parent) { assert(type->isPointer()); numDims = dims.size(); initValues = init; - addOperands(dims); + // addOperands(dims); 同GlobalValue,维度信息已经被记录到Type中,dim只是为了方便初始化 } public: + unsigned getNumIndices() const { + return numDims; + } ///< 获取索引数量 + unsigned getIndex(unsigned index) const { + assert(index < getNumIndices() && "Index out of bounds for ConstantVariable!"); + Type *ConstantVariableType = getType()->as()->getBaseType(); + for (unsigned i = 0; i < index; i++) { + ConstantVariableType = ConstantVariableType->as()->getElementType(); + } + return ConstantVariableType->as()->getNumElements(); + } ///< 获取索引个数(从第0个开始) Value* getByIndex(unsigned index) const { return initValues.getValue(index); } ///< 通过一维位置index获取值 Value* getByIndices(const std::vector &indices) const { int index = 0; // 计算偏移量 + Type *ConstantVariableType = getType()->as()->getBaseType(); for (size_t i = 0; i < indices.size(); i++) { // Ensure dims[i] and indices[i] are ConstantInteger and retrieve their values correctly - auto dim_val = dynamic_cast(getDim(i)); + // ConstantVariableType->as()->getNumElements(); + auto dim_val = ConstantVariableType->as()->getNumElements(); auto idx_val = dynamic_cast(indices[i]); assert(dim_val && idx_val && "Dims and indices must be constant integers"); - index = dim_val->getInt() * index + idx_val->getInt(); + index = dim_val * index + idx_val->getInt(); + ConstantVariableType = ConstantVariableType->as()->getElementType(); } return getByIndex(index); } ///< 通过多维索引indices获取初始值 - unsigned getNumDims() const { return numDims; } ///< 获取维度数量 - Value* getDim(unsigned index) const { return getOperand(index); } ///< 获取位置为index的维度 - auto getDims() const { return getOperands(); } ///< 获取维度列表 + // unsigned getNumDims() const { return numDims; } ///< 获取维度数量 + // Value* getDim(unsigned index) const { return getOperand(index); } ///< 获取位置为index的维度 + // auto getDims() const { return getOperands(); } ///< 获取维度列表 const ValueCounter& getInitValues() const { return initValues; } ///< 获取初始值 }; @@ -1457,7 +1486,7 @@ class SymbolTable { SymbolTableNode *curNode{}; ///< 当前所在的作用域(符号表节点) std::map variableIndex; ///< 变量命名索引表 std::vector> globals; ///< 全局变量列表 - std::vector> consts; ///< 常量列表 + std::vector> globalconsts; ///< 全局常量列表 std::vector> nodeList; ///< 符号表节点列表 public: @@ -1466,7 +1495,7 @@ class SymbolTable { Value* getVariable(const std::string &name) const; ///< 根据名字name以及当前作用域获取变量 Value* addVariable(const std::string &name, Value *variable); ///< 添加变量 std::vector>& getGlobals(); ///< 获取全局变量列表 - const std::vector>& getConsts() const; ///< 获取常量列表 + const std::vector>& getConsts() const; ///< 获取全局常量列表 void enterNewScope(); ///< 进入新的作用域 void leaveScope(); ///< 离开作用域 bool isInGlobalScope() const; ///< 是否位于全局作用域 diff --git a/src/include/midend/SysYIRPrinter.h b/src/include/midend/SysYIRPrinter.h index deb22c0..6bff420 100644 --- a/src/include/midend/SysYIRPrinter.h +++ b/src/include/midend/SysYIRPrinter.h @@ -15,6 +15,7 @@ public: public: void printIR(); void printGlobalVariable(); + void printGlobalConstant(); public: diff --git a/src/midend/IR.cpp b/src/midend/IR.cpp index 02ecfdd..1b32eaf 100644 --- a/src/midend/IR.cpp +++ b/src/midend/IR.cpp @@ -652,6 +652,7 @@ Function * CallInst::getCallee() const { return dynamic_cast(getOper /** * 获取变量指针 + * 如果在当前作用域或父作用域中找到变量,则返回该变量的指针,否则返回nullptr */ auto SymbolTable::getVariable(const std::string &name) const -> Value * { auto node = curNode; @@ -688,7 +689,7 @@ auto SymbolTable::addVariable(const std::string &name, Value *variable) -> Value if (global != nullptr) { globals.emplace_back(global); } else if (constvar != nullptr) { - consts.emplace_back(constvar); + globalconsts.emplace_back(constvar); } result = variable; @@ -703,7 +704,7 @@ auto SymbolTable::getGlobals() -> std::vector> & { /** * 获取常量 */ -auto SymbolTable::getConsts() const -> const std::vector> & { return consts; } +auto SymbolTable::getConsts() const -> const std::vector> & { return globalconsts; } /** * 进入新的作用域 */ diff --git a/src/midend/SysYIRGenerator.cpp b/src/midend/SysYIRGenerator.cpp index 38fa52a..03f382b 100644 --- a/src/midend/SysYIRGenerator.cpp +++ b/src/midend/SysYIRGenerator.cpp @@ -132,8 +132,8 @@ std::any SysYIRGenerator::visitGlobalVarDecl(SysYParser::GlobalVarDeclContext *c return std::any(); } -std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext *ctx){ - Type* type = std::any_cast(visitBType(ctx->bType())); +std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext *ctx) { + Type *type = std::any_cast(visitBType(ctx->bType())); for (const auto constDef : ctx->constDef()) { std::vector dims = {}; std::string name = constDef->Ident()->getText(); @@ -144,19 +144,112 @@ std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext *ctx){ } } - ArrayValueTree* root = std::any_cast(constDef->constInitVal()->accept(this)); + Type *variableType = type; + if (!dims.empty()) { + variableType = buildArrayType(type, dims); // 构建完整的 ArrayType + } + + // 显式地为局部常量在栈上分配空间 + // alloca 的类型将是指针指向常量类型,例如 `int*` 或 `int[2][3]*` + AllocaInst *alloca = builder.createAllocaInst(Type::getPointerType(variableType), {}, name); + + ArrayValueTree *root = std::any_cast(constDef->constInitVal()->accept(this)); ValueCounter values; Utils::tree2Array(type, root, dims, dims.size(), values, &builder); delete root; - // 创建局部常量,并更新符号表 - Type* variableType = type; - if (!dims.empty()) { - variableType = buildArrayType(type, dims); // 构建完整的 ArrayType + // 根据维度信息进行 store 初始化 + if (dims.empty()) { // 标量常量初始化 + // 局部常量必须有初始值,且通常是单个值 + if (!values.getValues().empty()) { + builder.createStoreInst(values.getValue(0), alloca); + } else { + // 错误处理:局部标量常量缺少初始化值 + // 或者可以考虑默认初始化为0,但这通常不符合常量的语义 + assert(false && "Local scalar constant must have an initialization value!"); + return std::any(); // 直接返回,避免继续执行 + } + } else { // 数组常量初始化 + const std::vector &counterValues = values.getValues(); + const std::vector &counterNumbers = values.getNumbers(); + int numElements = 1; + std::vector dimSizes; + for (Value *dimVal : dims) { + if (ConstantInteger *constInt = dynamic_cast(dimVal)) { + int dimSize = constInt->getInt(); + numElements *= dimSize; + dimSizes.push_back(dimSize); + } + // TODO else 错误处理:数组维度必须是常量(对于静态分配) + else { + assert(false && "Array dimension must be a constant integer!"); + return std::any(); // 直接返回,避免继续执行 + } + } + unsigned int elementSizeInBytes = type->getSize(); + unsigned int totalSizeInBytes = numElements * elementSizeInBytes; + + // 检查是否所有初始化值都是零 + bool allValuesAreZero = false; + if (counterValues.empty()) { // 如果没有提供初始化值,通常视为全零初始化 + allValuesAreZero = true; + } else { + allValuesAreZero = true; + for (Value *val : counterValues) { + if (ConstantInteger *constInt = dynamic_cast(val)) { + if (constInt->getInt() != 0) { + allValuesAreZero = false; + break; + } + } else { // 如果不是常量整数,则不能确定是零 + allValuesAreZero = false; + break; + } + } + } + + if (allValuesAreZero) { + builder.createMemsetInst(alloca, ConstantInteger::get(0), ConstantInteger::get(totalSizeInBytes), + ConstantInteger::get(0)); + } else { + int linearIndexOffset = 0; // 用于追踪当前处理的线性索引的偏移量 + for (int k = 0; k < counterValues.size(); ++k) { + // 当前 Value 的值和重复次数 + Value *currentValue = counterValues[k]; + unsigned currentRepeatNum = counterNumbers[k]; + + for (unsigned i = 0; i < currentRepeatNum; ++i) { + std::vector currentIndices; + int tempLinearIndex = linearIndexOffset + i; // 使用偏移量和当前重复次数内的索引 + + // 将线性索引转换为多维索引 + for (int dimIdx = dimSizes.size() - 1; dimIdx >= 0; --dimIdx) { + currentIndices.insert(currentIndices.begin(), + ConstantInteger::get(static_cast(tempLinearIndex % dimSizes[dimIdx]))); + tempLinearIndex /= dimSizes[dimIdx]; + } + + // 对于局部数组,alloca 本身就是 GEP 的基指针。 + // GEP 的第一个索引必须是 0,用于“步过”整个数组。 + std::vector gepIndicesForInit; + gepIndicesForInit.push_back(ConstantInteger::get(0)); + gepIndicesForInit.insert(gepIndicesForInit.end(), currentIndices.begin(), currentIndices.end()); + + // 计算元素的地址 + Value *elementAddress = getGEPAddressInst(alloca, gepIndicesForInit); + // 生成 store 指令 + builder.createStoreInst(currentValue, elementAddress); + } + // 更新线性索引偏移量,以便下一次迭代从正确的位置开始 + linearIndexOffset += currentRepeatNum; + } + } } - module->createConstVar(name, Type::getPointerType(variableType), values, dims); + + // 更新符号表,将常量名称与 AllocaInst 关联起来 + module->addVariable(name, alloca); } - return 0; + return std::any(); } std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) { diff --git a/src/midend/SysYIRPrinter.cpp b/src/midend/SysYIRPrinter.cpp index 877e4ab..e2c5e17 100644 --- a/src/midend/SysYIRPrinter.cpp +++ b/src/midend/SysYIRPrinter.cpp @@ -13,6 +13,7 @@ void SysYPrinter::printIR() { //TODO: Print target datalayout and triple (minimal required by LLVM) printGlobalVariable(); + printGlobalConstant(); for (const auto &iter : functions) { if (iter.second->getName() == "main") { @@ -137,6 +138,48 @@ void SysYPrinter::printGlobalVariable() { } } + +void SysYPrinter::printGlobalConstant() { + auto &globalConstants = pModule->getConsts(); + + for (const auto &globalConstant : globalConstants) { + std::cout << "@" << globalConstant->getName() << " = global constant "; + + // 全局变量的类型是一个指针,指向其基类型 (可能是 ArrayType 或 Integer/FloatType) + auto globalVarBaseType = dynamic_cast(globalConstant->getType())->getBaseType(); + printType(globalVarBaseType); // 打印全局变量的实际类型 (例如 i32 或 [10 x i32]) + + std::cout << " "; + + // 检查是否是数组类型 (通过检查 globalVarBaseType 是否是 ArrayType) + if (globalVarBaseType->isArray()) { + // 数组初始化器 + std::cout << "["; // LLVM IR 数组初始化器格式: [type value, type value, ...] + auto values = globalConstant->getInitValues(); // 假设 getInitValues() 返回一个 ValueCounter + const std::vector &counterValues = values.getValues(); // 获取所有值 + + for (size_t i = 0; i < counterValues.size(); i++) { + if (i > 0) std::cout << ", "; + // 打印元素类型,这个元素类型应该是数组的最终元素类型,例如 i32 或 float + // 可以从 globalVarBaseType 逐层剥离得到最终元素类型,但这里简化为直接从值获取 + printType(counterValues[i]->getType()); + std::cout << " "; + printValue(counterValues[i]); + } + std::cout << "]"; + } else { + // 标量初始化器 + // 假设标量全局变量的初始化值通过 getByIndex(0) 获取 + Value* initVal = globalConstant->getByIndex(0); + printType(initVal->getType()); // 打印标量值的类型 + std::cout << " "; + printValue(initVal); // 打印标量值 + } + + std::cout << ", align 4" << std::endl; + } +} + void SysYPrinter::printBlock(BasicBlock *block) { std::cout << getBlockName(block); }