diff --git a/examples/0001-basic.c b/examples/0001-basic.c index 4a92297..558d5b1 100644 --- a/examples/0001-basic.c +++ b/examples/0001-basic.c @@ -31,18 +31,12 @@ int main(int argc, char **argv) ir_consistency_check(); - ir_init(&ctx, IR_FUNCTION, IR_CONSTS_LIMIT_MIN, IR_INSNS_LIMIT_MIN); + ir_init(&ctx, IR_FUNCTION | IR_OPT_FOLDING, IR_CONSTS_LIMIT_MIN, IR_INSNS_LIMIT_MIN); gen_myfunc(&ctx); - ir_build_def_use_lists(&ctx); - ir_build_cfg(&ctx); - ir_match(&ctx); - ir_assign_virtual_registers(&ctx); - ir_compute_dessa_moves(&ctx); - size_t size; - void *entry = ir_emit_code(&ctx, &size); + void *entry = ir_jit_compile(&ctx, 2, &size); if (entry) { printf("42 - 24 = %d\n", ((myfunc_t)entry)(42, 24)); } diff --git a/examples/0001-while.c b/examples/0001-while.c index 5873d3a..302fb86 100644 --- a/examples/0001-while.c +++ b/examples/0001-while.c @@ -41,18 +41,12 @@ int main(int argc, char **argv) ir_consistency_check(); - ir_init(&ctx, IR_FUNCTION, IR_CONSTS_LIMIT_MIN, IR_INSNS_LIMIT_MIN); + ir_init(&ctx, IR_FUNCTION | IR_OPT_FOLDING, IR_CONSTS_LIMIT_MIN, IR_INSNS_LIMIT_MIN); gen_myfunc(&ctx); - ir_build_def_use_lists(&ctx); - ir_build_cfg(&ctx); - ir_match(&ctx); - ir_assign_virtual_registers(&ctx); - ir_compute_dessa_moves(&ctx); - size_t size; - void *entry = ir_emit_code(&ctx, &size); + void *entry = ir_jit_compile(&ctx, 2, &size); if (entry) { printf("%d\n", ((myfunc_t)entry)()); } diff --git a/examples/0005-basic-runner-func.c b/examples/0005-basic-runner-func.c index c0bb7b5..c6e0e3f 100644 --- a/examples/0005-basic-runner-func.c +++ b/examples/0005-basic-runner-func.c @@ -47,18 +47,12 @@ int main(int argc, char **argv) ir_consistency_check(); - ir_init(&ctx, IR_FUNCTION, 256, 1024); + ir_init(&ctx, IR_FUNCTION | IR_OPT_FOLDING, 256, 1024); gen_myfunc(&ctx); - ir_build_def_use_lists(&ctx); - ir_build_cfg(&ctx); - ir_match(&ctx); - ir_assign_virtual_registers(&ctx); - ir_compute_dessa_moves(&ctx); - size_t size; - void *entry = ir_emit_code(&ctx, &size); + void *entry = ir_jit_compile(&ctx, 2, &size); if (entry) { run(entry); } diff --git a/ir.h b/ir.h index ae006b7..283c4f5 100644 --- a/ir.h +++ b/ir.h @@ -757,6 +757,61 @@ uint32_t ir_cpuinfo(void); /* Deoptimization helpers */ const void *ir_emit_exitgroup(uint32_t first_exit_point, uint32_t exit_points_per_group, const void *exit_addr, void *code_buffer, size_t code_buffer_size, size_t *size_ptr); +/* A reference IR JIT compiler */ +IR_ALWAYS_INLINE void *ir_jit_compile(ir_ctx *ctx, int opt_level, size_t *size) +{ + if (opt_level == 0) { + if (ctx->flags & IR_OPT_FOLDING) { + // IR_ASSERT(0 && "IR_OPT_FOLDING is incompatible with -O0"); + return NULL; + } + ctx->flags &= ~(IR_OPT_CFG | IR_OPT_CODEGEN); + + ir_build_def_use_lists(ctx); + + if (!ir_build_cfg(ctx) + || !ir_match(ctx) + || !ir_assign_virtual_registers(ctx) + || !ir_compute_dessa_moves(ctx)) { + return NULL; + } + + return ir_emit_code(ctx, size); + } else if (opt_level == 1 || opt_level == 2) { + if (!(ctx->flags & IR_OPT_FOLDING)) { + // IR_ASSERT(0 && "IR_OPT_FOLDING must be set in ir_init() for -O1 and -O2"); + return NULL; + } + ctx->flags |= IR_OPT_CFG | IR_OPT_CODEGEN; + + ir_build_def_use_lists(ctx); + + if (opt_level == 2 + && !ir_sccp(ctx)) { + return NULL; + } + + if (!ir_build_cfg(ctx) + || !ir_build_dominators_tree(ctx) + || !ir_find_loops(ctx) + || !ir_gcm(ctx) + || !ir_schedule(ctx) + || !ir_match(ctx) + || !ir_assign_virtual_registers(ctx) + || !ir_compute_live_ranges(ctx) + || !ir_coalesce(ctx) + || !ir_reg_alloc(ctx) + || !ir_schedule_blocks(ctx)) { + return NULL; + } + + return ir_emit_code(ctx, size); + } else { + // IR_ASSERT(0 && "wrong optimization level"); + return NULL; + } +} + /* IR Memmory Allocation */ #ifndef ir_mem_malloc # define ir_mem_malloc malloc