Merge branch 'midend' into backend-float
This commit is contained in:
@ -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*, 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
|
||||
) {
|
||||
// 空指针错误处理
|
||||
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<ConstantValue*>(val_ir)) {
|
||||
}
|
||||
if (auto const_val = dynamic_cast<ConstantValue*>(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<GlobalValue*>(val_ir)) {
|
||||
}
|
||||
if (dynamic_cast<GlobalValue*>(val_ir)) {
|
||||
return create_node(DAGNode::CONSTANT, val_ir, value_to_node, nodes_storage);
|
||||
} else if (dynamic_cast<AllocaInst*>(val_ir)) {
|
||||
}
|
||||
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 是一个叶子节点,它代表一个在函数入口就可用的值。
|
||||
}
|
||||
if (dynamic_cast<Argument*>(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<ConstantVariable*>(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<Instruction*>(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<std::unique_ptr<RISCv64ISel::DAGNode>> RISCv64ISel::build_dag(BasicBlock* bb) {
|
||||
@ -1396,6 +1420,7 @@ void RISCv64ISel::print_dag(const std::vector<std::unique_ptr<DAGNode>>& 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";
|
||||
}
|
||||
};
|
||||
|
||||
@ -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<int>(getVal());
|
||||
auto val = getVal();
|
||||
if (std::holds_alternative<int>(val)) {
|
||||
return std::get<int>(val);
|
||||
} else if (std::holds_alternative<float>(val)) {
|
||||
return static_cast<int>(std::get<float>(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<float>(getVal());
|
||||
auto val = getVal();
|
||||
if (std::holds_alternative<float>(val)) {
|
||||
return std::get<float>(val);
|
||||
} else if (std::holds_alternative<int>(val)) {
|
||||
return static_cast<float>(std::get<int>(val));
|
||||
}
|
||||
// Handle other possible types if needed
|
||||
return 0.0f; // Default fallback
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
Reference in New Issue
Block a user