[midend][backend]添加了DAG中的Argument类型,添加了Argument节点的处理逻辑
This commit is contained in:
@@ -10,7 +10,7 @@ namespace sysy {
|
|||||||
|
|
||||||
// DAG节点定义 (内部实现)
|
// DAG节点定义 (内部实现)
|
||||||
struct RISCv64ISel::DAGNode {
|
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;
|
NodeKind kind;
|
||||||
Value* value = nullptr;
|
Value* value = nullptr;
|
||||||
std::vector<DAGNode*> operands;
|
std::vector<DAGNode*> operands;
|
||||||
@@ -139,10 +139,10 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
// 因此,这里我们只处理当前节点。
|
// 因此,这里我们只处理当前节点。
|
||||||
|
|
||||||
switch (node->kind) {
|
switch (node->kind) {
|
||||||
// [V2优点] 采纳“延迟物化”(Late Materialization)思想。
|
// “延迟物化”(Late Materialization)思想。
|
||||||
// 这两个节点仅作为标记,不直接生成指令。它们的目的是在DAG中保留类型信息。
|
// 这三种节点仅作为标记,不直接生成指令。它们的目的是在DAG中保留类型信息。
|
||||||
// 加载其值的责任,被转移给了使用它们的父节点(如STORE, BINARY等)。
|
// 加载其值的责任,被转移给了使用它们的父节点(如STORE, BINARY等)。
|
||||||
// 这修复了之前版本中“使用未初始化虚拟寄存器”的根本性bug。
|
case DAGNode::ARGUMENT:
|
||||||
case DAGNode::CONSTANT:
|
case DAGNode::CONSTANT:
|
||||||
case DAGNode::ALLOCA_ADDR:
|
case DAGNode::ALLOCA_ADDR:
|
||||||
if (node->value) {
|
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) {
|
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)) {
|
if (value_to_node.count(val_ir)) {
|
||||||
return value_to_node[val_ir];
|
return value_to_node[val_ir];
|
||||||
} else if (dynamic_cast<ConstantValue*>(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);
|
return create_node(DAGNode::CONSTANT, val_ir, value_to_node, nodes_storage);
|
||||||
} else if (dynamic_cast<AllocaInst*>(val_ir)) {
|
} else if (dynamic_cast<AllocaInst*>(val_ir)) {
|
||||||
return create_node(DAGNode::ALLOCA_ADDR, val_ir, value_to_node, nodes_storage);
|
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);
|
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枚举转换为字符串的辅助函数
|
// 将NodeKind枚举转换为字符串的辅助函数
|
||||||
auto get_kind_string = [](DAGNode::NodeKind kind) {
|
auto get_kind_string = [](DAGNode::NodeKind kind) {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
|
case DAGNode::ARGUMENT: return "ARGUMENT";
|
||||||
case DAGNode::CONSTANT: return "CONSTANT";
|
case DAGNode::CONSTANT: return "CONSTANT";
|
||||||
case DAGNode::LOAD: return "LOAD";
|
case DAGNode::LOAD: return "LOAD";
|
||||||
case DAGNode::STORE: return "STORE";
|
case DAGNode::STORE: return "STORE";
|
||||||
|
|||||||
Reference in New Issue
Block a user