Merge branch 'midend' into backend
This commit is contained in:
10
src/IR.cpp
10
src/IR.cpp
@@ -530,8 +530,14 @@ Function * Function::clone(const std::string &suffix) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto ¶m : blocks.front()->getArguments()) {
|
// for (const auto ¶m : blocks.front()->getArguments()) {
|
||||||
newFunction->getEntryBlock()->insertArgument(dynamic_cast<AllocaInst *>(oldNewValueMap.at(param)));
|
// newFunction->getEntryBlock()->insertArgument(dynamic_cast<AllocaInst *>(oldNewValueMap.at(param)));
|
||||||
|
// }
|
||||||
|
for (const auto &arg : arguments) {
|
||||||
|
auto newArg = dynamic_cast<Argument *>(oldNewValueMap.at(arg));
|
||||||
|
if (newArg != nullptr) {
|
||||||
|
newFunction->insertArgument(newArg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newFunction;
|
return newFunction;
|
||||||
|
|||||||
@@ -47,45 +47,45 @@ void RISCv64AsmPrinter::printPrologue() {
|
|||||||
*OS << " addi s0, sp, " << aligned_stack_size << "\n";
|
*OS << " addi s0, sp, " << aligned_stack_size << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// 为函数参数分配寄存器
|
// // 为函数参数分配寄存器
|
||||||
Function* F = MFunc->getFunc();
|
// Function* F = MFunc->getFunc();
|
||||||
if (F && F->getEntryBlock()) {
|
// if (F && F->getEntryBlock()) {
|
||||||
int arg_idx = 0;
|
// int arg_idx = 0;
|
||||||
RISCv64ISel* isel = MFunc->getISel();
|
// RISCv64ISel* isel = MFunc->getISel();
|
||||||
|
|
||||||
// 获取函数所有参数的类型列表
|
// // 获取函数所有参数的类型列表
|
||||||
auto param_types = F->getParamTypes();
|
// auto param_types = F->getParamTypes();
|
||||||
|
|
||||||
for (AllocaInst* alloca_for_param : F->getEntryBlock()->getArguments()) {
|
// for (AllocaInst* alloca_for_param : F->getEntryBlock()->getArguments()) {
|
||||||
if (arg_idx >= 8) break;
|
// if (arg_idx >= 8) break;
|
||||||
|
|
||||||
unsigned vreg = isel->getVReg(alloca_for_param);
|
// unsigned vreg = isel->getVReg(alloca_for_param);
|
||||||
if (frame_info.alloca_offsets.count(vreg)) {
|
// if (frame_info.alloca_offsets.count(vreg)) {
|
||||||
int offset = frame_info.alloca_offsets.at(vreg);
|
// int offset = frame_info.alloca_offsets.at(vreg);
|
||||||
auto arg_reg = static_cast<PhysicalReg>(static_cast<int>(PhysicalReg::A0) + arg_idx);
|
// auto arg_reg = static_cast<PhysicalReg>(static_cast<int>(PhysicalReg::A0) + arg_idx);
|
||||||
|
|
||||||
// 1. 获取当前参数的真实类型
|
// // 1. 获取当前参数的真实类型
|
||||||
// 注意:F->getParamTypes() 返回的是一个 range-based view,需要转换为vector或直接使用
|
// // 注意:F->getParamTypes() 返回的是一个 range-based view,需要转换为vector或直接使用
|
||||||
Type* current_param_type = nullptr;
|
// Type* current_param_type = nullptr;
|
||||||
int temp_idx = 0;
|
// int temp_idx = 0;
|
||||||
for(auto p_type : param_types) {
|
// for(auto p_type : param_types) {
|
||||||
if (temp_idx == arg_idx) {
|
// if (temp_idx == arg_idx) {
|
||||||
current_param_type = p_type;
|
// current_param_type = p_type;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
temp_idx++;
|
// temp_idx++;
|
||||||
}
|
// }
|
||||||
assert(current_param_type && "Could not find parameter type.");
|
// assert(current_param_type && "Could not find parameter type.");
|
||||||
|
|
||||||
// 2. 根据类型决定使用 "sw" 还是 "sd"
|
// // 2. 根据类型决定使用 "sw" 还是 "sd"
|
||||||
const char* store_op = current_param_type->isPointer() ? "sd" : "sw";
|
// const char* store_op = current_param_type->isPointer() ? "sd" : "sw";
|
||||||
|
|
||||||
// 3. 打印正确的存储指令
|
// // 3. 打印正确的存储指令
|
||||||
*OS << " " << store_op << " " << regToString(arg_reg) << ", " << offset << "(s0)\n";
|
// *OS << " " << store_op << " " << regToString(arg_reg) << ", " << offset << "(s0)\n";
|
||||||
}
|
// }
|
||||||
arg_idx++;
|
// arg_idx++;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void RISCv64AsmPrinter::printEpilogue() {
|
void RISCv64AsmPrinter::printEpilogue() {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace sysy {
|
|||||||
|
|
||||||
// DAG节点定义 (内部实现)
|
// DAG节点定义 (内部实现)
|
||||||
struct RISCv64ISel::DAGNode {
|
struct RISCv64ISel::DAGNode {
|
||||||
enum NodeKind { CONSTANT, LOAD, STORE, BINARY, CALL, RETURN, BRANCH, ALLOCA_ADDR, UNARY, MEMSET, GET_ELEMENT_PTR};
|
enum NodeKind {ARGUMENT, CONSTANT, LOAD, STORE, BINARY, CALL, RETURN, BRANCH, ALLOCA_ADDR, UNARY, MEMSET, GET_ELEMENT_PTR};
|
||||||
NodeKind kind;
|
NodeKind kind;
|
||||||
Value* value = nullptr;
|
Value* value = nullptr;
|
||||||
std::vector<DAGNode*> operands;
|
std::vector<DAGNode*> operands;
|
||||||
@@ -51,22 +51,28 @@ std::unique_ptr<MachineFunction> RISCv64ISel::runOnFunction(Function* func) {
|
|||||||
|
|
||||||
// 指令选择主流程
|
// 指令选择主流程
|
||||||
void RISCv64ISel::select() {
|
void RISCv64ISel::select() {
|
||||||
|
// 遍历基本块,为它们创建对应的MachineBasicBlock
|
||||||
for (const auto& bb_ptr : F->getBasicBlocks()) {
|
for (const auto& bb_ptr : F->getBasicBlocks()) {
|
||||||
auto mbb = std::make_unique<MachineBasicBlock>(bb_ptr->getName(), MFunc.get());
|
auto mbb = std::make_unique<MachineBasicBlock>(bb_ptr->getName(), MFunc.get());
|
||||||
bb_map[bb_ptr.get()] = mbb.get();
|
bb_map[bb_ptr.get()] = mbb.get();
|
||||||
MFunc->addBlock(std::move(mbb));
|
MFunc->addBlock(std::move(mbb));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (F->getEntryBlock()) {
|
// 遍历Argument对象,为它们分配虚拟寄存器。
|
||||||
for (auto* arg_alloca : F->getEntryBlock()->getArguments()) {
|
if (F) {
|
||||||
getVReg(arg_alloca);
|
for (Argument* arg : F->getArguments()) {
|
||||||
|
// getVReg会为每个代表参数的Argument对象在vreg_map中创建一个条目。
|
||||||
|
// 这样,当后续的store指令使用这个参数时,就能找到对应的vreg。
|
||||||
|
getVReg(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 遍历基本块,进行指令选择
|
||||||
for (const auto& bb_ptr : F->getBasicBlocks()) {
|
for (const auto& bb_ptr : F->getBasicBlocks()) {
|
||||||
selectBasicBlock(bb_ptr.get());
|
selectBasicBlock(bb_ptr.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 链接MachineBasicBlock的前驱和后继
|
||||||
for (const auto& bb_ptr : F->getBasicBlocks()) {
|
for (const auto& bb_ptr : F->getBasicBlocks()) {
|
||||||
CurMBB = bb_map.at(bb_ptr.get());
|
CurMBB = bb_map.at(bb_ptr.get());
|
||||||
for (auto succ : bb_ptr->getSuccessors()) {
|
for (auto succ : bb_ptr->getSuccessors()) {
|
||||||
@@ -133,10 +139,10 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
// 因此,这里我们只处理当前节点。
|
// 因此,这里我们只处理当前节点。
|
||||||
|
|
||||||
switch (node->kind) {
|
switch (node->kind) {
|
||||||
// [V2优点] 采纳“延迟物化”(Late Materialization)思想。
|
// “延迟物化”(Late Materialization)思想。
|
||||||
// 这两个节点仅作为标记,不直接生成指令。它们的目的是在DAG中保留类型信息。
|
// 这三种节点仅作为标记,不直接生成指令。它们的目的是在DAG中保留类型信息。
|
||||||
// 加载其值的责任,被转移给了使用它们的父节点(如STORE, BINARY等)。
|
// 加载其值的责任,被转移给了使用它们的父节点(如STORE, BINARY等)。
|
||||||
// 这修复了之前版本中“使用未初始化虚拟寄存器”的根本性bug。
|
case DAGNode::ARGUMENT:
|
||||||
case DAGNode::CONSTANT:
|
case DAGNode::CONSTANT:
|
||||||
case DAGNode::ALLOCA_ADDR:
|
case DAGNode::ALLOCA_ADDR:
|
||||||
if (node->value) {
|
if (node->value) {
|
||||||
@@ -937,6 +943,7 @@ RISCv64ISel::DAGNode* RISCv64ISel::create_node(int kind_int, Value* val, std::ma
|
|||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
// 规则1:如果这个Value已经有对应的节点,直接返回
|
||||||
if (value_to_node.count(val_ir)) {
|
if (value_to_node.count(val_ir)) {
|
||||||
return value_to_node[val_ir];
|
return value_to_node[val_ir];
|
||||||
} else if (dynamic_cast<ConstantValue*>(val_ir)) {
|
} else if (dynamic_cast<ConstantValue*>(val_ir)) {
|
||||||
@@ -945,7 +952,14 @@ RISCv64ISel::DAGNode* RISCv64ISel::get_operand_node(Value* val_ir, std::map<Valu
|
|||||||
return create_node(DAGNode::CONSTANT, val_ir, value_to_node, nodes_storage);
|
return create_node(DAGNode::CONSTANT, val_ir, value_to_node, nodes_storage);
|
||||||
} else if (dynamic_cast<AllocaInst*>(val_ir)) {
|
} else if (dynamic_cast<AllocaInst*>(val_ir)) {
|
||||||
return create_node(DAGNode::ALLOCA_ADDR, val_ir, value_to_node, nodes_storage);
|
return create_node(DAGNode::ALLOCA_ADDR, val_ir, value_to_node, nodes_storage);
|
||||||
|
} else if (dynamic_cast<Argument*>(val_ir)) {
|
||||||
|
// Argument 是一个叶子节点,它代表一个在函数入口就可用的值。
|
||||||
|
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);
|
return create_node(DAGNode::LOAD, val_ir, value_to_node, nodes_storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1085,6 +1099,7 @@ void RISCv64ISel::print_dag(const std::vector<std::unique_ptr<DAGNode>>& dag, co
|
|||||||
// 将NodeKind枚举转换为字符串的辅助函数
|
// 将NodeKind枚举转换为字符串的辅助函数
|
||||||
auto get_kind_string = [](DAGNode::NodeKind kind) {
|
auto get_kind_string = [](DAGNode::NodeKind kind) {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
|
case DAGNode::ARGUMENT: return "ARGUMENT";
|
||||||
case DAGNode::CONSTANT: return "CONSTANT";
|
case DAGNode::CONSTANT: return "CONSTANT";
|
||||||
case DAGNode::LOAD: return "LOAD";
|
case DAGNode::LOAD: return "LOAD";
|
||||||
case DAGNode::STORE: return "STORE";
|
case DAGNode::STORE: return "STORE";
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ RISCv64RegAlloc::RISCv64RegAlloc(MachineFunction* mfunc) : MFunc(mfunc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RISCv64RegAlloc::run() {
|
void RISCv64RegAlloc::run() {
|
||||||
|
handleCallingConvention();
|
||||||
eliminateFrameIndices();
|
eliminateFrameIndices();
|
||||||
analyzeLiveness();
|
analyzeLiveness();
|
||||||
buildInterferenceGraph();
|
buildInterferenceGraph();
|
||||||
@@ -25,16 +26,67 @@ void RISCv64RegAlloc::run() {
|
|||||||
rewriteFunction();
|
rewriteFunction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 处理调用约定,预先为函数参数分配物理寄存器。
|
||||||
|
*/
|
||||||
|
void RISCv64RegAlloc::handleCallingConvention() {
|
||||||
|
Function* F = MFunc->getFunc();
|
||||||
|
RISCv64ISel* isel = MFunc->getISel();
|
||||||
|
|
||||||
|
// 获取函数的Argument对象列表
|
||||||
|
if (F) {
|
||||||
|
auto& args = F->getArguments();
|
||||||
|
|
||||||
|
// RISC-V RV64G调用约定:前8个整型/指针参数通过 a0-a7 传递
|
||||||
|
int arg_idx = 0;
|
||||||
|
// 遍历 AllocaInst* 列表
|
||||||
|
for (Argument* arg : args) {
|
||||||
|
if (arg_idx >= 8) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 获取该 Argument 对象对应的虚拟寄存器
|
||||||
|
unsigned vreg = isel->getVReg(arg);
|
||||||
|
|
||||||
|
// 2. 根据参数索引,确定对应的物理寄存器 (a0, a1, ...)
|
||||||
|
auto preg = static_cast<PhysicalReg>(static_cast<int>(PhysicalReg::A0) + arg_idx);
|
||||||
|
|
||||||
|
// 3. 在 color_map 中,将 vreg "预着色" 为对应的物理寄存器
|
||||||
|
color_map[vreg] = preg;
|
||||||
|
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RISCv64RegAlloc::eliminateFrameIndices() {
|
void RISCv64RegAlloc::eliminateFrameIndices() {
|
||||||
StackFrameInfo& frame_info = MFunc->getFrameInfo();
|
StackFrameInfo& frame_info = MFunc->getFrameInfo();
|
||||||
// 初始偏移量,为保存ra和s0留出空间。可以根据你的函数序言调整。
|
// 初始偏移量,为保存ra和s0留出空间。
|
||||||
// 假设序言是 addi sp, sp, -stack_size; sd ra, stack_size-8(sp); sd s0, stack_size-16(sp);
|
// 假设序言是 addi sp, sp, -stack_size; sd ra, stack_size-8(sp); sd s0, stack_size-16(sp);
|
||||||
int current_offset = 16;
|
int current_offset = 16;
|
||||||
|
|
||||||
Function* F = MFunc->getFunc();
|
Function* F = MFunc->getFunc();
|
||||||
RISCv64ISel* isel = MFunc->getISel();
|
RISCv64ISel* isel = MFunc->getISel();
|
||||||
|
|
||||||
|
// 在处理局部变量前,首先为栈参数计算偏移量。
|
||||||
|
if (F) {
|
||||||
|
int arg_idx = 0;
|
||||||
|
for (Argument* arg : F->getArguments()) {
|
||||||
|
// 我们只关心第8个索引及之后的参数(即第9个参数开始)
|
||||||
|
if (arg_idx >= 8) {
|
||||||
|
// 计算偏移量:第一个栈参数(idx=8)在0(s0),第二个(idx=9)在8(s0),以此类推。
|
||||||
|
int offset = (arg_idx - 8) * 8;
|
||||||
|
unsigned vreg = isel->getVReg(arg);
|
||||||
|
|
||||||
// --- MODIFICATION START: 动态计算栈帧大小 ---
|
// 将这个vreg和它的栈偏移存入map。
|
||||||
|
// 我们可以复用alloca_offsets,因为它们都代表“vreg到栈偏移”的映射。
|
||||||
|
frame_info.alloca_offsets[vreg] = offset;
|
||||||
|
}
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理局部变量
|
||||||
// 遍历AllocaInst来计算局部变量所需的总空间
|
// 遍历AllocaInst来计算局部变量所需的总空间
|
||||||
for (auto& bb : F->getBasicBlocks()) {
|
for (auto& bb : F->getBasicBlocks()) {
|
||||||
for (auto& inst : bb->getInstructions()) {
|
for (auto& inst : bb->getInstructions()) {
|
||||||
@@ -49,12 +101,12 @@ void RISCv64RegAlloc::eliminateFrameIndices() {
|
|||||||
|
|
||||||
current_offset += size;
|
current_offset += size;
|
||||||
unsigned alloca_vreg = isel->getVReg(alloca);
|
unsigned alloca_vreg = isel->getVReg(alloca);
|
||||||
|
// 局部变量使用相对于s0的负向偏移
|
||||||
frame_info.alloca_offsets[alloca_vreg] = -current_offset;
|
frame_info.alloca_offsets[alloca_vreg] = -current_offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
frame_info.locals_size = current_offset;
|
frame_info.locals_size = current_offset;
|
||||||
// --- MODIFICATION END ---
|
|
||||||
|
|
||||||
// 遍历所有机器指令,将伪指令展开为真实指令
|
// 遍历所有机器指令,将伪指令展开为真实指令
|
||||||
for (auto& mbb : MFunc->getBlocks()) {
|
for (auto& mbb : MFunc->getBlocks()) {
|
||||||
@@ -325,13 +377,17 @@ void RISCv64RegAlloc::buildInterferenceGraph() {
|
|||||||
void RISCv64RegAlloc::colorGraph() {
|
void RISCv64RegAlloc::colorGraph() {
|
||||||
std::vector<unsigned> sorted_vregs;
|
std::vector<unsigned> sorted_vregs;
|
||||||
for (auto const& [vreg, neighbors] : interference_graph) {
|
for (auto const& [vreg, neighbors] : interference_graph) {
|
||||||
sorted_vregs.push_back(vreg);
|
if (color_map.find(vreg) == color_map.end()) {
|
||||||
|
sorted_vregs.push_back(vreg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 排序
|
||||||
std::sort(sorted_vregs.begin(), sorted_vregs.end(), [&](unsigned a, unsigned b) {
|
std::sort(sorted_vregs.begin(), sorted_vregs.end(), [&](unsigned a, unsigned b) {
|
||||||
return interference_graph[a].size() > interference_graph[b].size();
|
return interference_graph[a].size() > interference_graph[b].size();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 着色
|
||||||
for (unsigned vreg : sorted_vregs) {
|
for (unsigned vreg : sorted_vregs) {
|
||||||
std::set<PhysicalReg> used_colors;
|
std::set<PhysicalReg> used_colors;
|
||||||
for (unsigned neighbor : interference_graph.at(vreg)) {
|
for (unsigned neighbor : interference_graph.at(vreg)) {
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ bool SysYCFGOptUtils::SysYBlockMerge(Function *func) {
|
|||||||
// std::cout << "merge block: " << blockiter->get()->getName() << std::endl;
|
// std::cout << "merge block: " << blockiter->get()->getName() << std::endl;
|
||||||
BasicBlock* block = blockiter->get();
|
BasicBlock* block = blockiter->get();
|
||||||
BasicBlock* nextBlock = blockiter->get()->getSuccessors()[0];
|
BasicBlock* nextBlock = blockiter->get()->getSuccessors()[0];
|
||||||
auto nextarguments = nextBlock->getArguments();
|
// auto nextarguments = nextBlock->getArguments();
|
||||||
// 删除br指令
|
// 删除br指令
|
||||||
if (block->getNumInstructions() != 0) {
|
if (block->getNumInstructions() != 0) {
|
||||||
auto thelastinstinst = block->end();
|
auto thelastinstinst = block->end();
|
||||||
@@ -108,12 +108,6 @@ bool SysYCFGOptUtils::SysYBlockMerge(Function *func) {
|
|||||||
block->getInstructions().emplace_back(institer->release());
|
block->getInstructions().emplace_back(institer->release());
|
||||||
institer = nextBlock->getInstructions().erase(institer);
|
institer = nextBlock->getInstructions().erase(institer);
|
||||||
}
|
}
|
||||||
// 合并参数
|
|
||||||
// TODO:是否需要去重?
|
|
||||||
for (auto &argm : nextarguments) {
|
|
||||||
argm->setParent(block);
|
|
||||||
block->insertArgument(argm);
|
|
||||||
}
|
|
||||||
// 更新前驱后继关系,类似树节点操作
|
// 更新前驱后继关系,类似树节点操作
|
||||||
block->removeSuccessor(nextBlock);
|
block->removeSuccessor(nextBlock);
|
||||||
nextBlock->removePredecessor(block);
|
nextBlock->removePredecessor(block);
|
||||||
|
|||||||
@@ -335,7 +335,6 @@ std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext *ctx){
|
|||||||
module->enterNewScope();
|
module->enterNewScope();
|
||||||
|
|
||||||
auto name = ctx->Ident()->getText();
|
auto name = ctx->Ident()->getText();
|
||||||
std::vector<Type *> paramTypes;
|
|
||||||
std::vector<Type *> paramActualTypes;
|
std::vector<Type *> paramActualTypes;
|
||||||
std::vector<std::string> paramNames;
|
std::vector<std::string> paramNames;
|
||||||
std::vector<std::vector<Value *>> paramDims;
|
std::vector<std::vector<Value *>> paramDims;
|
||||||
@@ -400,12 +399,25 @@ std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext *ctx){
|
|||||||
BasicBlock* entry = function->getEntryBlock();
|
BasicBlock* entry = function->getEntryBlock();
|
||||||
builder.setPosition(entry, entry->end());
|
builder.setPosition(entry, entry->end());
|
||||||
|
|
||||||
|
for(int i = 0; i < paramActualTypes.size(); ++i) {
|
||||||
|
Argument* arg = new Argument(paramActualTypes[i], function, i, paramNames[i]);
|
||||||
|
function->insertArgument(arg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
auto funcArgs = function->getArguments();
|
||||||
|
std::vector<AllocaInst *> allocas;
|
||||||
for (int i = 0; i < paramActualTypes.size(); ++i) {
|
for (int i = 0; i < paramActualTypes.size(); ++i) {
|
||||||
AllocaInst* alloca = builder.createAllocaInst(Type::getPointerType(paramActualTypes[i]), {},paramNames[i]);
|
AllocaInst *alloca = builder.createAllocaInst(Type::getPointerType(paramActualTypes[i]), {}, paramNames[i]);
|
||||||
entry->insertArgument(alloca);
|
allocas.push_back(alloca);
|
||||||
module->addVariable(paramNames[i], alloca);
|
module->addVariable(paramNames[i], alloca);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < paramActualTypes.size(); ++i) {
|
||||||
|
Value *argValue = funcArgs[i];
|
||||||
|
builder.createStoreInst(argValue, allocas[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// 在处理函数体之前,创建一个新的基本块作为函数体的实际入口
|
// 在处理函数体之前,创建一个新的基本块作为函数体的实际入口
|
||||||
// 这样 entryBB 就可以在完成初始化后跳转到这里
|
// 这样 entryBB 就可以在完成初始化后跳转到这里
|
||||||
BasicBlock* funcBodyEntry = function->addBasicBlock("funcBodyEntry_" + name);
|
BasicBlock* funcBodyEntry = function->addBasicBlock("funcBodyEntry_" + name);
|
||||||
@@ -902,18 +914,18 @@ std::any SysYIRGenerator::visitCall(SysYParser::CallContext *ctx) {
|
|||||||
|
|
||||||
// 获取形参列表。`getArguments()` 返回的是 `Argument*` 的集合,
|
// 获取形参列表。`getArguments()` 返回的是 `Argument*` 的集合,
|
||||||
// 每个 `Argument` 代表一个函数形参,其 `getType()` 就是指向形参的类型的指针类型。
|
// 每个 `Argument` 代表一个函数形参,其 `getType()` 就是指向形参的类型的指针类型。
|
||||||
auto formalParamsAlloca = function->getEntryBlock()->getArguments();
|
auto formalParams = function->getArguments();
|
||||||
|
|
||||||
// 检查实参和形参数量是否匹配。
|
// 检查实参和形参数量是否匹配。
|
||||||
if (args.size() != formalParamsAlloca.size()) {
|
if (args.size() != formalParams.size()) {
|
||||||
std::cerr << "Error: Function call argument count mismatch for function '" << funcName << "'." << std::endl;
|
std::cerr << "Error: Function call argument count mismatch for function '" << funcName << "'." << std::endl;
|
||||||
assert(false && "Function call argument count mismatch!");
|
assert(false && "Function call argument count mismatch!");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < args.size(); i++) {
|
for (int i = 0; i < args.size(); i++) {
|
||||||
// 形参的类型 (e.g., i32, float, i32*, [10 x i32]*)
|
// 形参的类型 (e.g., i32, float, i32*, [10 x i32]*)
|
||||||
Type* formalParamExpectedValueType = formalParamsAlloca[i]->getType()->as<PointerType>()->getBaseType();
|
Type* formalParamExpectedValueType = formalParams[i]->getType();
|
||||||
// 实参的实际类型 (e.g., i32, float, i32*, [67 x i32]*)
|
// 实参的实际类型 (e.g., i32, float, i32*, [67 x i32]*)
|
||||||
Type* actualArgType = args[i]->getType();
|
Type* actualArgType = args[i]->getType();
|
||||||
// 如果实参类型与形参类型不匹配,则尝试进行类型转换
|
// 如果实参类型与形参类型不匹配,则尝试进行类型转换
|
||||||
if (formalParamExpectedValueType != actualArgType) {
|
if (formalParamExpectedValueType != actualArgType) {
|
||||||
@@ -1422,10 +1434,12 @@ void Utils::createExternalFunction(
|
|||||||
pBuilder->setPosition(entry, entry->end());
|
pBuilder->setPosition(entry, entry->end());
|
||||||
|
|
||||||
for (int i = 0; i < paramTypes.size(); ++i) {
|
for (int i = 0; i < paramTypes.size(); ++i) {
|
||||||
|
auto arg = new Argument(paramTypes[i], function, i, paramNames[i]);
|
||||||
auto alloca = pBuilder->createAllocaInst(
|
auto alloca = pBuilder->createAllocaInst(
|
||||||
Type::getPointerType(paramTypes[i]), {}, paramNames[i]);
|
Type::getPointerType(paramTypes[i]), {}, paramNames[i]);
|
||||||
entry->insertArgument(alloca);
|
function->insertArgument(arg);
|
||||||
// pModule->addVariable(paramNames[i], alloca);
|
auto store = pBuilder->createStoreInst(arg, alloca);
|
||||||
|
pModule->addVariable(paramNames[i], alloca);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ std::string SysYPrinter::getValueName(Value *value) {
|
|||||||
return std::to_string(constVal->getInt());
|
return std::to_string(constVal->getInt());
|
||||||
} else if (auto constVar = dynamic_cast<ConstantVariable*>(value)) {
|
} else if (auto constVar = dynamic_cast<ConstantVariable*>(value)) {
|
||||||
return constVar->getName(); // 假设ConstantVariable有自己的名字或通过getByIndices获取值
|
return constVar->getName(); // 假设ConstantVariable有自己的名字或通过getByIndices获取值
|
||||||
|
} else if (auto argVar = dynamic_cast<Argument*>(value)) {
|
||||||
|
return "%" + argVar->getName(); // 假设ArgumentVariable有自己的名字
|
||||||
}
|
}
|
||||||
assert(false && "Unknown value type or unable to get value name");
|
assert(false && "Unknown value type or unable to get value name");
|
||||||
return "";
|
return "";
|
||||||
@@ -134,7 +136,7 @@ void SysYPrinter::printFunction(Function *function) {
|
|||||||
|
|
||||||
auto entryBlock = function->getEntryBlock();
|
auto entryBlock = function->getEntryBlock();
|
||||||
const auto &args_types = function->getParamTypes();
|
const auto &args_types = function->getParamTypes();
|
||||||
auto &args = entryBlock->getArguments();
|
auto &args = function->getArguments();
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const auto &args_type : args_types) {
|
for (const auto &args_type : args_types) {
|
||||||
|
|||||||
@@ -468,7 +468,6 @@ public:
|
|||||||
|
|
||||||
// --- End of refactored ConstantValue and related classes ---
|
// --- End of refactored ConstantValue and related classes ---
|
||||||
|
|
||||||
|
|
||||||
class Instruction;
|
class Instruction;
|
||||||
class Function;
|
class Function;
|
||||||
class BasicBlock;
|
class BasicBlock;
|
||||||
@@ -487,7 +486,6 @@ public:
|
|||||||
|
|
||||||
using inst_list = std::list<std::unique_ptr<Instruction>>;
|
using inst_list = std::list<std::unique_ptr<Instruction>>;
|
||||||
using iterator = inst_list::iterator;
|
using iterator = inst_list::iterator;
|
||||||
using arg_list = std::vector<AllocaInst *>;
|
|
||||||
using block_list = std::vector<BasicBlock *>;
|
using block_list = std::vector<BasicBlock *>;
|
||||||
using block_set = std::unordered_set<BasicBlock *>;
|
using block_set = std::unordered_set<BasicBlock *>;
|
||||||
|
|
||||||
@@ -495,7 +493,6 @@ protected:
|
|||||||
|
|
||||||
Function *parent; ///< 从属的函数
|
Function *parent; ///< 从属的函数
|
||||||
inst_list instructions; ///< 拥有的指令序列
|
inst_list instructions; ///< 拥有的指令序列
|
||||||
arg_list arguments; ///< 分配空间后的形式参数列表
|
|
||||||
block_list successors; ///< 前驱列表
|
block_list successors; ///< 前驱列表
|
||||||
block_list predecessors; ///< 后继列表
|
block_list predecessors; ///< 后继列表
|
||||||
bool reachable = false;
|
bool reachable = false;
|
||||||
@@ -515,14 +512,12 @@ public:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
unsigned getNumInstructions() const { return instructions.size(); }
|
unsigned getNumInstructions() const { return instructions.size(); }
|
||||||
unsigned getNumArguments() const { return arguments.size(); }
|
|
||||||
unsigned getNumPredecessors() const { return predecessors.size(); }
|
unsigned getNumPredecessors() const { return predecessors.size(); }
|
||||||
unsigned getNumSuccessors() const { return successors.size(); }
|
unsigned getNumSuccessors() const { return successors.size(); }
|
||||||
Function* getParent() const { return parent; }
|
Function* getParent() const { return parent; }
|
||||||
void setParent(Function *func) { parent = func; }
|
void setParent(Function *func) { parent = func; }
|
||||||
inst_list& getInstructions() { return instructions; }
|
inst_list& getInstructions() { return instructions; }
|
||||||
auto getInstructions_Range() const { return make_range(instructions); }
|
auto getInstructions_Range() const { return make_range(instructions); }
|
||||||
arg_list& getArguments() { return arguments; }
|
|
||||||
block_list& getPredecessors() { return predecessors; }
|
block_list& getPredecessors() { return predecessors; }
|
||||||
void clearPredecessors() { predecessors.clear(); }
|
void clearPredecessors() { predecessors.clear(); }
|
||||||
block_list& getSuccessors() { return successors; }
|
block_list& getSuccessors() { return successors; }
|
||||||
@@ -530,7 +525,6 @@ public:
|
|||||||
iterator begin() { return instructions.begin(); }
|
iterator begin() { return instructions.begin(); }
|
||||||
iterator end() { return instructions.end(); }
|
iterator end() { return instructions.end(); }
|
||||||
iterator terminator() { return std::prev(end()); }
|
iterator terminator() { return std::prev(end()); }
|
||||||
void insertArgument(AllocaInst *inst) { arguments.push_back(inst); }
|
|
||||||
bool hasSuccessor(BasicBlock *block) const {
|
bool hasSuccessor(BasicBlock *block) const {
|
||||||
return std::find(successors.begin(), successors.end(), block) != successors.end();
|
return std::find(successors.begin(), successors.end(), block) != successors.end();
|
||||||
} ///< 判断是否有后继块
|
} ///< 判断是否有后继块
|
||||||
@@ -1065,6 +1059,8 @@ public:
|
|||||||
}; // class UncondBrInst
|
}; // class UncondBrInst
|
||||||
|
|
||||||
//! Conditional branch
|
//! Conditional branch
|
||||||
|
// 这里的args是指向条件分支的两个分支的参数列表但是现在弃用了
|
||||||
|
// 通过mem2reg优化后,数据流分析将不会由arguments来传递
|
||||||
class CondBrInst : public Instruction {
|
class CondBrInst : public Instruction {
|
||||||
friend class IRBuilder;
|
friend class IRBuilder;
|
||||||
friend class Function;
|
friend class Function;
|
||||||
@@ -1090,17 +1086,17 @@ public:
|
|||||||
BasicBlock* getElseBlock() const {
|
BasicBlock* getElseBlock() const {
|
||||||
return dynamic_cast<BasicBlock *>(getOperand(2));
|
return dynamic_cast<BasicBlock *>(getOperand(2));
|
||||||
}
|
}
|
||||||
auto getThenArguments() const {
|
// auto getThenArguments() const {
|
||||||
auto begin = std::next(operand_begin(), 3);
|
// auto begin = std::next(operand_begin(), 3);
|
||||||
auto end = std::next(begin, getThenBlock()->getNumArguments());
|
// // auto end = std::next(begin, getThenBlock()->getNumArguments());
|
||||||
return make_range(begin, end);
|
// return make_range(begin, end);
|
||||||
}
|
// }
|
||||||
auto getElseArguments() const {
|
// auto getElseArguments() const {
|
||||||
auto begin =
|
// auto begin =
|
||||||
std::next(operand_begin(), 3 + getThenBlock()->getNumArguments());
|
// std::next(operand_begin(), 3 + getThenBlock()->getNumArguments());
|
||||||
auto end = operand_end();
|
// auto end = operand_end();
|
||||||
return make_range(begin, end);
|
// return make_range(begin, end);
|
||||||
}
|
// }
|
||||||
|
|
||||||
}; // class CondBrInst
|
}; // class CondBrInst
|
||||||
|
|
||||||
@@ -1243,6 +1239,21 @@ public:
|
|||||||
class GlobalValue;
|
class GlobalValue;
|
||||||
|
|
||||||
|
|
||||||
|
class Argument : public Value {
|
||||||
|
protected:
|
||||||
|
Function *func;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Argument(Type *type, Function *func, int index, const std::string &name = "")
|
||||||
|
: Value(type, name), func(func), index(index) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Function* getParent() const { return func; }
|
||||||
|
int getIndex() const { return index; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Module;
|
class Module;
|
||||||
//! Function definitionclass
|
//! Function definitionclass
|
||||||
class Function : public Value {
|
class Function : public Value {
|
||||||
@@ -1254,6 +1265,7 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
using block_list = std::list<std::unique_ptr<BasicBlock>>;
|
using block_list = std::list<std::unique_ptr<BasicBlock>>;
|
||||||
|
using arg_list = std::vector<Argument *>;
|
||||||
enum FunctionAttribute : uint64_t {
|
enum FunctionAttribute : uint64_t {
|
||||||
PlaceHolder = 0x0UL,
|
PlaceHolder = 0x0UL,
|
||||||
Pure = 0x1UL << 0,
|
Pure = 0x1UL << 0,
|
||||||
@@ -1265,6 +1277,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
Module *parent; ///< 函数的父模块
|
Module *parent; ///< 函数的父模块
|
||||||
block_list blocks; ///< 函数包含的基本块列表
|
block_list blocks; ///< 函数包含的基本块列表
|
||||||
|
arg_list arguments; ///< 函数参数列表
|
||||||
FunctionAttribute attribute = PlaceHolder; ///< 函数属性
|
FunctionAttribute attribute = PlaceHolder; ///< 函数属性
|
||||||
std::set<Function *> callees; ///< 函数调用的函数集合
|
std::set<Function *> callees; ///< 函数调用的函数集合
|
||||||
public:
|
public:
|
||||||
@@ -1289,6 +1302,16 @@ protected:
|
|||||||
auto getBasicBlocks() { return make_range(blocks); }
|
auto getBasicBlocks() { return make_range(blocks); }
|
||||||
block_list& getBasicBlocks_NoRange() { return blocks; }
|
block_list& getBasicBlocks_NoRange() { return blocks; }
|
||||||
BasicBlock* getEntryBlock() { return blocks.front().get(); }
|
BasicBlock* getEntryBlock() { return blocks.front().get(); }
|
||||||
|
void insertArgument(Argument *arg) { arguments.push_back(arg); }
|
||||||
|
arg_list& getArguments() { return arguments; }
|
||||||
|
unsigned getNumArguments() const { return arguments.size(); }
|
||||||
|
Argument* getArgument(unsigned index) const {
|
||||||
|
assert(index < arguments.size() && "Argument index out of bounds");
|
||||||
|
return arguments[index];
|
||||||
|
} ///< 获取位置为index的参数
|
||||||
|
auto getArgumentsRange() const {
|
||||||
|
return make_range(arguments.begin(), arguments.end());
|
||||||
|
} ///< 获取参数列表的范围
|
||||||
void removeBasicBlock(BasicBlock *blockToRemove) {
|
void removeBasicBlock(BasicBlock *blockToRemove) {
|
||||||
auto is_same_ptr = [blockToRemove](const std::unique_ptr<BasicBlock> &ptr) { return ptr.get() == blockToRemove; };
|
auto is_same_ptr = [blockToRemove](const std::unique_ptr<BasicBlock> &ptr) { return ptr.get() == blockToRemove; };
|
||||||
blocks.remove_if(is_same_ptr);
|
blocks.remove_if(is_same_ptr);
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ private:
|
|||||||
// 辅助函数,获取指令的Use/Def集合
|
// 辅助函数,获取指令的Use/Def集合
|
||||||
void getInstrUseDef(MachineInstr* instr, LiveSet& use, LiveSet& def);
|
void getInstrUseDef(MachineInstr* instr, LiveSet& use, LiveSet& def);
|
||||||
|
|
||||||
|
// 辅助函数,处理调用约定
|
||||||
|
void handleCallingConvention();
|
||||||
|
|
||||||
MachineFunction* MFunc;
|
MachineFunction* MFunc;
|
||||||
|
|
||||||
// 活跃性分析结果
|
// 活跃性分析结果
|
||||||
|
|||||||
Reference in New Issue
Block a user