[midend]非全0初始化数组情况下,检查0初始值个数,超过阈值(目前为16)则生成menset减少大量store操作
This commit is contained in:
@ -653,7 +653,44 @@ std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext *ctx) {
|
|||||||
Value *currentValue = counterValues[k];
|
Value *currentValue = counterValues[k];
|
||||||
unsigned currentRepeatNum = counterNumbers[k];
|
unsigned currentRepeatNum = counterNumbers[k];
|
||||||
|
|
||||||
|
// 检查是否是0,并且重复次数足够大(例如 >16),才用 memset
|
||||||
|
if (ConstantInteger *constInt = dynamic_cast<ConstantInteger *>(currentValue)) {
|
||||||
|
if (constInt->getInt() == 0 && currentRepeatNum >= 16) { // 阈值可调整(如16、32等)
|
||||||
|
// 计算 memset 的起始地址(基于当前线性偏移量)
|
||||||
|
std::vector<Value *> memsetStartIndices;
|
||||||
|
int tempLinearIndex = linearIndexOffset;
|
||||||
|
|
||||||
|
// 将线性索引转换为多维索引
|
||||||
|
for (int dimIdx = dimSizes.size() - 1; dimIdx >= 0; --dimIdx) {
|
||||||
|
memsetStartIndices.insert(memsetStartIndices.begin(),
|
||||||
|
ConstantInteger::get(static_cast<int>(tempLinearIndex % dimSizes[dimIdx])));
|
||||||
|
tempLinearIndex /= dimSizes[dimIdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造 GEP 计算 memset 的起始地址
|
||||||
|
std::vector<Value *> 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) {
|
for (unsigned i = 0; i < currentRepeatNum; ++i) {
|
||||||
|
// 对于非零值,生成对应的 store 指令
|
||||||
std::vector<Value *> currentIndices;
|
std::vector<Value *> currentIndices;
|
||||||
int tempLinearIndex = linearIndexOffset + i; // 使用偏移量和当前重复次数内的索引
|
int tempLinearIndex = linearIndexOffset + i; // 使用偏移量和当前重复次数内的索引
|
||||||
|
|
||||||
@ -767,7 +804,42 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) {
|
|||||||
// 当前 Value 的值和重复次数
|
// 当前 Value 的值和重复次数
|
||||||
Value *currentValue = counterValues[k];
|
Value *currentValue = counterValues[k];
|
||||||
unsigned currentRepeatNum = counterNumbers[k];
|
unsigned currentRepeatNum = counterNumbers[k];
|
||||||
|
// 检查是否是0,并且重复次数足够大(例如 >16),才用 memset
|
||||||
|
if (ConstantInteger *constInt = dynamic_cast<ConstantInteger *>(currentValue)) {
|
||||||
|
if (constInt->getInt() == 0 && currentRepeatNum >= 16) { // 阈值可调整(如16、32等)
|
||||||
|
// 计算 memset 的起始地址(基于当前线性偏移量)
|
||||||
|
std::vector<Value *> memsetStartIndices;
|
||||||
|
int tempLinearIndex = linearIndexOffset;
|
||||||
|
|
||||||
|
// 将线性索引转换为多维索引
|
||||||
|
for (int dimIdx = dimSizes.size() - 1; dimIdx >= 0; --dimIdx) {
|
||||||
|
memsetStartIndices.insert(memsetStartIndices.begin(),
|
||||||
|
ConstantInteger::get(static_cast<int>(tempLinearIndex % dimSizes[dimIdx])));
|
||||||
|
tempLinearIndex /= dimSizes[dimIdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造 GEP 计算 memset 的起始地址
|
||||||
|
std::vector<Value *> 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) {
|
for (unsigned i = 0; i < currentRepeatNum; ++i) {
|
||||||
std::vector<Value *> currentIndices;
|
std::vector<Value *> currentIndices;
|
||||||
int tempLinearIndex = linearIndexOffset + i; // 使用偏移量和当前重复次数内的索引
|
int tempLinearIndex = linearIndexOffset + i; // 使用偏移量和当前重复次数内的索引
|
||||||
@ -793,7 +865,6 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) {
|
|||||||
// 更新线性索引偏移量,以便下一次迭代从正确的位置开始
|
// 更新线性索引偏移量,以便下一次迭代从正确的位置开始
|
||||||
linearIndexOffset += currentRepeatNum;
|
linearIndexOffset += currentRepeatNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user