[midend][backend]添加了DAG中的Argument类型,添加了Argument节点的处理逻辑

This commit is contained in:
Lixuanwang
2025-07-26 16:55:32 +08:00
parent a231267fc5
commit 828515bc2f

View File

@@ -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<DAGNode*> 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*, DAGNode*>& value_to_node, std::vector<std::unique_ptr<DAGNode>>& nodes_storage) {
// 规则1如果这个Value已经有对应的节点直接返回
if (value_to_node.count(val_ir)) {
return value_to_node[val_ir];
} else if (dynamic_cast<ConstantValue*>(val_ir)) {
@@ -951,7 +952,14 @@ RISCv64ISel::DAGNode* RISCv64ISel::get_operand_node(Value* val_ir, std::map<Valu
return create_node(DAGNode::CONSTANT, val_ir, value_to_node, nodes_storage);
} else if (dynamic_cast<AllocaInst*>(val_ir)) {
return create_node(DAGNode::ALLOCA_ADDR, val_ir, value_to_node, nodes_storage);
} else if (dynamic_cast<Argument*>(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<std::unique_ptr<DAGNode>>& 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";