deploy-20250820-3 #1

Merged
gh0s7 merged 352 commits from deploy-20250820-3 into master 2025-08-20 21:20:33 +08:00
2 changed files with 196 additions and 16 deletions
Showing only changes of commit 2040670f8c - Show all commits

View File

@@ -83,6 +83,10 @@ void RISCv64ISel::selectBasicBlock(BasicBlock* bb) {
CurMBB = bb_map.at(bb);
auto dag = build_dag(bb);
if (DEBUG) { // 使用 DEBUG 宏或变量来控制是否打印
print_dag(dag, bb->getName());
}
std::map<Value*, DAGNode*> value_to_node;
for(const auto& node : dag) {
if (node->value) {
@@ -486,7 +490,9 @@ void RISCv64ISel::selectNode(DAGNode* node) {
case DAGNode::CALL: {
auto call = dynamic_cast<CallInst*>(node->value);
// 处理函数参数放入a0-a7物理寄存器
for (size_t i = 0; i < node->operands.size() && i < 8; ++i) {
size_t num_operands = node->operands.size();
size_t reg_arg_count = std::min(num_operands, (size_t)8);
for (size_t i = 0; i < reg_arg_count; ++i) {
DAGNode* arg_node = node->operands[i];
auto arg_preg = static_cast<PhysicalReg>(static_cast<int>(PhysicalReg::A0) + i);
@@ -505,11 +511,63 @@ void RISCv64ISel::selectNode(DAGNode* node) {
CurMBB->addInstruction(std::move(mv));
}
}
if (num_operands > 8) {
size_t stack_arg_count = num_operands - 8;
int stack_space = stack_arg_count * 8; // RV64中每个参数槽位8字节
// 2a. 在栈上分配空间
auto alloc_instr = std::make_unique<MachineInstr>(RVOpcodes::ADDI);
alloc_instr->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP));
alloc_instr->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP));
alloc_instr->addOperand(std::make_unique<ImmOperand>(-stack_space));
CurMBB->addInstruction(std::move(alloc_instr));
// 2b. 存储每个栈参数
for (size_t i = 8; i < num_operands; ++i) {
DAGNode* arg_node = node->operands[i];
unsigned src_vreg;
// 准备源寄存器
if (arg_node->kind == DAGNode::CONSTANT) {
// 如果是常量,先加载到临时寄存器
src_vreg = getNewVReg();
auto const_val = dynamic_cast<ConstantValue*>(arg_node->value);
auto li = std::make_unique<MachineInstr>(RVOpcodes::LI);
li->addOperand(std::make_unique<RegOperand>(src_vreg));
li->addOperand(std::make_unique<ImmOperand>(const_val->getInt()));
CurMBB->addInstruction(std::move(li));
} else {
src_vreg = getVReg(arg_node->value);
}
// 计算在栈上的偏移量
int offset = (i - 8) * 8;
// 生成 sd 指令
auto sd_instr = std::make_unique<MachineInstr>(RVOpcodes::SD);
sd_instr->addOperand(std::make_unique<RegOperand>(src_vreg));
sd_instr->addOperand(std::make_unique<MemOperand>(
std::make_unique<RegOperand>(PhysicalReg::SP),
std::make_unique<ImmOperand>(offset)
));
CurMBB->addInstruction(std::move(sd_instr));
}
}
auto call_instr = std::make_unique<MachineInstr>(RVOpcodes::CALL);
call_instr->addOperand(std::make_unique<LabelOperand>(call->getCallee()->getName()));
CurMBB->addInstruction(std::move(call_instr));
if (num_operands > 8) {
size_t stack_arg_count = num_operands - 8;
int stack_space = stack_arg_count * 8;
auto dealloc_instr = std::make_unique<MachineInstr>(RVOpcodes::ADDI);
dealloc_instr->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP));
dealloc_instr->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP));
dealloc_instr->addOperand(std::make_unique<ImmOperand>(stack_space));
CurMBB->addInstruction(std::move(dealloc_instr));
}
// 处理返回值从a0移动到目标虚拟寄存器
if (!call->getType()->isVoid()) {
auto mv_instr = std::make_unique<MachineInstr>(RVOpcodes::MV);
@@ -545,33 +603,59 @@ void RISCv64ISel::selectNode(DAGNode* node) {
}
case DAGNode::BRANCH: {
if (auto cond_br = dynamic_cast<CondBrInst*>(node->value)) {
// [V2优点] 采用更健壮的if-then-else分支逻辑。
auto cond_vreg = getVReg(cond_br->getCondition());
auto then_bb_name = cond_br->getThenBlock()->getName();
auto else_bb_name = cond_br->getElseBlock()->getName();
// 处理条件分支
if (auto cond_br = dynamic_cast<CondBrInst*>(node->value)) {
Value* condition = cond_br->getCondition();
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
auto j_instr = std::make_unique<MachineInstr>(RVOpcodes::J);
j_instr->addOperand(std::make_unique<LabelOperand>(then_bb_name));
CurMBB->addInstruction(std::move(j_instr));
} else { // 条件为 false
auto j_instr = std::make_unique<MachineInstr>(RVOpcodes::J);
j_instr->addOperand(std::make_unique<LabelOperand>(else_bb_name));
CurMBB->addInstruction(std::move(j_instr));
}
}
// 如果条件不是常量,则执行标准流程
else {
// [修复] 为条件变量生成加载指令(如果它是常量的话,尽管上面已经处理了)
// 这一步是为了逻辑完整,以防有其他类型的常量没有被捕获
if (auto const_val = dynamic_cast<ConstantValue*>(condition)) {
auto li = std::make_unique<MachineInstr>(RVOpcodes::LI);
li->addOperand(std::make_unique<RegOperand>(getVReg(const_val)));
li->addOperand(std::make_unique<ImmOperand>(const_val->getInt()));
CurMBB->addInstruction(std::move(li));
}
auto cond_vreg = getVReg(condition);
// bne cond, zero, then_label (如果cond不为0则跳转到then)
// 生成 bne cond, zero, then_label (如果cond不为0则跳转到then)
auto br_instr = std::make_unique<MachineInstr>(RVOpcodes::BNE);
br_instr->addOperand(std::make_unique<RegOperand>(cond_vreg));
br_instr->addOperand(std::make_unique<RegOperand>(PhysicalReg::ZERO));
br_instr->addOperand(std::make_unique<LabelOperand>(then_bb_name));
CurMBB->addInstruction(std::move(br_instr));
// 无条件跳转到else块 (如果上面分支未发生)
// 注意在实际的CFG中这个J指令可能不是必须的
// 因为else块可能是下一个块。但为了通用性这里生成它。
// 为else分支生成无条件跳转 (后续Pass可以优化掉不必要的跳转)
auto j_instr = std::make_unique<MachineInstr>(RVOpcodes::J);
j_instr->addOperand(std::make_unique<LabelOperand>(else_bb_name));
CurMBB->addInstruction(std::move(j_instr));
} else if (auto uncond_br = dynamic_cast<UncondBrInst*>(node->value)) {
auto j_instr = std::make_unique<MachineInstr>(RVOpcodes::J);
j_instr->addOperand(std::make_unique<LabelOperand>(uncond_br->getBlock()->getName()));
CurMBB->addInstruction(std::move(j_instr));
}
break;
}
// 处理无条件分支
else if (auto uncond_br = dynamic_cast<UncondBrInst*>(node->value)) {
auto j_instr = std::make_unique<MachineInstr>(RVOpcodes::J);
j_instr->addOperand(std::make_unique<LabelOperand>(uncond_br->getBlock()->getName()));
CurMBB->addInstruction(std::move(j_instr));
}
break;
}
case DAGNode::MEMSET: {
// [V1设计保留] Memset的核心展开逻辑在虚拟寄存器层面是正确的无需修改。
@@ -808,4 +892,98 @@ std::vector<std::unique_ptr<RISCv64ISel::DAGNode>> RISCv64ISel::build_dag(BasicB
return nodes_storage;
}
// [新] 打印DAG图以供调试的辅助函数
void RISCv64ISel::print_dag(const std::vector<std::unique_ptr<DAGNode>>& dag, const std::string& bb_name) {
// 检查是否有DEBUG宏或者全局变量避免在非调试模式下打印
// if (!DEBUG) return;
std::cerr << "=== DAG for Basic Block: " << bb_name << " ===\n";
std::set<DAGNode*> visited;
// 为节点分配临时ID方便阅读
std::map<DAGNode*, int> node_to_id;
int current_id = 0;
for (const auto& node_ptr : dag) {
node_to_id[node_ptr.get()] = current_id++;
}
// 将NodeKind枚举转换为字符串的辅助函数
auto get_kind_string = [](DAGNode::NodeKind kind) {
switch (kind) {
case DAGNode::CONSTANT: return "CONSTANT";
case DAGNode::LOAD: return "LOAD";
case DAGNode::STORE: return "STORE";
case DAGNode::BINARY: return "BINARY";
case DAGNode::CALL: return "CALL";
case DAGNode::RETURN: return "RETURN";
case DAGNode::BRANCH: return "BRANCH";
case DAGNode::ALLOCA_ADDR: return "ALLOCA_ADDR";
case DAGNode::UNARY: return "UNARY";
case DAGNode::MEMSET: return "MEMSET";
default: return "UNKNOWN";
}
};
// 递归打印节点的lambda表达式
std::function<void(DAGNode*, int)> print_node =
[&](DAGNode* node, int indent) {
if (!node) return;
std::string current_indent(indent, ' ');
int node_id = node_to_id.count(node) ? node_to_id[node] : -1;
std::cerr << current_indent << "Node#" << node_id << ": " << get_kind_string(node->kind);
// 尝试打印关联的虚拟寄存器
if (node->value && vreg_map.count(node->value)) {
std::cerr << " (vreg: %vreg" << vreg_map.at(node->value) << ")";
}
// 打印关联的IR Value信息
if (node->value) {
std::cerr << " [";
if (auto inst = dynamic_cast<Instruction*>(node->value)) {
std::cerr << inst->getKindString();
if (!inst->getName().empty()) {
std::cerr << "(" << inst->getName() << ")";
}
} else if (auto constant = dynamic_cast<ConstantValue*>(node->value)) {
std::cerr << "Const(" << constant->getInt() << ")";
} else if (auto global = dynamic_cast<GlobalValue*>(node->value)) {
std::cerr << "Global(" << global->getName() << ")";
} else if (auto alloca = dynamic_cast<AllocaInst*>(node->value)) {
std::cerr << "Alloca(" << alloca->getName() << ")";
}
std::cerr << "]";
}
std::cerr << "\n";
if (visited.count(node)) {
std::cerr << current_indent << " (已打印过子节点)\n";
return;
}
visited.insert(node);
if (!node->operands.empty()) {
std::cerr << current_indent << " Operands:\n";
for (auto operand : node->operands) {
print_node(operand, indent + 4);
}
}
};
// 从根节点(没有用户的节点,或有副作用的节点)开始打印
for (const auto& node_ptr : dag) {
if (node_ptr->users.empty() ||
node_ptr->kind == DAGNode::STORE ||
node_ptr->kind == DAGNode::RETURN ||
node_ptr->kind == DAGNode::BRANCH ||
node_ptr->kind == DAGNode::MEMSET)
{
print_node(node_ptr.get(), 0);
}
}
std::cerr << "======================================\n\n";
}
} // namespace sysy

View File

@@ -34,6 +34,8 @@ private:
DAGNode* get_operand_node(Value* val_ir, std::map<Value*, DAGNode*>&, std::vector<std::unique_ptr<DAGNode>>&);
DAGNode* create_node(int kind, Value* val, std::map<Value*, DAGNode*>&, std::vector<std::unique_ptr<DAGNode>>&);
void print_dag(const std::vector<std::unique_ptr<DAGNode>>& dag, const std::string& bb_name);
// 状态
Function* F; // 当前处理的高层IR函数
std::unique_ptr<MachineFunction> MFunc; // 正在构建的底层LLIR函数