From 722c1373ac8e8140faaf9917368a825fb63a341e Mon Sep 17 00:00:00 2001 From: ZhuangYumin Date: Tue, 22 Oct 2024 12:52:34 +0000 Subject: [PATCH] first trial --- Makefile | 2 +- include/IR/IR_basic.h | 2 ++ include/opt/gen.h | 31 +++++++++++++++++++++++++++++-- include/opt/liveanalysis.h | 1 + src/opt/regalloc.cpp | 10 +++++++++- 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 036d19f..95fdb88 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ build: @cd $(BUILD_DIR) && $(MAKE) -j4 acturalrun: - @cd $(BUILD_DIR) && ./zmxcc /dev/stdin -o /dev/stdout 2>/dev/null + @cd $(BUILD_DIR) && ./zmxcc /dev/stdin -o /dev/stdout --optimize-all 2>/dev/null # 运行目标,运行生成的可执行文件 run: acturalrun @cat $(BUILTIN_ASM) >>/dev/stdout diff --git a/include/IR/IR_basic.h b/include/IR/IR_basic.h index 9bf5415..d3b5a6f 100644 --- a/include/IR/IR_basic.h +++ b/include/IR/IR_basic.h @@ -269,6 +269,8 @@ class CallItem : public ActionItem { std::vector args_ty; std::vector args_val_full; + size_t move_sp_up; + CallItem() = default; void RecursivePrint(std::ostream &os) const { if (std::holds_alternative(return_type)) { diff --git a/include/opt/gen.h b/include/opt/gen.h index f7ccd52..3e21189 100644 --- a/include/opt/gen.h +++ b/include/opt/gen.h @@ -160,6 +160,8 @@ inline void FetchValueToReg(std::string original_val, std::string &out_reg, Func // immediate value out_reg = AllocateTmpReg(available_tmp_regs); StoreImmToReg(std::stoi(original_val), out_reg, code_lines); + } else if (original_val == "null") { + out_reg = "x0"; } else { throw std::runtime_error("Unknown value type"); } @@ -412,6 +414,10 @@ inline void GenerateASM(std::shared_ptr act, std::vector(act)) { // no need to to further process, as callling convention is handled in reg alloc code_lines.push_back("call " + call_act->func_name_raw); + if (call_act->move_sp_up) { + size_t delta = 4 * call_act->move_sp_up; + code_lines.push_back("addi sp, sp, " + std::to_string(delta)); + } } else if (auto phi_act = std::dynamic_pointer_cast(act)) { throw std::runtime_error("Phi should not be in the layout"); } else if (auto select_act = std::dynamic_pointer_cast(act)) { @@ -440,9 +446,30 @@ inline void GenerateASM(std::shared_ptr act, std::vectorresult_full, res_reg, layout, code_lines, available_tmp_regs); } } else if (auto load_spilled_args_act = std::dynamic_pointer_cast(act)) { - throw std::runtime_error("Not implemented"); + std::string res_reg; + bool need_extra_store = false; + if (load_spilled_args_act->var_full[0] == '$') { + res_reg = ExtractRegName(load_spilled_args_act->var_full); + } else if (load_spilled_args_act->var_full[0] == '#') { + need_extra_store = true; + res_reg = AllocateTmpReg(available_tmp_regs); + } else { + throw std::runtime_error("Unknown result type"); + } + size_t offset = 4 * (load_spilled_args_act->arg_id - 8); + code_lines.push_back("lw " + res_reg + ", " + std::to_string(offset) + "(s0)"); + if (need_extra_store) { + WriteToSpilledVar(load_spilled_args_act->var_full, res_reg, layout, code_lines, available_tmp_regs); + } } else if (auto store_spilled_args_act = std::dynamic_pointer_cast(act)) { - throw std::runtime_error("Not implemented"); + if (store_spilled_args_act->move_sp_down) { + size_t delta = 4 * store_spilled_args_act->move_sp_down; + code_lines.push_back("addi sp, sp, -" + std::to_string(delta)); + } + std::string val_reg; + FetchValueToReg(store_spilled_args_act->var_full, val_reg, layout, code_lines, available_tmp_regs); + size_t offset = 4 * (store_spilled_args_act->arg_id - 8); + code_lines.push_back("sw " + val_reg + ", " + std::to_string(offset) + "(sp)"); } else if (auto move_act = std::dynamic_pointer_cast(act)) { std::string src_reg; FetchValueToReg(move_act->src_full, src_reg, layout, code_lines, available_tmp_regs); diff --git a/include/opt/liveanalysis.h b/include/opt/liveanalysis.h index e8ca237..2d47078 100644 --- a/include/opt/liveanalysis.h +++ b/include/opt/liveanalysis.h @@ -35,6 +35,7 @@ class StoreSpilledArgs : public ActionItem { size_t arg_id; // [8,+inf) std::string var_full; LLVMType ty; + size_t move_sp_down; StoreSpilledArgs() = default; void RecursivePrint(std::ostream &os) const { os << "[Persudo] store spilled args " << var_full << "with id=" << arg_id << "\n"; diff --git a/src/opt/regalloc.cpp b/src/opt/regalloc.cpp index a9ebb10..5fc3436 100644 --- a/src/opt/regalloc.cpp +++ b/src/opt/regalloc.cpp @@ -100,15 +100,23 @@ void EnforcePhysicalRegs(CFGType &cfg) { caller_saved_regs_to_process.erase(arg_regs[i]); } if (call_act->args_val_full.size() > 8) { - for (size_t i = 8; i < call_act->args_val_full.size(); i++) { + for (size_t i = call_act->args_val_full.size() - 1; i >= 8; i--) { auto new_store = std::make_shared(); new_store->arg_id = i; new_store->var_full = call_act->args_val_full[i]; new_store->ty = call_act->args_ty[i]; block->actions.insert(it_act, new_store); + if (i == call_act->args_val_full.size() - 1) { + new_store->move_sp_down = call_act->args_val_full.size() - 8; + } else { + new_store->move_sp_down = 0; + } } + call_act->move_sp_up = call_act->args_val_full.size() - 8; call_act->args_val_full.resize(8); call_act->args_ty.resize(8); + } else { + call_act->move_sp_up = 0; } for (auto reg : caller_saved_regs_to_process) { auto new_def = std::make_shared();