[backend] debugging array

This commit is contained in:
Lixuanwang
2025-06-25 17:07:37 +08:00
parent 44fb098aff
commit 019cb6dc0d
2 changed files with 126 additions and 147 deletions

View File

@ -325,46 +325,68 @@ std::string RISCv64CodeGen::basicBlock_gen(BasicBlock* bb, const RegAllocResult&
return ss.str();
}
// 辅助函数,用于创建 DAGNode 并管理其所有权
sysy::RISCv64CodeGen::DAGNode* sysy::RISCv64CodeGen::create_node(
DAGNode::NodeKind kind,
Value* val,
std::map<Value*, DAGNode*>& value_to_node, // 需要外部传入
std::vector<std::unique_ptr<DAGNode>>& nodes_storage // 需要外部传入
) {
// 优化:如果一个值已经有节点并且它不是控制流/存储/Alloca地址/一元操作,则重用它 (CSE)
// 对于 AllocaInst我们想创建一个代表其地址的节点但不一定直接为 AllocaInst 本身分配虚拟寄存器。
if (val && value_to_node.count(val) && kind != DAGNode::STORE && kind != DAGNode::RETURN && kind != DAGNode::BRANCH && kind != DAGNode::ALLOCA_ADDR && kind != DAGNode::UNARY) {
return value_to_node[val];
}
auto node = std::make_unique<DAGNode>(kind);
node->value = val;
// 为产生结果的值分配虚拟寄存器
if (val && value_vreg_map.count(val) && !dynamic_cast<AllocaInst*>(val)) { // 排除 AllocaInst
node->result_vreg = value_vreg_map.at(val);
}
DAGNode* raw_node_ptr = node.get();
nodes_storage.push_back(std::move(node)); // 存储 unique_ptr
// 仅当 IR Value 表示一个计算值时,才将其映射到创建的 DAGNode
// 且它应该已经在 register_allocation 中被分配了 vreg
if (val && value_vreg_map.count(val) && kind != DAGNode::STORE && kind != DAGNode::RETURN && kind != DAGNode::BRANCH && !dynamic_cast<AllocaInst*>(val)) {
value_to_node[val] = raw_node_ptr;
}
return raw_node_ptr;
}
// 辅助函数:获取值的 DAG 节点。
// 如果 value 已经映射到 DAG 节点,则直接返回。
// 如果是常量,则创建 CONSTANT 节点。
// 如果是 AllocaInst则创建 ALLOCA_ADDR 节点。
// 否则,假定需要通过 LOAD 获取该值。
sysy::RISCv64CodeGen::DAGNode* sysy::RISCv64CodeGen::get_operand_node(
Value* val_ir,
std::map<Value*, DAGNode*>& value_to_node, // 接受 value_to_node
std::vector<std::unique_ptr<DAGNode>>& nodes_storage // 接受 nodes_storage
) {
if (value_to_node.count(val_ir)) {
return value_to_node[val_ir];
} else if (auto constant = dynamic_cast<ConstantValue*>(val_ir)) {
return create_node(DAGNode::CONSTANT, constant, value_to_node, nodes_storage); // 调用成员函数版 create_node
} else if (auto alloca = dynamic_cast<AllocaInst*>(val_ir)) {
return create_node(DAGNode::ALLOCA_ADDR, alloca, value_to_node, nodes_storage); // 调用成员函数版 create_node
} else if (auto global = dynamic_cast<GlobalValue*>(val_ir)) {
// 确保 GlobalValue 也能正确处理,如果 DAGNode::CONSTANT 无法存储 GlobalValue*
// 则需要新的 DAGNode 类型,例如 DAGNode::GLOBAL_ADDR
return create_node(DAGNode::CONSTANT, global, value_to_node, nodes_storage); // 调用成员函数版 create_node
}
// 这是一个尚未在此块中计算的值,假设它需要加载 (从内存或参数)
return create_node(DAGNode::LOAD, val_ir, value_to_node, nodes_storage); // 调用成员函数版 create_node
}
std::vector<std::unique_ptr<RISCv64CodeGen::DAGNode>> RISCv64CodeGen::build_dag(BasicBlock* bb) {
std::vector<std::unique_ptr<DAGNode>> nodes_storage; // 存储所有 unique_ptr
std::map<Value*, DAGNode*> value_to_node; // 将 IR Value* 映射到原始 DAGNode*,用于快速查找
// 辅助函数,用于创建 DAGNode 并管理其所有权
auto create_node = [&](DAGNode::NodeKind kind, Value* val = nullptr) -> DAGNode* {
// 优化:如果一个值已经有节点并且它不是控制流/存储/Alloca地址/一元操作,则重用它 (CSE)
// 对于 AllocaInst我们想创建一个代表其地址的节点但不一定直接为 AllocaInst 本身分配虚拟寄存器。
if (val && value_to_node.count(val) && kind != DAGNode::STORE && kind != DAGNode::RETURN && kind != DAGNode::BRANCH && kind != DAGNode::ALLOCA_ADDR && kind != DAGNode::UNARY) {
return value_to_node[val];
}
auto node = std::make_unique<DAGNode>(kind);
node->value = val;
// 为产生结果的值分配虚拟寄存器
// 注意这里的vreg分配是在每个块中独立进行的但寄存器分配器是在函数级别运行的
// 我们在寄存器分配前已经为整个函数的所有value预分配了vreg
// 此处的逻辑应完全依赖于 register_allocation 阶段已经建立的 value_vreg_map
// 并且 AllocaInst 不应在此处获取 result_vreg因为它不映射到物理寄存器。
if (val && value_vreg_map.count(val) && !dynamic_cast<AllocaInst*>(val)) { // 排除 AllocaInst
node->result_vreg = value_vreg_map.at(val);
}
// 如果 val 即使在 value_vreg_map 中存在,但它是 AllocaInst则不分配 result_vreg。
// 对于 DAGNode::ALLOCA_ADDR 节点,它的 result_vreg 应该为空,因为其“值”是内存地址,
// 在指令选择时直接转换为 s0 + 偏移量。
DAGNode* raw_node_ptr = node.get();
nodes_storage.push_back(std::move(node)); // 存储 unique_ptr
// 仅当 IR Value 表示一个计算值时,才将其映射到创建的 DAGNode
// 且它应该已经在 register_allocation 中被分配了 vreg
if (val && value_vreg_map.count(val) && kind != DAGNode::STORE && kind != DAGNode::RETURN && kind != DAGNode::BRANCH && !dynamic_cast<AllocaInst*>(val)) {
value_to_node[val] = raw_node_ptr;
}
return raw_node_ptr;
};
for (const auto& inst_ptr : bb->getInstructions()) {
auto inst = inst_ptr.get();
@ -375,194 +397,134 @@ std::vector<std::unique_ptr<RISCv64CodeGen::DAGNode>> RISCv64CodeGen::build_dag(
// 我们将 AllocaInst 指针存储在 DAGNode 的 `value` 字段中。
// 修正AllocaInst 类型的 DAGNode 应该有一个 value 对应 AllocaInst*
// 但它本身不应该有 result_vreg因为不映射到物理寄存器。
create_node(DAGNode::ALLOCA_ADDR, alloca);
create_node(DAGNode::ALLOCA_ADDR, alloca, value_to_node, nodes_storage);
} else if (auto store = dynamic_cast<StoreInst*>(inst)) {
auto store_node = create_node(DAGNode::STORE, store); // 将 store inst 绑定到 node
auto store_node = create_node(DAGNode::STORE, store, value_to_node, nodes_storage); // 调用成员函数版 create_node
// 获取要存储的值
Value* val_to_store_ir = store->getValue();
DAGNode* val_node = nullptr;
if (value_to_node.count(val_to_store_ir)) {
val_node = value_to_node[val_to_store_ir];
} else if (auto constant = dynamic_cast<ConstantValue*>(val_to_store_ir)) {
val_node = create_node(DAGNode::CONSTANT, constant);
} else { // 这是一个尚未在此块中计算的值,假设它需要加载 (从内存或参数)
val_node = create_node(DAGNode::LOAD, val_to_store_ir);
}
DAGNode* val_node = get_operand_node(store->getValue(), value_to_node, nodes_storage); // 传递参数
// 获取内存位置的指针
// 获取内存位置的指针 (基地址)
Value* ptr_ir = store->getPointer();
DAGNode* ptr_node = nullptr;
if (value_to_node.count(ptr_ir)) {
ptr_node = value_to_node[ptr_ir];
} else if (auto alloca = dynamic_cast<AllocaInst*>(ptr_ir)) {
// 如果是alloca我们应该找到代表它地址的节点
// 为了简化,如果没找到,就创建一个
// 修正AllocaInst 应该直接映射到 ALLOCA_ADDR 节点,其值是 AllocaInst*
ptr_node = create_node(DAGNode::ALLOCA_ADDR, alloca);
} else if (auto global = dynamic_cast<GlobalValue*>(ptr_ir)) {
ptr_node = create_node(DAGNode::CONSTANT, global); // 全局地址将被加载
} else { // 必须是存储在虚拟寄存器中的指针
ptr_node = create_node(DAGNode::LOAD, ptr_ir); // 这是一个产生指针的指令
}
DAGNode* ptr_node = get_operand_node(ptr_ir, value_to_node, nodes_storage); // 传递参数
store_node->operands.push_back(val_node);
store_node->operands.push_back(ptr_node);
val_node->users.push_back(store_node);
ptr_node->users.push_back(store_node);
} else if (auto load = dynamic_cast<LoadInst*>(inst)) {
if (value_to_node.count(load)) continue; // 共同子表达式消除 (CSE)
auto load_node = create_node(DAGNode::LOAD, load); // 为 load_node 分配 result_vreg 并映射 load
Value* ptr_ir = load->getPointer();
DAGNode* ptr_node = nullptr;
if (value_to_node.count(ptr_ir)) {
ptr_node = value_to_node[ptr_ir];
} else if (auto alloca = dynamic_cast<AllocaInst*>(ptr_ir)) {
// 修正AllocaInst 应该直接映射到 ALLOCA_ADDR 节点
ptr_node = create_node(DAGNode::ALLOCA_ADDR, alloca);
} else if (auto global = dynamic_cast<GlobalValue*>(ptr_ir)) {
ptr_node = create_node(DAGNode::CONSTANT, global); // 全局地址将被加载
} else { // 必须是存储在虚拟寄存器中的指针
ptr_node = create_node(DAGNode::LOAD, ptr_ir); // 这是一个产生指针的指令
// !!! 新增:处理 StoreInst 的 indices
for (int i = 0; i < store->getNumIndices(); ++i) {
Value* index_ir = store->getIndex(i);
DAGNode* index_node = get_operand_node(index_ir, value_to_node, nodes_storage); // 传递参数
store_node->operands.push_back(index_node);
index_node->users.push_back(store_node);
}
} else if (auto load = dynamic_cast<LoadInst*>(inst)) {
auto load_node = create_node(DAGNode::LOAD, load, value_to_node, nodes_storage); // 调用成员函数版 create_node
// 获取内存位置的指针 (基地址)
Value* ptr_ir = load->getPointer();
DAGNode* ptr_node = get_operand_node(ptr_ir, value_to_node, nodes_storage); // 传递参数
load_node->operands.push_back(ptr_node);
ptr_node->users.push_back(load_node);
// !!! 新增:处理 LoadInst 的 indices
for (int i = 0; i < load->getNumIndices(); ++i) {
Value* index_ir = load->getIndex(i);
DAGNode* index_node = get_operand_node(index_ir, value_to_node, nodes_storage); // 传递参数
load_node->operands.push_back(index_node);
index_node->users.push_back(load_node);
}
// 关联 load_node 的结果到 value_to_node
value_to_node[load] = load_node; // 这里的 value_to_node 是局部变量OK
} else if (auto bin = dynamic_cast<BinaryInst*>(inst)) {
if (value_to_node.count(bin)) continue; // CSE
// --- 关键修改:识别 SUB 0, X 或 FSUB 0.0, X 模式为 NEG ---
if (bin->getKind() == BinaryInst::kSub || bin->getKind() == BinaryInst::kFSub) {
Value* lhs_ir = bin->getLhs();
if (auto const_lhs = dynamic_cast<ConstantValue*>(lhs_ir)) { // 修正:使用 ConstantValue
if (auto const_lhs = dynamic_cast<ConstantValue*>(lhs_ir)) {
bool is_neg = false;
if (const_lhs->getType()->isInt()) { // 整数类型
if (const_lhs->getType()->isInt()) {
if (const_lhs->getInt() == 0) {
is_neg = true;
}
} else if (const_lhs->getType()->isFloat()) { // 浮点类型
// 浮点数零的比较需要考虑精度使用一个小的epsilon
} else if (const_lhs->getType()->isFloat()) {
if (std::fabs(const_lhs->getFloat()) < std::numeric_limits<float>::epsilon()) {
is_neg = true;
}
}
if (is_neg) {
// 这是一个 neg 操作 (0 - X 或 0.0 - X)
auto unary_node = create_node(DAGNode::UNARY, bin); // 绑定到原 BinaryInst但类型是 UNARY
Value* operand_ir = bin->getRhs(); // 右操作数是实际被 neg 的值
DAGNode* operand_node = nullptr;
if (value_to_node.count(operand_ir)) {
operand_node = value_to_node[operand_ir];
} else if (auto constant = dynamic_cast<ConstantValue*>(operand_ir)) {
operand_node = create_node(DAGNode::CONSTANT, constant);
} else {
operand_node = create_node(DAGNode::LOAD, operand_ir);
}
auto unary_node = create_node(DAGNode::UNARY, bin, value_to_node, nodes_storage); // 传递参数
Value* operand_ir = bin->getRhs();
DAGNode* operand_node = get_operand_node(operand_ir, value_to_node, nodes_storage); // 传递参数
unary_node->operands.push_back(operand_node);
operand_node->users.push_back(unary_node);
continue; // 已处理,跳过后续的常规 Binary 处理
continue;
}
}
}
// --- 结束关键修改 ---
// 常规二进制操作
auto bin_node = create_node(DAGNode::BINARY, bin);
auto bin_node = create_node(DAGNode::BINARY, bin, value_to_node, nodes_storage); // 传递参数
auto get_operand_node = [&](Value* operand_ir) -> DAGNode* {
if (value_to_node.count(operand_ir)) {
return value_to_node[operand_ir];
} else if (auto constant = dynamic_cast<ConstantValue*>(operand_ir)) {
return create_node(DAGNode::CONSTANT, constant);
} else {
// 这是一个由另一个指令或参数产生的值,如果不在 map 中,则假设需要加载
return create_node(DAGNode::LOAD, operand_ir);
}
};
// !!! 移除 lambda 版本的 get_operand_node现在调用成员函数版本 !!!
// auto get_operand_node = [&](Value* operand_ir) -> DAGNode* { ... };
DAGNode* lhs_node = get_operand_node(bin->getLhs());
DAGNode* rhs_node = get_operand_node(bin->getRhs());
DAGNode* lhs_node = get_operand_node(bin->getLhs(), value_to_node, nodes_storage); // 传递参数
DAGNode* rhs_node = get_operand_node(bin->getRhs(), value_to_node, nodes_storage); // 传递参数
bin_node->operands.push_back(lhs_node);
bin_node->operands.push_back(rhs_node);
lhs_node->users.push_back(bin_node);
rhs_node->users.push_back(bin_node);
} else if (auto un_inst = dynamic_cast<UnaryInst*>(inst)) { // 处理一元指令
if (value_to_node.count(un_inst)) continue; // CSE
} else if (auto un_inst = dynamic_cast<UnaryInst*>(inst)) {
if (value_to_node.count(un_inst)) continue;
auto unary_node = create_node(DAGNode::UNARY, un_inst); // 为 unary_node 分配 result_vreg 并映射 un_inst
auto unary_node = create_node(DAGNode::UNARY, un_inst, value_to_node, nodes_storage); // 传递参数
// 修正UnaryInst::getOperand() 不接受参数
Value* operand_ir = un_inst->getOperand();
DAGNode* operand_node = nullptr;
if (value_to_node.count(operand_ir)) {
operand_node = value_to_node[operand_ir];
} else if (auto constant = dynamic_cast<ConstantValue*>(operand_ir)) {
operand_node = create_node(DAGNode::CONSTANT, constant);
} else {
operand_node = create_node(DAGNode::LOAD, operand_ir);
}
DAGNode* operand_node = get_operand_node(operand_ir, value_to_node, nodes_storage); // 传递参数
unary_node->operands.push_back(operand_node);
operand_node->users.push_back(unary_node);
} else if (auto call = dynamic_cast<CallInst*>(inst)) {
if (value_to_node.count(call)) continue; // CSE (如果结果被重用)
if (value_to_node.count(call)) continue;
auto call_node = create_node(DAGNode::CALL, call); // 如果调用返回一个值,则分配 result_vreg
auto call_node = create_node(DAGNode::CALL, call, value_to_node, nodes_storage); // 传递参数
for (auto arg : call->getArguments()) {
auto arg_val_ir = arg->getValue();
DAGNode* arg_node = nullptr;
if (value_to_node.count(arg_val_ir)) {
arg_node = value_to_node[arg_val_ir];
} else if (auto constant = dynamic_cast<ConstantValue*>(arg_val_ir)) {
arg_node = create_node(DAGNode::CONSTANT, constant);
} else {
arg_node = create_node(DAGNode::LOAD, arg_val_ir);
}
DAGNode* arg_node = get_operand_node(arg_val_ir, value_to_node, nodes_storage); // 传递参数
call_node->operands.push_back(arg_node);
arg_node->users.push_back(call_node);
}
} else if (auto ret = dynamic_cast<ReturnInst*>(inst)) {
auto ret_node = create_node(DAGNode::RETURN, ret); // 将 return inst 绑定到 node
auto ret_node = create_node(DAGNode::RETURN, ret, value_to_node, nodes_storage); // 传递参数
if (ret->hasReturnValue()) {
auto val_ir = ret->getReturnValue();
DAGNode* val_node = nullptr;
if (value_to_node.count(val_ir)) {
val_node = value_to_node[val_ir];
} else if (auto constant = dynamic_cast<ConstantValue*>(val_ir)) {
val_node = create_node(DAGNode::CONSTANT, constant);
} else {
val_node = create_node(DAGNode::LOAD, val_ir);
}
DAGNode* val_node = get_operand_node(val_ir, value_to_node, nodes_storage); // 传递参数
ret_node->operands.push_back(val_node);
val_node->users.push_back(ret_node);
}
} else if (auto cond_br = dynamic_cast<CondBrInst*>(inst)) {
auto br_node = create_node(DAGNode::BRANCH, cond_br); // 将 cond_br inst 绑定到 node
auto br_node = create_node(DAGNode::BRANCH, cond_br, value_to_node, nodes_storage); // 传递参数
auto cond_ir = cond_br->getCondition();
if (auto constant_cond = dynamic_cast<ConstantValue*>(cond_ir)) {
// 优化常量条件分支为无条件跳转
br_node->inst = "j " + (constant_cond->getInt() ? cond_br->getThenBlock()->getName() : cond_br->getElseBlock()->getName());
// 对于直接跳转,不需要操作数
} else {
DAGNode* cond_node = nullptr;
if (value_to_node.count(cond_ir)) {
cond_node = value_to_node[cond_ir];
} else if (auto bin_cond = dynamic_cast<BinaryInst*>(cond_ir)) {
cond_node = create_node(DAGNode::BINARY, bin_cond);
} else { // 必须是一个需要加载的值
cond_node = create_node(DAGNode::LOAD, cond_ir);
}
DAGNode* cond_node = get_operand_node(cond_ir, value_to_node, nodes_storage); // 传递参数
br_node->operands.push_back(cond_node);
cond_node->users.push_back(br_node);
}
} else if (auto uncond_br = dynamic_cast<UncondBrInst*>(inst)) {
auto br_node = create_node(DAGNode::BRANCH, uncond_br); // 将 uncond_br inst 绑定到 node
auto br_node = create_node(DAGNode::BRANCH, uncond_br, value_to_node, nodes_storage); // 传递参数
br_node->inst = "j " + uncond_br->getBlock()->getName();
}
}

View File

@ -93,6 +93,23 @@ private:
// 为空标签定义一个伪名称前缀,加上块索引以确保唯一性
const std::string ENTRY_BLOCK_PSEUDO_NAME = "entry_block_";
// !!! 修改get_operand_node 辅助函数现在需要传入 value_to_node 和 nodes_storage 的引用
// 因为它们是 build_dag 局部管理的
DAGNode* get_operand_node(
Value* val_ir,
std::map<Value*, DAGNode*>& value_to_node,
std::vector<std::unique_ptr<DAGNode>>& nodes_storage
);
// !!! 新增create_node 辅助函数也需要传入 value_to_node 和 nodes_storage 的引用
// 并且它应该不再是 lambda而是一个真正的成员函数
DAGNode* create_node(
DAGNode::NodeKind kind,
Value* val,
std::map<Value*, DAGNode*>& value_to_node,
std::vector<std::unique_ptr<DAGNode>>& nodes_storage
);
};
} // namespace sysy