[backend]解决了重构后数组初始化不正确的问题
This commit is contained in:
@@ -18,7 +18,7 @@ bool isMemoryOp(RVOpcodes opcode) {
|
|||||||
|
|
||||||
RISCv64AsmPrinter::RISCv64AsmPrinter(MachineFunction* mfunc) : MFunc(mfunc) {}
|
RISCv64AsmPrinter::RISCv64AsmPrinter(MachineFunction* mfunc) : MFunc(mfunc) {}
|
||||||
|
|
||||||
void RISCv64AsmPrinter::run(std::ostream& os) {
|
void RISCv64AsmPrinter::run(std::ostream& os, bool debug) {
|
||||||
OS = &os;
|
OS = &os;
|
||||||
|
|
||||||
*OS << ".globl " << MFunc->getName() << "\n";
|
*OS << ".globl " << MFunc->getName() << "\n";
|
||||||
@@ -27,7 +27,7 @@ void RISCv64AsmPrinter::run(std::ostream& os) {
|
|||||||
printPrologue();
|
printPrologue();
|
||||||
|
|
||||||
for (auto& mbb : MFunc->getBlocks()) {
|
for (auto& mbb : MFunc->getBlocks()) {
|
||||||
printBasicBlock(mbb.get());
|
printBasicBlock(mbb.get(), debug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,16 +73,16 @@ void RISCv64AsmPrinter::printEpilogue() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RISCv64AsmPrinter::printBasicBlock(MachineBasicBlock* mbb) {
|
void RISCv64AsmPrinter::printBasicBlock(MachineBasicBlock* mbb, bool debug) {
|
||||||
if (!mbb->getName().empty()) {
|
if (!mbb->getName().empty()) {
|
||||||
*OS << mbb->getName() << ":\n";
|
*OS << mbb->getName() << ":\n";
|
||||||
}
|
}
|
||||||
for (auto& instr : mbb->getInstructions()) {
|
for (auto& instr : mbb->getInstructions()) {
|
||||||
printInstruction(instr.get());
|
printInstruction(instr.get(), debug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RISCv64AsmPrinter::printInstruction(MachineInstr* instr) {
|
void RISCv64AsmPrinter::printInstruction(MachineInstr* instr, bool debug) {
|
||||||
auto opcode = instr->getOpcode();
|
auto opcode = instr->getOpcode();
|
||||||
if (opcode == RVOpcodes::RET) {
|
if (opcode == RVOpcodes::RET) {
|
||||||
printEpilogue();
|
printEpilogue();
|
||||||
@@ -137,9 +137,17 @@ void RISCv64AsmPrinter::printInstruction(MachineInstr* instr) {
|
|||||||
// *OS << ":";
|
// *OS << ":";
|
||||||
break;
|
break;
|
||||||
case RVOpcodes::FRAME_LOAD:
|
case RVOpcodes::FRAME_LOAD:
|
||||||
|
// It should have been eliminated by RegAlloc
|
||||||
|
if (!debug) throw std::runtime_error("FRAME pseudo-instruction not eliminated before AsmPrinter");
|
||||||
|
*OS << "frame_load "; break;
|
||||||
case RVOpcodes::FRAME_STORE:
|
case RVOpcodes::FRAME_STORE:
|
||||||
// These should have been eliminated by RegAlloc
|
// It should have been eliminated by RegAlloc
|
||||||
throw std::runtime_error("FRAME pseudo-instruction not eliminated before AsmPrinter");
|
if (!debug) throw std::runtime_error("FRAME pseudo-instruction not eliminated before AsmPrinter");
|
||||||
|
*OS << "frame_store "; break;
|
||||||
|
case RVOpcodes::FRAME_ADDR:
|
||||||
|
// It should have been eliminated by RegAlloc
|
||||||
|
if (!debug) throw std::runtime_error("FRAME pseudo-instruction not eliminated before AsmPrinter");
|
||||||
|
*OS << "frame_addr "; break;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Unknown opcode in AsmPrinter");
|
throw std::runtime_error("Unknown opcode in AsmPrinter");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
|
|||||||
RISCv64ISel isel;
|
RISCv64ISel isel;
|
||||||
std::unique_ptr<MachineFunction> mfunc = isel.runOnFunction(func);
|
std::unique_ptr<MachineFunction> mfunc = isel.runOnFunction(func);
|
||||||
|
|
||||||
|
std::stringstream ss1;
|
||||||
|
RISCv64AsmPrinter printer1(mfunc.get());
|
||||||
|
printer1.run(ss1, true);
|
||||||
|
|
||||||
// 阶段 2: 指令调度 (Instruction Scheduling)
|
// 阶段 2: 指令调度 (Instruction Scheduling)
|
||||||
PreRA_Scheduler scheduler;
|
PreRA_Scheduler scheduler;
|
||||||
scheduler.runOnMachineFunction(mfunc.get());
|
scheduler.runOnMachineFunction(mfunc.get());
|
||||||
@@ -81,7 +85,7 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
RISCv64AsmPrinter printer(mfunc.get());
|
RISCv64AsmPrinter printer(mfunc.get());
|
||||||
printer.run(ss);
|
printer.run(ss);
|
||||||
|
if (DEBUG) ss << ss1.str(); // 将指令选择阶段的结果也包含在最终输出中
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <cmath> // For std::fabs
|
#include <cmath> // For std::fabs
|
||||||
#include <limits> // For std::numeric_limits
|
#include <limits> // For std::numeric_limits
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace sysy {
|
namespace sysy {
|
||||||
|
|
||||||
@@ -92,6 +93,10 @@ void RISCv64ISel::selectBasicBlock(BasicBlock* bb) {
|
|||||||
std::set<DAGNode*> selected_nodes;
|
std::set<DAGNode*> selected_nodes;
|
||||||
std::function<void(DAGNode*)> select_recursive =
|
std::function<void(DAGNode*)> select_recursive =
|
||||||
[&](DAGNode* node) {
|
[&](DAGNode* node) {
|
||||||
|
if (DEEPDEBUG) {
|
||||||
|
std::cout << "[DEEPDEBUG] select_recursive: Visiting node with kind: " << node->kind
|
||||||
|
<< " (Value: " << (node->value ? node->value->getName() : "null") << ")" << std::endl;
|
||||||
|
}
|
||||||
if (!node || selected_nodes.count(node)) return;
|
if (!node || selected_nodes.count(node)) return;
|
||||||
for (auto operand : node->operands) {
|
for (auto operand : node->operands) {
|
||||||
select_recursive(operand);
|
select_recursive(operand);
|
||||||
@@ -118,24 +123,37 @@ void RISCv64ISel::selectBasicBlock(BasicBlock* bb) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 核心函数:为DAG节点选择并生成MachineInstr (忠实移植版)
|
// 核心函数:为DAG节点选择并生成MachineInstr (已修复和增强的完整版本)
|
||||||
void RISCv64ISel::selectNode(DAGNode* node) {
|
void RISCv64ISel::selectNode(DAGNode* node) {
|
||||||
|
// 调用者(select_recursive)已经保证了操作数节点会先于当前节点被选择。
|
||||||
|
// 因此,这里我们只处理当前节点。
|
||||||
|
|
||||||
switch (node->kind) {
|
switch (node->kind) {
|
||||||
|
// [V2优点] 采纳“延迟物化”(Late Materialization)思想。
|
||||||
|
// 这两个节点仅作为标记,不直接生成指令。它们的目的是在DAG中保留类型信息。
|
||||||
|
// 加载其值的责任,被转移给了使用它们的父节点(如STORE, BINARY等)。
|
||||||
|
// 这修复了之前版本中“使用未初始化虚拟寄存器”的根本性bug。
|
||||||
case DAGNode::CONSTANT:
|
case DAGNode::CONSTANT:
|
||||||
case DAGNode::ALLOCA_ADDR:
|
case DAGNode::ALLOCA_ADDR:
|
||||||
if (node->value) getVReg(node->value);
|
if (node->value) {
|
||||||
|
// 确保它有一个关联的虚拟寄存器即可,不生成代码。
|
||||||
|
getVReg(node->value);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DAGNode::LOAD: {
|
case DAGNode::LOAD: {
|
||||||
auto dest_vreg = getVReg(node->value);
|
auto dest_vreg = getVReg(node->value);
|
||||||
Value* ptr_val = node->operands[0]->value;
|
Value* ptr_val = node->operands[0]->value;
|
||||||
|
|
||||||
|
// [V1设计保留] 对于从栈变量加载,继续使用伪指令 FRAME_LOAD。
|
||||||
|
// 这种设计将栈帧布局的具体计算推迟到后续的 `eliminateFrameIndices` 阶段,保持了模块化。
|
||||||
if (auto alloca = dynamic_cast<AllocaInst*>(ptr_val)) {
|
if (auto alloca = dynamic_cast<AllocaInst*>(ptr_val)) {
|
||||||
auto instr = std::make_unique<MachineInstr>(RVOpcodes::FRAME_LOAD);
|
auto instr = std::make_unique<MachineInstr>(RVOpcodes::FRAME_LOAD);
|
||||||
instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||||
instr->addOperand(std::make_unique<RegOperand>(getVReg(alloca)));
|
instr->addOperand(std::make_unique<RegOperand>(getVReg(alloca)));
|
||||||
CurMBB->addInstruction(std::move(instr));
|
CurMBB->addInstruction(std::move(instr));
|
||||||
} else if (auto global = dynamic_cast<GlobalValue*>(ptr_val)) {
|
} else if (auto global = dynamic_cast<GlobalValue*>(ptr_val)) {
|
||||||
|
// 对于全局变量,先用 la 加载其地址,再用 lw 加载其值。
|
||||||
auto addr_vreg = getNewVReg();
|
auto addr_vreg = getNewVReg();
|
||||||
auto la = std::make_unique<MachineInstr>(RVOpcodes::LA);
|
auto la = std::make_unique<MachineInstr>(RVOpcodes::LA);
|
||||||
la->addOperand(std::make_unique<RegOperand>(addr_vreg));
|
la->addOperand(std::make_unique<RegOperand>(addr_vreg));
|
||||||
@@ -150,6 +168,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
));
|
));
|
||||||
CurMBB->addInstruction(std::move(lw));
|
CurMBB->addInstruction(std::move(lw));
|
||||||
} else {
|
} else {
|
||||||
|
// 对于已经在虚拟寄存器中的指针地址,直接通过该地址加载。
|
||||||
auto ptr_vreg = getVReg(ptr_val);
|
auto ptr_vreg = getVReg(ptr_val);
|
||||||
auto lw = std::make_unique<MachineInstr>(RVOpcodes::LW);
|
auto lw = std::make_unique<MachineInstr>(RVOpcodes::LW);
|
||||||
lw->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
lw->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||||
@@ -166,7 +185,13 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
Value* val_to_store = node->operands[0]->value;
|
Value* val_to_store = node->operands[0]->value;
|
||||||
Value* ptr_val = node->operands[1]->value;
|
Value* ptr_val = node->operands[1]->value;
|
||||||
|
|
||||||
|
// [V2优点] 在STORE节点内部负责加载作为源的常量。
|
||||||
|
// 如果要存储的值是一个常量,就在这里生成 `li` 指令加载它。
|
||||||
if (auto val_const = dynamic_cast<ConstantValue*>(val_to_store)) {
|
if (auto val_const = dynamic_cast<ConstantValue*>(val_to_store)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
std::cout << "[DEBUG] selectNode-BINARY: Found constant operand with value " << val_const->getInt()
|
||||||
|
<< ". Generating LI instruction." << std::endl;
|
||||||
|
}
|
||||||
auto li = std::make_unique<MachineInstr>(RVOpcodes::LI);
|
auto li = std::make_unique<MachineInstr>(RVOpcodes::LI);
|
||||||
li->addOperand(std::make_unique<RegOperand>(getVReg(val_const)));
|
li->addOperand(std::make_unique<RegOperand>(getVReg(val_const)));
|
||||||
li->addOperand(std::make_unique<ImmOperand>(val_const->getInt()));
|
li->addOperand(std::make_unique<ImmOperand>(val_const->getInt()));
|
||||||
@@ -174,13 +199,15 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
}
|
}
|
||||||
auto val_vreg = getVReg(val_to_store);
|
auto val_vreg = getVReg(val_to_store);
|
||||||
|
|
||||||
|
// [V1设计保留] 同样,对于向栈变量的存储,使用 FRAME_STORE 伪指令。
|
||||||
if (auto alloca = dynamic_cast<AllocaInst*>(ptr_val)) {
|
if (auto alloca = dynamic_cast<AllocaInst*>(ptr_val)) {
|
||||||
auto instr = std::make_unique<MachineInstr>(RVOpcodes::FRAME_STORE);
|
auto instr = std::make_unique<MachineInstr>(RVOpcodes::FRAME_STORE);
|
||||||
instr->addOperand(std::make_unique<RegOperand>(val_vreg));
|
instr->addOperand(std::make_unique<RegOperand>(val_vreg));
|
||||||
instr->addOperand(std::make_unique<RegOperand>(getVReg(alloca)));
|
instr->addOperand(std::make_unique<RegOperand>(getVReg(alloca)));
|
||||||
CurMBB->addInstruction(std::move(instr));
|
CurMBB->addInstruction(std::move(instr));
|
||||||
} else if (auto global = dynamic_cast<GlobalValue*>(ptr_val)) {
|
} else if (auto global = dynamic_cast<GlobalValue*>(ptr_val)) {
|
||||||
auto addr_vreg = getNewVReg();
|
// 向全局变量存储。
|
||||||
|
auto addr_vreg = getNewVReg();
|
||||||
auto la = std::make_unique<MachineInstr>(RVOpcodes::LA);
|
auto la = std::make_unique<MachineInstr>(RVOpcodes::LA);
|
||||||
la->addOperand(std::make_unique<RegOperand>(addr_vreg));
|
la->addOperand(std::make_unique<RegOperand>(addr_vreg));
|
||||||
la->addOperand(std::make_unique<LabelOperand>(global->getName()));
|
la->addOperand(std::make_unique<LabelOperand>(global->getName()));
|
||||||
@@ -194,6 +221,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
));
|
));
|
||||||
CurMBB->addInstruction(std::move(sw));
|
CurMBB->addInstruction(std::move(sw));
|
||||||
} else {
|
} else {
|
||||||
|
// 向一个指针(存储在虚拟寄存器中)指向的地址存储。
|
||||||
auto ptr_vreg = getVReg(ptr_val);
|
auto ptr_vreg = getVReg(ptr_val);
|
||||||
auto sw = std::make_unique<MachineInstr>(RVOpcodes::SW);
|
auto sw = std::make_unique<MachineInstr>(RVOpcodes::SW);
|
||||||
sw->addOperand(std::make_unique<RegOperand>(val_vreg));
|
sw->addOperand(std::make_unique<RegOperand>(val_vreg));
|
||||||
@@ -211,36 +239,53 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
Value* lhs = bin->getLhs();
|
Value* lhs = bin->getLhs();
|
||||||
Value* rhs = bin->getRhs();
|
Value* rhs = bin->getRhs();
|
||||||
|
|
||||||
|
// [V2优点] 在BINARY节点内部按需加载常量操作数。
|
||||||
auto load_val_if_const = [&](Value* val) {
|
auto load_val_if_const = [&](Value* val) {
|
||||||
if (auto c = dynamic_cast<ConstantValue*>(val)) {
|
if (auto c = dynamic_cast<ConstantValue*>(val)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
std::cout << "[DEBUG] selectNode-BINARY: Found constant operand with value " << c->getInt()
|
||||||
|
<< ". Generating LI instruction." << std::endl;
|
||||||
|
}
|
||||||
auto li = std::make_unique<MachineInstr>(RVOpcodes::LI);
|
auto li = std::make_unique<MachineInstr>(RVOpcodes::LI);
|
||||||
li->addOperand(std::make_unique<RegOperand>(getVReg(c)));
|
li->addOperand(std::make_unique<RegOperand>(getVReg(c)));
|
||||||
li->addOperand(std::make_unique<ImmOperand>(c->getInt()));
|
li->addOperand(std::make_unique<ImmOperand>(c->getInt()));
|
||||||
CurMBB->addInstruction(std::move(li));
|
CurMBB->addInstruction(std::move(li));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
load_val_if_const(lhs);
|
|
||||||
load_val_if_const(rhs);
|
|
||||||
|
|
||||||
auto dest_vreg = getVReg(bin);
|
// 检查是否能应用立即数优化。
|
||||||
auto lhs_vreg = getVReg(lhs);
|
bool rhs_is_imm_opt = false;
|
||||||
auto rhs_vreg = getVReg(rhs);
|
if (auto rhs_const = dynamic_cast<ConstantValue*>(rhs)) {
|
||||||
|
if (bin->getKind() == BinaryInst::kAdd && rhs_const->getInt() >= -2048 && rhs_const->getInt() < 2048) {
|
||||||
if (bin->getKind() == BinaryInst::kAdd) {
|
rhs_is_imm_opt = true;
|
||||||
if (auto rhs_const = dynamic_cast<ConstantValue*>(rhs)) {
|
|
||||||
if (rhs_const->getInt() >= -2048 && rhs_const->getInt() < 2048) {
|
|
||||||
auto instr = std::make_unique<MachineInstr>(RVOpcodes::ADDIW);
|
|
||||||
instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
|
||||||
instr->addOperand(std::make_unique<RegOperand>(lhs_vreg));
|
|
||||||
instr->addOperand(std::make_unique<ImmOperand>(rhs_const->getInt()));
|
|
||||||
CurMBB->addInstruction(std::move(instr));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 仅在不能作为立即数操作数时才需要提前加载。
|
||||||
|
load_val_if_const(lhs);
|
||||||
|
if (!rhs_is_imm_opt) {
|
||||||
|
load_val_if_const(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dest_vreg = getVReg(bin);
|
||||||
|
auto lhs_vreg = getVReg(lhs);
|
||||||
|
|
||||||
|
// [V2优点] 融合 ADDIW 优化。
|
||||||
|
if (rhs_is_imm_opt) {
|
||||||
|
auto rhs_const = dynamic_cast<ConstantValue*>(rhs);
|
||||||
|
auto instr = std::make_unique<MachineInstr>(RVOpcodes::ADDIW);
|
||||||
|
instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||||
|
instr->addOperand(std::make_unique<RegOperand>(lhs_vreg));
|
||||||
|
instr->addOperand(std::make_unique<ImmOperand>(rhs_const->getInt()));
|
||||||
|
CurMBB->addInstruction(std::move(instr));
|
||||||
|
return; // 指令已生成,直接返回。
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rhs_vreg = getVReg(rhs);
|
||||||
|
|
||||||
switch (bin->getKind()) {
|
switch (bin->getKind()) {
|
||||||
case BinaryInst::kAdd: {
|
case BinaryInst::kAdd: {
|
||||||
|
// 区分指针运算(64位)和整数运算(32位)。
|
||||||
RVOpcodes opcode = (lhs->getType()->isPointer() || rhs->getType()->isPointer()) ? RVOpcodes::ADD : RVOpcodes::ADDW;
|
RVOpcodes opcode = (lhs->getType()->isPointer() || rhs->getType()->isPointer()) ? RVOpcodes::ADD : RVOpcodes::ADDW;
|
||||||
auto instr = std::make_unique<MachineInstr>(opcode);
|
auto instr = std::make_unique<MachineInstr>(opcode);
|
||||||
instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||||
@@ -281,7 +326,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
CurMBB->addInstruction(std::move(instr));
|
CurMBB->addInstruction(std::move(instr));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BinaryInst::kICmpEQ: {
|
case BinaryInst::kICmpEQ: { // 等于 (a == b) -> (subw; seqz)
|
||||||
auto sub = std::make_unique<MachineInstr>(RVOpcodes::SUBW);
|
auto sub = std::make_unique<MachineInstr>(RVOpcodes::SUBW);
|
||||||
sub->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
sub->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||||
sub->addOperand(std::make_unique<RegOperand>(lhs_vreg));
|
sub->addOperand(std::make_unique<RegOperand>(lhs_vreg));
|
||||||
@@ -294,7 +339,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
CurMBB->addInstruction(std::move(seqz));
|
CurMBB->addInstruction(std::move(seqz));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BinaryInst::kICmpNE: {
|
case BinaryInst::kICmpNE: { // 不等于 (a != b) -> (subw; snez)
|
||||||
auto sub = std::make_unique<MachineInstr>(RVOpcodes::SUBW);
|
auto sub = std::make_unique<MachineInstr>(RVOpcodes::SUBW);
|
||||||
sub->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
sub->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||||
sub->addOperand(std::make_unique<RegOperand>(lhs_vreg));
|
sub->addOperand(std::make_unique<RegOperand>(lhs_vreg));
|
||||||
@@ -307,7 +352,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
CurMBB->addInstruction(std::move(snez));
|
CurMBB->addInstruction(std::move(snez));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BinaryInst::kICmpLT: {
|
case BinaryInst::kICmpLT: { // 小于 (a < b) -> slt
|
||||||
auto instr = std::make_unique<MachineInstr>(RVOpcodes::SLT);
|
auto instr = std::make_unique<MachineInstr>(RVOpcodes::SLT);
|
||||||
instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||||
instr->addOperand(std::make_unique<RegOperand>(lhs_vreg));
|
instr->addOperand(std::make_unique<RegOperand>(lhs_vreg));
|
||||||
@@ -315,7 +360,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
CurMBB->addInstruction(std::move(instr));
|
CurMBB->addInstruction(std::move(instr));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BinaryInst::kICmpGT: {
|
case BinaryInst::kICmpGT: { // 大于 (a > b) -> (b < a) -> slt
|
||||||
auto instr = std::make_unique<MachineInstr>(RVOpcodes::SLT);
|
auto instr = std::make_unique<MachineInstr>(RVOpcodes::SLT);
|
||||||
instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||||
instr->addOperand(std::make_unique<RegOperand>(rhs_vreg));
|
instr->addOperand(std::make_unique<RegOperand>(rhs_vreg));
|
||||||
@@ -323,7 +368,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
CurMBB->addInstruction(std::move(instr));
|
CurMBB->addInstruction(std::move(instr));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BinaryInst::kICmpLE: {
|
case BinaryInst::kICmpLE: { // 小于等于 (a <= b) -> !(b < a) -> (slt; xori)
|
||||||
auto slt = std::make_unique<MachineInstr>(RVOpcodes::SLT);
|
auto slt = std::make_unique<MachineInstr>(RVOpcodes::SLT);
|
||||||
slt->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
slt->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||||
slt->addOperand(std::make_unique<RegOperand>(rhs_vreg));
|
slt->addOperand(std::make_unique<RegOperand>(rhs_vreg));
|
||||||
@@ -337,7 +382,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
CurMBB->addInstruction(std::move(xori));
|
CurMBB->addInstruction(std::move(xori));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BinaryInst::kICmpGE: {
|
case BinaryInst::kICmpGE: { // 大于等于 (a >= b) -> !(a < b) -> (slt; xori)
|
||||||
auto slt = std::make_unique<MachineInstr>(RVOpcodes::SLT);
|
auto slt = std::make_unique<MachineInstr>(RVOpcodes::SLT);
|
||||||
slt->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
slt->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||||
slt->addOperand(std::make_unique<RegOperand>(lhs_vreg));
|
slt->addOperand(std::make_unique<RegOperand>(lhs_vreg));
|
||||||
@@ -363,7 +408,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
auto src_vreg = getVReg(unary->getOperand());
|
auto src_vreg = getVReg(unary->getOperand());
|
||||||
|
|
||||||
switch (unary->getKind()) {
|
switch (unary->getKind()) {
|
||||||
case UnaryInst::kNeg: {
|
case UnaryInst::kNeg: { // 取负: 0 - src
|
||||||
auto instr = std::make_unique<MachineInstr>(RVOpcodes::SUBW);
|
auto instr = std::make_unique<MachineInstr>(RVOpcodes::SUBW);
|
||||||
instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||||
instr->addOperand(std::make_unique<RegOperand>(PhysicalReg::ZERO));
|
instr->addOperand(std::make_unique<RegOperand>(PhysicalReg::ZERO));
|
||||||
@@ -371,7 +416,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
CurMBB->addInstruction(std::move(instr));
|
CurMBB->addInstruction(std::move(instr));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UnaryInst::kNot: {
|
case UnaryInst::kNot: { // 逻辑非: src == 0 ? 1 : 0
|
||||||
auto instr = std::make_unique<MachineInstr>(RVOpcodes::SEQZ);
|
auto instr = std::make_unique<MachineInstr>(RVOpcodes::SEQZ);
|
||||||
instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
instr->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||||
instr->addOperand(std::make_unique<RegOperand>(src_vreg));
|
instr->addOperand(std::make_unique<RegOperand>(src_vreg));
|
||||||
@@ -386,6 +431,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
|
|
||||||
case DAGNode::CALL: {
|
case DAGNode::CALL: {
|
||||||
auto call = dynamic_cast<CallInst*>(node->value);
|
auto call = dynamic_cast<CallInst*>(node->value);
|
||||||
|
// 处理函数参数,放入a0-a7物理寄存器
|
||||||
for (size_t i = 0; i < node->operands.size() && i < 8; ++i) {
|
for (size_t i = 0; i < node->operands.size() && i < 8; ++i) {
|
||||||
DAGNode* arg_node = node->operands[i];
|
DAGNode* arg_node = node->operands[i];
|
||||||
auto arg_preg = static_cast<PhysicalReg>(static_cast<int>(PhysicalReg::A0) + i);
|
auto arg_preg = static_cast<PhysicalReg>(static_cast<int>(PhysicalReg::A0) + i);
|
||||||
@@ -409,7 +455,8 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
auto call_instr = std::make_unique<MachineInstr>(RVOpcodes::CALL);
|
auto call_instr = std::make_unique<MachineInstr>(RVOpcodes::CALL);
|
||||||
call_instr->addOperand(std::make_unique<LabelOperand>(call->getCallee()->getName()));
|
call_instr->addOperand(std::make_unique<LabelOperand>(call->getCallee()->getName()));
|
||||||
CurMBB->addInstruction(std::move(call_instr));
|
CurMBB->addInstruction(std::move(call_instr));
|
||||||
|
|
||||||
|
// 处理返回值,从a0移动到目标虚拟寄存器
|
||||||
if (!call->getType()->isVoid()) {
|
if (!call->getType()->isVoid()) {
|
||||||
auto mv_instr = std::make_unique<MachineInstr>(RVOpcodes::MV);
|
auto mv_instr = std::make_unique<MachineInstr>(RVOpcodes::MV);
|
||||||
mv_instr->addOperand(std::make_unique<RegOperand>(getVReg(call)));
|
mv_instr->addOperand(std::make_unique<RegOperand>(getVReg(call)));
|
||||||
@@ -423,6 +470,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
auto ret_inst_ir = dynamic_cast<ReturnInst*>(node->value);
|
auto ret_inst_ir = dynamic_cast<ReturnInst*>(node->value);
|
||||||
if (ret_inst_ir && ret_inst_ir->hasReturnValue()) {
|
if (ret_inst_ir && ret_inst_ir->hasReturnValue()) {
|
||||||
Value* ret_val = ret_inst_ir->getReturnValue();
|
Value* ret_val = ret_inst_ir->getReturnValue();
|
||||||
|
// [V2优点] 在RETURN节点内加载常量返回值
|
||||||
if (auto const_val = dynamic_cast<ConstantValue*>(ret_val)) {
|
if (auto const_val = dynamic_cast<ConstantValue*>(ret_val)) {
|
||||||
auto li_instr = std::make_unique<MachineInstr>(RVOpcodes::LI);
|
auto li_instr = std::make_unique<MachineInstr>(RVOpcodes::LI);
|
||||||
li_instr->addOperand(std::make_unique<RegOperand>(PhysicalReg::A0));
|
li_instr->addOperand(std::make_unique<RegOperand>(PhysicalReg::A0));
|
||||||
@@ -435,6 +483,8 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
CurMBB->addInstruction(std::move(mv_instr));
|
CurMBB->addInstruction(std::move(mv_instr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// [V1设计保留] 函数尾声(epilogue)不由RETURN节点生成,
|
||||||
|
// 而是由后续的AsmPrinter或其它Pass统一处理,这是一种常见且有效的模块化设计。
|
||||||
auto ret_mi = std::make_unique<MachineInstr>(RVOpcodes::RET);
|
auto ret_mi = std::make_unique<MachineInstr>(RVOpcodes::RET);
|
||||||
CurMBB->addInstruction(std::move(ret_mi));
|
CurMBB->addInstruction(std::move(ret_mi));
|
||||||
break;
|
break;
|
||||||
@@ -442,11 +492,25 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
|
|
||||||
case DAGNode::BRANCH: {
|
case DAGNode::BRANCH: {
|
||||||
if (auto cond_br = dynamic_cast<CondBrInst*>(node->value)) {
|
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();
|
||||||
|
|
||||||
|
// bne cond, zero, then_label (如果cond不为0,则跳转到then)
|
||||||
auto br_instr = std::make_unique<MachineInstr>(RVOpcodes::BNE);
|
auto br_instr = std::make_unique<MachineInstr>(RVOpcodes::BNE);
|
||||||
br_instr->addOperand(std::make_unique<RegOperand>(getVReg(cond_br->getCondition())));
|
br_instr->addOperand(std::make_unique<RegOperand>(cond_vreg));
|
||||||
br_instr->addOperand(std::make_unique<RegOperand>(PhysicalReg::ZERO));
|
br_instr->addOperand(std::make_unique<RegOperand>(PhysicalReg::ZERO));
|
||||||
br_instr->addOperand(std::make_unique<LabelOperand>(cond_br->getThenBlock()->getName()));
|
br_instr->addOperand(std::make_unique<LabelOperand>(then_bb_name));
|
||||||
CurMBB->addInstruction(std::move(br_instr));
|
CurMBB->addInstruction(std::move(br_instr));
|
||||||
|
|
||||||
|
// 无条件跳转到else块 (如果上面分支未发生)
|
||||||
|
// 注意:在实际的CFG中,这个J指令可能不是必须的,
|
||||||
|
// 因为else块可能是下一个块。但为了通用性,这里生成它。
|
||||||
|
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)) {
|
} else if (auto uncond_br = dynamic_cast<UncondBrInst*>(node->value)) {
|
||||||
auto j_instr = std::make_unique<MachineInstr>(RVOpcodes::J);
|
auto j_instr = std::make_unique<MachineInstr>(RVOpcodes::J);
|
||||||
j_instr->addOperand(std::make_unique<LabelOperand>(uncond_br->getBlock()->getName()));
|
j_instr->addOperand(std::make_unique<LabelOperand>(uncond_br->getBlock()->getName()));
|
||||||
@@ -456,15 +520,58 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case DAGNode::MEMSET: {
|
case DAGNode::MEMSET: {
|
||||||
|
// [V1设计保留] Memset的核心展开逻辑在虚拟寄存器层面是正确的,无需修改。
|
||||||
|
// 之前的bug是由于其输入(地址、值、大小)的虚拟寄存器未被正确初始化。
|
||||||
|
// 在修复了CONSTANT/ALLOCA_ADDR的加载问题后,此处的逻辑现在可以正常工作。
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
std::cout << "[DEBUG] selectNode-MEMSET: Processing MEMSET node." << std::endl;
|
||||||
|
}
|
||||||
auto memset = dynamic_cast<MemsetInst*>(node->value);
|
auto memset = dynamic_cast<MemsetInst*>(node->value);
|
||||||
|
Value* val_to_set = memset->getValue();
|
||||||
|
Value* size_to_set = memset->getSize();
|
||||||
|
Value* ptr_val = memset->getPointer();
|
||||||
|
auto dest_addr_vreg = getVReg(ptr_val);
|
||||||
|
|
||||||
|
if (auto const_val = dynamic_cast<ConstantValue*>(val_to_set)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
std::cout << "[DEBUG] selectNode-MEMSET: Found constant 'value' operand (" << const_val->getInt() << "). Generating LI." << std::endl;
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
if (auto const_size = dynamic_cast<ConstantValue*>(size_to_set)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
std::cout << "[DEBUG] selectNode-MEMSET: Found constant 'size' operand (" << const_size->getInt() << "). Generating LI." << std::endl;
|
||||||
|
}
|
||||||
|
auto li = std::make_unique<MachineInstr>(RVOpcodes::LI);
|
||||||
|
li->addOperand(std::make_unique<RegOperand>(getVReg(const_size)));
|
||||||
|
li->addOperand(std::make_unique<ImmOperand>(const_size->getInt()));
|
||||||
|
CurMBB->addInstruction(std::move(li));
|
||||||
|
}
|
||||||
|
if (auto alloca = dynamic_cast<AllocaInst*>(ptr_val)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
std::cout << "[DEBUG] selectNode-MEMSET: Found 'pointer' operand is an AllocaInst. Generating FRAME_ADDR." << std::endl;
|
||||||
|
}
|
||||||
|
// 生成新的伪指令来获取栈地址
|
||||||
|
auto instr = std::make_unique<MachineInstr>(RVOpcodes::FRAME_ADDR);
|
||||||
|
instr->addOperand(std::make_unique<RegOperand>(dest_addr_vreg)); // 目标虚拟寄存器
|
||||||
|
instr->addOperand(std::make_unique<RegOperand>(getVReg(alloca))); // 源AllocaInst
|
||||||
|
CurMBB->addInstruction(std::move(instr));
|
||||||
|
}
|
||||||
auto r_dest_addr = getVReg(memset->getPointer());
|
auto r_dest_addr = getVReg(memset->getPointer());
|
||||||
auto r_num_bytes = getVReg(memset->getSize());
|
auto r_num_bytes = getVReg(memset->getSize());
|
||||||
auto r_value_byte = getVReg(memset->getValue());
|
auto r_value_byte = getVReg(memset->getValue());
|
||||||
|
|
||||||
|
// 为memset内部逻辑创建新的临时虚拟寄存器
|
||||||
auto r_counter = getNewVReg();
|
auto r_counter = getNewVReg();
|
||||||
auto r_end_addr = getNewVReg();
|
auto r_end_addr = getNewVReg();
|
||||||
auto r_current_addr = getNewVReg();
|
auto r_current_addr = getNewVReg();
|
||||||
auto r_temp_val = getNewVReg();
|
auto r_temp_val = getNewVReg();
|
||||||
|
|
||||||
|
// 定义一系列lambda表达式来简化指令创建
|
||||||
auto add_instr = [&](RVOpcodes op, unsigned rd, unsigned rs1, unsigned rs2) {
|
auto add_instr = [&](RVOpcodes op, unsigned rd, unsigned rs1, unsigned rs2) {
|
||||||
auto i = std::make_unique<MachineInstr>(op);
|
auto i = std::make_unique<MachineInstr>(op);
|
||||||
i->addOperand(std::make_unique<RegOperand>(rd));
|
i->addOperand(std::make_unique<RegOperand>(rd));
|
||||||
@@ -503,12 +610,14 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
CurMBB->addInstruction(std::move(i));
|
CurMBB->addInstruction(std::move(i));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 生成唯一的循环标签
|
||||||
int unique_id = this->local_label_counter++;
|
int unique_id = this->local_label_counter++;
|
||||||
std::string loop_start_label = MFunc->getName() + "_memset_loop_start_" + std::to_string(unique_id);
|
std::string loop_start_label = MFunc->getName() + "_memset_loop_start_" + std::to_string(unique_id);
|
||||||
std::string loop_end_label = MFunc->getName() + "_memset_loop_end_" + std::to_string(unique_id);
|
std::string loop_end_label = MFunc->getName() + "_memset_loop_end_" + std::to_string(unique_id);
|
||||||
std::string remainder_label = MFunc->getName() + "_memset_remainder_" + std::to_string(unique_id);
|
std::string remainder_label = MFunc->getName() + "_memset_remainder_" + std::to_string(unique_id);
|
||||||
std::string done_label = MFunc->getName() + "_memset_done_" + std::to_string(unique_id);
|
std::string done_label = MFunc->getName() + "_memset_done_" + std::to_string(unique_id);
|
||||||
|
|
||||||
|
// 构造64位的填充值
|
||||||
addi_instr(RVOpcodes::ANDI, r_temp_val, r_value_byte, 255);
|
addi_instr(RVOpcodes::ANDI, r_temp_val, r_value_byte, 255);
|
||||||
addi_instr(RVOpcodes::SLLI, r_value_byte, r_temp_val, 8);
|
addi_instr(RVOpcodes::SLLI, r_value_byte, r_temp_val, 8);
|
||||||
add_instr(RVOpcodes::OR, r_temp_val, r_temp_val, r_value_byte);
|
add_instr(RVOpcodes::OR, r_temp_val, r_temp_val, r_value_byte);
|
||||||
@@ -516,6 +625,8 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
add_instr(RVOpcodes::OR, r_temp_val, r_temp_val, r_value_byte);
|
add_instr(RVOpcodes::OR, r_temp_val, r_temp_val, r_value_byte);
|
||||||
addi_instr(RVOpcodes::SLLI, r_value_byte, r_temp_val, 32);
|
addi_instr(RVOpcodes::SLLI, r_value_byte, r_temp_val, 32);
|
||||||
add_instr(RVOpcodes::OR, r_temp_val, r_temp_val, r_value_byte);
|
add_instr(RVOpcodes::OR, r_temp_val, r_temp_val, r_value_byte);
|
||||||
|
|
||||||
|
// 计算循环边界
|
||||||
add_instr(RVOpcodes::ADD, r_end_addr, r_dest_addr, r_num_bytes);
|
add_instr(RVOpcodes::ADD, r_end_addr, r_dest_addr, r_num_bytes);
|
||||||
auto mv = std::make_unique<MachineInstr>(RVOpcodes::MV);
|
auto mv = std::make_unique<MachineInstr>(RVOpcodes::MV);
|
||||||
mv->addOperand(std::make_unique<RegOperand>(r_current_addr));
|
mv->addOperand(std::make_unique<RegOperand>(r_current_addr));
|
||||||
@@ -523,17 +634,22 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
CurMBB->addInstruction(std::move(mv));
|
CurMBB->addInstruction(std::move(mv));
|
||||||
addi_instr(RVOpcodes::ANDI, r_counter, r_num_bytes, -8);
|
addi_instr(RVOpcodes::ANDI, r_counter, r_num_bytes, -8);
|
||||||
add_instr(RVOpcodes::ADD, r_counter, r_dest_addr, r_counter);
|
add_instr(RVOpcodes::ADD, r_counter, r_dest_addr, r_counter);
|
||||||
|
|
||||||
|
// 8字节主循环
|
||||||
label_instr(loop_start_label);
|
label_instr(loop_start_label);
|
||||||
branch_instr(RVOpcodes::BGEU, r_current_addr, r_counter, loop_end_label);
|
branch_instr(RVOpcodes::BGEU, r_current_addr, r_counter, loop_end_label);
|
||||||
store_instr(RVOpcodes::SD, r_temp_val, r_current_addr, 0);
|
store_instr(RVOpcodes::SD, r_temp_val, r_current_addr, 0);
|
||||||
addi_instr(RVOpcodes::ADDI, r_current_addr, r_current_addr, 8);
|
addi_instr(RVOpcodes::ADDI, r_current_addr, r_current_addr, 8);
|
||||||
jump_instr(loop_start_label);
|
jump_instr(loop_start_label);
|
||||||
|
|
||||||
|
// 1字节收尾循环
|
||||||
label_instr(loop_end_label);
|
label_instr(loop_end_label);
|
||||||
label_instr(remainder_label);
|
label_instr(remainder_label);
|
||||||
branch_instr(RVOpcodes::BGEU, r_current_addr, r_end_addr, done_label);
|
branch_instr(RVOpcodes::BGEU, r_current_addr, r_end_addr, done_label);
|
||||||
store_instr(RVOpcodes::SB, r_temp_val, r_current_addr, 0);
|
store_instr(RVOpcodes::SB, r_temp_val, r_current_addr, 0);
|
||||||
addi_instr(RVOpcodes::ADDI, r_current_addr, r_current_addr, 1);
|
addi_instr(RVOpcodes::ADDI, r_current_addr, r_current_addr, 1);
|
||||||
jump_instr(remainder_label);
|
jump_instr(remainder_label);
|
||||||
|
|
||||||
label_instr(done_label);
|
label_instr(done_label);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -590,6 +706,12 @@ std::vector<std::unique_ptr<RISCv64ISel::DAGNode>> RISCv64ISel::build_dag(BasicB
|
|||||||
memset_node->operands.push_back(get_operand_node(memset->getBegin(), value_to_node, nodes_storage));
|
memset_node->operands.push_back(get_operand_node(memset->getBegin(), value_to_node, nodes_storage));
|
||||||
memset_node->operands.push_back(get_operand_node(memset->getSize(), value_to_node, nodes_storage));
|
memset_node->operands.push_back(get_operand_node(memset->getSize(), value_to_node, nodes_storage));
|
||||||
memset_node->operands.push_back(get_operand_node(memset->getValue(), value_to_node, nodes_storage));
|
memset_node->operands.push_back(get_operand_node(memset->getValue(), value_to_node, nodes_storage));
|
||||||
|
if (DEBUG) {
|
||||||
|
std::cout << "[DEBUG] build_dag: Created MEMSET node for: " << memset->getName() << std::endl;
|
||||||
|
for (size_t i = 0; i < memset_node->operands.size(); ++i) {
|
||||||
|
std::cout << " -> Operand " << i << " has kind: " << memset_node->operands[i]->kind << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (auto load = dynamic_cast<LoadInst*>(inst)) {
|
} else if (auto load = dynamic_cast<LoadInst*>(inst)) {
|
||||||
auto load_node = create_node(DAGNode::LOAD, load, value_to_node, nodes_storage);
|
auto load_node = create_node(DAGNode::LOAD, load, value_to_node, nodes_storage);
|
||||||
load_node->operands.push_back(get_operand_node(load->getPointer(), value_to_node, nodes_storage));
|
load_node->operands.push_back(get_operand_node(load->getPointer(), value_to_node, nodes_storage));
|
||||||
|
|||||||
@@ -94,6 +94,18 @@ void RISCv64RegAlloc::eliminateFrameIndices() {
|
|||||||
std::make_unique<RegOperand>(addr_vreg),
|
std::make_unique<RegOperand>(addr_vreg),
|
||||||
std::make_unique<ImmOperand>(0)));
|
std::make_unique<ImmOperand>(0)));
|
||||||
new_instructions.push_back(std::move(sw));
|
new_instructions.push_back(std::move(sw));
|
||||||
|
} else if (instr_ptr->getOpcode() == RVOpcodes::FRAME_ADDR) { // [新] 处理FRAME_ADDR
|
||||||
|
auto& operands = instr_ptr->getOperands();
|
||||||
|
unsigned dest_vreg = static_cast<RegOperand*>(operands[0].get())->getVRegNum();
|
||||||
|
unsigned alloca_vreg = static_cast<RegOperand*>(operands[1].get())->getVRegNum();
|
||||||
|
int offset = frame_info.alloca_offsets.at(alloca_vreg);
|
||||||
|
|
||||||
|
// 将 `frame_addr rd, rs` 展开为 `addi rd, s0, offset`
|
||||||
|
auto addi = std::make_unique<MachineInstr>(RVOpcodes::ADDI);
|
||||||
|
addi->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||||
|
addi->addOperand(std::make_unique<RegOperand>(PhysicalReg::S0)); // 基地址是帧指针 s0
|
||||||
|
addi->addOperand(std::make_unique<ImmOperand>(offset));
|
||||||
|
new_instructions.push_back(std::move(addi));
|
||||||
} else {
|
} else {
|
||||||
new_instructions.push_back(std::move(instr_ptr));
|
new_instructions.push_back(std::move(instr_ptr));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,20 +4,23 @@
|
|||||||
#include "RISCv64LLIR.h"
|
#include "RISCv64LLIR.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
extern int DEBUG;
|
||||||
|
extern int DEEPDEBUG;
|
||||||
|
|
||||||
namespace sysy {
|
namespace sysy {
|
||||||
|
|
||||||
class RISCv64AsmPrinter {
|
class RISCv64AsmPrinter {
|
||||||
public:
|
public:
|
||||||
RISCv64AsmPrinter(MachineFunction* mfunc);
|
RISCv64AsmPrinter(MachineFunction* mfunc);
|
||||||
// 主入口
|
// 主入口
|
||||||
void run(std::ostream& os);
|
void run(std::ostream& os, bool debug = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 打印各个部分
|
// 打印各个部分
|
||||||
void printPrologue();
|
void printPrologue();
|
||||||
void printEpilogue();
|
void printEpilogue();
|
||||||
void printBasicBlock(MachineBasicBlock* mbb);
|
void printBasicBlock(MachineBasicBlock* mbb, bool debug = false);
|
||||||
void printInstruction(MachineInstr* instr);
|
void printInstruction(MachineInstr* instr, bool debug = false);
|
||||||
|
|
||||||
// 辅助函数
|
// 辅助函数
|
||||||
std::string regToString(PhysicalReg reg);
|
std::string regToString(PhysicalReg reg);
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
#include "IR.h"
|
#include "IR.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
extern int DEBUG;
|
||||||
|
extern int DEEPDEBUG;
|
||||||
|
|
||||||
namespace sysy {
|
namespace sysy {
|
||||||
|
|
||||||
// RISCv64CodeGen 现在是一个高层驱动器
|
// RISCv64CodeGen 现在是一个高层驱动器
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#include "RISCv64LLIR.h"
|
#include "RISCv64LLIR.h"
|
||||||
|
|
||||||
|
extern int DEBUG;
|
||||||
|
extern int DEEPDEBUG;
|
||||||
|
|
||||||
namespace sysy {
|
namespace sysy {
|
||||||
|
|
||||||
class RISCv64ISel {
|
class RISCv64ISel {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ enum class RVOpcodes {
|
|||||||
// 新增伪指令,用于解耦栈帧处理
|
// 新增伪指令,用于解耦栈帧处理
|
||||||
FRAME_LOAD, // 从栈帧加载 (AllocaInst)
|
FRAME_LOAD, // 从栈帧加载 (AllocaInst)
|
||||||
FRAME_STORE, // 保存到栈帧 (AllocaInst)
|
FRAME_STORE, // 保存到栈帧 (AllocaInst)
|
||||||
|
FRAME_ADDR, // [新] 获取栈帧变量的地址
|
||||||
};
|
};
|
||||||
|
|
||||||
class MachineOperand;
|
class MachineOperand;
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ int main(int argc, char **argv) {
|
|||||||
// 设置 DEBUG 模式(如果指定了 'asmd')
|
// 设置 DEBUG 模式(如果指定了 'asmd')
|
||||||
if (argStopAfter == "asmd") {
|
if (argStopAfter == "asmd") {
|
||||||
DEBUG = 1;
|
DEBUG = 1;
|
||||||
// DEEPDEBUG = 1;
|
DEEPDEBUG = 1;
|
||||||
}
|
}
|
||||||
sysy::RISCv64CodeGen codegen(moduleIR); // 传入优化后的 moduleIR
|
sysy::RISCv64CodeGen codegen(moduleIR); // 传入优化后的 moduleIR
|
||||||
string asmCode = codegen.code_gen();
|
string asmCode = codegen.code_gen();
|
||||||
|
|||||||
Reference in New Issue
Block a user