Skip to content

Commit

Permalink
Revise for self-hosting at commit 2b5d7b6
Browse files Browse the repository at this point in the history
Loading an address that pointing to .data section increments the
stack index of `live_kill` by 1 when analyzing. The inline libc has
~700 times loading in single basic block. So the macro
`MAX_ANALYSIS_STACK_SIZE` is set to 700 here.
  • Loading branch information
vacantron committed Dec 11, 2023
1 parent ef73e2b commit aa878b6
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 60 deletions.
65 changes: 57 additions & 8 deletions src/arm-codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,39 @@ void cfg_flatten()
ph2_ir = ph2_ir->next) {
switch (ph2_ir->op) {
case OP_load_constant:
if (ph2_ir->src0 < 0)
elf_offset += 12;
else if (ph2_ir->src0 > 255)
elf_offset += 8;
else
elf_offset += 4;
break;
case OP_global_address_of:
if (ph2_ir->src0 < 0)
abort();
else if (ph2_ir->src0 > 255)
elf_offset += 12;
else
elf_offset += 4;
break;
case OP_assign:
case OP_global_store:
elf_offset += 4;
break;
case OP_global_store:
if (ph2_ir->src1 < 0)
abort();
else if (ph2_ir->src1 > 4095)
elf_offset += 16;
else
elf_offset += 4;
break;
default:
printf("Unknown opcode\n");
abort();
}
}
/* jump to main */
elf_offset += 4;
/* prepare `argc` and `argv`, then proceed to `main` function */
elf_offset += 24;

fn_t *fn;
for (fn = FUNC_LIST.head; fn; fn = fn->next) {
Expand Down Expand Up @@ -84,6 +105,7 @@ void cfg_flatten()
}
break;
case OP_address_of:
case OP_global_address_of:
flatten_ir = add_ph2_ir(OP_address_of);
memcpy(flatten_ir, insn, sizeof(ph2_ir_t));

Expand Down Expand Up @@ -126,7 +148,6 @@ void cfg_flatten()
elf_offset += 4;

break;
case OP_global_address_of:
case OP_read:
case OP_write:
case OP_jump:
Expand Down Expand Up @@ -226,23 +247,51 @@ void code_generate()

switch (ph2_ir->op) {
case OP_load_constant:
emit(__mov_i(__AL, rd, ph2_ir->src0));
if (ph2_ir->src0 < 0) {
emit(__movw(__AL, __r8, -ph2_ir->src0));
emit(__movt(__AL, __r8, -ph2_ir->src0));
emit(__rsb_i(__AL, rd, 0, __r8));
} else if (ph2_ir->src0 > 255) {
emit(__movw(__AL, rd, ph2_ir->src0));
emit(__movt(__AL, rd, ph2_ir->src0));
} else
emit(__mov_i(__AL, rd, ph2_ir->src0));
break;
case OP_global_address_of:
emit(__add_i(__AL, rd, __r12, ph2_ir->src0));
if (ph2_ir->src0 < 0)
abort();
else if (ph2_ir->src0 > 255) {
emit(__movw(__AL, __r8, ph2_ir->src0));
emit(__movt(__AL, __r8, ph2_ir->src0));
emit(__add_r(__AL, rd, __r12, __r8));
} else
emit(__add_i(__AL, rd, __r12, ph2_ir->src0));
break;
case OP_assign:
emit(__mov_r(__AL, rd, rn));
break;
case OP_global_store:
emit(__sw(__AL, rn, __r12, ph2_ir->src1));
if (ph2_ir->src1 < 0)
abort();
else if (ph2_ir->src1 > 4095) {
emit(__movw(__AL, __r8, ph2_ir->src1));
emit(__movt(__AL, __r8, ph2_ir->src1));
emit(__add_r(__AL, __r8, __r12, __r8));
emit(__sw(__AL, rn, __r8, 0));
} else
emit(__sw(__AL, rn, __r12, ph2_ir->src1));
break;
default:
printf("Unknown opcode\n");
abort();
}
}
/* jump to main */
/* prepare `argc` and `argv`, then proceed to `main` function */
emit(__movw(__AL, __r8, GLOBAL_FUNC.stack_size));
emit(__movt(__AL, __r8, GLOBAL_FUNC.stack_size));
emit(__add_r(__AL, __r8, __r12, __r8));
emit(__lw(__AL, __r0, __r8, 0));
emit(__add_i(__AL, __r1, __r8, 4));
emit(__b(__AL, MAIN_BB->elf_offset - elf_code_idx));

