合并backend、backend-IRC到midend
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
#include <stdexcept>
|
||||
#include <set>
|
||||
#include <functional>
|
||||
#include <cmath> // For std::fabs
|
||||
#include <limits> // For std::numeric_limits
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <iostream>
|
||||
|
||||
namespace sysy {
|
||||
@@ -402,7 +402,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
||||
Value* base = nullptr;
|
||||
Value* offset = nullptr;
|
||||
|
||||
// [修改] 扩展基地址的判断,使其可以识别 AllocaInst 或 GlobalValue
|
||||
// 扩展基地址的判断,使其可以识别 AllocaInst 或 GlobalValue
|
||||
if (dynamic_cast<AllocaInst*>(lhs) || dynamic_cast<GlobalValue*>(lhs)) {
|
||||
base = lhs;
|
||||
offset = rhs;
|
||||
@@ -421,7 +421,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
||||
CurMBB->addInstruction(std::move(li));
|
||||
}
|
||||
|
||||
// 2. [修改] 根据基地址的类型,生成不同的指令来获取基地址
|
||||
// 2. 根据基地址的类型,生成不同的指令来获取基地址
|
||||
auto base_addr_vreg = getNewVReg(Type::getIntType()); // 创建一个新的临时vreg来存放基地址
|
||||
|
||||
// 情况一:基地址是局部栈变量
|
||||
@@ -452,7 +452,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
||||
}
|
||||
}
|
||||
|
||||
// [V2优点] 在BINARY节点内部按需加载常量操作数。
|
||||
// 在BINARY节点内部按需加载常量操作数。
|
||||
auto load_val_if_const = [&](Value* val) {
|
||||
if (auto c = dynamic_cast<ConstantValue*>(val)) {
|
||||
if (DEBUG) {
|
||||
@@ -483,7 +483,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
||||
auto dest_vreg = getVReg(bin);
|
||||
auto lhs_vreg = getVReg(lhs);
|
||||
|
||||
// [V2优点] 融合 ADDIW 优化。
|
||||
// 融合 ADDIW 优化。
|
||||
if (rhs_is_imm_opt) {
|
||||
auto rhs_const = dynamic_cast<ConstantValue*>(rhs);
|
||||
auto instr = std::make_unique<MachineInstr>(RVOpcodes::ADDIW);
|
||||
@@ -952,7 +952,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
||||
|
||||
// --- 步骤 3: 生成CALL指令 ---
|
||||
auto call_instr = std::make_unique<MachineInstr>(RVOpcodes::CALL);
|
||||
// [协议] 如果函数有返回值,将它的目标虚拟寄存器作为第一个操作数
|
||||
// 如果函数有返回值,将它的目标虚拟寄存器作为第一个操作数
|
||||
if (!call->getType()->isVoid()) {
|
||||
unsigned dest_vreg = getVReg(call);
|
||||
call_instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||
@@ -1029,7 +1029,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
||||
} else {
|
||||
// --- 处理整数/指针返回值 ---
|
||||
// 返回值需要被放入 a0
|
||||
// [V2优点] 在RETURN节点内加载常量返回值
|
||||
// 在RETURN节点内加载常量返回值
|
||||
if (auto const_val = dynamic_cast<ConstantValue*>(ret_val)) {
|
||||
auto li_instr = std::make_unique<MachineInstr>(RVOpcodes::LI);
|
||||
li_instr->addOperand(std::make_unique<RegOperand>(PhysicalReg::A0));
|
||||
@@ -1043,7 +1043,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// [V1设计保留] 函数尾声(epilogue)不由RETURN节点生成,
|
||||
// 函数尾声(epilogue)不由RETURN节点生成,
|
||||
// 而是由后续的AsmPrinter或其它Pass统一处理,这是一种常见且有效的模块化设计。
|
||||
auto ret_mi = std::make_unique<MachineInstr>(RVOpcodes::RET);
|
||||
CurMBB->addInstruction(std::move(ret_mi));
|
||||
@@ -1057,7 +1057,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
||||
auto then_bb_name = cond_br->getThenBlock()->getName();
|
||||
auto else_bb_name = cond_br->getElseBlock()->getName();
|
||||
|
||||
// [优化] 检查分支条件是否为编译期常量
|
||||
// 检查分支条件是否为编译期常量
|
||||
if (auto const_cond = dynamic_cast<ConstantValue*>(condition)) {
|
||||
// 如果条件是常量,直接生成一个无条件跳转J,而不是BNE
|
||||
if (const_cond->getInt() != 0) { // 条件为 true
|
||||
@@ -1072,7 +1072,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
||||
}
|
||||
// 如果条件不是常量,则执行标准流程
|
||||
else {
|
||||
// [修复] 为条件变量生成加载指令(如果它是常量的话,尽管上面已经处理了)
|
||||
// 为条件变量生成加载指令(如果它是常量的话,尽管上面已经处理了)
|
||||
// 这一步是为了逻辑完整,以防有其他类型的常量没有被捕获
|
||||
if (auto const_val = dynamic_cast<ConstantValue*>(condition)) {
|
||||
auto li = std::make_unique<MachineInstr>(RVOpcodes::LI);
|
||||
@@ -1106,7 +1106,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
||||
}
|
||||
|
||||
case DAGNode::MEMSET: {
|
||||
// [V1设计保留] Memset的核心展开逻辑在虚拟寄存器层面是正确的,无需修改。
|
||||
// Memset的核心展开逻辑在虚拟寄存器层面是正确的,无需修改。
|
||||
// 之前的bug是由于其输入(地址、值、大小)的虚拟寄存器未被正确初始化。
|
||||
// 在修复了CONSTANT/ALLOCA_ADDR的加载问题后,此处的逻辑现在可以正常工作。
|
||||
|
||||
@@ -1454,7 +1454,7 @@ std::vector<std::unique_ptr<RISCv64ISel::DAGNode>> RISCv64ISel::build_dag(BasicB
|
||||
|
||||
// 依次添加所有索引作为后续的操作数
|
||||
for (auto index : gep->getIndices()) {
|
||||
// [修复] 从 Use 对象中获取真正的 Value*
|
||||
// 从 Use 对象中获取真正的 Value*
|
||||
gep_node->operands.push_back(get_operand_node(index->getValue(), value_to_node, nodes_storage));
|
||||
}
|
||||
} else if (auto load = dynamic_cast<LoadInst*>(inst)) {
|
||||
@@ -1558,7 +1558,7 @@ unsigned RISCv64ISel::getTypeSizeInBytes(Type* type) {
|
||||
}
|
||||
}
|
||||
|
||||
// [新] 打印DAG图以供调试的辅助函数
|
||||
// 打印DAG图以供调试的辅助函数
|
||||
void RISCv64ISel::print_dag(const std::vector<std::unique_ptr<DAGNode>>& dag, const std::string& bb_name) {
|
||||
// 检查是否有DEBUG宏或者全局变量,避免在非调试模式下打印
|
||||
// if (!DEBUG) return;
|
||||
|
||||
Reference in New Issue
Block a user