From 828515bc2f612f690d24abdc3b6060a4ab23dea3 Mon Sep 17 00:00:00 2001 From: Lixuanwang Date: Sat, 26 Jul 2025 16:55:32 +0800 Subject: [PATCH] =?UTF-8?q?[midend][backend]=E6=B7=BB=E5=8A=A0=E4=BA=86DAG?= =?UTF-8?q?=E4=B8=AD=E7=9A=84Argument=E7=B1=BB=E5=9E=8B=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=BA=86Argument=E8=8A=82=E7=82=B9=E7=9A=84=E5=A4=84?= =?UTF-8?q?=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/RISCv64ISel.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/RISCv64ISel.cpp b/src/RISCv64ISel.cpp index 6e0b87b..c5a7144 100644 --- a/src/RISCv64ISel.cpp +++ b/src/RISCv64ISel.cpp @@ -10,7 +10,7 @@ namespace sysy { // DAG节点定义 (内部实现) struct RISCv64ISel::DAGNode { - enum NodeKind { CONSTANT, LOAD, STORE, BINARY, CALL, RETURN, BRANCH, ALLOCA_ADDR, UNARY, MEMSET, GET_ELEMENT_PTR}; + enum NodeKind {ARGUMENT, CONSTANT, LOAD, STORE, BINARY, CALL, RETURN, BRANCH, ALLOCA_ADDR, UNARY, MEMSET, GET_ELEMENT_PTR}; NodeKind kind; Value* value = nullptr; std::vector operands; @@ -139,10 +139,10 @@ void RISCv64ISel::selectNode(DAGNode* node) { // 因此,这里我们只处理当前节点。 switch (node->kind) { - // [V2优点] 采纳“延迟物化”(Late Materialization)思想。 - // 这两个节点仅作为标记,不直接生成指令。它们的目的是在DAG中保留类型信息。 + // “延迟物化”(Late Materialization)思想。 + // 这三种节点仅作为标记,不直接生成指令。它们的目的是在DAG中保留类型信息。 // 加载其值的责任,被转移给了使用它们的父节点(如STORE, BINARY等)。 - // 这修复了之前版本中“使用未初始化虚拟寄存器”的根本性bug。 + case DAGNode::ARGUMENT: case DAGNode::CONSTANT: case DAGNode::ALLOCA_ADDR: if (node->value) { @@ -943,6 +943,7 @@ RISCv64ISel::DAGNode* RISCv64ISel::create_node(int kind_int, Value* val, std::ma } RISCv64ISel::DAGNode* RISCv64ISel::get_operand_node(Value* val_ir, std::map& value_to_node, std::vector>& nodes_storage) { + // 规则1:如果这个Value已经有对应的节点,直接返回 if (value_to_node.count(val_ir)) { return value_to_node[val_ir]; } else if (dynamic_cast(val_ir)) { @@ -951,7 +952,14 @@ RISCv64ISel::DAGNode* RISCv64ISel::get_operand_node(Value* val_ir, std::map(val_ir)) { return create_node(DAGNode::ALLOCA_ADDR, val_ir, value_to_node, nodes_storage); + } else if (dynamic_cast(val_ir)) { + // Argument 是一个叶子节点,它代表一个在函数入口就可用的值。 + return create_node(DAGNode::ARGUMENT, val_ir, value_to_node, nodes_storage); } + // 默认行为:如果一个操作数不是上面任何一种叶子节点, + // 并且没有在value_to_node中找到(意味着它不是由另一条指令定义的), + // 这是一个逻辑问题。但为了保持向前兼容,我们暂时保留旧的LOAD行为, + // 尽管在修复Argument后,它不应该再被错误触发。 return create_node(DAGNode::LOAD, val_ir, value_to_node, nodes_storage); } @@ -1091,6 +1099,7 @@ void RISCv64ISel::print_dag(const std::vector>& dag, co // 将NodeKind枚举转换为字符串的辅助函数 auto get_kind_string = [](DAGNode::NodeKind kind) { switch (kind) { + case DAGNode::ARGUMENT: return "ARGUMENT"; case DAGNode::CONSTANT: return "CONSTANT"; case DAGNode::LOAD: return "LOAD"; case DAGNode::STORE: return "STORE";