int i;
Expand Down
23 changes: 17 additions & 6 deletions src/cfront.c
Original file line number Diff line number Diff line change
Expand Up @@ -1729,6 +1729,8 @@ void read_lvalue(lvalue_t *lvalue,
strcpy(vd->var_name, gen_name());
vd->init_val = 1;
side_effect[se_idx].dest = vd;
side_effect[se_idx].src0 = NULL;
side_effect[se_idx].src1 = NULL;
se_idx++;

side_effect[se_idx].op = lex_accept(T_increment) ? OP_add : OP_sub;
Expand All @@ -1744,15 +1746,17 @@ void read_lvalue(lvalue_t *lvalue,

if (lvalue->is_reference) {
side_effect[se_idx].op = OP_write;
side_effect[se_idx].src0 = vd;
side_effect[se_idx].dest = opstack_pop();
side_effect[se_idx].src1 = vd;
side_effect[se_idx].src0 = opstack_pop();
side_effect[se_idx].size = lvalue->size;
side_effect[se_idx].dest = NULL;
opstack_push(t);
se_idx++;
} else {
side_effect[se_idx].op = OP_assign;
side_effect[se_idx].src0 = vd;
side_effect[se_idx].dest = operand_stack[operand_stack_idx - 1];
side_effect[se_idx].src1 = NULL;
se_idx++;
}
} else {
Expand Down Expand Up @@ -1780,10 +1784,6 @@ void read_ternary_operation(block_t *parent, basic_block_t **bb)
if (!lex_accept(T_question))
return;

basic_block_t *n = bb_create(parent);
bb_connect(*bb, n, NEXT);
*bb = n;

/* ternary-operator */
ph1_ir = add_ph1_ir(OP_branch);
ph1_ir->dest = opstack_pop();
Expand Down Expand Up @@ -1849,6 +1849,7 @@ void read_ternary_operation(block_t *parent, basic_block_t **bb)
strcpy(vd->var_name, end_label);
ph1_ir->src0 = vd;

var->is_ternary_ret = 1;
opstack_push(var);
*bb = end_ternary;
}
Expand Down Expand Up @@ -2693,6 +2694,15 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)

strcpy(var_break->var_name, vd->var_name);
break_exit_idx--;

int i, dangling = 1;
for (i = 0; i < MAX_BB_PRED; i++)
if (switch_end->prev[i].bb)
dangling = 0;

if (dangling)
return NULL;

return switch_end;
}

