Skip to content

Commit

Permalink
Prepare dump_ir to apply optimization or not
Browse files Browse the repository at this point in the history
Split `gen_defun` to generating code
and applying optimization/register allocation.
  • Loading branch information
tyfkda committed Oct 17, 2023
1 parent cd7bb42 commit 0061c91
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 21 deletions.
40 changes: 29 additions & 11 deletions src/_debug/dump_ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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<v%d>", regtype, vreg->phys, kSize[vreg->vsize], vreg->virt);
} else {
fprintf(fp, "v%d", vreg->virt);
}
}

Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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;
Expand Down
32 changes: 22 additions & 10 deletions src/cc/backend/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down
7 changes: 7 additions & 0 deletions src/cc/backend/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

0 comments on commit 0061c91

Please sign in to comment.