[midend][backend]添加了DAG中的Argument类型,添加了Argument节点的处理逻辑
This commit is contained in:
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user