Expand Down Expand Up @@ -2936,6 +2946,7 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
/* multiple (partial) declarations */
nv = require_var(parent);
read_partial_var_decl(nv, var); /* partial */
add_insn(parent, bb, OP_allocat, nv, NULL, NULL, 0, NULL);
add_symbol(bb, nv);
if (lex_accept(T_assign)) {
read_expr(parent, &bb);
Expand Down
16 changes: 9 additions & 7 deletions src/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
#define MAX_VAR_LEN 32
#define MAX_TYPE_LEN 32
#define MAX_PARAMS 8
#define MAX_LOCALS 900
#define MAX_LOCALS 1450
#define MAX_FIELDS 32
#define MAX_FUNCS 256
#define MAX_FUNC_TRIES 1536
#define MAX_BLOCKS 750
#define MAX_BLOCKS 900
#define MAX_TYPES 64
#define MAX_IR_INSTR 32768
#define MAX_BB_PRED 16
#define MAX_BB_PRED 128
#define MAX_BB_DOM_SUCC 64
#define MAX_GLOBAL_IR 256
#define MAX_LABEL 4096
Expand All @@ -37,6 +37,7 @@
#define MAX_CASES 128
#define MAX_NESTING 128
#define MAX_OPERAND_STACK_SIZE 32
#define MAX_ANALYSIS_STACK_SIZE 700

#define ELF_START 0x10000
#define PTR_SIZE 4
Expand Down Expand Up @@ -152,6 +153,7 @@ struct var {
rename_t rename;
ref_block_list_t ref_block_list; /* blocks which kill variable */
int consumed;
int is_ternary_ret;
};

typedef struct var var_t;
Expand Down Expand Up @@ -326,13 +328,13 @@ struct basic_block {
struct basic_block *idom;
struct basic_block *rpo_next;
struct basic_block *rpo_r_next;
var_t *live_gen[64];
var_t *live_gen[MAX_ANALYSIS_STACK_SIZE];
int live_gen_idx;
var_t *live_kill[64];
var_t *live_kill[MAX_ANALYSIS_STACK_SIZE];
int live_kill_idx;
var_t *live_in[64];
var_t *live_in[MAX_ANALYSIS_STACK_SIZE];
int live_in_idx;
var_t *live_out[64];
var_t *live_out[MAX_ANALYSIS_STACK_SIZE];
int live_out_idx;
int rpo;
int rpo_r;
Expand Down
37 changes: 27 additions & 10 deletions src/reg-alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,26 +227,39 @@ void reg_alloc()
global_insn = global_insn->next) {
ph2_ir_t *ir;
int dest, src0;
int sz;

switch (global_insn->opcode) {
case OP_allocat:
sz = global_insn->rd->is_ptr
? PTR_SIZE
: find_type(global_insn->rd->type_name)->size;
if (global_insn->rd->array_size) {
GLOBAL_FUNC.stack_size += (global_insn->rd->array_size * sz);
global_insn->rd->offset = GLOBAL_FUNC.stack_size;
GLOBAL_FUNC.stack_size += PTR_SIZE;
src0 = GLOBAL_FUNC.stack_size;
if (global_insn->rd->is_ptr)
GLOBAL_FUNC.stack_size +=
(PTR_SIZE * global_insn->rd->array_size);
else {
type_t *type = find_type(global_insn->rd->type_name);
GLOBAL_FUNC.stack_size +=
(global_insn->rd->array_size * type->size);
}

dest =
prepare_dest(GLOBAL_FUNC.fn->bbs, global_insn->rd, -1, -1);
ir = bb_add_ph2_ir(GLOBAL_FUNC.fn->bbs, OP_global_address_of);
ir->src0 = global_insn->rd->offset;
ir->src0 = src0;
ir->dest = dest;
spill_var(GLOBAL_FUNC.fn->bbs, global_insn->rd, dest);
} else {
global_insn->rd->offset = GLOBAL_FUNC.stack_size;
GLOBAL_FUNC.stack_size += sz;
if (global_insn->rd->is_ptr)
GLOBAL_FUNC.stack_size += PTR_SIZE;
else if (strcmp(global_insn->rd->type_name, "int") &&
strcmp(global_insn->rd->type_name, "char"))
GLOBAL_FUNC.stack_size +=
find_type(global_insn->rd->type_name)->size;
else
/* `char` is aligned to one byte for the convenience */
GLOBAL_FUNC.stack_size += 4;
}
break;
case OP_load_constant:
Expand All @@ -262,6 +275,9 @@ void reg_alloc()
ir->src0 = src0;
ir->dest = dest;
spill_var(GLOBAL_FUNC.fn->bbs, global_insn->rd, dest);
/* release the unused constant number in register manually */
REGS[src0].polluted = 0;
REGS[src0].var = NULL;
break;
default:
printf("Unsupported global operation\n");
Expand Down Expand Up @@ -331,6 +347,8 @@ void reg_alloc()
insn->rd->array_size == 0)
break;

insn->rd->offset = fn->func->stack_size;
fn->func->stack_size += PTR_SIZE;
src0 = fn->func->stack_size;

if (insn->rd->is_ptr)
Expand All @@ -343,9 +361,6 @@ void reg_alloc()
else
fn->func->stack_size += sz;

insn->rd->offset = fn->func->stack_size;
fn->func->stack_size += PTR_SIZE;

dest = prepare_dest(bb, insn->rd, -1, -1);
ir = bb_add_ph2_ir(bb, OP_address_of);
ir->src0 = src0;
Expand Down Expand Up @@ -444,6 +459,8 @@ void reg_alloc()
ir = bb_add_ph2_ir(bb, OP_assign);
ir->src0 = src0;
ir->dest = args++;
REGS[ir->dest].var = insn->rs1;
REGS[ir->dest].polluted = 0;
break;
case OP_call:
if (!find_func(insn->str)->num_params)
Expand Down
Loading

0 comments on commit aa878b6

Please sign in to comment.