From bfe218be07583681ad14a8bfb50922ae72fbf0cc Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Sat, 2 Aug 2025 02:33:25 +0800 Subject: [PATCH] =?UTF-8?q?[midend]=E9=9D=9E=E5=85=A80=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E6=95=B0=E7=BB=84=E6=83=85=E5=86=B5=E4=B8=8B=EF=BC=8C?= =?UTF-8?q?=E6=A3=80=E6=9F=A50=E5=88=9D=E5=A7=8B=E5=80=BC=E4=B8=AA?= =?UTF-8?q?=E6=95=B0=EF=BC=8C=E8=B6=85=E8=BF=87=E9=98=88=E5=80=BC=EF=BC=88?= =?UTF-8?q?=E7=9B=AE=E5=89=8D=E4=B8=BA16=EF=BC=89=E5=88=99=E7=94=9F?= =?UTF-8?q?=E6=88=90menset=E5=87=8F=E5=B0=91=E5=A4=A7=E9=87=8Fstore?= =?UTF-8?q?=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/midend/SysYIRGenerator.cpp | 125 ++++++++++++++++++++++++++------- 1 file changed, 98 insertions(+), 27 deletions(-) diff --git a/src/midend/SysYIRGenerator.cpp b/src/midend/SysYIRGenerator.cpp index cd0ac3c..97b25b5 100644 --- a/src/midend/SysYIRGenerator.cpp +++ b/src/midend/SysYIRGenerator.cpp @@ -653,7 +653,44 @@ std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext *ctx) { Value *currentValue = counterValues[k]; unsigned currentRepeatNum = counterNumbers[k]; + // 检查是否是0,并且重复次数足够大(例如 >16),才用 memset + if (ConstantInteger *constInt = dynamic_cast(currentValue)) { + if (constInt->getInt() == 0 && currentRepeatNum >= 16) { // 阈值可调整(如16、32等) + // 计算 memset 的起始地址(基于当前线性偏移量) + std::vector memsetStartIndices; + int tempLinearIndex = linearIndexOffset; + + // 将线性索引转换为多维索引 + for (int dimIdx = dimSizes.size() - 1; dimIdx >= 0; --dimIdx) { + memsetStartIndices.insert(memsetStartIndices.begin(), + ConstantInteger::get(static_cast(tempLinearIndex % dimSizes[dimIdx]))); + tempLinearIndex /= dimSizes[dimIdx]; + } + + // 构造 GEP 计算 memset 的起始地址 + std::vector gepIndicesForMemset; + gepIndicesForMemset.push_back(ConstantInteger::get(0)); // 跳过 alloca 类型 + gepIndicesForMemset.insert(gepIndicesForMemset.end(), memsetStartIndices.begin(), + memsetStartIndices.end()); + + Value *memsetPtr = builder.createGetElementPtrInst(alloca, gepIndicesForMemset); + + // 计算 memset 的字节数 = 元素个数 × 元素大小 + Type *elementType = type;; + uint64_t elementSize = elementType->getSize(); + Value *size = ConstantInteger::get(currentRepeatNum * elementSize); + + // 生成 memset 指令(假设你的 IRBuilder 有 createMemset 方法) + builder.createMemsetInst(memsetPtr, ConstantInteger::get(0), size, ConstantInteger::get(0)); + + // 跳过这些已处理的0 + linearIndexOffset += currentRepeatNum; + continue; // 直接进入下一次循环 + } + } + for (unsigned i = 0; i < currentRepeatNum; ++i) { + // 对于非零值,生成对应的 store 指令 std::vector currentIndices; int tempLinearIndex = linearIndexOffset + i; // 使用偏移量和当前重复次数内的索引 @@ -761,39 +798,73 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) { ConstantInteger::get(0)); } else { - + int linearIndexOffset = 0; // 用于追踪当前处理的线性索引的偏移量 for (int k = 0; k < counterValues.size(); ++k) { - // 当前 Value 的值和重复次数 - Value* currentValue = counterValues[k]; - unsigned currentRepeatNum = counterNumbers[k]; + // 当前 Value 的值和重复次数 + Value *currentValue = counterValues[k]; + unsigned currentRepeatNum = counterNumbers[k]; + // 检查是否是0,并且重复次数足够大(例如 >16),才用 memset + if (ConstantInteger *constInt = dynamic_cast(currentValue)) { + if (constInt->getInt() == 0 && currentRepeatNum >= 16) { // 阈值可调整(如16、32等) + // 计算 memset 的起始地址(基于当前线性偏移量) + std::vector memsetStartIndices; + int tempLinearIndex = linearIndexOffset; - for (unsigned i = 0; i < currentRepeatNum; ++i) { - std::vector currentIndices; - int tempLinearIndex = linearIndexOffset + i; // 使用偏移量和当前重复次数内的索引 + // 将线性索引转换为多维索引 + for (int dimIdx = dimSizes.size() - 1; dimIdx >= 0; --dimIdx) { + memsetStartIndices.insert(memsetStartIndices.begin(), + ConstantInteger::get(static_cast(tempLinearIndex % dimSizes[dimIdx]))); + tempLinearIndex /= dimSizes[dimIdx]; + } - // 将线性索引转换为多维索引 - 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); + // 构造 GEP 计算 memset 的起始地址 + std::vector gepIndicesForMemset; + gepIndicesForMemset.push_back(ConstantInteger::get(0)); // 跳过 alloca 类型 + gepIndicesForMemset.insert(gepIndicesForMemset.end(), memsetStartIndices.begin(), + memsetStartIndices.end()); + + Value *memsetPtr = builder.createGetElementPtrInst(alloca, gepIndicesForMemset); + + // 计算 memset 的字节数 = 元素个数 × 元素大小 + Type *elementType = type; + ; + uint64_t elementSize = elementType->getSize(); + Value *size = ConstantInteger::get(currentRepeatNum * elementSize); + + // 生成 memset 指令(假设你的 IRBuilder 有 createMemset 方法) + builder.createMemsetInst(memsetPtr, ConstantInteger::get(0), size, ConstantInteger::get(0)); + + // 跳过这些已处理的0 + linearIndexOffset += currentRepeatNum; + continue; // 直接进入下一次循环 } - // 更新线性索引偏移量,以便下一次迭代从正确的位置开始 - linearIndexOffset += currentRepeatNum; - } + } + 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; + } } } }