diff --git a/src/backend/RISCv64/RISCv64ISel.cpp b/src/backend/RISCv64/RISCv64ISel.cpp index 4e42081..b5686ca 100644 --- a/src/backend/RISCv64/RISCv64ISel.cpp +++ b/src/backend/RISCv64/RISCv64ISel.cpp @@ -1201,30 +1201,54 @@ RISCv64ISel::DAGNode* RISCv64ISel::create_node(int kind_int, Value* val, std::ma return raw_node_ptr; } -RISCv64ISel::DAGNode* RISCv64ISel::get_operand_node(Value* val_ir, std::map& value_to_node, std::vector>& nodes_storage) { +RISCv64ISel::DAGNode* RISCv64ISel::get_operand_node( + Value* val_ir, + std::map& value_to_node, + std::vector>& nodes_storage +) { + // 空指针错误处理 + if (val_ir == nullptr) { + throw std::runtime_error("get_operand_node received a null Value."); + } + // 规则1:如果这个Value已经有对应的节点,直接返回 if (value_to_node.count(val_ir)) { return value_to_node[val_ir]; - } else if (auto const_val = dynamic_cast(val_ir)) { + } + if (auto const_val = dynamic_cast(val_ir)) { if (const_val->isInt()) { return create_node(DAGNode::CONSTANT, val_ir, value_to_node, nodes_storage); } else { // 为浮点常量创建新的FP_CONSTANT节点 return create_node(DAGNode::FP_CONSTANT, val_ir, value_to_node, nodes_storage); } - } else if (dynamic_cast(val_ir)) { + } + if (dynamic_cast(val_ir)) { return create_node(DAGNode::CONSTANT, val_ir, value_to_node, nodes_storage); - } else if (dynamic_cast(val_ir)) { + } + if (dynamic_cast(val_ir)) { return create_node(DAGNode::ALLOCA_ADDR, val_ir, value_to_node, nodes_storage); - } else if (dynamic_cast(val_ir)) { - // Argument 是一个叶子节点,它代表一个在函数入口就可用的值。 + } + if (dynamic_cast(val_ir)) { 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); + if (dynamic_cast(val_ir)) { + // 全局常量数组和全局变量类似,在指令选择层面都表现为一个常量地址 + // 因此也为它创建一个 CONSTANT 类型的节点 + return create_node(DAGNode::CONSTANT, val_ir, value_to_node, nodes_storage); + } + // 如果代码执行到这里,意味着val_ir不是上述任何一种叶子节点, + // 且它也不是在当前基本块中定义的(否则它会在value_to_node中被找到)。 + // 这说明它是一个来自前驱块的Live-In值。 + + // 我们将其视为一个与函数参数(Argument)类似的“块输入值”,并为它创建一个ARGUMENT节点。 + // 这样,后续的指令选择逻辑就知道这个值是直接可用的,无需在当前块内计算。 + if (dynamic_cast(val_ir)) { + return create_node(DAGNode::ARGUMENT, val_ir, value_to_node, nodes_storage); + } + + // 如果一个Value不是任何已知类型,也不是指令,那说明出现了未处理的情况,抛出异常。 + throw std::runtime_error("Unhandled Value type in get_operand_node for value named: " + val_ir->getName()); } std::vector> RISCv64ISel::build_dag(BasicBlock* bb) { @@ -1396,6 +1420,7 @@ void RISCv64ISel::print_dag(const std::vector>& dag, co case DAGNode::ALLOCA_ADDR: return "ALLOCA_ADDR"; case DAGNode::UNARY: return "UNARY"; case DAGNode::MEMSET: return "MEMSET"; + case DAGNode::GET_ELEMENT_PTR: return "GET_ELEMENT_PTR"; default: return "UNKNOWN"; } }; diff --git a/src/include/midend/IR.h b/src/include/midend/IR.h index 6d21f04..8828a79 100644 --- a/src/include/midend/IR.h +++ b/src/include/midend/IR.h @@ -359,12 +359,25 @@ public: // Helper methods to access constant values with appropriate casting int getInt() const { - assert(getType()->isInt() && "Calling getInt() on non-integer type"); - return std::get(getVal()); + auto val = getVal(); + if (std::holds_alternative(val)) { + return std::get(val); + } else if (std::holds_alternative(val)) { + return static_cast(std::get(val)); + } + // Handle other possible types if needed + return 0; // Default fallback } + float getFloat() const { - assert(getType()->isFloat() && "Calling getFloat() on non-float type"); - return std::get(getVal()); + auto val = getVal(); + if (std::holds_alternative(val)) { + return std::get(val); + } else if (std::holds_alternative(val)) { + return static_cast(std::get(val)); + } + // Handle other possible types if needed + return 0.0f; // Default fallback } template