[backend]解决了非零数组初始化不正确的问题
This commit is contained in:
@ -238,7 +238,52 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
auto bin = dynamic_cast<BinaryInst*>(node->value);
|
auto bin = dynamic_cast<BinaryInst*>(node->value);
|
||||||
Value* lhs = bin->getLhs();
|
Value* lhs = bin->getLhs();
|
||||||
Value* rhs = bin->getRhs();
|
Value* rhs = bin->getRhs();
|
||||||
|
|
||||||
|
// 检查是否是“基地址+偏移量”的地址计算模式
|
||||||
|
if (bin->getKind() == BinaryInst::kAdd) {
|
||||||
|
Value* base = nullptr;
|
||||||
|
Value* offset = nullptr;
|
||||||
|
|
||||||
|
// 判断哪个是基地址(AllocaInst),哪个是偏移量
|
||||||
|
if (dynamic_cast<AllocaInst*>(lhs)) {
|
||||||
|
base = lhs;
|
||||||
|
offset = rhs;
|
||||||
|
} else if (dynamic_cast<AllocaInst*>(rhs)) {
|
||||||
|
base = rhs;
|
||||||
|
offset = lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果成功匹配到该模式
|
||||||
|
if (base) {
|
||||||
|
// [最终修复]
|
||||||
|
// 1. 先为偏移量加载常量(如果它是常量的话)
|
||||||
|
if (auto const_offset = dynamic_cast<ConstantValue*>(offset)) {
|
||||||
|
auto li = std::make_unique<MachineInstr>(RVOpcodes::LI);
|
||||||
|
li->addOperand(std::make_unique<RegOperand>(getVReg(const_offset)));
|
||||||
|
li->addOperand(std::make_unique<ImmOperand>(const_offset->getInt()));
|
||||||
|
CurMBB->addInstruction(std::move(li));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 使用FRAME_ADDR伪指令来获取基地址
|
||||||
|
auto base_addr_vreg = getNewVReg(); // 创建一个新的临时vreg来存放基地址
|
||||||
|
auto frame_addr_instr = std::make_unique<MachineInstr>(RVOpcodes::FRAME_ADDR);
|
||||||
|
frame_addr_instr->addOperand(std::make_unique<RegOperand>(base_addr_vreg));
|
||||||
|
frame_addr_instr->addOperand(std::make_unique<RegOperand>(getVReg(base)));
|
||||||
|
CurMBB->addInstruction(std::move(frame_addr_instr));
|
||||||
|
|
||||||
|
// 3. 生成真正的add指令,计算最终地址
|
||||||
|
auto final_addr_vreg = getVReg(bin); // 这是整个二元运算的结果vreg
|
||||||
|
auto offset_vreg = getVReg(offset);
|
||||||
|
auto add_instr = std::make_unique<MachineInstr>(RVOpcodes::ADD); // 指针运算是64位
|
||||||
|
add_instr->addOperand(std::make_unique<RegOperand>(final_addr_vreg));
|
||||||
|
add_instr->addOperand(std::make_unique<RegOperand>(base_addr_vreg));
|
||||||
|
add_instr->addOperand(std::make_unique<RegOperand>(offset_vreg));
|
||||||
|
CurMBB->addInstruction(std::move(add_instr));
|
||||||
|
|
||||||
|
return; // 地址计算处理完毕,直接返回
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// [V2优点] 在BINARY节点内部按需加载常量操作数。
|
// [V2优点] 在BINARY节点内部按需加载常量操作数。
|
||||||
auto load_val_if_const = [&](Value* val) {
|
auto load_val_if_const = [&](Value* val) {
|
||||||
if (auto c = dynamic_cast<ConstantValue*>(val)) {
|
if (auto c = dynamic_cast<ConstantValue*>(val)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user