From 0061c91ebcd81a2d16716892053fd31cdf32ac99 Mon Sep 17 00:00:00 2001 From: tyfkda Date: Thu, 12 Oct 2023 17:59:55 +0900 Subject: [PATCH] Prepare dump_ir to apply optimization or not Split `gen_defun` to generating code and applying optimization/register allocation. --- src/_debug/dump_ir.c | 40 +++++++++++++++++++++++++++++----------- src/cc/backend/codegen.c | 32 ++++++++++++++++++++++---------- src/cc/backend/codegen.h | 7 +++++++ 3 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/_debug/dump_ir.c b/src/_debug/dump_ir.c index 7d6891b3f..ec1fa9bad 100644 --- a/src/_debug/dump_ir.c +++ b/src/_debug/dump_ir.c @@ -8,6 +8,7 @@ #include "fe_misc.h" #include "ir.h" #include "lexer.h" +#include "optimize.h" #include "parser.h" #include "regalloc.h" #include "table.h" @@ -24,11 +25,13 @@ static void dump_vreg(FILE *fp, VReg *vreg) { static const char *kSize[] = {"b", "w", "d", ""}; if (vreg->flag & VRF_CONST) { fprintf(fp, "(%" PRId64 ")", vreg->fixnum); - } else { + } else if (vreg->phys >= 0) { char regtype = 'R'; if (vreg->flag & VRF_FLONUM) regtype = 'F'; fprintf(fp, "%c%d%s", regtype, vreg->phys, kSize[vreg->vsize], vreg->virt); + } else { + fprintf(fp, "v%d", vreg->virt); } } @@ -215,18 +218,35 @@ static void dump_func_ir(Function *func) { } void do_dump_ir(Vector *decls) { + if (decls == NULL) + return; + for (int i = 0, len = decls->len; i < len; ++i) { Declaration *decl = decls->data[i]; - if (decl == NULL) + if (decl == NULL || decl->kind != DCL_DEFUN) + continue; + Function *func = decl->defun.func; + if (!gen_defun(func)) continue; - switch (decl->kind) { - case DCL_DEFUN: - dump_func_ir(decl->defun.func); - break; - case DCL_VARDECL: - break; - } + curfunc = func; + FuncBackend *fnbe = func->extra; + + optimize(fnbe->ra, fnbe->bbcon); + + prepare_register_allocation(func); + // tweak_irs(fnbe); + analyze_reg_flow(fnbe->bbcon); + + alloc_physical_registers(fnbe->ra, fnbe->bbcon); + map_virtual_to_physical_registers(fnbe->ra); + detect_living_registers(fnbe->ra, fnbe->bbcon); + + alloc_stack_variables_onto_stack_frame(func); + + curfunc = NULL; + + dump_func_ir(func); } } @@ -271,8 +291,6 @@ int main(int argc, char *argv[]) { if (compile_error_count != 0) exit(1); - gen(toplevel); - do_dump_ir(toplevel); return 0; diff --git a/src/cc/backend/codegen.c b/src/cc/backend/codegen.c index dcf0be12b..3d28182d4 100644 --- a/src/cc/backend/codegen.c +++ b/src/cc/backend/codegen.c @@ -654,7 +654,7 @@ void gen_stmt(Stmt *stmt) { //////////////////////////////////////////////// -static void prepare_register_allocation(Function *func) { +void prepare_register_allocation(Function *func) { bool require_stack_frame = (func->flag & FUNCF_STACK_MODIFIED) != 0; // Handle function parameters first. const Vector *params = func->type->func.params; @@ -732,7 +732,7 @@ static void prepare_register_allocation(Function *func) { } } -static void map_virtual_to_physical_registers(RegAlloc *ra) { +void map_virtual_to_physical_registers(RegAlloc *ra) { for (int i = 0, vreg_count = ra->vregs->len; i < vreg_count; ++i) { VReg *vreg = ra->vregs->data[i]; if (vreg == NULL) @@ -743,7 +743,7 @@ static void map_virtual_to_physical_registers(RegAlloc *ra) { } // Detect living registers for each instruction. -static void detect_living_registers(RegAlloc *ra, BBContainer *bbcon) { +void detect_living_registers(RegAlloc *ra, BBContainer *bbcon) { int maxbit = ra->settings->phys_max + ra->settings->fphys_max; unsigned long living_pregs = 0; assert((int)sizeof(living_pregs) * CHAR_BIT >= maxbit); @@ -809,7 +809,7 @@ static void detect_living_registers(RegAlloc *ra, BBContainer *bbcon) { #undef VREGFOR } -static void alloc_stack_variables_onto_stack_frame(Function *func) { +void alloc_stack_variables_onto_stack_frame(Function *func) { FuncBackend *fnbe = func->extra; size_t frame_size = fnbe->frame_size; @@ -880,14 +880,14 @@ static void alloc_stack_variables_onto_stack_frame(Function *func) { fnbe->frame_size = frame_size; } -static void gen_defun(Function *func) { +bool gen_defun(Function *func) { if (func->scopes == NULL) // Prototype definition - return; + return false; VarInfo *funcvi = scope_find(global_scope, func->name, NULL); if (funcvi != NULL && satisfy_inline_criteria(funcvi) && !(funcvi->storage & VS_STATIC)) { // Omit inline function: func->extra preserves the value (NULL). - return; + return false; } curfunc = func; @@ -924,6 +924,15 @@ static void gen_defun(Function *func) { set_curbb(fnbe->ret_bb); curbb = NULL; + curfunc = NULL; + curra = NULL; + return true; +} + +static void gen_defun_after(Function *func) { + FuncBackend *fnbe = func->extra; + curfunc = func; + optimize(fnbe->ra, fnbe->bbcon); prepare_register_allocation(func); @@ -937,16 +946,19 @@ static void gen_defun(Function *func) { alloc_stack_variables_onto_stack_frame(func); curfunc = NULL; - curra = NULL; } -void gen_decl(Declaration *decl) { +static void gen_decl(Declaration *decl) { if (decl == NULL) return; switch (decl->kind) { case DCL_DEFUN: - gen_defun(decl->defun.func); + { + Function *func = decl->defun.func; + if (gen_defun(func)) + gen_defun_after(func); + } break; case DCL_VARDECL: break; diff --git a/src/cc/backend/codegen.h b/src/cc/backend/codegen.h index e308b5074..a47ab5b04 100644 --- a/src/cc/backend/codegen.h +++ b/src/cc/backend/codegen.h @@ -10,6 +10,7 @@ typedef struct BB BB; typedef struct Expr Expr; typedef struct Function Function; +typedef struct RegAlloc RegAlloc; typedef struct Stmt Stmt; typedef struct StructInfo StructInfo; typedef struct Type Type; @@ -54,3 +55,9 @@ typedef struct { void enumerate_register_params( Function *func, RegParamInfo iargs[], int max_ireg, RegParamInfo fargs[], int max_freg, int *piarg_count, int *pfarg_count); + +bool gen_defun(Function *func); +void prepare_register_allocation(Function *func); +void map_virtual_to_physical_registers(RegAlloc *ra); +void detect_living_registers(RegAlloc *ra, BBContainer *bbcon); +void alloc_stack_variables_onto_stack_frame(Function *func);