[backend] debugging array
This commit is contained in:
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user