From 98511efd919efad353e98f84edf666bb06e57f36 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Wed, 30 Jul 2025 14:40:10 +0800 Subject: [PATCH 1/4] =?UTF-8?q?[midend]=E4=BF=AE=E6=94=B9constdecl?= =?UTF-8?q?=E7=9A=84=E9=80=BB=E8=BE=91=E5=8C=BA=E5=88=86=E5=B1=80=E9=83=A8?= =?UTF-8?q?=E5=B8=B8=E9=87=8F=E5=92=8C=E5=85=A8=E5=B1=80=E5=B8=B8=E9=87=8F?= =?UTF-8?q?=E5=A3=B0=E6=98=8E=E9=80=BB=E8=BE=91=EF=BC=8C=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E8=AE=BF=E9=97=AE=E5=85=A8=E5=B1=80=E5=8F=98?= =?UTF-8?q?=E9=87=8F=EF=BC=8C=E5=B8=B8=E9=87=8F=E7=9A=84=E7=BB=B4=E5=BA=A6?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=EF=BC=8C=E4=BF=AE=E6=94=B9GlobalValue?= =?UTF-8?q?=EF=BC=8CConstantVariable=E7=9A=84=E7=BB=A7=E6=89=BF=E7=88=B6?= =?UTF-8?q?=E7=B1=BB(User->Value)=E7=BB=B4=E5=BA=A6=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E5=9C=A8Type=E4=B8=AD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/midend/IR.h | 67 ++++++++++++++------ src/midend/IR.cpp | 5 +- src/midend/SysYIRGenerator.cpp | 111 ++++++++++++++++++++++++++++++--- 3 files changed, 153 insertions(+), 30 deletions(-) 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/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) { From 38bee5d5ac353bc67a1bf73a53c1a99877610ba9 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Wed, 30 Jul 2025 14:46:28 +0800 Subject: [PATCH 2/4] =?UTF-8?q?[midend]IRPrinter=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E4=BA=86=E6=89=93=E5=8D=B0=E5=85=A8=E5=B1=80=E5=B8=B8=E9=87=8F?= =?UTF-8?q?=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/midend/SysYIRPrinter.h | 1 + src/midend/SysYIRPrinter.cpp | 43 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) 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/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); } From a3c4d5a2b83a5f8fe37714322011d69772746431 Mon Sep 17 00:00:00 2001 From: CGH0S7 <776459475@qq.com> Date: Wed, 30 Jul 2025 15:27:23 +0800 Subject: [PATCH 3/4] =?UTF-8?q?[Optimize]=E5=AF=B9PreRA=E6=8C=87=E4=BB=A4?= =?UTF-8?q?=E8=B0=83=E5=BA=A6=E8=BF=9B=E8=A1=8C=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RISCv64/Optimize/PreRA_Scheduler.cpp | 164 ++++++++++++------ 1 file changed, 110 insertions(+), 54 deletions(-) diff --git a/src/backend/RISCv64/Optimize/PreRA_Scheduler.cpp b/src/backend/RISCv64/Optimize/PreRA_Scheduler.cpp index 8497429..e26d1b6 100644 --- a/src/backend/RISCv64/Optimize/PreRA_Scheduler.cpp +++ b/src/backend/RISCv64/Optimize/PreRA_Scheduler.cpp @@ -1,8 +1,8 @@ #include "PreRA_Scheduler.h" #include "RISCv64LLIR.h" #include -#include -#include +#include +#include #include #define MAX_SCHEDULING_BLOCK_SIZE 1000 // 严格限制调度块大小 @@ -66,9 +66,44 @@ static bool hasMemoryAccess(MachineInstr *instr) { return isLoadInstr(instr) || isStoreInstr(instr); } -// 获取指令定义的虚拟寄存器 -static std::set getDefinedVirtualRegisters(MachineInstr *instr) { - std::set defined_regs; +// 获取内存访问位置信息 +struct MemoryLocation { + unsigned base_reg; + int64_t offset; + bool is_valid; + + MemoryLocation() : base_reg(0), offset(0), is_valid(false) {} + MemoryLocation(unsigned base, int64_t off) + : base_reg(base), offset(off), is_valid(true) {} + + bool operator==(const MemoryLocation &other) const { + return is_valid && other.is_valid && base_reg == other.base_reg && + offset == other.offset; + } +}; + +// 缓存指令分析信息 +struct InstrInfo { + std::unordered_set defined_regs; + std::unordered_set used_regs; + MemoryLocation mem_location; + bool is_load; + bool is_store; + bool is_terminator; + bool is_call; + bool has_side_effect; + bool has_memory_access; + + InstrInfo() : is_load(false), is_store(false), is_terminator(false), + is_call(false), has_side_effect(false), has_memory_access(false) {} +}; + +// 指令信息缓存 +static std::unordered_map instr_info_cache; + +// 获取指令定义的虚拟寄存器 - 优化版本 +static std::unordered_set getDefinedVirtualRegisters(MachineInstr *instr) { + std::unordered_set defined_regs; RVOpcodes opcode = instr->getOpcode(); // CALL指令可能定义返回值寄存器 @@ -101,9 +136,9 @@ static std::set getDefinedVirtualRegisters(MachineInstr *instr) { return defined_regs; } -// 获取指令使用的虚拟寄存器 -static std::set getUsedVirtualRegisters(MachineInstr *instr) { - std::set used_regs; +// 获取指令使用的虚拟寄存器 - 优化版本 +static std::unordered_set getUsedVirtualRegisters(MachineInstr *instr) { + std::unordered_set used_regs; RVOpcodes opcode = instr->getOpcode(); // CALL指令:跳过第一个操作数(返回值),其余为参数 @@ -164,22 +199,6 @@ static std::set getUsedVirtualRegisters(MachineInstr *instr) { return used_regs; } -// 获取内存访问位置信息 -struct MemoryLocation { - unsigned base_reg; - int64_t offset; - bool is_valid; - - MemoryLocation() : base_reg(0), offset(0), is_valid(false) {} - MemoryLocation(unsigned base, int64_t off) - : base_reg(base), offset(off), is_valid(true) {} - - bool operator==(const MemoryLocation &other) const { - return is_valid && other.is_valid && base_reg == other.base_reg && - offset == other.offset; - } -}; - // 获取内存访问位置 static MemoryLocation getMemoryLocation(MachineInstr *instr) { if (!isLoadInstr(instr) && !isStoreInstr(instr)) { @@ -199,6 +218,27 @@ static MemoryLocation getMemoryLocation(MachineInstr *instr) { return MemoryLocation(); } +// 预计算并缓存指令信息 +static const InstrInfo& getInstrInfo(MachineInstr *instr) { + auto it = instr_info_cache.find(instr); + if (it != instr_info_cache.end()) { + return it->second; + } + + InstrInfo& info = instr_info_cache[instr]; + info.defined_regs = getDefinedVirtualRegisters(instr); + info.used_regs = getUsedVirtualRegisters(instr); + info.mem_location = getMemoryLocation(instr); + info.is_load = isLoadInstr(instr); + info.is_store = isStoreInstr(instr); + info.is_terminator = isTerminatorInstr(instr); + info.is_call = isCallInstr(instr); + info.has_side_effect = hasSideEffect(instr); + info.has_memory_access = hasMemoryAccess(instr); + + return info; +} + // 检查两个内存位置是否可能别名 static bool mayAlias(const MemoryLocation &loc1, const MemoryLocation &loc2) { if (!loc1.is_valid || !loc2.is_valid) { @@ -214,30 +254,28 @@ static bool mayAlias(const MemoryLocation &loc1, const MemoryLocation &loc2) { return loc1.offset == loc2.offset; } -// 检查两个指令之间是否存在数据依赖 +// 检查两个指令之间是否存在数据依赖 - 优化版本 static bool hasDataDependency(MachineInstr *first, MachineInstr *second) { - auto defined_regs_first = getDefinedVirtualRegisters(first); - auto used_regs_first = getUsedVirtualRegisters(first); - auto defined_regs_second = getDefinedVirtualRegisters(second); - auto used_regs_second = getUsedVirtualRegisters(second); + const InstrInfo& info_first = getInstrInfo(first); + const InstrInfo& info_second = getInstrInfo(second); // RAW依赖: second读取first写入的寄存器 - for (const auto ® : defined_regs_first) { - if (used_regs_second.count(reg)) { + for (const auto ® : info_first.defined_regs) { + if (info_second.used_regs.find(reg) != info_second.used_regs.end()) { return true; } } // WAR依赖: second写入first读取的寄存器 - for (const auto ® : used_regs_first) { - if (defined_regs_second.count(reg)) { + for (const auto ® : info_first.used_regs) { + if (info_second.defined_regs.find(reg) != info_second.defined_regs.end()) { return true; } } // WAW依赖: 两个指令写入同一寄存器 - for (const auto ® : defined_regs_first) { - if (defined_regs_second.count(reg)) { + for (const auto ® : info_first.defined_regs) { + if (info_second.defined_regs.find(reg) != info_second.defined_regs.end()) { return true; } } @@ -245,40 +283,41 @@ static bool hasDataDependency(MachineInstr *first, MachineInstr *second) { return false; } -// 检查两个指令之间是否存在内存依赖 +// 检查两个指令之间是否存在内存依赖 - 优化版本 static bool hasMemoryDependency(MachineInstr *first, MachineInstr *second) { - bool first_accesses_memory = isLoadInstr(first) || isStoreInstr(first); - bool second_accesses_memory = isLoadInstr(second) || isStoreInstr(second); + const InstrInfo& info_first = getInstrInfo(first); + const InstrInfo& info_second = getInstrInfo(second); - if (!first_accesses_memory || !second_accesses_memory) { + if (!info_first.has_memory_access || !info_second.has_memory_access) { return false; } // 如果至少有一个是存储指令,需要检查别名 - if (isStoreInstr(first) || isStoreInstr(second)) { - MemoryLocation loc1 = getMemoryLocation(first); - MemoryLocation loc2 = getMemoryLocation(second); - return mayAlias(loc1, loc2); + if (info_first.is_store || info_second.is_store) { + return mayAlias(info_first.mem_location, info_second.mem_location); } return false; // 两个加载指令之间没有依赖 } -// 检查两个指令之间是否存在控制依赖 +// 检查两个指令之间是否存在控制依赖 - 优化版本 static bool hasControlDependency(MachineInstr *first, MachineInstr *second) { + const InstrInfo& info_first = getInstrInfo(first); + const InstrInfo& info_second = getInstrInfo(second); + // 终结指令与任何其他指令都有控制依赖 - if (isTerminatorInstr(first)) { + if (info_first.is_terminator) { return true; // first是终结指令,second不能移动到first之前 } - if (isTerminatorInstr(second)) { + if (info_second.is_terminator) { return false; // second是终结指令,可以保持在后面 } // CALL指令具有控制副作用,但可以参与有限的调度 - if (isCallInstr(first) || isCallInstr(second)) { + if (info_first.is_call || info_second.is_call) { // CALL指令之间保持顺序 - if (isCallInstr(first) && isCallInstr(second)) { + if (info_first.is_call && info_second.is_call) { return true; } // 其他情况允许调度(通过数据依赖控制) @@ -287,7 +326,7 @@ static bool hasControlDependency(MachineInstr *first, MachineInstr *second) { return false; } -// 综合检查两个指令是否可以交换 +// 综合检查两个指令是否可以交换 - 优化版本 static bool canSwapInstructions(MachineInstr *first, MachineInstr *second) { // 检查所有类型的依赖 if (hasDataDependency(first, second) || hasDataDependency(second, first)) { @@ -306,15 +345,17 @@ static bool canSwapInstructions(MachineInstr *first, MachineInstr *second) { return true; } -// 找到基本块中的调度边界 +// 找到基本块中的调度边界 - 优化版本 static std::vector findSchedulingBoundaries(const std::vector &instrs) { std::vector boundaries; + boundaries.reserve(instrs.size() / 10); // 预估边界数量 boundaries.push_back(0); // 起始边界 for (size_t i = 0; i < instrs.size(); i++) { + const InstrInfo& info = getInstrInfo(instrs[i]); // 终结指令前后都是边界 - if (isTerminatorInstr(instrs[i])) { + if (info.is_terminator) { if (i > 0) boundaries.push_back(i); if (i + 1 < instrs.size()) @@ -333,7 +374,7 @@ findSchedulingBoundaries(const std::vector &instrs) { return boundaries; } -// 在单个调度区域内进行指令调度 +// 在单个调度区域内进行指令调度 - 优化版本 static void scheduleRegion(std::vector &instrs, size_t start, size_t end) { if (end - start <= 1) { @@ -347,7 +388,8 @@ static void scheduleRegion(std::vector &instrs, size_t start, // 简单的调度算法:只尝试将加载指令尽可能前移 for (size_t i = start + 1; i < end; i++) { - if (isLoadInstr(instrs[i])) { + const InstrInfo& info = getInstrInfo(instrs[i]); + if (info.is_load) { // 尝试将加载指令向前移动 for (size_t j = i; j > start; j--) { // 检查是否可以与前一条指令交换 @@ -369,12 +411,21 @@ static void scheduleBlock(MachineBasicBlock *mbb) { return; } + // 清理缓存,避免无效指针 + instr_info_cache.clear(); + // 构建指令列表 std::vector instr_list; + instr_list.reserve(instructions.size()); // 预分配容量 for (auto &instr : instructions) { instr_list.push_back(instr.get()); } + // 预计算所有指令信息 + for (auto* instr : instr_list) { + getInstrInfo(instr); + } + // 找到调度边界 std::vector boundaries = findSchedulingBoundaries(instr_list); @@ -386,12 +437,14 @@ static void scheduleBlock(MachineBasicBlock *mbb) { } // 重建指令序列 - std::map> instr_map; + std::unordered_map> instr_map; + instr_map.reserve(instructions.size()); // 预分配容量 for (auto &instr : instructions) { instr_map[instr.get()] = std::move(instr); } instructions.clear(); + instructions.reserve(instr_list.size()); // 预分配容量 for (auto *instr : instr_list) { instructions.push_back(std::move(instr_map[instr])); } @@ -405,6 +458,9 @@ void PreRA_Scheduler::runOnMachineFunction(MachineFunction *mfunc) { for (auto &mbb : mfunc->getBlocks()) { scheduleBlock(mbb.get()); } + + // 清理全局缓存 + instr_info_cache.clear(); } } // namespace sysy \ No newline at end of file From 48b0aec6c353799ba07e8031cf9d62e1b14589f1 Mon Sep 17 00:00:00 2001 From: Lixuanwang Date: Wed, 30 Jul 2025 18:23:56 +0800 Subject: [PATCH 4/4] =?UTF-8?q?[midend][backend]=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BA=86=E5=85=A8=E5=B1=80=E5=B8=B8=E9=87=8F=E6=95=B0=E7=BB=84?= =?UTF-8?q?=E7=9A=84=E8=AE=BF=E9=97=AE=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/RISCv64/RISCv64Backend.cpp | 48 +++++++++++++++++++------- src/backend/RISCv64/RISCv64ISel.cpp | 5 +++ 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/backend/RISCv64/RISCv64Backend.cpp b/src/backend/RISCv64/RISCv64Backend.cpp index c32af0c..2a99b72 100644 --- a/src/backend/RISCv64/RISCv64Backend.cpp +++ b/src/backend/RISCv64/RISCv64Backend.cpp @@ -16,7 +16,7 @@ std::string RISCv64CodeGen::code_gen() { std::string RISCv64CodeGen::module_gen() { std::stringstream ss; - // --- [新逻辑] 步骤1:将全局变量分为.data和.bss两组 --- + // --- 步骤1:将全局变量(GlobalValue)分为.data和.bss两组 --- std::vector data_globals; std::vector bss_globals; @@ -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) { @@ -42,33 +41,56 @@ std::string RISCv64CodeGen::module_gen() { } } - // --- [新逻辑] 步骤2:生成 .bss 段的代码 --- + // --- 步骤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"; } } - // --- [旧逻辑保留] 步骤3:生成 .data 段的代码 --- - if (!data_globals.empty()) { - ss << ".data\n"; // 切换到 .data 段 + // --- [修改] 步骤3:生成 .data 段的代码 --- + // 我们需要检查 data_globals 和 常量列表是否都为空 + if (!data_globals.empty() || !module->getConsts().empty()) { + ss << ".data\n"; + + // a. 先处理普通的全局变量 (GlobalValue) for (GlobalValue* global : data_globals) { ss << ".globl " << global->getName() << "\n"; ss << global->getName() << ":\n"; const auto& init_values = global->getInitValues(); - // 使用您原有的逻辑来处理显式初始化的值 + 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"; + } + } + } + } + } + + // 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]; diff --git a/src/backend/RISCv64/RISCv64ISel.cpp b/src/backend/RISCv64/RISCv64ISel.cpp index 01e9bb6..a6efc09 100644 --- a/src/backend/RISCv64/RISCv64ISel.cpp +++ b/src/backend/RISCv64/RISCv64ISel.cpp @@ -862,6 +862,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);